diff --git a/CHANGELOG.md b/CHANGELOG.md index 623e320d3c..68a6dfeeb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,22 @@ # Changelog -## Version 1.5.4 - released January 12, 2020 +## Version 1.6.0 - released February 7, 2021 + +### Features/Improvements +- New Table design supports multiple columns +- Graph tile supports linking multi-column tables +- Teacher-only curriculum content (solutions) +- Support for separate teacher guide content +- Smaller bundle size + +### Asset Sizes + +| File | Size | % Change from Previous Release | +|---|---|---| +| index.css | 389,427 bytes | -22.5% | +| index.js | 4,148,062 bytes | -16.4% | + +## Version 1.5.4 - released January 12, 2021 ### Features/Improvements - Content updates (Comparing and Scaling) diff --git a/cypress/integration/clue/branch/student_tests/canvas_test_spec.js b/cypress/integration/clue/branch/student_tests/canvas_test_spec.js index 443bfa9508..87d9c8c1fb 100644 --- a/cypress/integration/clue/branch/student_tests/canvas_test_spec.js +++ b/cypress/integration/clue/branch/student_tests/canvas_test_spec.js @@ -69,6 +69,7 @@ context('Test Canvas', function () { clueCanvas.addTile('table'); clueCanvas.addTile('text'); textToolTile.enterText('this is ' + studentWorkspace); + textToolTile.getTextTile().should('be.visible').and('contain', studentWorkspace); }); it('verify copy of personal workspace', function () { canvas.copyDocument(copyTitle); @@ -162,7 +163,7 @@ context('Test Canvas', function () { //1-up view has 4-up button visible and 1-up canvas clueCanvas.getFourUpViewToggle().should('be.visible'); canvas.getSingleCanvas().should('be.visible'); - clueCanvas.getFourUpView().should('not.be.visible'); + clueCanvas.getFourUpView().should('not.exist'); clueCanvas.openFourUpView(); //4-up view is visible and 1-up button is visible clueCanvas.getFourToOneUpViewToggle().should('be.visible'); @@ -176,7 +177,7 @@ context('Test Canvas', function () { clueCanvas.openOneUpViewFromFourUp(); canvas.getSingleCanvas().should('be.visible'); clueCanvas.getFourUpViewToggle().should('be.visible'); - clueCanvas.getFourUpView().should('not.be.visible'); + clueCanvas.getFourUpView().should('not.exist'); }); it('verify share button', function () { diff --git a/cypress/integration/clue/branch/student_tests/nav_panel_test_spec.js b/cypress/integration/clue/branch/student_tests/nav_panel_test_spec.js index 769a631517..6c297e3e27 100644 --- a/cypress/integration/clue/branch/student_tests/nav_panel_test_spec.js +++ b/cypress/integration/clue/branch/student_tests/nav_panel_test_spec.js @@ -95,7 +95,7 @@ describe('Test nav panel tabs', function () { cy.getCanvasItemTitle('learning-log').contains(this.title).should('not.exist'); cy.getCanvasItemTitle('learning-log').should('have.length', 1); }); - it('verify user starter learning log canvas exists', function () { + it('verify user starter learning log canvas exists', function () { cy.getCanvasItemTitle('learning-log').contains("My First Learning Log").should('be.visible'); }); it('verify open of learning log canvas into main workspace', function () { @@ -134,7 +134,7 @@ describe('Test nav panel tabs', function () { cy.openDocumentThumbnail('problem-workspaces', this.title); }); it('will verify that published canvas does not have Edit button', function () { - cy.get('.edit-button').should("not.be.visible"); + cy.get('.edit-button').should("not.exist"); }); }); }); diff --git a/cypress/integration/clue/branch/student_tests/table_tool_spec.js b/cypress/integration/clue/branch/student_tests/table_tool_spec.js index 29f5fedfee..7b479f6664 100644 --- a/cypress/integration/clue/branch/student_tests/table_tool_spec.js +++ b/cypress/integration/clue/branch/student_tests/table_tool_spec.js @@ -15,7 +15,7 @@ let canvas = new Canvas, cy.waitForSpinner(); }); -context('Table Tool Tile',function(){ +context.skip('Table Tool Tile',function(){ describe('test menu functions of table', function(){ it('will add a table to canvas', function(){ clueCanvas.addTile('table'); diff --git a/cypress/integration/clue/branch/teacher_tests/teacher_dashboard_spec.js b/cypress/integration/clue/branch/teacher_tests/teacher_dashboard_spec.js index 3cb69dc08b..464d7cc4f2 100644 --- a/cypress/integration/clue/branch/teacher_tests/teacher_dashboard_spec.js +++ b/cypress/integration/clue/branch/teacher_tests/teacher_dashboard_spec.js @@ -40,7 +40,7 @@ const baseUrl = `${Cypress.config("baseUrl")}`; dashboard.getProblemDropdown().click({ force: true }); dashboard.getProblemList().should('not.have.class','show'); // Check class list UI and visibility - dashboard.getClassList().should('not.have.class','show'); + dashboard.getClassList().should('not.exist'); dashboard.getClassDropdown().should('contain',clueData.teacherName); // dashboard.getClassDropdown().should('contain',tempClass.className); dashboard.getClassDropdown().should('be.visible').click({ force: true }); @@ -93,7 +93,7 @@ const baseUrl = `${Cypress.config("baseUrl")}`; describe('Header element functionality', () => { it('verify dashboard/workspace switch changes workspace view', () => { dashboard.getViewToggle('Dashboard').should('be.visible').and('have.class', 'selected'); - clueCanvas.getSingleWorkspace().should('not.be.visible'); + clueCanvas.getSingleWorkspace().should('not.exist'); dashboard.getViewToggle('Workspace').should('be.visible').and('not.have.class', 'selected'); dashboard.getViewToggle('Workspace').click({ force: true }); dashboard.getViewToggle("Workspace").should('have.class', 'selected'); diff --git a/cypress/integration/clue/smoke/single_student_canvas_test.js b/cypress/integration/clue/smoke/single_student_canvas_test.js index 4350487132..5a095a122c 100644 --- a/cypress/integration/clue/smoke/single_student_canvas_test.js +++ b/cypress/integration/clue/smoke/single_student_canvas_test.js @@ -59,7 +59,7 @@ context('single student functional test',()=>{ //1-up view has 4-up button visible and 1-up canvas clueCanvas.getFourUpViewToggle().should('be.visible'); canvas.getSingleCanvas().should('be.visible'); - clueCanvas.getFourUpView().should('not.be.visible'); + clueCanvas.getFourUpView().should('not.exist'); clueCanvas.openFourUpView(); //4-up view is visible and 1-up button is visible clueCanvas.getFourToOneUpViewToggle().should('be.visible'); @@ -73,7 +73,7 @@ context('single student functional test',()=>{ clueCanvas.openOneUpViewFromFourUp(); canvas.getSingleCanvas().should('be.visible'); clueCanvas.getFourUpViewToggle().should('be.visible'); - clueCanvas.getFourUpView().should('not.be.visible'); + clueCanvas.getFourUpView().should('not.exist'); }); it('verify share button', function(){ @@ -119,11 +119,12 @@ context('single student functional test',()=>{ }); }); context('save and restore of canvas', function(){ - let canvas1='Document 1'; + // let canvas1='Document 1'; let canvas2='Document 2'; before(function(){ //Open a different document to see if original document is restored - canvas.copyDocument(canvas1); + // canvas.copyDocument(canvas1); canvas.createNewExtraDocumentFromFileMenu(canvas2, "my-work"); + canvas.getPersonalDocTitle().should('contain', canvas2); textToolTile.getTextTile().should('not.exist'); }); describe('verify that canvas is saved from various locations', function(){ @@ -165,7 +166,7 @@ context('single student functional test',()=>{ cy.get(".document-tabs.class-work .documents-panel .canvas-area").find('.geometry-content').should('exist'); cy.get(".document-tabs.class-work .documents-panel .canvas-area").find('.drawing-tool').should('exist'); cy.get(".document-tabs.class-work .documents-panel .canvas-area").find('.image-tool').should('exist'); - cy.get(".document-tabs.class-work .documents-panel .canvas-area").find('.neo-codap-case-table').should('exist'); + // cy.get(".document-tabs.class-work .documents-panel .canvas-area").find('.neo-codap-case-table').should('exist'); }); }); }); diff --git a/package-lock.json b/package-lock.json index b7d43dcf32..e2db0d01bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,30 +1,9 @@ { "name": "collaborative-learning", - "version": "1.5.4", + "version": "1.6.0", "lockfileVersion": 1, "requires": true, "dependencies": { - "@ag-grid-community/client-side-row-model": { - "version": "22.1.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/client-side-row-model/-/client-side-row-model-22.1.1.tgz", - "integrity": "sha512-lLqYuYHngb8pC5wSnBRYzszBDeTxRkz6TmxpVP8CHYM3QSqe2xUTp8KFkzO+RrlySB7uCCx1ym0bOR4vRkkaAw==", - "requires": { - "@ag-grid-community/core": "~22.1.1" - } - }, - "@ag-grid-community/core": { - "version": "22.1.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/core/-/core-22.1.1.tgz", - "integrity": "sha512-x9dLUnsIsa+3bsweYKM8UWN42b7i5FDMvGpabAlOS0jAcJRs6krZUBK8XyZwzCc2vELuoBQ6VrKG5RWCN2phjg==" - }, - "@ag-grid-community/react": { - "version": "22.1.2", - "resolved": "https://registry.npmjs.org/@ag-grid-community/react/-/react-22.1.2.tgz", - "integrity": "sha512-rouYVp1NFq4hwBMmazMQ5sxcmwImcBOQC2YVn5/39uoP8+3UHTNcimMbKviAN+jMQgIHDlBTTBgjDAH9mMKmQg==", - "requires": { - "prop-types": "^15.6.2" - } - }, "@babel/code-frame": { "version": "7.5.5", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", @@ -34,15 +13,10 @@ } }, "@babel/compat-data": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.11.0.tgz", - "integrity": "sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "semver": "^5.5.0" - } + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", + "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "dev": true }, "@babel/core": { "version": "7.11.4", @@ -235,145 +209,157 @@ } } }, - "@babel/helper-builder-react-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz", - "integrity": "sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg==", + "@babel/helper-compilation-targets": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/compat-data": "^7.12.5", + "@babel/helper-validator-option": "^7.12.1", + "browserslist": "^4.14.5", + "semver": "^5.5.0" }, "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" } }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", - "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" - } + "caniuse-lite": { + "version": "1.0.30001183", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001183.tgz", + "integrity": "sha512-7JkwTEE1hlRKETbCFd8HDZeLiQIUcl8rC6JgNjvHCNaxOeNmQ9V4LvQXRUsKIV2CC73qKxljwVhToaA3kLRqTw==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.650", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.650.tgz", + "integrity": "sha512-j6pRuNylFBbroG6NB8Lw/Im9oDY74s2zWHBP5TmdYg73cBuL6cz//SMgolVa0gIJk/DSL+kO7baJ1DSXW1FUZg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "dev": true } } }, - "@babel/helper-builder-react-jsx-experimental": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.10.5.tgz", - "integrity": "sha512-Buewnx6M4ttG+NLkKyt7baQn7ScC/Td+e99G914fRU8fGIUivDDgVIQeDHFa5e4CRSJQt58WpNHhsAZgtzVhsg==", + "@babel/helper-create-class-features-plugin": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", + "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", "dev": true, "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", - "@babel/types": "^7.10.5" + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.10.4" }, "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/highlight": "^7.10.4" } }, - "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } - } - } - }, - "@babel/helper-compilation-targets": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz", - "integrity": "sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.10.4", - "browserslist": "^4.12.0", - "invariant": "^2.2.4", - "levenary": "^1.1.1", - "semver": "^5.5.0" - } - }, - "@babel/helper-create-class-features-plugin": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz", - "integrity": "sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A==", - "dev": true, - "requires": { - "@babel/helper-function-name": "^7.10.4", - "@babel/helper-member-expression-to-functions": "^7.10.5", - "@babel/helper-optimise-call-expression": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", - "@babel/helper-split-export-declaration": "^7.10.4" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@babel/highlight": "^7.10.4" + "@babel/types": "^7.12.10" } }, - "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.7" } }, - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + }, + "dependencies": { + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + } } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -386,32 +372,58 @@ } }, "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } } } }, @@ -742,70 +754,38 @@ } }, "@babel/helper-remap-async-to-generator": { - "version": "7.11.4", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz", - "integrity": "sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", + "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", "@babel/helper-wrap-function": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.1" }, "dependencies": { - "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, - "requires": { - "@babel/highlight": "^7.10.4" - } - }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", - "dev": true, - "requires": { - "@babel/types": "^7.10.4" - } - }, - "@babel/highlight": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", - "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/types": "^7.12.10" } }, - "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true }, - "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" - } - }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1001,21 +981,27 @@ } }, "@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz", - "integrity": "sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.1" }, "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1036,6 +1022,12 @@ "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", "dev": true }, + "@babel/helper-validator-option": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz", + "integrity": "sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw==", + "dev": true + }, "@babel/helper-wrap-function": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz", @@ -1307,30 +1299,30 @@ "integrity": "sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A==" }, "@babel/plugin-proposal-async-generator-functions": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz", - "integrity": "sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", + "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1", "@babel/plugin-syntax-async-generators": "^7.8.0" } }, "@babel/plugin-proposal-class-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz", - "integrity": "sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-proposal-dynamic-import": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz", - "integrity": "sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", + "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1338,9 +1330,9 @@ } }, "@babel/plugin-proposal-export-namespace-from": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz", - "integrity": "sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", + "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1348,9 +1340,9 @@ } }, "@babel/plugin-proposal-json-strings": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz", - "integrity": "sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", + "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1358,9 +1350,9 @@ } }, "@babel/plugin-proposal-logical-assignment-operators": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz", - "integrity": "sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", + "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1368,9 +1360,9 @@ } }, "@babel/plugin-proposal-nullish-coalescing-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz", - "integrity": "sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1378,9 +1370,9 @@ } }, "@babel/plugin-proposal-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz", - "integrity": "sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", + "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1388,20 +1380,20 @@ } }, "@babel/plugin-proposal-object-rest-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz", - "integrity": "sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.10.4" + "@babel/plugin-transform-parameters": "^7.12.1" } }, "@babel/plugin-proposal-optional-catch-binding": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz", - "integrity": "sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", + "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", @@ -1409,23 +1401,23 @@ } }, "@babel/plugin-proposal-optional-chaining": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz", - "integrity": "sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", + "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, "@babel/plugin-proposal-private-methods": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz", - "integrity": "sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", + "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", "dev": true, "requires": { - "@babel/helper-create-class-features-plugin": "^7.10.4", + "@babel/helper-create-class-features-plugin": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4" } }, @@ -1503,9 +1495,9 @@ } }, "@babel/plugin-syntax-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz", - "integrity": "sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz", + "integrity": "sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1575,41 +1567,47 @@ } }, "@babel/plugin-transform-arrow-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz", - "integrity": "sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", + "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-async-to-generator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz", - "integrity": "sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", + "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", "dev": true, "requires": { - "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-module-imports": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-remap-async-to-generator": "^7.10.4" + "@babel/helper-remap-async-to-generator": "^7.12.1" }, "dependencies": { "@babel/helper-module-imports": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.5" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1617,27 +1615,27 @@ } }, "@babel/plugin-transform-block-scoped-functions": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz", - "integrity": "sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", + "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-block-scoping": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz", - "integrity": "sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", + "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-classes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz", - "integrity": "sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", + "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", "dev": true, "requires": { "@babel/helper-annotate-as-pure": "^7.10.4", @@ -1645,58 +1643,107 @@ "@babel/helper-function-name": "^7.10.4", "@babel/helper-optimise-call-expression": "^7.10.4", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", "@babel/helper-split-export-declaration": "^7.10.4", "globals": "^11.1.0" }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + }, + "dependencies": { + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + } } }, "@babel/helper-split-export-declaration": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz", - "integrity": "sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "@babel/types": "^7.11.0" + "@babel/types": "^7.12.11" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -1709,48 +1756,74 @@ } }, "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } } } }, "@babel/plugin-transform-computed-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz", - "integrity": "sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", + "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-destructuring": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz", - "integrity": "sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", + "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" @@ -1767,18 +1840,18 @@ } }, "@babel/plugin-transform-duplicate-keys": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz", - "integrity": "sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", + "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-exponentiation-operator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz", - "integrity": "sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", + "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", "dev": true, "requires": { "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", @@ -1786,18 +1859,18 @@ } }, "@babel/plugin-transform-for-of": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz", - "integrity": "sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", + "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz", - "integrity": "sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", + "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", "dev": true, "requires": { "@babel/helper-function-name": "^7.10.4", @@ -1805,34 +1878,40 @@ }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" } }, "@babel/helper-function-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz", - "integrity": "sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/template": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/types": "^7.12.10" } }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", @@ -1845,29 +1924,29 @@ } }, "@babel/parser": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.11.5.tgz", - "integrity": "sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, "@babel/template": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.4.tgz", - "integrity": "sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA==", + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/parser": "^7.10.4", - "@babel/types": "^7.10.4" + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" } @@ -1875,1571 +1954,3487 @@ } }, "@babel/plugin-transform-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz", - "integrity": "sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", + "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-member-expression-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz", - "integrity": "sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", + "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.10.4" } }, "@babel/plugin-transform-modules-amd": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz", - "integrity": "sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.5", - "@babel/helper-plugin-utils": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-commonjs": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz", - "integrity": "sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-simple-access": "^7.10.4", - "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-systemjs": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz", - "integrity": "sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", + "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", "dev": true, "requires": { - "@babel/helper-hoist-variables": "^7.10.4", - "@babel/helper-module-transforms": "^7.10.5", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", "babel-plugin-dynamic-import-node": "^2.3.3" - } - }, - "@babel/plugin-transform-modules-umd": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz", - "integrity": "sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA==", - "dev": true, - "requires": { - "@babel/helper-module-transforms": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz", - "integrity": "sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4" - } - }, - "@babel/plugin-transform-new-target": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz", - "integrity": "sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-object-super": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz", - "integrity": "sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-replace-supers": "^7.10.4" - } - }, - "@babel/plugin-transform-parameters": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz", - "integrity": "sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw==", - "dev": true, - "requires": { - "@babel/helper-get-function-arity": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { - "@babel/helper-get-function-arity": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz", - "integrity": "sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/highlight": "^7.10.4" } }, - "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } - } - } - }, - "@babel/plugin-transform-property-literals": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz", - "integrity": "sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-react-constant-elements": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.10.4.tgz", - "integrity": "sha512-cYmQBW1pXrqBte1raMkAulXmi7rjg3VI6ZLg9QIic8Hq7BtYXaWuZSxsr2siOMI6SWwpxjWfnwhTUrd7JlAV7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-react-display-name": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz", - "integrity": "sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz", - "integrity": "sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx": "^7.10.4", - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" - } - }, - "@babel/plugin-transform-react-jsx-development": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.4.tgz", - "integrity": "sha512-RM3ZAd1sU1iQ7rI2dhrZRZGv0aqzNQMbkIUCS1txYpi9wHQ2ZHNjo5TwX+UD6pvFW4AbWqLVYvKy5qJSAyRGjQ==", - "dev": true, - "requires": { - "@babel/helper-builder-react-jsx-experimental": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" - } - }, - "@babel/plugin-transform-react-jsx-self": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz", - "integrity": "sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" - } - }, - "@babel/plugin-transform-react-jsx-source": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz", - "integrity": "sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-jsx": "^7.10.4" - } - }, - "@babel/plugin-transform-react-pure-annotations": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz", - "integrity": "sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", "@babel/helper-validator-identifier": "^7.10.4", - "lodash": "^4.17.19", - "to-fast-properties": "^2.0.0" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" } - } - } - }, - "@babel/plugin-transform-regenerator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz", - "integrity": "sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw==", - "dev": true, - "requires": { - "regenerator-transform": "^0.14.2" - } - }, - "@babel/plugin-transform-reserved-words": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz", - "integrity": "sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-shorthand-properties": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz", - "integrity": "sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-spread": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz", - "integrity": "sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-skip-transparent-expression-wrappers": "^7.11.0" - } - }, - "@babel/plugin-transform-sticky-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz", - "integrity": "sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/helper-regex": "^7.10.4" - } - }, - "@babel/plugin-transform-template-literals": { - "version": "7.10.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz", - "integrity": "sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw==", - "dev": true, - "requires": { - "@babel/helper-annotate-as-pure": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - }, - "dependencies": { - "@babel/helper-annotate-as-pure": { + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } + }, + "@babel/highlight": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz", - "integrity": "sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA==", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" } } } }, - "@babel/plugin-transform-typeof-symbol": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz", - "integrity": "sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-unicode-escapes": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz", - "integrity": "sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-transform-unicode-regex": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz", - "integrity": "sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A==", - "dev": true, - "requires": { - "@babel/helper-create-regexp-features-plugin": "^7.10.4", - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/preset-env": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.11.5.tgz", - "integrity": "sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA==", + "@babel/plugin-transform-modules-commonjs": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", + "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", "dev": true, "requires": { - "@babel/compat-data": "^7.11.0", - "@babel/helper-compilation-targets": "^7.10.4", - "@babel/helper-module-imports": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-proposal-async-generator-functions": "^7.10.4", - "@babel/plugin-proposal-class-properties": "^7.10.4", - "@babel/plugin-proposal-dynamic-import": "^7.10.4", - "@babel/plugin-proposal-export-namespace-from": "^7.10.4", - "@babel/plugin-proposal-json-strings": "^7.10.4", - "@babel/plugin-proposal-logical-assignment-operators": "^7.11.0", - "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.4", - "@babel/plugin-proposal-numeric-separator": "^7.10.4", - "@babel/plugin-proposal-object-rest-spread": "^7.11.0", - "@babel/plugin-proposal-optional-catch-binding": "^7.10.4", - "@babel/plugin-proposal-optional-chaining": "^7.11.0", - "@babel/plugin-proposal-private-methods": "^7.10.4", - "@babel/plugin-proposal-unicode-property-regex": "^7.10.4", - "@babel/plugin-syntax-async-generators": "^7.8.0", - "@babel/plugin-syntax-class-properties": "^7.10.4", - "@babel/plugin-syntax-dynamic-import": "^7.8.0", - "@babel/plugin-syntax-export-namespace-from": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.0", - "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", - "@babel/plugin-syntax-numeric-separator": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", - "@babel/plugin-syntax-optional-chaining": "^7.8.0", - "@babel/plugin-syntax-top-level-await": "^7.10.4", - "@babel/plugin-transform-arrow-functions": "^7.10.4", - "@babel/plugin-transform-async-to-generator": "^7.10.4", - "@babel/plugin-transform-block-scoped-functions": "^7.10.4", - "@babel/plugin-transform-block-scoping": "^7.10.4", - "@babel/plugin-transform-classes": "^7.10.4", - "@babel/plugin-transform-computed-properties": "^7.10.4", - "@babel/plugin-transform-destructuring": "^7.10.4", - "@babel/plugin-transform-dotall-regex": "^7.10.4", - "@babel/plugin-transform-duplicate-keys": "^7.10.4", - "@babel/plugin-transform-exponentiation-operator": "^7.10.4", - "@babel/plugin-transform-for-of": "^7.10.4", - "@babel/plugin-transform-function-name": "^7.10.4", - "@babel/plugin-transform-literals": "^7.10.4", - "@babel/plugin-transform-member-expression-literals": "^7.10.4", - "@babel/plugin-transform-modules-amd": "^7.10.4", - "@babel/plugin-transform-modules-commonjs": "^7.10.4", - "@babel/plugin-transform-modules-systemjs": "^7.10.4", - "@babel/plugin-transform-modules-umd": "^7.10.4", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.10.4", - "@babel/plugin-transform-new-target": "^7.10.4", - "@babel/plugin-transform-object-super": "^7.10.4", - "@babel/plugin-transform-parameters": "^7.10.4", - "@babel/plugin-transform-property-literals": "^7.10.4", - "@babel/plugin-transform-regenerator": "^7.10.4", - "@babel/plugin-transform-reserved-words": "^7.10.4", - "@babel/plugin-transform-shorthand-properties": "^7.10.4", - "@babel/plugin-transform-spread": "^7.11.0", - "@babel/plugin-transform-sticky-regex": "^7.10.4", - "@babel/plugin-transform-template-literals": "^7.10.4", - "@babel/plugin-transform-typeof-symbol": "^7.10.4", - "@babel/plugin-transform-unicode-escapes": "^7.10.4", - "@babel/plugin-transform-unicode-regex": "^7.10.4", - "@babel/preset-modules": "^0.1.3", - "@babel/types": "^7.11.5", - "browserslist": "^4.12.0", - "core-js-compat": "^3.6.2", - "invariant": "^2.2.2", - "levenary": "^1.1.1", - "semver": "^5.5.0" + "@babel/helper-simple-access": "^7.12.1", + "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } + }, + "@babel/highlight": { "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz", - "integrity": "sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw==", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@babel/types": "^7.10.4" + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, "@babel/types": { - "version": "7.11.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.5.tgz", - "integrity": "sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q==", + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.10.4", + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } - } - } - }, - "@babel/preset-modules": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", - "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", - "@babel/plugin-transform-dotall-regex": "^7.4.4", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" - } - }, - "@babel/preset-react": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.10.4.tgz", - "integrity": "sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-transform-react-display-name": "^7.10.4", - "@babel/plugin-transform-react-jsx": "^7.10.4", - "@babel/plugin-transform-react-jsx-development": "^7.10.4", - "@babel/plugin-transform-react-jsx-self": "^7.10.4", - "@babel/plugin-transform-react-jsx-source": "^7.10.4", - "@babel/plugin-transform-react-pure-annotations": "^7.10.4" - } - }, - "@babel/runtime": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", - "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/runtime-corejs3": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.11.2.tgz", - "integrity": "sha512-qh5IR+8VgFz83VBa6OkaET6uN/mJOhHONuy3m1sgF0CV6mXdPSEBdA7e1eUbVvyNtANjMbg22JUv71BaDXLY6A==", - "dev": true, - "requires": { - "core-js-pure": "^3.0.0", - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.6.0", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", - "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", - "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.6.0", - "@babel/types": "^7.6.0" - } - }, - "@babel/traverse": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", - "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", - "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.6.3", - "@babel/helper-function-name": "^7.1.0", - "@babel/helper-split-export-declaration": "^7.4.4", - "@babel/parser": "^7.6.3", - "@babel/types": "^7.6.3", - "debug": "^4.1.0", - "globals": "^11.1.0", - "lodash": "^4.17.13" - }, - "dependencies": { + }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } }, - "@babel/types": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", - "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", - "requires": { - "esutils": "^2.0.2", - "lodash": "^4.17.13", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@blueprintjs/core": { - "version": "3.31.0", - "resolved": "https://registry.npmjs.org/@blueprintjs/core/-/core-3.31.0.tgz", - "integrity": "sha512-kfCYeyY2ojTMU5hxURNCwV4jQNDmLjTMOPImtbdW3Z7gHwiT2OA9qgNCkM0lhUjv0vyZ5py+AtZalx2FOH6PiA==", - "requires": { - "@blueprintjs/icons": "^3.20.1", - "@types/dom4": "^2.0.1", - "classnames": "^2.2", - "dom4": "^2.1.5", - "normalize.css": "^8.0.1", - "popper.js": "^1.16.1", - "react-lifecycles-compat": "^3.0.4", - "react-popper": "^1.3.7", - "react-transition-group": "^2.9.0", - "resize-observer-polyfill": "^1.5.1", - "tslib": "~1.13.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "@blueprintjs/icons": { - "version": "3.20.1", - "resolved": "https://registry.npmjs.org/@blueprintjs/icons/-/icons-3.20.1.tgz", - "integrity": "sha512-BYXr2oOeKlcYoqpbCj2qCmTvAMf1HEM98v0yo024NXKFcnBdcf9ZF3/y4vmrRUijSJ2JLLCR+a0XE3lhweFWow==", - "requires": { - "classnames": "^2.2", - "tslib": "~1.13.0" - }, - "dependencies": { - "tslib": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", - "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" - } - } - }, - "@cnakazawa/watch": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", - "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", - "dev": true, - "requires": { - "exec-sh": "^0.3.2", - "minimist": "^1.2.0" - } - }, - "@concord-consortium/jsxgraph": { - "version": "0.99.8-cc.1", - "resolved": "https://registry.npmjs.org/@concord-consortium/jsxgraph/-/jsxgraph-0.99.8-cc.1.tgz", - "integrity": "sha512-85NTCoo3Kslz9vHnHmE1VQpSXxc8OTIEoU4hMrkYgTTEQZX04GoJy3MPPpbCA4GrQCenYh7+ejv1exlmsMi65w==", - "requires": { - "requirejs": "^2.3.5" - } - }, - "@concord-consortium/react-components": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/@concord-consortium/react-components/-/react-components-0.1.14.tgz", - "integrity": "sha512-Glqi0Jm7HtPZpXUNXdQeaB9m1kCDNIlUMV0672tERW3Cdwv/yCJ3WGAh1slrcY/onulwHI8P8Mp2JlGFeSvHvQ==", - "requires": { - "styled-components": "^4.4.0" - } - }, - "@cypress/listr-verbose-renderer": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", - "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "@babel/plugin-transform-modules-systemjs": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", + "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", "dev": true, "requires": { - "chalk": "^1.1.3", - "cli-cursor": "^1.0.2", - "date-fns": "^1.27.2", - "figures": "^1.7.0" + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-identifier": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" }, "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "@cypress/request": { - "version": "2.88.5", - "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz", - "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==", - "dev": true, - "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "dependencies": { - "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, - "tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "psl": "^1.1.28", - "punycode": "^2.1.1" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, - "uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "dev": true - } - } - }, - "@cypress/webpack-preprocessor": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.4.5.tgz", - "integrity": "sha512-KH9B//f5DanvnO4RxyEq9RRGqeFqbzsk/wvINWhJAZcyCSZ9iD/J5E1picHt7UZxw9iXw3hzJWcuKNxdR4nk5w==", - "dev": true, - "requires": { - "bluebird": "^3.7.1", - "debug": "^4.1.1", - "lodash": "^4.17.20" - }, - "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } }, - "@cypress/xvfb": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", - "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", - "dev": true, - "requires": { - "debug": "^3.1.0", - "lodash.once": "^4.1.1" - } - }, - "@emotion/is-prop-valid": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz", - "integrity": "sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg==", - "requires": { - "@emotion/memoize": "0.7.3" - } - }, - "@emotion/memoize": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.3.tgz", - "integrity": "sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==" - }, - "@emotion/unitless": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.4.tgz", - "integrity": "sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ==" - }, - "@eslint/eslintrc": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz", - "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==", + "@babel/plugin-transform-modules-umd": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", + "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", "dev": true, "requires": { - "ajv": "^6.12.4", - "debug": "^4.1.1", - "espree": "^7.3.0", - "globals": "^12.1.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^3.13.1", - "lodash": "^4.17.19", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "@babel/highlight": "^7.10.4" } }, - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "ms": "2.1.2" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } }, - "globals": { - "version": "12.4.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", - "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "type-fest": "^0.8.1" + "@babel/types": "^7.12.10" } }, - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } } } }, - "@firebase/analytics": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.5.0.tgz", - "integrity": "sha512-WyQ8BT6JSoXpg4q7SV9Yg5EPXbGbG8FkkXAIhV/AnslCglhpxegO1FU33qbuT4Grzc525hZJA97oqtQS8tm4Wg==", + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", + "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "dev": true, "requires": { - "@firebase/analytics-types": "0.4.0", - "@firebase/component": "0.1.19", - "@firebase/installations": "0.4.17", - "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.2", - "tslib": "^1.11.1" + "@babel/helper-create-regexp-features-plugin": "^7.12.1" }, "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } - } - }, - "@firebase/analytics-types": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.4.0.tgz", - "integrity": "sha512-Jj2xW+8+8XPfWGkv9HPv/uR+Qrmq37NPYT352wf7MvE9LrstpLVmFg3LqG6MCRr5miLAom5sen2gZ+iOhVDeRA==" + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + } + } }, - "@firebase/app": { - "version": "0.6.11", - "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.6.11.tgz", - "integrity": "sha512-FH++PaoyTzfTAVuJ0gITNYEIcjT5G+D0671La27MU8Vvr6MTko+5YUZ4xS9QItyotSeRF4rMJ1KR7G8LSyySiA==", + "@babel/plugin-transform-new-target": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", + "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "dev": true, "requires": { - "@firebase/app-types": "0.6.1", - "@firebase/component": "0.1.19", - "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.2", - "dom-storage": "2.1.0", - "tslib": "^1.11.1", - "xmlhttprequest": "1.8.0" + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", + "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1" }, "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", + "dev": true, + "requires": { + "@babel/types": "^7.12.7" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } } } }, - "@firebase/app-types": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", - "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==" - }, - "@firebase/auth": { - "version": "0.14.9", - "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.14.9.tgz", - "integrity": "sha512-PxYa2r5qUEdheXTvqROFrMstK8W4uPiP7NVfp+2Bec+AjY5PxZapCx/YFDLkU0D7YBI82H74PtZrzdJZw7TJ4w==", + "@babel/plugin-transform-parameters": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", + "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "dev": true, "requires": { - "@firebase/auth-types": "0.10.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/auth-interop-types": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", - "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==" + "@babel/plugin-transform-property-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", + "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "@firebase/auth-types": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.10.1.tgz", - "integrity": "sha512-/+gBHb1O9x/YlG7inXfxff/6X3BPZt4zgBv4kql6HEmdzNQCodIRlEYnI+/da+lN+dha7PjaFH7C7ewMmfV7rw==" + "@babel/plugin-transform-react-constant-elements": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.12.1.tgz", + "integrity": "sha512-KOHd0tIRLoER+J+8f9DblZDa1fLGPwaaN1DI1TVHuQFOpjHV22C3CUB3obeC4fexHY9nx+fH0hQNvLFFfA1mxA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "@firebase/component": { - "version": "0.1.19", - "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.19.tgz", - "integrity": "sha512-L0S3g8eqaerg8y0zox3oOHSTwn/FE8RbcRHiurnbESvDViZtP5S5WnhuAPd7FnFxa8ElWK0z1Tr3ikzWDv1xdQ==", + "@babel/plugin-transform-react-display-name": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz", + "integrity": "sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w==", + "dev": true, "requires": { - "@firebase/util": "0.3.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/database": { - "version": "0.6.13", - "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.6.13.tgz", - "integrity": "sha512-NommVkAPzU7CKd1gyehmi3lz0K78q0KOfiex7Nfy7MBMwknLm7oNqKovXSgQV1PCLvKXvvAplDSFhDhzIf9obA==", + "@babel/plugin-transform-react-jsx": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz", + "integrity": "sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw==", + "dev": true, "requires": { - "@firebase/auth-interop-types": "0.1.5", - "@firebase/component": "0.1.19", - "@firebase/database-types": "0.5.2", - "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.2", - "faye-websocket": "0.11.3", - "tslib": "^1.11.1" + "@babel/helper-annotate-as-pure": "^7.12.10", + "@babel/helper-module-imports": "^7.12.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-jsx": "^7.12.1", + "@babel/types": "^7.12.12" }, "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.5" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } } } }, - "@firebase/database-types": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.5.2.tgz", - "integrity": "sha512-ap2WQOS3LKmGuVFKUghFft7RxXTyZTDr0Xd8y2aqmWsbJVjgozi0huL/EUMgTjGFrATAjcf2A7aNs8AKKZ2a8g==", + "@babel/plugin-transform-react-jsx-development": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz", + "integrity": "sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg==", + "dev": true, "requires": { - "@firebase/app-types": "0.6.1" + "@babel/plugin-transform-react-jsx": "^7.12.12" } }, - "@firebase/firestore": { - "version": "1.17.2", - "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.17.2.tgz", - "integrity": "sha512-B0x0/AlKz4VkIkRW7vzPQvl4FGi2ClCDrTDCh3W5kryuIEMPLdyboglqA8JtaOGklcRYO8gpRwZGmw0EVzmyVg==", + "@babel/plugin-transform-react-pure-annotations": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz", + "integrity": "sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/firestore-types": "1.13.0", - "@firebase/logger": "0.2.6", - "@firebase/util": "0.3.2", - "@firebase/webchannel-wrapper": "0.3.0", - "@grpc/grpc-js": "^1.0.0", - "@grpc/proto-loader": "^0.5.0", - "node-fetch": "2.6.1", - "tslib": "^1.11.1" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } } } }, - "@firebase/firestore-types": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-1.13.0.tgz", - "integrity": "sha512-QF5CAuYOHE6Zbsn1uEg6wkl836iP+i6C0C/Zs3kF60eebxZvTWp8JSZk19Ar+jj4w+ye8/7H5olu5CqDNjWpEA==" - }, - "@firebase/functions": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.5.1.tgz", - "integrity": "sha512-yyjPZXXvzFPjkGRSqFVS5Hc2Y7Y48GyyMH+M3i7hLGe69r/59w6wzgXKqTiSYmyE1pxfjxU4a1YqBDHNkQkrYQ==", + "@babel/plugin-transform-regenerator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", + "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/functions-types": "0.3.17", - "@firebase/messaging-types": "0.5.0", - "node-fetch": "2.6.1", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "regenerator-transform": "^0.14.2" } }, - "@firebase/functions-types": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.3.17.tgz", - "integrity": "sha512-DGR4i3VI55KnYk4IxrIw7+VG7Q3gA65azHnZxo98Il8IvYLr2UTBlSh72dTLlDf25NW51HqvJgYJDKvSaAeyHQ==" - }, - "@firebase/installations": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.17.tgz", - "integrity": "sha512-AE/TyzIpwkC4UayRJD419xTqZkKzxwk0FLht3Dci8WI2OEKHSwoZG9xv4hOBZebe+fDzoV2EzfatQY8c/6Avig==", + "@babel/plugin-transform-reserved-words": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", + "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/installations-types": "0.3.4", - "@firebase/util": "0.3.2", - "idb": "3.0.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/installations-types": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.4.tgz", - "integrity": "sha512-RfePJFovmdIXb6rYwtngyxuEcWnOrzdZd9m7xAW0gRxDIjBT20n3BOhjpmgRWXo/DAxRmS7bRjWAyTHY9cqN7Q==" - }, - "@firebase/logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", - "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" - }, - "@firebase/messaging": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.7.1.tgz", - "integrity": "sha512-iev/ST9v0xd/8YpGYrZtDcqdD9J6ZWzSuceRn8EKy5vIgQvW/rk2eTQc8axzvDpQ36ZfphMYuhW6XuNrR3Pd2Q==", + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", + "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/installations": "0.4.17", - "@firebase/messaging-types": "0.5.0", - "@firebase/util": "0.3.2", - "idb": "3.0.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/messaging-types": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.5.0.tgz", - "integrity": "sha512-QaaBswrU6umJYb/ZYvjR5JDSslCGOH6D9P136PhabFAHLTR4TWjsaACvbBXuvwrfCXu10DtcjMxqfhdNIB1Xfg==" - }, - "@firebase/performance": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.4.1.tgz", - "integrity": "sha512-eAqS3/456xnUwuTg4w58x2fYbvTtQpgt67lpBUX3DuhOqwiM8+JELRte52nDgum2lTaTZWiu5de9mPuAYx2WDg==", + "@babel/plugin-transform-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", + "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/installations": "0.4.17", - "@firebase/logger": "0.2.6", - "@firebase/performance-types": "0.0.13", - "@firebase/util": "0.3.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" } }, - "@firebase/performance-types": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.13.tgz", - "integrity": "sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==" - }, - "@firebase/polyfill": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", - "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", + "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "dev": true, "requires": { - "core-js": "3.6.5", - "promise-polyfill": "8.1.3", - "whatwg-fetch": "2.0.4" - }, - "dependencies": { - "whatwg-fetch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/remote-config": { - "version": "0.1.28", - "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.28.tgz", - "integrity": "sha512-4zSdyxpt94jAnFhO8toNjG8oMKBD+xTuBIcK+Nw8BdQWeJhEamgXlupdBARUk1uf3AvYICngHH32+Si/dMVTbw==", + "@babel/plugin-transform-template-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", + "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/installations": "0.4.17", - "@firebase/logger": "0.2.6", - "@firebase/remote-config-types": "0.1.9", - "@firebase/util": "0.3.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/remote-config-types": { - "version": "0.1.9", - "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.9.tgz", - "integrity": "sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==" - }, - "@firebase/storage": { - "version": "0.3.43", - "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.43.tgz", - "integrity": "sha512-Jp54jcuyimLxPhZHFVAhNbQmgTu3Sda7vXjXrNpPEhlvvMSq4yuZBR6RrZxe/OrNVprLHh/6lTCjwjOVSo3bWA==", + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", + "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "dev": true, "requires": { - "@firebase/component": "0.1.19", - "@firebase/storage-types": "0.3.13", - "@firebase/util": "0.3.2", - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/storage-types": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.3.13.tgz", - "integrity": "sha512-pL7b8d5kMNCCL0w9hF7pr16POyKkb3imOW7w0qYrhBnbyJTdVxMWZhb0HxCFyQWC0w3EiIFFmxoz8NTFZDEFog==" - }, - "@firebase/util": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.2.tgz", - "integrity": "sha512-Dqs00++c8rwKky6KCKLLY2T1qYO4Q+X5t+lF7DInXDNF4ae1Oau35bkD+OpJ9u7l1pEv7KHowP6CUKuySCOc8g==", + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", + "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "dev": true, "requires": { - "tslib": "^1.11.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.0.tgz", - "integrity": "sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw==" - } + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@firebase/webchannel-wrapper": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.3.0.tgz", - "integrity": "sha512-VniCGPIgSGNEgOkh5phb3iKmSGIzcwrccy3IomMFRWPCMiCk2y98UQNJEoDs1yIHtZMstVjYWKYxnunIGzC5UQ==" - }, - "@google-cloud/common": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.4.1.tgz", - "integrity": "sha512-e5z0CwsM0RXky+PnyPtQ3QK46ksqm+kE7kX8pm8X+ddBwZJipHchKeazMM5fLlGCS+AALalzXb+uYmH72TRnpQ==", + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", + "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", "dev": true, - "optional": true, "requires": { - "@google-cloud/projectify": "^2.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.1", - "duplexify": "^4.1.1", - "ent": "^2.2.0", - "extend": "^3.0.2", - "google-auth-library": "^6.1.1", - "retry-request": "^4.1.1", - "teeny-request": "^7.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" }, "dependencies": { - "duplexify": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", - "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, - "optional": true, "requires": { - "end-of-stream": "^1.4.1", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1", - "stream-shift": "^1.0.0" + "@babel/types": "^7.12.10" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "regexpu-core": "^4.7.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" } } } }, - "@google-cloud/firestore": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.4.0.tgz", - "integrity": "sha512-nixsumd4C7eL+hHEgyihspzhBBNe3agsvNFRX0xfqO3uR/6ro4CUj9XdcCvdnSSd3yTyqKfdBSRK2fEj1jIbYg==", + "@babel/preset-env": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", + "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", "dev": true, - "optional": true, "requires": { - "fast-deep-equal": "^3.1.1", - "functional-red-black-tree": "^1.0.1", - "google-gax": "^2.2.0" + "@babel/compat-data": "^7.12.7", + "@babel/helper-compilation-targets": "^7.12.5", + "@babel/helper-module-imports": "^7.12.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-option": "^7.12.11", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.7", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.11", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.7", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.10", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.12.11", + "core-js-compat": "^3.8.0", + "semver": "^5.5.0" }, "dependencies": { - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "optional": true - } - } - }, - "@google-cloud/paginator": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", - "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", - "dev": true, - "optional": true, - "requires": { - "arrify": "^2.0.0", - "extend": "^3.0.2" - } - }, - "@google-cloud/projectify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", - "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", - "dev": true, - "optional": true - }, - "@google-cloud/promisify": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", - "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", - "dev": true, - "optional": true - }, - "@google-cloud/storage": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.3.0.tgz", - "integrity": "sha512-3t5UF3SZ14Bw2kcBHubCai6EIugU2GnQOstYWVSFuoO8IJ94RAaIOPq/dtexvQbUTpBTAGpd5smVR9WPL1mJVw==", - "dev": true, - "optional": true, - "requires": { - "@google-cloud/common": "^3.3.0", - "@google-cloud/paginator": "^3.0.0", - "@google-cloud/promisify": "^2.0.0", - "arrify": "^2.0.0", - "compressible": "^2.0.12", - "concat-stream": "^2.0.0", - "date-and-time": "^0.14.0", - "duplexify": "^3.5.0", - "extend": "^3.0.2", - "gaxios": "^3.0.0", - "gcs-resumable-upload": "^3.1.0", - "hash-stream-validation": "^0.2.2", - "mime": "^2.2.0", - "mime-types": "^2.0.8", - "onetime": "^5.1.0", - "p-limit": "^3.0.1", - "pumpify": "^2.0.0", - "snakeize": "^0.1.0", - "stream-events": "^1.0.1", - "xdg-basedir": "^4.0.0" - }, - "dependencies": { - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "optional": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "optional": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", - "dev": true, - "optional": true, - "requires": { - "p-try": "^2.0.0" - } - } - } - }, - "@grpc/grpc-js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.1.7.tgz", - "integrity": "sha512-EuxMstI0u778dp0nk6Fe3gHXYPeV6FYsWOe0/QFwxv1NQ6bc5Wl/0Yxa4xl9uBlKElL6AIxuASmSfu7KEJhqiw==", - "requires": { - "@grpc/proto-loader": "^0.6.0-pre14", - "@types/node": "^12.12.47", - "google-auth-library": "^6.0.0", - "semver": "^6.2.0" - }, - "dependencies": { - "@grpc/proto-loader": { - "version": "0.6.0-pre9", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.0-pre9.tgz", - "integrity": "sha512-oM+LjpEjNzW5pNJjt4/hq1HYayNeQT+eGrOPABJnYHv7TyNPDNzkQ76rDYZF86X5swJOa4EujEMzQ9iiTdPgww==", - "requires": { - "@types/long": "^4.0.1", - "lodash.camelcase": "^4.3.0", - "long": "^4.0.0", - "protobufjs": "^6.9.0", - "yargs": "^15.3.1" - } - }, - "@types/node": { - "version": "12.12.64", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.64.tgz", - "integrity": "sha512-UV1/ZJMC+HcP902wWdpC43cAcGu0IQk/I5bXjP2aSuCjsk3cE74mDvFrLKga7oDC170ugOAYBwfT4DSQW3akDA==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@grpc/proto-loader": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.5.tgz", - "integrity": "sha512-WwN9jVNdHRQoOBo9FDH7qU+mgfjPc8GygPYms3M+y3fbQLfnCe/Kv/E01t7JRgnrsOHH8euvSbed3mIalXhwqQ==", - "requires": { - "lodash.camelcase": "^4.3.0", - "protobufjs": "^6.8.6" - } - }, - "@hapi/hoek": { - "version": "9.1.1", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", - "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==", - "dev": true - }, - "@hapi/topo": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", - "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "@babel/types": "^7.12.10" } }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", "dev": true, "requires": { - "p-locate": "^4.1.0" + "@babel/helper-annotate-as-pure": "^7.10.4", + "regexpu-core": "^4.7.1" } }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "p-limit": "^2.2.0" + "@babel/types": "^7.12.5" } }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", "dev": true }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", - "dev": true - }, - "@jest/console": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.3.0.tgz", - "integrity": "sha512-/5Pn6sJev0nPUcAdpJHMVIsA8sKizL2ZkcKPE5+dJrCccks7tcM7c9wbgHudBJbxXLoTbqsHkG1Dofoem4F09w==", - "dev": true, - "requires": { - "@jest/types": "^26.3.0", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^26.3.0", - "jest-util": "^26.3.0", - "slash": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", + "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", + "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" } } } }, - "@jest/core": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.4.2.tgz", - "integrity": "sha512-sDva7YkeNprxJfepOctzS8cAk9TOekldh+5FhVuXS40+94SHbiicRO1VV2tSoRtgIo+POs/Cdyf8p76vPTd6dg==", + "@babel/preset-modules": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.4.tgz", + "integrity": "sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==", "dev": true, "requires": { - "@jest/console": "^26.3.0", - "@jest/reporters": "^26.4.1", - "@jest/test-result": "^26.3.0", - "@jest/transform": "^26.3.0", - "@jest/types": "^26.3.0", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.4", - "jest-changed-files": "^26.3.0", - "jest-config": "^26.4.2", - "jest-haste-map": "^26.3.0", - "jest-message-util": "^26.3.0", - "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.4.0", - "jest-resolve-dependencies": "^26.4.2", - "jest-runner": "^26.4.2", - "jest-runtime": "^26.4.2", - "jest-snapshot": "^26.4.2", - "jest-util": "^26.3.0", - "jest-validate": "^26.4.2", - "jest-watcher": "^26.3.0", - "micromatch": "^4.0.2", - "p-each-series": "^2.1.0", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "ansi-escapes": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", - "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, - "requires": { - "type-fest": "^0.11.0" - } - }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/preset-react": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.12.10.tgz", + "integrity": "sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-transform-react-display-name": "^7.12.1", + "@babel/plugin-transform-react-jsx": "^7.12.10", + "@babel/plugin-transform-react-jsx-development": "^7.12.7", + "@babel/plugin-transform-react-pure-annotations": "^7.12.1" + } + }, + "@babel/runtime": { + "version": "7.11.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.11.2.tgz", + "integrity": "sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz", + "integrity": "sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ==", + "dev": true, + "requires": { + "core-js-pure": "^3.0.0", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.6.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz", + "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.6.0", + "@babel/types": "^7.6.0" + } + }, + "@babel/traverse": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.3.tgz", + "integrity": "sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw==", + "requires": { + "@babel/code-frame": "^7.5.5", + "@babel/generator": "^7.6.3", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.6.3", + "@babel/types": "^7.6.3", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.3.tgz", + "integrity": "sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA==", + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@blueprintjs/core": { + "version": "3.38.2", + "resolved": "https://registry.npmjs.org/@blueprintjs/core/-/core-3.38.2.tgz", + "integrity": "sha512-YOTZ8UkaKCjP/g8fm9e2py5/9TvAWHwhhDQAH30NV53FD5oBOjYu0+mUU1hRys9TrBflvA3cQn8EgHRP1y/K9A==", + "requires": { + "@blueprintjs/icons": "^3.24.0", + "@types/dom4": "^2.0.1", + "classnames": "^2.2", + "dom4": "^2.1.5", + "normalize.css": "^8.0.1", + "popper.js": "^1.16.1", + "react-lifecycles-compat": "^3.0.4", + "react-popper": "^1.3.7", + "react-transition-group": "^2.9.0", + "resize-observer-polyfill": "^1.5.1", + "tslib": "~1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + } + } + }, + "@blueprintjs/icons": { + "version": "3.24.0", + "resolved": "https://registry.npmjs.org/@blueprintjs/icons/-/icons-3.24.0.tgz", + "integrity": "sha512-OvDDI5EUueS1Y3t594iS8LAGoHhLhYjC2GuN/01a85n+ASLSp0jf0/+uix2JeCOj41iTdRRCINbWuRwVQNNGPw==", + "requires": { + "classnames": "^2.2", + "tslib": "~1.13.0" + }, + "dependencies": { + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==" + } + } + }, + "@cnakazawa/watch": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@cnakazawa/watch/-/watch-1.0.4.tgz", + "integrity": "sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==", + "dev": true, + "requires": { + "exec-sh": "^0.3.2", + "minimist": "^1.2.0" + } + }, + "@concord-consortium/jsxgraph": { + "version": "0.99.8-cc.1", + "resolved": "https://registry.npmjs.org/@concord-consortium/jsxgraph/-/jsxgraph-0.99.8-cc.1.tgz", + "integrity": "sha512-85NTCoo3Kslz9vHnHmE1VQpSXxc8OTIEoU4hMrkYgTTEQZX04GoJy3MPPpbCA4GrQCenYh7+ejv1exlmsMi65w==", + "requires": { + "requirejs": "^2.3.5" + } + }, + "@concord-consortium/react-components": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/@concord-consortium/react-components/-/react-components-0.1.14.tgz", + "integrity": "sha512-Glqi0Jm7HtPZpXUNXdQeaB9m1kCDNIlUMV0672tERW3Cdwv/yCJ3WGAh1slrcY/onulwHI8P8Mp2JlGFeSvHvQ==", + "requires": { + "styled-components": "^4.4.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "@cypress/request": { + "version": "2.88.5", + "resolved": "https://registry.npmjs.org/@cypress/request/-/request-2.88.5.tgz", + "integrity": "sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + } + } + }, + "@cypress/webpack-preprocessor": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.5.0.tgz", + "integrity": "sha512-iqwPygSNZ1u6bM3r5QRVv6qYngkcgI2xCzi9Jmo4mrkcofwX08UaItJq7xlB2/dHbB2aryQYOsfe4xNKtQIm3A==", + "dev": true, + "requires": { + "bluebird": "^3.7.1", + "debug": "^4.1.1", + "lodash": "^4.17.20" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + } + } + }, + "@cypress/xvfb": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.4.tgz", + "integrity": "sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "@emotion/is-prop-valid": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.5.tgz", + "integrity": "sha512-6ZODuZSFofbxSbcxwsFz+6ioPjb0ISJRRPLZ+WIbjcU2IMU0Io+RGQjjaTgOvNQl007KICBm7zXQaYQEC1r6Bg==", + "requires": { + "@emotion/memoize": "0.7.3" + } + }, + "@emotion/memoize": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.3.tgz", + "integrity": "sha512-2Md9mH6mvo+ygq1trTeVp2uzAKwE2P7In0cRpD/M9Q70aH8L+rxMLbb3JCN2JoSWsV2O+DdFjfbbXoMoLBczow==" + }, + "@emotion/unitless": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.4.tgz", + "integrity": "sha512-kBa+cDHOR9jpRJ+kcGMsysrls0leukrm68DmFQoMIWQcXdr2cZvyvypWuGYT7U+9kAExUE7+T7r6G3C3A6L8MQ==" + }, + "@eslint/eslintrc": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.20", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + } + } + }, + "@firebase/analytics": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics/-/analytics-0.6.0.tgz", + "integrity": "sha512-6qYEOPUVYrMhqvJ46Z5Uf1S4uULd6d7vGpMP5Qz+u8kIWuOQGcPdJKQap+Hla6Rq164or9gC2HRXuYXKlgWfpw==", + "requires": { + "@firebase/analytics-types": "0.4.0", + "@firebase/component": "0.1.19", + "@firebase/installations": "0.4.17", + "@firebase/logger": "0.2.6", + "@firebase/util": "0.3.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/analytics-types": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/analytics-types/-/analytics-types-0.4.0.tgz", + "integrity": "sha512-Jj2xW+8+8XPfWGkv9HPv/uR+Qrmq37NPYT352wf7MvE9LrstpLVmFg3LqG6MCRr5miLAom5sen2gZ+iOhVDeRA==" + }, + "@firebase/app": { + "version": "0.6.11", + "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.6.11.tgz", + "integrity": "sha512-FH++PaoyTzfTAVuJ0gITNYEIcjT5G+D0671La27MU8Vvr6MTko+5YUZ4xS9QItyotSeRF4rMJ1KR7G8LSyySiA==", + "requires": { + "@firebase/app-types": "0.6.1", + "@firebase/component": "0.1.19", + "@firebase/logger": "0.2.6", + "@firebase/util": "0.3.2", + "dom-storage": "2.1.0", + "tslib": "^1.11.1", + "xmlhttprequest": "1.8.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/app-types": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.6.1.tgz", + "integrity": "sha512-L/ZnJRAq7F++utfuoTKX4CLBG5YR7tFO3PLzG1/oXXKEezJ0kRL3CMRoueBEmTCzVb/6SIs2Qlaw++uDgi5Xyg==" + }, + "@firebase/auth": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@firebase/auth/-/auth-0.15.0.tgz", + "integrity": "sha512-IFuzhxS+HtOQl7+SZ/Mhaghy/zTU7CENsJFWbC16tv2wfLZbayKF5jYGdAU3VFLehgC8KjlcIWd10akc3XivfQ==", + "requires": { + "@firebase/auth-types": "0.10.1" + } + }, + "@firebase/auth-interop-types": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.5.tgz", + "integrity": "sha512-88h74TMQ6wXChPA6h9Q3E1Jg6TkTHep2+k63OWg3s0ozyGVMeY+TTOti7PFPzq5RhszQPQOoCi59es4MaRvgCw==" + }, + "@firebase/auth-types": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@firebase/auth-types/-/auth-types-0.10.1.tgz", + "integrity": "sha512-/+gBHb1O9x/YlG7inXfxff/6X3BPZt4zgBv4kql6HEmdzNQCodIRlEYnI+/da+lN+dha7PjaFH7C7ewMmfV7rw==" + }, + "@firebase/component": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.19.tgz", + "integrity": "sha512-L0S3g8eqaerg8y0zox3oOHSTwn/FE8RbcRHiurnbESvDViZtP5S5WnhuAPd7FnFxa8ElWK0z1Tr3ikzWDv1xdQ==", + "requires": { + "@firebase/util": "0.3.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/database": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.6.13.tgz", + "integrity": "sha512-NommVkAPzU7CKd1gyehmi3lz0K78q0KOfiex7Nfy7MBMwknLm7oNqKovXSgQV1PCLvKXvvAplDSFhDhzIf9obA==", + "requires": { + "@firebase/auth-interop-types": "0.1.5", + "@firebase/component": "0.1.19", + "@firebase/database-types": "0.5.2", + "@firebase/logger": "0.2.6", + "@firebase/util": "0.3.2", + "faye-websocket": "0.11.3", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/database-types": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.5.2.tgz", + "integrity": "sha512-ap2WQOS3LKmGuVFKUghFft7RxXTyZTDr0Xd8y2aqmWsbJVjgozi0huL/EUMgTjGFrATAjcf2A7aNs8AKKZ2a8g==", + "requires": { + "@firebase/app-types": "0.6.1" + } + }, + "@firebase/firestore": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.18.0.tgz", + "integrity": "sha512-maMq4ltkrwjDRusR2nt0qS4wldHQMp+0IDSfXIjC+SNmjnWY/t/+Skn9U3Po+dB38xpz3i7nsKbs+8utpDnPSw==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/firestore-types": "1.14.0", + "@firebase/logger": "0.2.6", + "@firebase/util": "0.3.2", + "@firebase/webchannel-wrapper": "0.4.0", + "@grpc/grpc-js": "^1.0.0", + "@grpc/proto-loader": "^0.5.0", + "node-fetch": "2.6.1", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/firestore-types": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/@firebase/firestore-types/-/firestore-types-1.14.0.tgz", + "integrity": "sha512-WF8IBwHzZDhwyOgQnmB0pheVrLNP78A8PGxk1nxb/Nrgh1amo4/zYvFMGgSsTeaQK37xMYS/g7eS948te/dJxw==" + }, + "@firebase/functions": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.5.1.tgz", + "integrity": "sha512-yyjPZXXvzFPjkGRSqFVS5Hc2Y7Y48GyyMH+M3i7hLGe69r/59w6wzgXKqTiSYmyE1pxfjxU4a1YqBDHNkQkrYQ==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/functions-types": "0.3.17", + "@firebase/messaging-types": "0.5.0", + "node-fetch": "2.6.1", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/functions-types": { + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@firebase/functions-types/-/functions-types-0.3.17.tgz", + "integrity": "sha512-DGR4i3VI55KnYk4IxrIw7+VG7Q3gA65azHnZxo98Il8IvYLr2UTBlSh72dTLlDf25NW51HqvJgYJDKvSaAeyHQ==" + }, + "@firebase/installations": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/@firebase/installations/-/installations-0.4.17.tgz", + "integrity": "sha512-AE/TyzIpwkC4UayRJD419xTqZkKzxwk0FLht3Dci8WI2OEKHSwoZG9xv4hOBZebe+fDzoV2EzfatQY8c/6Avig==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/installations-types": "0.3.4", + "@firebase/util": "0.3.2", + "idb": "3.0.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/installations-types": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/installations-types/-/installations-types-0.3.4.tgz", + "integrity": "sha512-RfePJFovmdIXb6rYwtngyxuEcWnOrzdZd9m7xAW0gRxDIjBT20n3BOhjpmgRWXo/DAxRmS7bRjWAyTHY9cqN7Q==" + }, + "@firebase/logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.2.6.tgz", + "integrity": "sha512-KIxcUvW/cRGWlzK9Vd2KB864HlUnCfdTH0taHE0sXW5Xl7+W68suaeau1oKNEqmc3l45azkd4NzXTCWZRZdXrw==" + }, + "@firebase/messaging": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.7.1.tgz", + "integrity": "sha512-iev/ST9v0xd/8YpGYrZtDcqdD9J6ZWzSuceRn8EKy5vIgQvW/rk2eTQc8axzvDpQ36ZfphMYuhW6XuNrR3Pd2Q==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/installations": "0.4.17", + "@firebase/messaging-types": "0.5.0", + "@firebase/util": "0.3.2", + "idb": "3.0.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/messaging-types": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@firebase/messaging-types/-/messaging-types-0.5.0.tgz", + "integrity": "sha512-QaaBswrU6umJYb/ZYvjR5JDSslCGOH6D9P136PhabFAHLTR4TWjsaACvbBXuvwrfCXu10DtcjMxqfhdNIB1Xfg==" + }, + "@firebase/performance": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@firebase/performance/-/performance-0.4.2.tgz", + "integrity": "sha512-irHTCVWJ/sxJo0QHg+yQifBeVu8ZJPihiTqYzBUz/0AGc51YSt49FZwqSfknvCN2+OfHaazz/ARVBn87g7Ex8g==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/installations": "0.4.17", + "@firebase/logger": "0.2.6", + "@firebase/performance-types": "0.0.13", + "@firebase/util": "0.3.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/performance-types": { + "version": "0.0.13", + "resolved": "https://registry.npmjs.org/@firebase/performance-types/-/performance-types-0.0.13.tgz", + "integrity": "sha512-6fZfIGjQpwo9S5OzMpPyqgYAUZcFzZxHFqOyNtorDIgNXq33nlldTL/vtaUZA8iT9TT5cJlCrF/jthKU7X21EA==" + }, + "@firebase/polyfill": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@firebase/polyfill/-/polyfill-0.3.36.tgz", + "integrity": "sha512-zMM9oSJgY6cT2jx3Ce9LYqb0eIpDE52meIzd/oe/y70F+v9u1LDqk5kUF5mf16zovGBWMNFmgzlsh6Wj0OsFtg==", + "requires": { + "core-js": "3.6.5", + "promise-polyfill": "8.1.3", + "whatwg-fetch": "2.0.4" + }, + "dependencies": { + "whatwg-fetch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + } + } + }, + "@firebase/remote-config": { + "version": "0.1.28", + "resolved": "https://registry.npmjs.org/@firebase/remote-config/-/remote-config-0.1.28.tgz", + "integrity": "sha512-4zSdyxpt94jAnFhO8toNjG8oMKBD+xTuBIcK+Nw8BdQWeJhEamgXlupdBARUk1uf3AvYICngHH32+Si/dMVTbw==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/installations": "0.4.17", + "@firebase/logger": "0.2.6", + "@firebase/remote-config-types": "0.1.9", + "@firebase/util": "0.3.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/remote-config-types": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/@firebase/remote-config-types/-/remote-config-types-0.1.9.tgz", + "integrity": "sha512-G96qnF3RYGbZsTRut7NBX0sxyczxt1uyCgXQuH/eAfUCngxjEGcZQnBdy6mvSdqdJh5mC31rWPO4v9/s7HwtzA==" + }, + "@firebase/storage": { + "version": "0.3.43", + "resolved": "https://registry.npmjs.org/@firebase/storage/-/storage-0.3.43.tgz", + "integrity": "sha512-Jp54jcuyimLxPhZHFVAhNbQmgTu3Sda7vXjXrNpPEhlvvMSq4yuZBR6RrZxe/OrNVprLHh/6lTCjwjOVSo3bWA==", + "requires": { + "@firebase/component": "0.1.19", + "@firebase/storage-types": "0.3.13", + "@firebase/util": "0.3.2", + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/storage-types": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@firebase/storage-types/-/storage-types-0.3.13.tgz", + "integrity": "sha512-pL7b8d5kMNCCL0w9hF7pr16POyKkb3imOW7w0qYrhBnbyJTdVxMWZhb0HxCFyQWC0w3EiIFFmxoz8NTFZDEFog==" + }, + "@firebase/util": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.2.tgz", + "integrity": "sha512-Dqs00++c8rwKky6KCKLLY2T1qYO4Q+X5t+lF7DInXDNF4ae1Oau35bkD+OpJ9u7l1pEv7KHowP6CUKuySCOc8g==", + "requires": { + "tslib": "^1.11.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + } + } + }, + "@firebase/webchannel-wrapper": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.4.0.tgz", + "integrity": "sha512-8cUA/mg0S+BxIZ72TdZRsXKBP5n5uRcE3k29TZhZw6oIiHBt9JA7CTb/4pE1uKtE/q5NeTY2tBDcagoZ+1zjXQ==" + }, + "@google-cloud/common": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-3.5.0.tgz", + "integrity": "sha512-10d7ZAvKhq47L271AqvHEd8KzJqGU45TY+rwM2Z3JHuB070FeTi7oJJd7elfrnKaEvaktw3hH2wKnRWxk/3oWQ==", + "dev": true, + "optional": true, + "requires": { + "@google-cloud/projectify": "^2.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.1", + "duplexify": "^4.1.1", + "ent": "^2.2.0", + "extend": "^3.0.2", + "google-auth-library": "^6.1.1", + "retry-request": "^4.1.1", + "teeny-request": "^7.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "dev": true, + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + } + } + }, + "@google-cloud/firestore": { + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.9.1.tgz", + "integrity": "sha512-lmg9xXGq56uS/T2PxyYWZCJ4FeCMgWPwx5iNU/IjLvru90qXRlxVcT4pg2acxng+MC7RntnZJQaExWvJR7Jgsg==", + "dev": true, + "optional": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "functional-red-black-tree": "^1.0.1", + "google-gax": "^2.9.2" + }, + "dependencies": { + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "optional": true + } + } + }, + "@google-cloud/paginator": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.5.tgz", + "integrity": "sha512-N4Uk4BT1YuskfRhKXBs0n9Lg2YTROZc6IMpkO/8DIHODtm5s3xY8K5vVBo23v/2XulY3azwITQlYWgT4GdLsUw==", + "dev": true, + "optional": true, + "requires": { + "arrify": "^2.0.0", + "extend": "^3.0.2" + } + }, + "@google-cloud/projectify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.0.1.tgz", + "integrity": "sha512-ZDG38U/Yy6Zr21LaR3BTiiLtpJl6RkPS/JwoRT453G+6Q1DhlV0waNf8Lfu+YVYGIIxgKnLayJRfYlFJfiI8iQ==", + "dev": true, + "optional": true + }, + "@google-cloud/promisify": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.3.tgz", + "integrity": "sha512-d4VSA86eL/AFTe5xtyZX+ePUjE8dIFu2T8zmdeNBSa5/kNgXPCx/o/wbFNHAGLJdGnk1vddRuMESD9HbOC8irw==", + "dev": true, + "optional": true + }, + "@google-cloud/storage": { + "version": "5.7.4", + "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.7.4.tgz", + "integrity": "sha512-fynB3kDT+lhx71laML+LtUs/w9Ezcf+SVAsaP0fhAyPQzOc0kp43uYTymYCvF9GffYR7jcy6yqYifeMSU9VEVA==", + "dev": true, + "optional": true, + "requires": { + "@google-cloud/common": "^3.5.0", + "@google-cloud/paginator": "^3.0.0", + "@google-cloud/promisify": "^2.0.0", + "arrify": "^2.0.0", + "async-retry": "^1.3.1", + "compressible": "^2.0.12", + "date-and-time": "^0.14.2", + "duplexify": "^4.0.0", + "extend": "^3.0.2", + "gaxios": "^4.0.0", + "gcs-resumable-upload": "^3.1.0", + "get-stream": "^6.0.0", + "hash-stream-validation": "^0.2.2", + "mime": "^2.2.0", + "mime-types": "^2.0.8", + "onetime": "^5.1.0", + "p-limit": "^3.0.1", + "pumpify": "^2.0.0", + "snakeize": "^0.1.0", + "stream-events": "^1.0.1", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "duplexify": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.1.tgz", + "integrity": "sha512-DY3xVEmVHTv1wSzKNbwoU6nVjzI369Y6sPoqfYr0/xlx3IdX2n94xIszTcjPO8W8ZIv0Wb0PXNcjuZyT4wiICA==", + "dev": true, + "optional": true, + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, + "get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true, + "optional": true + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "optional": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "optional": true, + "requires": { + "yocto-queue": "^0.1.0" + } + } + } + }, + "@grpc/grpc-js": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.2.5.tgz", + "integrity": "sha512-CBCNwedw8McnEBq9jvoiJikws16WN0OiHFejQPovY71XkFWSiIqgvydYiDwpvIYDJmhPQ7qZNzW9BPndhXbx1Q==", + "requires": { + "@types/node": "^12.12.47", + "google-auth-library": "^6.1.1", + "semver": "^6.2.0" + }, + "dependencies": { + "@types/node": { + "version": "12.19.15", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.15.tgz", + "integrity": "sha512-lowukE3GUI+VSYSu6VcBXl14d61Rp5hA1D+61r16qnwC0lYNSqdxcvRh0pswejorHfS+HgwBasM8jLXz0/aOsw==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@grpc/proto-loader": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.5.6.tgz", + "integrity": "sha512-DT14xgw3PSzPxwS13auTEwxhMMOoz33DPUKNtmYK/QYbBSpLXJy78FGGs5yVoxVobEqPm4iW9MOIoz0A3bLTRQ==", + "requires": { + "lodash.camelcase": "^4.3.0", + "protobufjs": "^6.8.6" + } + }, + "@hapi/hoek": { + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.1.1.tgz", + "integrity": "sha512-CAEbWH7OIur6jEOzaai83jq3FmKmv4PmX1JYfs9IrYcGEVI/lyL1EXJGCj7eFVJ0bg5QR8LMxBlEtA+xKiLpFw==", + "dev": true + }, + "@hapi/topo": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.0.0.tgz", + "integrity": "sha512-tFJlT47db0kMqVm3H4nQYgn6Pwg10GTZHb1pwmSiv1K4ks6drQOtfEF5ZnPjkvC+y4/bUPHK+bc87QvLcL+WMw==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", + "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "dev": true + }, + "@jest/console": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-26.6.2.tgz", + "integrity": "sha512-IY1R2i2aLsLr7Id3S6p2BA82GNWryt4oSvEXLAKc+L2zdi89dSkE8xC1C+0kpATG4JhBJREnQOH7/zmccM2B0g==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^26.6.2", + "jest-util": "^26.6.2", + "slash": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/core": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-26.6.3.tgz", + "integrity": "sha512-xvV1kKbhfUqFVuZ8Cyo+JPpipAHHAV3kcDBftiduK8EICXmTFddryy3P7NfZt8Pv37rA9nEJBKCCkglCPt/Xjw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/reporters": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.4", + "jest-changed-files": "^26.6.2", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-resolve": "^26.6.2", + "jest-resolve-dependencies": "^26.6.3", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", + "jest-watcher": "^26.6.2", + "micromatch": "^4.0.2", + "p-each-series": "^2.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + } + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "@jest/environment": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.6.2.tgz", + "integrity": "sha512-nFy+fHl28zUrRsCeMB61VDThV1pVTtlEokBRgqPrcT1JNq4yRNIyTHfyht6PqtUvY9IsuLGTrbG8kPXjSZIZwA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/node": "*", + "jest-mock": "^26.6.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/fake-timers": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.6.2.tgz", + "integrity": "sha512-14Uleatt7jdzefLPYM3KLcnUl1ZNikaKq34enpb5XG9i81JpppDb5muZvonvKyrl7ftEHkKS5L5/eB/kxJ+bvA==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@sinonjs/fake-timers": "^6.0.1", + "@types/node": "*", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/globals": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.6.2.tgz", + "integrity": "sha512-85Ltnm7HlB/KesBUuALwQ68YTU72w9H2xW9FjZ1eL1U3lhtefjjl5c2MiUbpXt/i6LaPRvoOFJ22yCBSfQ0JIA==", + "dev": true, + "requires": { + "@jest/environment": "^26.6.2", + "@jest/types": "^26.6.2", + "expect": "^26.6.2" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/reporters": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.6.2.tgz", + "integrity": "sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.2.4", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^4.0.3", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "jest-haste-map": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", + "node-notifier": "^8.0.0", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^7.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "@jest/source-map": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.6.2.tgz", + "integrity": "sha512-YwYcCwAnNmOVsZ8mr3GfnzdXDAl4LaenZP5z+G0c8bzC9/dugL8zRmxZzdoTl4IaS3CryS1uWnROLPFmb6lVvA==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.4", + "source-map": "^0.6.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@jest/test-result": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.6.2.tgz", + "integrity": "sha512-5O7H5c/7YlojphYNrK02LlDIV2GNPYisKwHm2QTKjNZeEzezCbwYs9swJySv2UfPMyZ0VdsmMv7jIlD/IKYQpQ==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/types": "^26.6.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/test-sequencer": { + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.6.3.tgz", + "integrity": "sha512-YHlVIjP5nfEyjlrSr8t/YdNfU/1XEt7c5b4OxcXCjyRhjzLYu/rO69/WHPuYcbCWkz8kAeZVZp2N2+IOLLEPGw==", + "dev": true, + "requires": { + "@jest/test-result": "^26.6.2", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-runner": "^26.6.3", + "jest-runtime": "^26.6.3" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + } + } + }, + "@jest/transform": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.6.2.tgz", + "integrity": "sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^26.6.2", + "babel-plugin-istanbul": "^6.0.0", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.4", + "jest-haste-map": "^26.6.2", + "jest-regex-util": "^26.0.0", + "jest-util": "^26.6.2", + "micromatch": "^4.0.2", + "pirates": "^4.0.1", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + } + }, + "@types/istanbul-reports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } }, "braces": { "version": "3.0.2", @@ -3502,6 +5497,20 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -3512,82 +5521,51 @@ "picomatch": "^2.0.5" } }, - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "type-fest": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true - } - } - }, - "@jest/environment": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-26.3.0.tgz", - "integrity": "sha512-EW+MFEo0DGHahf83RAaiqQx688qpXgl99wdb8Fy67ybyzHwR1a58LHcO376xQJHfmoXTu89M09dH3J509cx2AA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^26.3.0", - "@jest/types": "^26.3.0", - "@types/node": "*", - "jest-mock": "^26.3.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "is-number": "^7.0.0" } - }, + } + } + }, + "@jest/types": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^15.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -3623,9 +5601,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3633,1041 +5611,1422 @@ } } }, - "@jest/fake-timers": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-26.3.0.tgz", - "integrity": "sha512-ZL9ytUiRwVP8ujfRepffokBvD2KbxbqMhrXSBhSdAhISCw3gOkuntisiSFv+A6HN0n0fF4cxzICEKZENLmW+1A==", + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "dev": true, + "requires": { + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" + } + }, + "@nodelib/fs.stat": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "dev": true + }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, + "@npmcli/move-file": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.1.tgz", + "integrity": "sha512-LtWTicuF2wp7PNTuyCwABx7nNG+DnzSE8gN0iWxkC6mpgm/iOPu0ZMTkXuCxmJxtWFsDxUaixM9COSNJEMUfuQ==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "dependencies": { + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", + "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@sideway/address": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.0.tgz", + "integrity": "sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA==", + "dev": true, + "requires": { + "@hapi/hoek": "^9.0.0" + } + }, + "@sideway/formula": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", + "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", + "dev": true + }, + "@sideway/pinpoint": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", + "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", + "dev": true + }, + "@sinonjs/commons": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", + "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@svgr/babel-plugin-add-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-attribute": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", + "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", + "dev": true + }, + "@svgr/babel-plugin-remove-jsx-empty-expression": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", + "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", + "dev": true + }, + "@svgr/babel-plugin-replace-jsx-attribute-value": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", + "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", + "dev": true + }, + "@svgr/babel-plugin-svg-dynamic-title": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", + "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", + "dev": true + }, + "@svgr/babel-plugin-svg-em-dimensions": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", + "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", + "dev": true + }, + "@svgr/babel-plugin-transform-react-native-svg": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", + "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", + "dev": true + }, + "@svgr/babel-plugin-transform-svg-component": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.5.0.tgz", + "integrity": "sha512-q4jSH1UUvbrsOtlo/tKcgSeiCHRSBdXoIoqX1pgcKK/aU3JD27wmMKwGtpB8qRYUYoyXvfGxUVKchLuR5pB3rQ==", + "dev": true + }, + "@svgr/babel-preset": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.5.0.tgz", + "integrity": "sha512-4FiXBjvQ+z2j7yASeGPEi8VD/5rrGQk4Xrq3EdJmoZgz/tpqChpo5hgXDvmEauwtvOc52q8ghhZK4Oy7qph4ig==", + "dev": true, + "requires": { + "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", + "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", + "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", + "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", + "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", + "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", + "@svgr/babel-plugin-transform-svg-component": "^5.5.0" + } + }, + "@svgr/core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.5.0.tgz", + "integrity": "sha512-q52VOcsJPvV3jO1wkPtzTuKlvX7Y3xIcWRpCMtBF3MrteZJtBfQw/+u0B1BHy5ColpQc1/YVTrPEtSYIMNZlrQ==", + "dev": true, + "requires": { + "@svgr/plugin-jsx": "^5.5.0", + "camelcase": "^6.2.0", + "cosmiconfig": "^7.0.0" + }, + "dependencies": { + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + } + } + }, + "@svgr/hast-util-to-babel-ast": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.5.0.tgz", + "integrity": "sha512-cAaR/CAiZRB8GP32N+1jocovUtvlj0+e65TB50/6Lcime+EA49m/8l+P2ko+XPJ4dw3xaPS3jOL4F2X4KWxoeQ==", + "dev": true, + "requires": { + "@babel/types": "^7.12.6" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@svgr/plugin-jsx": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.5.0.tgz", + "integrity": "sha512-V/wVh33j12hGh05IDg8GpIUXbjAPnTdPTKuP4VNLggnwaHMPNQNae2pRnyTAILWCQdz5GyMqtO488g7CKM8CBA==", "dev": true, "requires": { - "@jest/types": "^26.3.0", - "@sinonjs/fake-timers": "^6.0.1", - "@types/node": "*", - "jest-message-util": "^26.3.0", - "jest-mock": "^26.3.0", - "jest-util": "^26.3.0" + "@babel/core": "^7.12.3", + "@svgr/babel-preset": "^5.5.0", + "@svgr/hast-util-to-babel-ast": "^5.5.0", + "svg-parser": "^2.0.2" }, "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/highlight": "^7.10.4" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/core": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", + "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.10", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.10", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "semver": "^5.4.1", + "source-map": "^0.5.0" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/types": "^7.12.10" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@babel/types": "^7.12.7" } - } - } - }, - "@jest/globals": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-26.4.2.tgz", - "integrity": "sha512-Ot5ouAlehhHLRhc+sDz2/9bmNv9p5ZWZ9LE1pXGGTCXBasmi5jnYjlgYcYt03FBwLmZXCZ7GrL29c33/XRQiow==", - "dev": true, - "requires": { - "@jest/environment": "^26.3.0", - "@jest/types": "^26.3.0", - "expect": "^26.4.2" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + }, + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/types": "^7.12.5" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/types": "^7.12.10" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/types": "^7.12.1" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@babel/types": "^7.12.11" } - } - } - }, - "@jest/reporters": { - "version": "26.4.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-26.4.1.tgz", - "integrity": "sha512-aROTkCLU8++yiRGVxLsuDmZsQEKO6LprlrxtAuzvtpbIFl3eIjgIf3EUxDKgomkS25R9ZzwGEdB5weCcBZlrpQ==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^26.3.0", - "@jest/test-result": "^26.3.0", - "@jest/transform": "^26.3.0", - "@jest/types": "^26.3.0", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.4", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^4.0.3", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "jest-haste-map": "^26.3.0", - "jest-resolve": "^26.4.0", - "jest-util": "^26.3.0", - "jest-worker": "^26.3.0", - "node-notifier": "^8.0.0", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^5.0.1" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + }, + "@babel/helpers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", + "dev": true + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/helper-validator-identifier": "^7.12.11", + "lodash": "^4.17.19", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "minimist": "^1.2.5" } } } - }, - "@jest/source-map": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-26.3.0.tgz", - "integrity": "sha512-hWX5IHmMDWe1kyrKl7IhFwqOuAreIwHhbe44+XH2ZRHjrKIh0LO5eLQ/vxHFeAfRwJapmxuqlGAEYLadDq6ZGQ==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.4", - "source-map": "^0.6.0" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + }, + "@svgr/plugin-svgo": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.5.0.tgz", + "integrity": "sha512-r5swKk46GuQl4RrVejVwpeeJaydoxkdwkM1mBKOgJLBUJPGaLci6ylg/IjhrRsREKDkr4kbMWdgOtbXEh0fyLQ==", + "dev": true, + "requires": { + "cosmiconfig": "^7.0.0", + "deepmerge": "^4.2.2", + "svgo": "^1.2.2" } }, - "@jest/test-result": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-26.3.0.tgz", - "integrity": "sha512-a8rbLqzW/q7HWheFVMtghXV79Xk+GWwOK1FrtimpI5n1la2SY0qHri3/b0/1F0Ve0/yJmV8pEhxDfVwiUBGtgg==", + "@svgr/webpack": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.5.0.tgz", + "integrity": "sha512-DOBOK255wfQxguUta2INKkzPj6AIS6iafZYiYmHn6W3pHlycSRRlvWKCfLDG10fXfLWqE3DJHgRUOyJYmARa7g==", "dev": true, "requires": { - "@jest/console": "^26.3.0", - "@jest/types": "^26.3.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" + "@babel/core": "^7.12.3", + "@babel/plugin-transform-react-constant-elements": "^7.12.1", + "@babel/preset-env": "^7.12.1", + "@babel/preset-react": "^7.12.5", + "@svgr/core": "^5.5.0", + "@svgr/plugin-jsx": "^5.5.0", + "@svgr/plugin-svgo": "^5.5.0", + "loader-utils": "^2.0.0" }, "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/highlight": "^7.10.4" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/compat-data": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.12.7.tgz", + "integrity": "sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw==", + "dev": true + }, + "@babel/core": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.10.tgz", + "integrity": "sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/code-frame": "^7.10.4", + "@babel/generator": "^7.12.10", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helpers": "^7.12.5", + "@babel/parser": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.10", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.19", + "semver": "^5.4.1", + "source-map": "^0.5.0" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/generator": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.12.11.tgz", + "integrity": "sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/types": "^7.12.11", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/helper-annotate-as-pure": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz", + "integrity": "sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/types": "^7.12.10" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/helper-compilation-targets": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz", + "integrity": "sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/compat-data": "^7.12.5", + "@babel/helper-validator-option": "^7.12.1", + "browserslist": "^4.14.5", + "semver": "^5.5.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "@babel/helper-create-class-features-plugin": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz", + "integrity": "sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-member-expression-to-functions": "^7.12.1", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.10.4" + } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "@babel/helper-create-regexp-features-plugin": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz", + "integrity": "sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.4", + "regexpu-core": "^4.7.1" + } }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "@babel/helper-function-name": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz", + "integrity": "sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@babel/helper-get-function-arity": "^7.12.10", + "@babel/template": "^7.12.7", + "@babel/types": "^7.12.11" } - } - } - }, - "@jest/test-sequencer": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-26.4.2.tgz", - "integrity": "sha512-83DRD8N3M0tOhz9h0bn6Kl6dSp+US6DazuVF8J9m21WAp5x7CqSMaNycMP0aemC/SH/pDQQddbsfHRTBXVUgog==", - "dev": true, - "requires": { - "@jest/test-result": "^26.3.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.3.0", - "jest-runner": "^26.4.2", - "jest-runtime": "^26.4.2" - }, - "dependencies": { - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true - } - } - }, - "@jest/transform": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-26.3.0.tgz", - "integrity": "sha512-Isj6NB68QorGoFWvcOjlUhpkT56PqNIsXKR7XfvoDlCANn/IANlh8DrKAA2l2JKC3yWSMH5wS0GwuQM20w3b2A==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^26.3.0", - "babel-plugin-istanbul": "^6.0.0", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.4", - "jest-haste-map": "^26.3.0", - "jest-regex-util": "^26.0.0", - "jest-util": "^26.3.0", - "micromatch": "^4.0.2", - "pirates": "^4.0.1", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + }, + "@babel/helper-get-function-arity": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz", + "integrity": "sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" + "@babel/types": "^7.12.10" } }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + "@babel/helper-member-expression-to-functions": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz", + "integrity": "sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "@babel/types": "^7.12.7" } }, - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "@babel/helper-module-imports": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", + "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/types": "^7.12.5" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "@babel/helper-module-transforms": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz", + "integrity": "sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-simple-access": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.11.0", + "@babel/helper-validator-identifier": "^7.10.4", + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.1", + "@babel/types": "^7.12.1", + "lodash": "^4.17.19" } }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "@babel/helper-optimise-call-expression": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz", + "integrity": "sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/types": "^7.12.10" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/helper-remap-async-to-generator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz", + "integrity": "sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-wrap-function": "^7.10.4", + "@babel/types": "^7.12.1" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "@babel/helper-replace-supers": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz", + "integrity": "sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.12.7", + "@babel/helper-optimise-call-expression": "^7.12.10", + "@babel/traverse": "^7.12.10", + "@babel/types": "^7.12.11" + } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "@babel/helper-simple-access": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz", + "integrity": "sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA==", "dev": true, "requires": { - "to-regex-range": "^5.0.1" + "@babel/types": "^7.12.1" } }, - "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", - "dev": true + "@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz", + "integrity": "sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.1" + } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "@babel/helper-split-export-declaration": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz", + "integrity": "sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g==", + "dev": true, + "requires": { + "@babel/types": "^7.12.11" + } }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "@babel/helpers": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.12.5.tgz", + "integrity": "sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA==", + "dev": true, + "requires": { + "@babel/template": "^7.10.4", + "@babel/traverse": "^7.12.5", + "@babel/types": "^7.12.5" + } }, - "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "@babel/parser": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.12.11.tgz", + "integrity": "sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg==", "dev": true }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz", + "integrity": "sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1", + "@babel/plugin-syntax-async-generators": "^7.8.0" } }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "@babel/plugin-proposal-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz", + "integrity": "sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w==", "dev": true, "requires": { - "is-number": "^7.0.0" + "@babel/helper-create-class-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" } - } - } - }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz", + "integrity": "sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-export-namespace-from": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz", + "integrity": "sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz", + "integrity": "sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-logical-assignment-operators": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz", + "integrity": "sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz", + "integrity": "sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz", + "integrity": "sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-numeric-separator": "^7.10.4" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", + "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.12.1" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz", + "integrity": "sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" } }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "@babel/plugin-proposal-optional-chaining": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz", + "integrity": "sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA==", "dev": true, "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" } }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "@babel/plugin-proposal-private-methods": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz", + "integrity": "sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w==", "dev": true, "requires": { - "color-name": "~1.1.4" + "@babel/helper-create-class-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz", + "integrity": "sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "@babel/plugin-syntax-class-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz", + "integrity": "sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "@babel/plugin-syntax-top-level-await": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz", + "integrity": "sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A==", "dev": true, "requires": { - "has-flag": "^4.0.0" + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz", + "integrity": "sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz", + "integrity": "sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-remap-async-to-generator": "^7.12.1" } - } - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, - "requires": { - "@nodelib/fs.stat": "2.0.3", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true - }, - "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.3", - "fastq": "^1.6.0" - } - }, - "@npmcli/move-file": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", - "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4" - }, - "dependencies": { - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "@protobufjs/aspromise": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", - "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" - }, - "@protobufjs/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" - }, - "@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" - }, - "@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" - }, - "@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", - "requires": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" - } - }, - "@protobufjs/float": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", - "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" - }, - "@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" - }, - "@protobufjs/path": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", - "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" - }, - "@protobufjs/pool": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", - "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" - }, - "@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" - }, - "@samverschueren/stream-to-observable": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.1.tgz", - "integrity": "sha512-c/qwwcHyafOQuVQJj0IlBjf5yYgBI7YPJ77k4fOJYesb41jio65eaJODRUmfYKhTOFBrIZ66kgvGPlNbjuoRdQ==", - "dev": true, - "requires": { - "any-observable": "^0.3.0" - } - }, - "@sideway/address": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.0.tgz", - "integrity": "sha512-wAH/JYRXeIFQRsxerIuLjgUu2Xszam+O5xKeatJ4oudShOOirfmsQ1D6LL54XOU2tizpCYku+s1wmU0SYdpoSA==", - "dev": true, - "requires": { - "@hapi/hoek": "^9.0.0" - } - }, - "@sideway/formula": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz", - "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==", - "dev": true - }, - "@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "dev": true - }, - "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", - "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@svgr/babel-plugin-add-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-ZFf2gs/8/6B8PnSofI0inYXr2SDNTDScPXhN7k5EqD4aZ3gi6u+rbmZHVB8IM3wDyx8ntKACZbtXSm7oZGRqVg==", - "dev": true - }, - "@svgr/babel-plugin-remove-jsx-attribute": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-5.4.0.tgz", - "integrity": "sha512-yaS4o2PgUtwLFGTKbsiAy6D0o3ugcUhWK0Z45umJ66EPWunAz9fuFw2gJuje6wqQvQWOTJvIahUwndOXb7QCPg==", - "dev": true - }, - "@svgr/babel-plugin-remove-jsx-empty-expression": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-5.0.1.tgz", - "integrity": "sha512-LA72+88A11ND/yFIMzyuLRSMJ+tRKeYKeQ+mR3DcAZ5I4h5CPWN9AHyUzJbWSYp/u2u0xhmgOe0+E41+GjEueA==", - "dev": true - }, - "@svgr/babel-plugin-replace-jsx-attribute-value": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-5.0.1.tgz", - "integrity": "sha512-PoiE6ZD2Eiy5mK+fjHqwGOS+IXX0wq/YDtNyIgOrc6ejFnxN4b13pRpiIPbtPwHEc+NT2KCjteAcq33/F1Y9KQ==", - "dev": true - }, - "@svgr/babel-plugin-svg-dynamic-title": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-5.4.0.tgz", - "integrity": "sha512-zSOZH8PdZOpuG1ZVx/cLVePB2ibo3WPpqo7gFIjLV9a0QsuQAzJiwwqmuEdTaW2pegyBE17Uu15mOgOcgabQZg==", - "dev": true - }, - "@svgr/babel-plugin-svg-em-dimensions": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-5.4.0.tgz", - "integrity": "sha512-cPzDbDA5oT/sPXDCUYoVXEmm3VIoAWAPT6mSPTJNbQaBNUuEKVKyGH93oDY4e42PYHRW67N5alJx/eEol20abw==", - "dev": true - }, - "@svgr/babel-plugin-transform-react-native-svg": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-5.4.0.tgz", - "integrity": "sha512-3eYP/SaopZ41GHwXma7Rmxcv9uRslRDTY1estspeB1w1ueZWd/tPlMfEOoccYpEMZU3jD4OU7YitnXcF5hLW2Q==", - "dev": true - }, - "@svgr/babel-plugin-transform-svg-component": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-5.4.0.tgz", - "integrity": "sha512-zLl4Fl3NvKxxjWNkqEcpdSOpQ3LGVH2BNFQ6vjaK6sFo2IrSznrhURIPI0HAphKiiIwNYjAfE0TNoQDSZv0U9A==", - "dev": true - }, - "@svgr/babel-preset": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/babel-preset/-/babel-preset-5.4.0.tgz", - "integrity": "sha512-Gyx7cCxua04DBtyILTYdQxeO/pwfTBev6+eXTbVbxe4HTGhOUW6yo7PSbG2p6eJMl44j6XSequ0ZDP7bl0nu9A==", - "dev": true, - "requires": { - "@svgr/babel-plugin-add-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-attribute": "^5.4.0", - "@svgr/babel-plugin-remove-jsx-empty-expression": "^5.0.1", - "@svgr/babel-plugin-replace-jsx-attribute-value": "^5.0.1", - "@svgr/babel-plugin-svg-dynamic-title": "^5.4.0", - "@svgr/babel-plugin-svg-em-dimensions": "^5.4.0", - "@svgr/babel-plugin-transform-react-native-svg": "^5.4.0", - "@svgr/babel-plugin-transform-svg-component": "^5.4.0" - } - }, - "@svgr/core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/core/-/core-5.4.0.tgz", - "integrity": "sha512-hWGm1DCCvd4IEn7VgDUHYiC597lUYhFau2lwJBYpQWDirYLkX4OsXu9IslPgJ9UpP7wsw3n2Ffv9sW7SXJVfqQ==", - "dev": true, - "requires": { - "@svgr/plugin-jsx": "^5.4.0", - "camelcase": "^6.0.0", - "cosmiconfig": "^6.0.0" - }, - "dependencies": { - "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", - "dev": true }, - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz", + "integrity": "sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA==", "dev": true, "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "@babel/plugin-transform-block-scoping": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz", + "integrity": "sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "@babel/helper-plugin-utils": "^7.10.4" } }, - "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "@babel/plugin-transform-classes": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz", + "integrity": "sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "@babel/helper-annotate-as-pure": "^7.10.4", + "@babel/helper-define-map": "^7.10.4", + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-optimise-call-expression": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1", + "@babel/helper-split-export-declaration": "^7.10.4", + "globals": "^11.1.0" } }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "@babel/plugin-transform-computed-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz", + "integrity": "sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } - } - }, - "@svgr/hast-util-to-babel-ast": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-5.4.0.tgz", - "integrity": "sha512-+U0TZZpPsP2V1WvVhqAOSTk+N+CjYHdZx+x9UBa1eeeZDXwH8pt0CrQf2+SvRl/h2CAPRFkm+Ey96+jKP8Bsgg==", - "dev": true, - "requires": { - "@babel/types": "^7.9.5" - }, - "dependencies": { - "@babel/types": { - "version": "7.11.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.11.0.tgz", - "integrity": "sha512-O53yME4ZZI0jO1EVGtF1ePGl0LHirG4P1ibcD80XyzZcKhcMFeCXmh4Xb1ifGBIV233Qg12x4rBfQgA+tmOukA==", + "@babel/plugin-transform-destructuring": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz", + "integrity": "sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz", + "integrity": "sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz", + "integrity": "sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz", + "integrity": "sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz", + "integrity": "sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz", + "integrity": "sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.4", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz", + "integrity": "sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz", + "integrity": "sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz", + "integrity": "sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz", + "integrity": "sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-simple-access": "^7.12.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz", + "integrity": "sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q==", "dev": true, "requires": { + "@babel/helper-hoist-variables": "^7.10.4", + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4", "@babel/helper-validator-identifier": "^7.10.4", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz", + "integrity": "sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz", + "integrity": "sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.1" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz", + "integrity": "sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz", + "integrity": "sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-replace-supers": "^7.12.1" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz", + "integrity": "sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz", + "integrity": "sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz", + "integrity": "sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz", + "integrity": "sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz", + "integrity": "sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz", + "integrity": "sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-skip-transparent-expression-wrappers": "^7.12.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz", + "integrity": "sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz", + "integrity": "sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.12.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz", + "integrity": "sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz", + "integrity": "sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz", + "integrity": "sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.12.1", + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/preset-env": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.12.11.tgz", + "integrity": "sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.12.7", + "@babel/helper-compilation-targets": "^7.12.5", + "@babel/helper-module-imports": "^7.12.5", + "@babel/helper-plugin-utils": "^7.10.4", + "@babel/helper-validator-option": "^7.12.11", + "@babel/plugin-proposal-async-generator-functions": "^7.12.1", + "@babel/plugin-proposal-class-properties": "^7.12.1", + "@babel/plugin-proposal-dynamic-import": "^7.12.1", + "@babel/plugin-proposal-export-namespace-from": "^7.12.1", + "@babel/plugin-proposal-json-strings": "^7.12.1", + "@babel/plugin-proposal-logical-assignment-operators": "^7.12.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1", + "@babel/plugin-proposal-numeric-separator": "^7.12.7", + "@babel/plugin-proposal-object-rest-spread": "^7.12.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.12.1", + "@babel/plugin-proposal-optional-chaining": "^7.12.7", + "@babel/plugin-proposal-private-methods": "^7.12.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.12.1", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.12.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-export-namespace-from": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-logical-assignment-operators": "^7.10.4", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.4", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.12.1", + "@babel/plugin-transform-arrow-functions": "^7.12.1", + "@babel/plugin-transform-async-to-generator": "^7.12.1", + "@babel/plugin-transform-block-scoped-functions": "^7.12.1", + "@babel/plugin-transform-block-scoping": "^7.12.11", + "@babel/plugin-transform-classes": "^7.12.1", + "@babel/plugin-transform-computed-properties": "^7.12.1", + "@babel/plugin-transform-destructuring": "^7.12.1", + "@babel/plugin-transform-dotall-regex": "^7.12.1", + "@babel/plugin-transform-duplicate-keys": "^7.12.1", + "@babel/plugin-transform-exponentiation-operator": "^7.12.1", + "@babel/plugin-transform-for-of": "^7.12.1", + "@babel/plugin-transform-function-name": "^7.12.1", + "@babel/plugin-transform-literals": "^7.12.1", + "@babel/plugin-transform-member-expression-literals": "^7.12.1", + "@babel/plugin-transform-modules-amd": "^7.12.1", + "@babel/plugin-transform-modules-commonjs": "^7.12.1", + "@babel/plugin-transform-modules-systemjs": "^7.12.1", + "@babel/plugin-transform-modules-umd": "^7.12.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.12.1", + "@babel/plugin-transform-new-target": "^7.12.1", + "@babel/plugin-transform-object-super": "^7.12.1", + "@babel/plugin-transform-parameters": "^7.12.1", + "@babel/plugin-transform-property-literals": "^7.12.1", + "@babel/plugin-transform-regenerator": "^7.12.1", + "@babel/plugin-transform-reserved-words": "^7.12.1", + "@babel/plugin-transform-shorthand-properties": "^7.12.1", + "@babel/plugin-transform-spread": "^7.12.1", + "@babel/plugin-transform-sticky-regex": "^7.12.7", + "@babel/plugin-transform-template-literals": "^7.12.1", + "@babel/plugin-transform-typeof-symbol": "^7.12.10", + "@babel/plugin-transform-unicode-escapes": "^7.12.1", + "@babel/plugin-transform-unicode-regex": "^7.12.1", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.12.11", + "core-js-compat": "^3.8.0", + "semver": "^5.5.0" + } + }, + "@babel/template": { + "version": "7.12.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.7.tgz", + "integrity": "sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/parser": "^7.12.7", + "@babel/types": "^7.12.7" + } + }, + "@babel/traverse": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.12.12.tgz", + "integrity": "sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.11", + "@babel/generator": "^7.12.11", + "@babel/helper-function-name": "^7.12.11", + "@babel/helper-split-export-declaration": "^7.12.11", + "@babel/parser": "^7.12.11", + "@babel/types": "^7.12.12", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.19" + } + }, + "@babel/types": { + "version": "7.12.12", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.12.tgz", + "integrity": "sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", + "dev": true + } } - } - } - }, - "@svgr/plugin-jsx": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-jsx/-/plugin-jsx-5.4.0.tgz", - "integrity": "sha512-SGzO4JZQ2HvGRKDzRga9YFSqOqaNrgLlQVaGvpZ2Iht2gwRp/tq+18Pvv9kS9ZqOMYgyix2LLxZMY1LOe9NPqw==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@svgr/babel-preset": "^5.4.0", - "@svgr/hast-util-to-babel-ast": "^5.4.0", - "svg-parser": "^2.0.2" - } - }, - "@svgr/plugin-svgo": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/plugin-svgo/-/plugin-svgo-5.4.0.tgz", - "integrity": "sha512-3Cgv3aYi1l6SHyzArV9C36yo4kgwVdF3zPQUC6/aCDUeXAofDYwE5kk3e3oT5ZO2a0N3lB+lLGvipBG6lnG8EA==", - "dev": true, - "requires": { - "cosmiconfig": "^6.0.0", - "merge-deep": "^3.0.2", - "svgo": "^1.2.2" - }, - "dependencies": { - "cosmiconfig": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", - "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + }, + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", "dev": true, "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.1.0", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.7.2" + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" } }, - "import-fresh": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", - "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "caniuse-lite": { + "version": "1.0.30001181", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001181.tgz", + "integrity": "sha512-m5ul/ARCX50JB8BSNM+oiPmQrR5UmngaQ3QThTTp5HcIIQGP/nPBs82BYLE+tigzm3VW+F4BJIhUyaVtEweelQ==", + "dev": true + }, + "core-js-compat": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", + "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", "dev": true, "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" + "browserslist": "^4.16.1", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } } }, - "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "ms": "2.1.2" } }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "electron-to-chromium": { + "version": "1.3.650", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.650.tgz", + "integrity": "sha512-j6pRuNylFBbroG6NB8Lw/Im9oDY74s2zWHBP5TmdYg73cBuL6cz//SMgolVa0gIJk/DSL+kO7baJ1DSXW1FUZg==", "dev": true }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - } - } - }, - "@svgr/webpack": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@svgr/webpack/-/webpack-5.4.0.tgz", - "integrity": "sha512-LjepnS/BSAvelnOnnzr6Gg0GcpLmnZ9ThGFK5WJtm1xOqdBE/1IACZU7MMdVzjyUkfFqGz87eRE4hFaSLiUwYg==", - "dev": true, - "requires": { - "@babel/core": "^7.9.0", - "@babel/plugin-transform-react-constant-elements": "^7.9.0", - "@babel/preset-env": "^7.9.5", - "@babel/preset-react": "^7.9.4", - "@svgr/core": "^5.4.0", - "@svgr/plugin-jsx": "^5.4.0", - "@svgr/plugin-svgo": "^5.4.0", - "loader-utils": "^2.0.0" - }, - "dependencies": { "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "dev": true }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -4683,28 +7042,49 @@ "emojis-list": "^3.0.0", "json5": "^2.1.2" } + }, + "node-releases": { + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "dev": true + }, + "regexpu-core": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.1.tgz", + "integrity": "sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } } } }, "@testing-library/dom": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.24.5.tgz", - "integrity": "sha512-oyOp8R2rhmnkOjgrySb4iYc2q73dzvQUAGddpbmicGJdCf4jkLmf5U9zOyobLMLWXbIHHK4UUHHjDTH8tSPLsA==", + "version": "7.29.4", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-7.29.4.tgz", + "integrity": "sha512-CtrJRiSYEfbtNGtEsd78mk1n1v2TUbeABlNIcOCJdDfkN5/JTOwQEbbQpoSRxGqzcWPgStMvJ4mNolSuBRv1NA==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.10.3", + "@babel/runtime": "^7.12.5", "@types/aria-query": "^4.2.0", "aria-query": "^4.2.2", "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.1", - "pretty-format": "^26.4.2" + "dom-accessibility-api": "^0.5.4", + "lz-string": "^1.4.4", + "pretty-format": "^26.6.2" }, "dependencies": { "@babel/code-frame": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", - "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", "dev": true, "requires": { "@babel/highlight": "^7.10.4" @@ -4733,35 +7113,16 @@ } } } - }, - "@jest/types": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.5.2.tgz", - "integrity": "sha512-QDs5d0gYiyetI8q+2xWdkixVQMklReZr4ltw7GFDtb4fuJIBCE6mzj2LnitGqCuAlLap6wPyb8fpoHgwZz5fdg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^15.0.0", - "chalk": "^4.0.0" - } - }, - "@types/istanbul-reports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", - "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", + }, + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", "dev": true, "requires": { - "@types/istanbul-lib-report": "*" + "regenerator-runtime": "^0.13.4" } }, - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true - }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -4812,46 +7173,28 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true - }, - "pretty-format": { - "version": "26.5.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.5.2.tgz", - "integrity": "sha512-VizyV669eqESlkOikKJI8Ryxl/kPpbdLwNdPs2GrbQs18MpySB5S0Yo0N7zkg2xTRiFq4CFw8ct5Vg4a0xP0og==", - "dev": true, - "requires": { - "@jest/types": "^26.5.2", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - } - } - }, - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true } } }, "@testing-library/react": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.0.4.tgz", - "integrity": "sha512-U0fZO2zxm7M0CB5h1+lh31lbAwMSmDMEMGpMT3BUPJwIjDEKYWOV4dx7lb3x2Ue0Pyt77gmz/VropuJnSz/Iew==", + "version": "11.2.5", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.2.5.tgz", + "integrity": "sha512-yEx7oIa/UWLe2F2dqK0FtMF9sJWNXD+2PPtp39BvE0Kh9MJ9Kl0HrZAgEuhUJR+Lx8Di6Xz+rKwSdEPY2UV8ZQ==", "dev": true, "requires": { - "@babel/runtime": "^7.11.2", - "@testing-library/dom": "^7.24.2" + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^7.28.1" + }, + "dependencies": { + "@babel/runtime": { + "version": "7.12.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", + "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + } } }, "@tootallnate/once": { @@ -4868,15 +7211,15 @@ "dev": true }, "@types/aria-query": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.0.tgz", - "integrity": "sha512-iIgQNzCm0v7QMhhe4Jjn9uRh+I6GoPmt03CbEtwx3ao8/EfoQcmgtqH4vQ5Db/lxiIGaWDv6nwvunuh0RyX0+A==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz", + "integrity": "sha512-S6oPal772qJZHoRZLFc/XoZW2gFvwXusYUmXPXkgxJLuEk2vOt7jc4Yo6z/vtI0EBkbPBVrJJ0B+prLIKiWqHg==", "dev": true }, "@types/babel__core": { - "version": "7.1.9", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.9.tgz", - "integrity": "sha512-sY2RsIJ5rpER1u3/aQ8OFSI7qGIy8o1NEEbgb2UaJcvOtXOMpd39ko723NBpjQFg9SIX7TXtjejZVGeIMLhoOw==", + "version": "7.1.12", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.12.tgz", + "integrity": "sha512-wMTHiiTiBAAPebqaPiPDLFA4LYPKr6Ph0Xq/6rq1Ur3v66HXyG+clfR9CNETkD7MQS8ZHvpQOtA53DLws5WAEQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -4887,18 +7230,18 @@ } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.2.tgz", + "integrity": "sha512-MdSJnBjl+bdwkLskZ3NGFp9YcXGx5ggLpQQPqtgakVhsWK0hTtNYhjpZLlWQTviGTvF8at+Bvli3jV7faPdgeQ==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.0.tgz", + "integrity": "sha512-NTPErx4/FiPCGScH7foPyr+/1Dkzkni+rHiYHHoTjvwou7AQzJkNeD60A9CXRy+ZEN2B1bggmkTMCDb+Mv5k+A==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -4906,33 +7249,34 @@ } }, "@types/babel__traverse": { - "version": "7.0.13", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.13.tgz", - "integrity": "sha512-i+zS7t6/s9cdQvbqKDARrcbrPvtJGlbYsMkazo03nTAK3RX9FNrLllXys22uiTGJapPOTZTQ35nHh4ISph4SLQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.11.0.tgz", + "integrity": "sha512-kSjgDMZONiIfSH1Nxcr5JIRMwUetDki63FSQfpTCz8ogF3Ulqm8+mr5f78dUYs6vMiB6gBusQqfQmBvHZj/lwg==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, "@types/cheerio": { - "version": "0.22.21", - "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.21.tgz", - "integrity": "sha512-aGI3DfswwqgKPiEOTaiHV2ZPC9KEhprpgEbJnv0fZl3SGX0cGgEva1126dGrMC6AJM6v/aihlUgJn9M5DbDZ/Q==", + "version": "0.22.23", + "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.23.tgz", + "integrity": "sha512-QfHLujVMlGqcS/ePSf3Oe5hK3H8wi/yN2JYuxSB1U10VvW1fO3K8C+mURQesFYS1Hn7lspOsTT75SKq/XtydQg==", "dev": true, "requires": { "@types/node": "*" } }, "@types/classnames": { - "version": "2.2.10", - "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.10.tgz", - "integrity": "sha512-1UzDldn9GfYYEsWWnn/P4wkTlkZDH7lDb0wBMGbtIQc9zXEQq7FlKBdZUn6OBqD8sKZZ2RQO2mAjGpXiDGoRmQ==", + "version": "2.2.11", + "resolved": "https://registry.npmjs.org/@types/classnames/-/classnames-2.2.11.tgz", + "integrity": "sha512-2koNhpWm3DgWRp5tpkiJ8JGc1xTn2q0l+jUNUE7oMKXUf5NpI9AIdC4kbjGNFBdHtcxBD18LAksoudAVhFKCjw==", "dev": true }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true }, "@types/color-string": { "version": "1.5.0", @@ -4947,9 +7291,9 @@ "dev": true }, "@types/d3-format": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.3.1.tgz", - "integrity": "sha512-KAWvReOKMDreaAwOjdfQMm0HjcUMlQG47GwqdVKgmm20vTd2pucj0a70c3gUSHrnsmo6H2AMrkBsZU2UhJLq8A==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.1.tgz", + "integrity": "sha512-ss9G2snEKmp2In5Z3T0Jpqv8QaDBc2xHltBw83KjnV5B5w+Iwphbvq5ph/Xnu4d03fmmsdt+o1aWch379rxIbA==", "dev": true }, "@types/dom4": { @@ -4958,9 +7302,9 @@ "integrity": "sha512-kSkVAvWmMZiCYtvqjqQEwOmvKwcH+V4uiv3qPQ8pAh1Xl39xggGEo8gHUqV4waYGHezdFw0rKBR8Jt0CrQSDZA==" }, "@types/enzyme": { - "version": "3.10.6", - "resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.6.tgz", - "integrity": "sha512-Jxyn2U+UfhmrE7EaeZYfV1sPA5OEDuZmg9Lxj8TxOnfCn71flf0Cn1136LWdCVYj7yapLFmUWqKCcgplWNZCJg==", + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@types/enzyme/-/enzyme-3.10.8.tgz", + "integrity": "sha512-vlOuzqsTHxog6PV79+tvOHFb6hq4QZKMq1lLD9MaWD1oec2lHTKndn76XOpSwCA0oFTaIbKVPrgM3k78Jjd16g==", "dev": true, "requires": { "@types/cheerio": "*", @@ -4993,18 +7337,18 @@ } }, "@types/graceful-fs": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.3.tgz", - "integrity": "sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==", + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.4.tgz", + "integrity": "sha512-mWA/4zFQhfvOA8zWkXobwJvBD7vzcxgrOQ0J5CH1votGqdq9m7+FwtGaqyCZqC3NyyBkc9z4m+iry4LlqcMWJg==", "dev": true, "requires": { "@types/node": "*" } }, "@types/html-minifier-terser": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.0.tgz", - "integrity": "sha512-iYCgjm1dGPRuo12+BStjd1HiVQqhlRhWDOQigNxn023HcjnhsiFz9pc6CzJj4HwDCSQca9bxTL4PxJDbkdm3PA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", + "integrity": "sha512-giAlZwstKbmvMk1OO7WXSj4OZ0keXAcl2TQq4LWHiiPH2ByaH7WeUzng+Qej8UPxxv+8lRTuouo0iaNDBuzIBA==", "dev": true }, "@types/is-hotkey": { @@ -5029,23 +7373,22 @@ } }, "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.0.tgz", + "integrity": "sha512-nwKNbvnwJ2/mndE9ItP/zc2TCzw6uuodnF4EHYWD+gCQDVBuRQL5UzbZD0/ezy1iKsFU2ZQiDqg4M9dN4+wZgA==", "dev": true, "requires": { - "@types/istanbul-lib-coverage": "*", "@types/istanbul-lib-report": "*" } }, "@types/jest": { - "version": "26.0.13", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.13.tgz", - "integrity": "sha512-sCzjKow4z9LILc6DhBvn5AkIfmQzDZkgtVVKmGwVrs5tuid38ws281D4l+7x1kP487+FlKDh5kfMZ8WSPAdmdA==", + "version": "26.0.20", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.20.tgz", + "integrity": "sha512-9zi2Y+5USJRxd0FsahERhBwlcvFh6D2GLQnY2FH2BzK8J9s9omvNHIbvABwIluXa0fD8XVKMLTO0aOEuUfACAA==", "dev": true, "requires": { - "jest-diff": "^25.2.1", - "pretty-format": "^25.2.1" + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" } }, "@types/json-schema": { @@ -5064,9 +7407,9 @@ } }, "@types/lodash": { - "version": "4.14.161", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.161.tgz", - "integrity": "sha512-EP6O3Jkr7bXvZZSZYlsgt5DIjiGr0dXP1/jVEwVLTFgg0d+3lWVQkRavYVQszV7dYUwvg0B8R0MBDpcmXg7XIA==", + "version": "4.14.168", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.168.tgz", + "integrity": "sha512-oVfRvqHV/V6D1yifJbVRU3TMp8OT6o6BG+U9MkwuJ3U8/CsDHvalRpsxBqivn71ztOFZBTfJMvETbqHiaNSj7Q==", "dev": true }, "@types/long": { @@ -5108,9 +7451,9 @@ "dev": true }, "@types/prettier": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.0.2.tgz", - "integrity": "sha512-IkVfat549ggtkZUthUzEX49562eGikhSYeVGX97SkMFn+sTZrgRewXjQ4tPKFPCykZHkX1Zfd9OoELGqKU2jJA==", + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.1.6.tgz", + "integrity": "sha512-6gOkRe7OIioWAXfnO/2lFiv+SJichKVSys1mSsgyrYHSEjk8Ctv4tSR/Odvnu+HWlH2C8j53dahU03XmQdd5fA==", "dev": true }, "@types/prop-types": { @@ -5135,9 +7478,9 @@ } }, "@types/react": { - "version": "16.9.49", - "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.49.tgz", - "integrity": "sha512-DtLFjSj0OYAdVLBbyjhuV9CdGVHCkHn2R+xr3XkBvK2rS1Y1tkc14XSGjYgm5Fjjr90AxH9tiSzc1pCFMGO06g==", + "version": "16.14.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.2.tgz", + "integrity": "sha512-BzzcAlyDxXl2nANlabtT4thtvbbnhee8hMmH/CcJrISDBVcJS1iOsP1f0OAgSdGE0MsY9tqcrb9YoZcOFv9dbQ==", "dev": true, "requires": { "@types/prop-types": "*", @@ -5145,9 +7488,18 @@ } }, "@types/react-dom": { - "version": "16.9.8", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.8.tgz", - "integrity": "sha512-ykkPQ+5nFknnlU6lDd947WbQ6TE3NNzbQAkInC2EKY1qeYdTKp7onFusmYZb+ityzx2YviqT6BXSu+LyWWJwcA==", + "version": "16.9.10", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.9.10.tgz", + "integrity": "sha512-ItatOrnXDMAYpv6G8UCk2VhbYVTjZT9aorLtA/OzDN9XJ2GKcfam68jutoAcILdRjsRUO8qb7AmyObF77Q8QFw==", + "dev": true, + "requires": { + "@types/react": "^16" + } + }, + "@types/react-modal": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@types/react-modal/-/react-modal-3.10.6.tgz", + "integrity": "sha512-XpshhwVYir1TRZ2HS5EfmNotJjB8UEC2IkT3omNtiQzROOXSzVLz5xsjwEpACP8U+PctkpfZepX+WT5oDf0a9g==", "dev": true, "requires": { "@types/react": "*" @@ -5175,9 +7527,9 @@ "dev": true }, "@types/slate": { - "version": "0.47.7", - "resolved": "https://registry.npmjs.org/@types/slate/-/slate-0.47.7.tgz", - "integrity": "sha512-Vy4E9lOKGFc5msZMwLWtVN9nrGYsdk6S7jXdC0Wf26UoMqJCS3yzXbNoFILSoCh7fq57ftJZrM6+8kkC/yT+LA==", + "version": "0.47.8", + "resolved": "https://registry.npmjs.org/@types/slate/-/slate-0.47.8.tgz", + "integrity": "sha512-peyg1SKD+01ly3VNoWPcPWmlOS+ltSDzAMkCWmBNTaAJ2s+WY91RQxaqk/cl1m9HQ3wmS1nB/7tbRnOcN5Wr4Q==", "dev": true, "requires": { "@types/react": "*", @@ -5221,9 +7573,9 @@ "dev": true }, "@types/stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.0.tgz", + "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, "@types/superagent": { @@ -5243,9 +7595,9 @@ "dev": true }, "@types/uglify-js": { - "version": "3.9.3", - "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.3.tgz", - "integrity": "sha512-KswB5C7Kwduwjj04Ykz+AjvPcfgv/37Za24O2EDzYNbwyzOo8+ydtvzUfZ5UMguiVu29Gx44l1A6VsPPcmYu9w==", + "version": "3.11.1", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.11.1.tgz", + "integrity": "sha512-7npvPKV+jINLu1SpSYVWG8KvyJBhBa8tmzMMdDoVc2pWUYHN8KIXlPJhjJ4LT97c4dXJA2SHL/q6ADbDriZN+Q==", "dev": true, "requires": { "source-map": "^0.6.1" @@ -5266,9 +7618,9 @@ "dev": true }, "@types/webpack": { - "version": "4.41.22", - "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.22.tgz", - "integrity": "sha512-JQDJK6pj8OMV9gWOnN1dcLCyU9Hzs6lux0wBO4lr1+gyEhIBR9U3FMrz12t2GPkg110XAxEAw2WHF6g7nZIbRQ==", + "version": "4.41.26", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.26.tgz", + "integrity": "sha512-7ZyTfxjCRwexh+EJFwRUM+CDB2XvgHl4vfuqf1ZKrgGvcS5BrNvPQqJh3tsZ0P6h6Aa1qClVHaJZszLPzpqHeA==", "dev": true, "requires": { "@types/anymatch": "*", @@ -5288,9 +7640,9 @@ } }, "@types/webpack-sources": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.2.tgz", - "integrity": "sha512-77T++JyKow4BQB/m9O96n9d/UUHWLQHlcqXb9Vsf4F1+wKNrrlWNFPDLKNT92RJnCSL6CieTc+NDXtCVZswdTw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-2.1.0.tgz", + "integrity": "sha512-LXn/oYIpBeucgP1EIJbKQ2/4ZmpvRl+dlrFdX7+94SKRUV3Evy3FsfMZY318vGhkWUS5MPhtOM3w1/hCOAOXcg==", "dev": true, "requires": { "@types/node": "*", @@ -5322,67 +7674,171 @@ "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.6.0.tgz", - "integrity": "sha512-1+419X+Ynijytr1iWI+/IcX/kJryc78YNpdaXR1aRO1sU3bC0vZrIAF1tIX7rudVI84W7o7M4zo5p1aVt70fAg==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.14.2.tgz", + "integrity": "sha512-uMGfG7GFYK/nYutK/iqYJv6K/Xuog/vrRRZX9aEP4Zv1jsYXuvFUMDFLhUnc8WFv3D2R5QhNQL3VYKmvLS5zsQ==", "dev": true, "requires": { - "@typescript-eslint/experimental-utils": "4.6.0", - "@typescript-eslint/scope-manager": "4.6.0", + "@typescript-eslint/experimental-utils": "4.14.2", + "@typescript-eslint/scope-manager": "4.14.2", "debug": "^4.1.1", "functional-red-black-tree": "^1.0.1", + "lodash": "^4.17.15", "regexpp": "^3.0.0", "semver": "^7.3.2", "tsutils": "^3.17.1" }, "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz", + "integrity": "sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/visitor-keys": "4.14.2" + } + }, + "@typescript-eslint/types": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.2.tgz", + "integrity": "sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q==", + "dev": true + }, + "@typescript-eslint/visitor-keys": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz", + "integrity": "sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.14.2", + "eslint-visitor-keys": "^2.0.0" + } + }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, "@typescript-eslint/experimental-utils": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.6.0.tgz", - "integrity": "sha512-pnh6Beh2/4xjJVNL+keP49DFHk3orDHHFylSp3WEjtgW3y1U+6l+jNnJrGlbs6qhAz5z96aFmmbUyKhunXKvKw==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.14.2.tgz", + "integrity": "sha512-mV9pmET4C2y2WlyHmD+Iun8SAEqkLahHGBkGqDVslHkmoj3VnxnGP4ANlwuxxfq1BsKdl/MPieDbohCEQgKrwA==", "dev": true, "requires": { "@types/json-schema": "^7.0.3", - "@typescript-eslint/scope-manager": "4.6.0", - "@typescript-eslint/types": "4.6.0", - "@typescript-eslint/typescript-estree": "4.6.0", + "@typescript-eslint/scope-manager": "4.14.2", + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/typescript-estree": "4.14.2", "eslint-scope": "^5.0.0", "eslint-utils": "^2.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz", + "integrity": "sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/visitor-keys": "4.14.2" + } + }, + "@typescript-eslint/types": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.2.tgz", + "integrity": "sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz", + "integrity": "sha512-ESiFl8afXxt1dNj8ENEZT12p+jl9PqRur+Y19m0Z/SPikGL6rqq4e7Me60SU9a2M28uz48/8yct97VQYaGl0Vg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/visitor-keys": "4.14.2", + "debug": "^4.1.1", + "globby": "^11.0.1", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^7.3.2", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz", + "integrity": "sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.14.2", + "eslint-visitor-keys": "^2.0.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "eslint-visitor-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==", + "dev": true + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } } }, "@typescript-eslint/parser": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.6.0.tgz", - "integrity": "sha512-Dj6NJxBhbdbPSZ5DYsQqpR32MwujF772F2H3VojWU6iT4AqL4BKuoNWOPFCoSZvCcADDvQjDpa6OLDAaiZPz2Q==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.14.2.tgz", + "integrity": "sha512-ipqSP6EuUsMu3E10EZIApOJgWSpcNXeKZaFeNKQyzqxnQl8eQCbV+TSNsl+s2GViX2d18m1rq3CWgnpOxDPgHg==", "dev": true, "requires": { - "@typescript-eslint/scope-manager": "4.6.0", - "@typescript-eslint/types": "4.6.0", - "@typescript-eslint/typescript-estree": "4.6.0", + "@typescript-eslint/scope-manager": "4.14.2", + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/typescript-estree": "4.14.2", "debug": "^4.1.1" }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -5391,29 +7847,29 @@ } }, "@typescript-eslint/scope-manager": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.6.0.tgz", - "integrity": "sha512-uZx5KvStXP/lwrMrfQQwDNvh2ppiXzz5TmyTVHb+5TfZ3sUP7U1onlz3pjoWrK9konRyFe1czyxObWTly27Ang==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.14.2.tgz", + "integrity": "sha512-cuV9wMrzKm6yIuV48aTPfIeqErt5xceTheAgk70N1V4/2Ecj+fhl34iro/vIssJlb7XtzcaD07hWk7Jk0nKghg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.6.0", - "@typescript-eslint/visitor-keys": "4.6.0" + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/visitor-keys": "4.14.2" } }, "@typescript-eslint/types": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.6.0.tgz", - "integrity": "sha512-5FAgjqH68SfFG4UTtIFv+rqYJg0nLjfkjD0iv+5O27a0xEeNZ5rZNDvFGZDizlCD1Ifj7MAbSW2DPMrf0E9zjA==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.14.2.tgz", + "integrity": "sha512-LltxawRW6wXy4Gck6ZKlBD05tCHQUj4KLn4iR69IyRiDHX3d3NCAhO+ix5OR2Q+q9bjCrHE/HKt+riZkd1At8Q==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.6.0.tgz", - "integrity": "sha512-s4Z9qubMrAo/tw0CbN0IN4AtfwuehGXVZM0CHNMdfYMGBDhPdwTEpBrecwhP7dRJu6d9tT9ECYNaWDHvlFSngA==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.14.2.tgz", + "integrity": "sha512-ESiFl8afXxt1dNj8ENEZT12p+jl9PqRur+Y19m0Z/SPikGL6rqq4e7Me60SU9a2M28uz48/8yct97VQYaGl0Vg==", "dev": true, "requires": { - "@typescript-eslint/types": "4.6.0", - "@typescript-eslint/visitor-keys": "4.6.0", + "@typescript-eslint/types": "4.14.2", + "@typescript-eslint/visitor-keys": "4.14.2", "debug": "^4.1.1", "globby": "^11.0.1", "is-glob": "^4.0.1", @@ -5423,29 +7879,32 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, "@typescript-eslint/visitor-keys": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.6.0.tgz", - "integrity": "sha512-38Aa9Ztl0XyFPVzmutHXqDMCu15Xx8yKvUo38Gu3GhsuckCh3StPI5t2WIO9LHEsOH7MLmlGfKUisU8eW1Sjhg==", + "version": "4.14.2", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.14.2.tgz", + "integrity": "sha512-KBB+xLBxnBdTENs/rUgeUKO0UkPBRs2vD09oMRRIkj5BEN8PX1ToXV532desXfpQnZsYTyLLviS7JrPhdL154w==", "dev": true, "requires": { - "@typescript-eslint/types": "4.6.0", + "@typescript-eslint/types": "4.14.2", "eslint-visitor-keys": "^2.0.0" }, "dependencies": { @@ -5645,9 +8104,9 @@ "dev": true }, "abab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.4.tgz", - "integrity": "sha512-Eu9ELJWCz/c1e9gTiCY+FceWxcqzjYEbqMgtndnuSqZSUCOL73TWNK2mHfIj4Cw2E/ongOp+JISVNCmovt2KYQ==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, "abbrev": { @@ -5703,17 +8162,17 @@ "dev": true }, "agent-base": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.1.tgz", - "integrity": "sha512-01q25QQDwLSsyfhrKbn8yuur+JNw0H+0Y4JiGIKd3z9aYk/w/2kxD/Upc+t2ZBBSUNff50VjPsSW2YxM8QYKVg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "requires": { "debug": "4" }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { "ms": "2.1.2" } @@ -5747,71 +8206,30 @@ "react-is": "^16.13.1" }, "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "dev": true }, - "is-callable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", - "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", - "dev": true - }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - }, "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz", + "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==", "dev": true, "requires": { - "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } }, "react-is": { @@ -6265,33 +8683,38 @@ "dev": true }, "array-includes": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", - "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.2.tgz", + "integrity": "sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.1", + "get-intrinsic": "^1.0.1", "is-string": "^1.0.5" }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -6312,25 +8735,58 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } } } }, @@ -6363,20 +8819,20 @@ }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.17.7", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.7.tgz", + "integrity": "sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-regex": "^1.1.1", + "object-inspect": "^1.8.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", + "object.assign": "^4.1.1", "string.prototype.trimend": "^1.0.1", "string.prototype.trimstart": "^1.0.1" } @@ -6399,25 +8855,38 @@ "dev": true }, "is-callable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", - "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } } } }, @@ -6511,33 +8980,37 @@ } }, "array.prototype.flatmap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz", - "integrity": "sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz", + "integrity": "sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", + "es-abstract": "^1.18.0-next.1", "function-bind": "^1.1.1" }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -6558,25 +9031,58 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } } } }, @@ -6654,9 +9160,9 @@ "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "async": { @@ -6683,6 +9189,16 @@ "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", "dev": true }, + "async-retry": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz", + "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==", + "dev": true, + "optional": true, + "requires": { + "retry": "0.12.0" + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -6765,33 +9281,33 @@ }, "dependencies": { "follow-redirects": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", - "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==", "dev": true } } }, "babel-jest": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.3.0.tgz", - "integrity": "sha512-sxPnQGEyHAOPF8NcUsD0g7hDCnvLL2XyblRBcgrzTWBB/mAIpWow3n1bEL+VghnnZfreLhFSBsFluRoK2tRK4g==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.6.3.tgz", + "integrity": "sha512-pl4Q+GAVOHwvjrck6jKjvmGhnO3jHX/xuB9d27f+EJZ/6k+6nMuPjorrYp7s++bKKdANwzElBWnLWaObvTnaZA==", "dev": true, "requires": { - "@jest/transform": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^26.3.0", + "babel-preset-jest": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -6811,12 +9327,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -6858,9 +9373,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -6869,22 +9384,21 @@ } }, "babel-loader": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", - "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.2.2.tgz", + "integrity": "sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==", "dev": true, "requires": { - "find-cache-dir": "^2.1.0", + "find-cache-dir": "^3.3.1", "loader-utils": "^1.4.0", - "mkdirp": "^0.5.3", - "pify": "^4.0.1", + "make-dir": "^3.1.0", "schema-utils": "^2.6.5" }, "dependencies": { "ajv": { - "version": "6.12.4", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.4.tgz", - "integrity": "sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -6893,6 +9407,12 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -6905,6 +9425,27 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, "loader-utils": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", @@ -6916,15 +9457,48 @@ "json5": "^1.0.1" } }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" } } } @@ -6952,9 +9526,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "26.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.2.0.tgz", - "integrity": "sha512-B/hVMRv8Nh1sQ1a3EY8I0n4Y1Wty3NrR5ebOyVT302op+DOAau+xNEImGMsUWOC3++ZlMooCytKz+NgN8aKGbA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.6.2.tgz", + "integrity": "sha512-PO9t0697lNTmcEHH69mdtYiOIkkOlj9fySqfO3K1eCcdISevLAE0xY59VLLUj0SoiPiTX/JU2CYFpILydUa5Lw==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -6980,9 +9554,9 @@ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" }, "babel-preset-current-node-syntax": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-0.1.3.tgz", - "integrity": "sha512-uyexu1sVwcdFnyq9o8UQYsXwXflIh8LvrF5+cKrYam93ned1CStffB3+BEcsxGSgagoA3GEyjDqO4a/58hyPYQ==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, "requires": { "@babel/plugin-syntax-async-generators": "^7.8.4", @@ -6995,17 +9569,18 @@ "@babel/plugin-syntax-numeric-separator": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.3", "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3" + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" } }, "babel-preset-jest": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.3.0.tgz", - "integrity": "sha512-5WPdf7nyYi2/eRxCbVrE1kKCWxgWY4RsPEbdJWFm7QsesFGqjdkyLeu1zRkwM1cxK6EPIlNd6d2AxLk7J+t4pw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-26.6.2.tgz", + "integrity": "sha512-YvdtlVm9t3k777c5NPQIv6cxFFFapys25HiUmuSgHwIZhfifweR5c5Sf5nwE3MAbfu327CYSvps8Yx6ANLyleQ==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^26.2.0", - "babel-preset-current-node-syntax": "^0.1.3" + "babel-plugin-jest-hoist": "^26.6.2", + "babel-preset-current-node-syntax": "^1.0.0" } }, "balanced-match": { @@ -7106,9 +9681,9 @@ "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" }, "binary-extensions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true, "optional": true }, @@ -7182,15 +9757,6 @@ "ms": "2.0.0" } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -7314,21 +9880,13 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } } }, "browserify-sign": { @@ -7517,6 +10075,16 @@ "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -7524,19 +10092,28 @@ "dev": true }, "camel-case": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.1.tgz", - "integrity": "sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "dev": true, "requires": { - "pascal-case": "^3.1.1", - "tslib": "^1.10.0" + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true }, "camelcase-keys": { "version": "2.1.0", @@ -7647,20 +10224,20 @@ } }, "chokidar": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz", - "integrity": "sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A==", + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", "dev": true, "optional": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", - "fsevents": "~2.1.2", + "fsevents": "~2.3.1", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", - "readdirp": "~3.4.0" + "readdirp": "~3.5.0" }, "dependencies": { "braces": { @@ -7683,6 +10260,13 @@ "to-regex-range": "^5.0.1" } }, + "fsevents": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.1.tgz", + "integrity": "sha512-YR47Eg4hChJGAB1O3yEAOkGO+rlzutoICGqGo9EZ4lKWokzZRSyIW1QmTzqjtw8MJdj9srP869CuWw/hyzSiBw==", + "dev": true, + "optional": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -7733,6 +10317,12 @@ "safe-buffer": "^5.0.1" } }, + "cjs-module-lexer": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-0.6.0.tgz", + "integrity": "sha512-uc2Vix1frTfnuzxxu1Hp4ktSvM3QaI4oXl4ZUqL1wjTu/BGki9TrCWoqLTg/drR1KwAEarXuRFCG2Svr1GxPFw==", + "dev": true + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -7852,6 +10442,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", @@ -7861,17 +10452,20 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7882,6 +10476,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -8256,9 +10851,9 @@ "dev": true }, "copy-webpack-plugin": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.1.0.tgz", - "integrity": "sha512-aWjIuLt1OVQxaDVffnt3bnGmLA8zGgAJaFwPA+a+QYVPh1vhIKjVfh3SbOFLV0kRPvGBITbw17n5CsmiBS4LQQ==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-6.4.1.tgz", + "integrity": "sha512-MXyPCjdPVx5iiWyl40Va3JGh27bKzOTNY3NjUTrosD2q7dR/cLD0013uqJ3BpFbUjyONINjb6qI7nDIJujrMbA==", "dev": true, "requires": { "cacache": "^15.0.5", @@ -8269,15 +10864,21 @@ "loader-utils": "^2.0.0", "normalize-path": "^3.0.0", "p-limit": "^3.0.2", - "schema-utils": "^2.7.1", - "serialize-javascript": "^4.0.0", + "schema-utils": "^3.0.0", + "serialize-javascript": "^5.0.1", "webpack-sources": "^1.4.3" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -8326,9 +10927,9 @@ } }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -8355,12 +10956,12 @@ } }, "p-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", - "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", "dev": true, "requires": { - "p-try": "^2.0.0" + "yocto-queue": "^0.1.0" } }, "p-locate": { @@ -8399,15 +11000,24 @@ } }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } } } }, @@ -8417,15 +11027,52 @@ "integrity": "sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA==" }, "core-js-compat": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", - "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.8.3.tgz", + "integrity": "sha512-1sCb0wBXnBIL16pfFG1Gkvei6UzvKyTNYpiC41yrdjEv0UoJoq9E/abTMzyYJ6JpTkAj15dLjbqifIzEBDVvog==", "dev": true, "requires": { - "browserslist": "^4.8.5", + "browserslist": "^4.16.1", "semver": "7.0.0" }, "dependencies": { + "browserslist": { + "version": "4.16.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", + "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001181", + "colorette": "^1.2.1", + "electron-to-chromium": "^1.3.649", + "escalade": "^3.1.1", + "node-releases": "^1.1.70" + } + }, + "caniuse-lite": { + "version": "1.0.30001183", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001183.tgz", + "integrity": "sha512-7JkwTEE1hlRKETbCFd8HDZeLiQIUcl8rC6JgNjvHCNaxOeNmQ9V4LvQXRUsKIV2CC73qKxljwVhToaA3kLRqTw==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.650", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.650.tgz", + "integrity": "sha512-j6pRuNylFBbroG6NB8Lw/Im9oDY74s2zWHBP5TmdYg73cBuL6cz//SMgolVa0gIJk/DSL+kO7baJ1DSXW1FUZg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "node-releases": { + "version": "1.1.70", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.70.tgz", + "integrity": "sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==", + "dev": true + }, "semver": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", @@ -8435,9 +11082,9 @@ } }, "core-js-pure": { - "version": "3.6.5", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.6.5.tgz", - "integrity": "sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA==", + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.8.3.tgz", + "integrity": "sha512-V5qQZVAr9K0xu7jXg1M7qTEwuxUgqr7dUOezGaNa7i+Xn9oXAU/d1fzqD9ObuwpVQOaorO5s70ckyi1woP9lVA==", "dev": true }, "core-util-is": { @@ -8533,10 +11180,16 @@ "warning": "^4.0.3" } }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, "cross-env": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", - "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", "dev": true, "requires": { "cross-spawn": "^7.0.1" @@ -8790,28 +11443,28 @@ "dev": true }, "csso": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", - "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", "dev": true, "requires": { - "css-tree": "1.0.0-alpha.39" + "css-tree": "^1.1.2" }, "dependencies": { "css-tree": { - "version": "1.0.0-alpha.39", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", - "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.2.tgz", + "integrity": "sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==", "dev": true, "requires": { - "mdn-data": "2.0.6", + "mdn-data": "2.0.14", "source-map": "^0.6.1" } }, "mdn-data": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", - "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", "dev": true }, "source-map": { @@ -8846,9 +11499,9 @@ } }, "csstype": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.3.tgz", - "integrity": "sha512-jPl+wbWPOWJ7SXsWyqGRk3lGecbar0Cb0OvZF/r/ZU011R4YqiRehgkQ9p4eQfo9DSDLqLL3wHwfxeJiuIsNag==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.6.tgz", + "integrity": "sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==", "dev": true }, "currently-unhandled": { @@ -8867,9 +11520,9 @@ "dev": true }, "cypress": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/cypress/-/cypress-5.6.0.tgz", - "integrity": "sha512-cs5vG3E2JLldAc16+5yQxaVRLLqMVya5RlrfPWkC72S5xrlHFdw7ovxPb61s4wYweROKTyH01WQc2PFzwwVvyQ==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-6.4.0.tgz", + "integrity": "sha512-SrsPsZ4IBterudkoFYBvkQmXOVxclh1/+ytbzpV8AH/D2FA+s2Qy5ISsaRzOFsbQa4KZWoi3AKwREmF1HucYkg==", "dev": true, "requires": { "@cypress/listr-verbose-renderer": "^0.4.1", @@ -8886,6 +11539,7 @@ "cli-table3": "~0.6.0", "commander": "^5.1.0", "common-tags": "^1.8.0", + "dayjs": "^1.9.3", "debug": "^4.1.1", "eventemitter2": "^6.4.2", "execa": "^4.0.2", @@ -8900,7 +11554,7 @@ "lodash": "^4.17.19", "log-symbols": "^4.0.0", "minimist": "^1.2.5", - "moment": "^2.27.0", + "moment": "^2.29.1", "ospath": "^1.2.2", "pretty-bytes": "^5.4.1", "ramda": "~0.26.1", @@ -8990,15 +11644,15 @@ } }, "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", "dev": true, "requires": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "get-stream": { @@ -9030,14 +11684,6 @@ "requires": { "graceful-fs": "^4.1.6", "universalify": "^2.0.0" - }, - "dependencies": { - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } } }, "npm-run-path": { @@ -9089,9 +11735,9 @@ } }, "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "which": { @@ -9158,6 +11804,12 @@ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", "dev": true }, + "dayjs": { + "version": "1.10.4", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz", + "integrity": "sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==", + "dev": true + }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", @@ -9178,12 +11830,13 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true }, "decimal.js": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz", - "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.1.tgz", + "integrity": "sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==", "dev": true }, "decode-uri-component": { @@ -9192,9 +11845,9 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" }, "deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.0.tgz", - "integrity": "sha512-ZbfWJq/wN1Z273o7mUSjILYqehAktR2NVoSrOukDkU9kg2v/Uv89yU4Cvz8seJeAmtN5oqiefKq8FPuXOboqLw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", "dev": true, "requires": { "is-arguments": "^1.0.4", @@ -9399,9 +12052,9 @@ "dev": true }, "diff-sequences": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-25.2.6.tgz", - "integrity": "sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "diffie-hellman": { @@ -9486,9 +12139,9 @@ } }, "dom-accessibility-api": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.3.tgz", - "integrity": "sha512-yfqzAi1GFxK6EoJIZKgxqJyK6j/OjEFEUi2qkNThD/kUhoCFSG1izq31B5xuxzbJBGw9/67uPtkPMYAzWL7L7Q==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.4.tgz", + "integrity": "sha512-TvrjBckDy2c6v6RLxPv5QXOnU+SmF9nBII5621Ve5fu6Z/BDrENurBEvlC1f44lKEUVqOpK4w9E5Idc5/EgkLQ==", "dev": true }, "dom-converter": { @@ -9530,9 +12183,9 @@ "dev": true }, "dom4": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/dom4/-/dom4-2.1.5.tgz", - "integrity": "sha512-gJbnVGq5zaBUY0lUh0LUEVGYrtN75Ks8ZwpwOYvnVFrKy/qzXK4R/1WuLIFExWj/tBxbRAkTzZUGJHXmqsBNjQ==" + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/dom4/-/dom4-2.1.6.tgz", + "integrity": "sha512-JkCVGnN4ofKGbjf5Uvc8mmxaATIErKQKSgACdBXpsQ3fY6DlIpAyWfiBSrGkttATssbDCp3psiAKWXk5gmjycA==" }, "domain-browser": { "version": "1.2.0", @@ -9583,13 +12236,21 @@ } }, "dot-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.3.tgz", - "integrity": "sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "dev": true, "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "dot-prop": { @@ -9691,18 +12352,18 @@ } }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { @@ -9714,15 +12375,16 @@ } }, "emittery": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.1.tgz", - "integrity": "sha512-d34LN4L6h18Bzz9xpoku2nPwKxCPlPMr3EEKTkoEBi+1/+b0lcRkRJ1UVyyZaKNeqGR3swcGl6s390DNO4YVgQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.7.2.tgz", + "integrity": "sha512-A8OG5SR/ij3SsJdWDJdkkSYUjQdCUx6APQXem0SaEePBSRg4eymGYwBkKo1Y6DU+af/Jn2dBQqDBvjnr9Vi8nQ==", "dev": true }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true }, "emojis-list": { "version": "2.1.0", @@ -9971,71 +12633,170 @@ } }, "enzyme-adapter-react-16": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.4.tgz", - "integrity": "sha512-wPzxs+JaGDK2TPYzl5a9YWGce6i2SQ3Cg51ScLeyj2WotUZ8Obcq1ke/U1Y2VGpYlb9rrX2yCjzSMgtKCeAt5w==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/enzyme-adapter-react-16/-/enzyme-adapter-react-16-1.15.6.tgz", + "integrity": "sha512-yFlVJCXh8T+mcQo8M6my9sPgeGzj85HSHi6Apgf1Cvq/7EL/J9+1JoJmJsRxZgyTvPMAqOEpRSu/Ii/ZpyOk0g==", "dev": true, "requires": { - "enzyme-adapter-utils": "^1.13.1", + "enzyme-adapter-utils": "^1.14.0", "enzyme-shallow-equal": "^1.0.4", "has": "^1.0.3", - "object.assign": "^4.1.0", - "object.values": "^1.1.1", + "object.assign": "^4.1.2", + "object.values": "^1.1.2", "prop-types": "^15.7.2", "react-is": "^16.13.1", "react-test-renderer": "^16.0.0-0", "semver": "^5.7.0" }, "dependencies": { + "es-abstract": { + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.1" + } + }, + "object-inspect": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.2.tgz", + "integrity": "sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1", + "has": "^1.0.3" + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } } } }, "enzyme-adapter-utils": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.1.tgz", - "integrity": "sha512-5A9MXXgmh/Tkvee3bL/9RCAAgleHqFnsurTYCbymecO4ohvtNO5zqIhHxV370t7nJAwaCfkgtffarKpC0GPt0g==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz", + "integrity": "sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg==", "dev": true, "requires": { "airbnb-prop-types": "^2.16.0", - "function.prototype.name": "^1.1.2", - "object.assign": "^4.1.0", - "object.fromentries": "^2.0.2", + "function.prototype.name": "^1.1.3", + "has": "^1.0.3", + "object.assign": "^4.1.2", + "object.fromentries": "^2.0.3", "prop-types": "^15.7.2", "semver": "^5.7.1" - } - }, - "enzyme-shallow-equal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", - "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==", - "dev": true, - "requires": { - "has": "^1.0.3", - "object-is": "^1.1.2" }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -10056,34 +12817,91 @@ "dev": true }, "is-callable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", - "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "object-is": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", - "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.fromentries": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.3.tgz", + "integrity": "sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.5" + "es-abstract": "^1.18.0-next.1", + "has": "^1.0.3" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + } + } + }, + "enzyme-shallow-equal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/enzyme-shallow-equal/-/enzyme-shallow-equal-1.0.4.tgz", + "integrity": "sha512-MttIwB8kKxypwHvRynuC3ahyNc+cFbR8mjVIltnmzQ0uKGqmsfO4bfBuLxb0beLNPhjblUEYvEbsg+VSygvF1Q==", + "dev": true, + "requires": { + "has": "^1.0.3", + "object-is": "^1.1.2" + }, + "dependencies": { + "object-is": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.4.tgz", + "integrity": "sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -10228,13 +13046,13 @@ } }, "eslint": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.12.1.tgz", - "integrity": "sha512-HlMTEdr/LicJfN08LB3nM1rRYliDXOmfoO4vj39xN6BLpFzF00hbwBoqHk8UcJ2M/3nlARZWy/mslvGEuZFvsg==", + "version": "7.19.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.19.0.tgz", + "integrity": "sha512-CGlMgJY56JZ9ZSYhJuhow61lMPPjUzWmChFya71Z/jilVos7mR/jPgaEfVGgMBY5DshbKdG8Ezb8FDCHcoMEMg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@eslint/eslintrc": "^0.2.1", + "@eslint/eslintrc": "^0.3.0", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -10244,10 +13062,10 @@ "eslint-scope": "^5.1.1", "eslint-utils": "^2.1.0", "eslint-visitor-keys": "^2.0.0", - "espree": "^7.3.0", + "espree": "^7.3.1", "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", @@ -10258,7 +13076,7 @@ "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", - "lodash": "^4.17.19", + "lodash": "^4.17.20", "minimatch": "^3.0.4", "natural-compare": "^1.4.0", "optionator": "^0.9.1", @@ -10267,7 +13085,7 @@ "semver": "^7.2.1", "strip-ansi": "^6.0.0", "strip-json-comments": "^3.1.0", - "table": "^5.2.3", + "table": "^6.0.4", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, @@ -10324,9 +13142,9 @@ } }, "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -10366,10 +13184,13 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "shebang-command": { "version": "2.0.0", @@ -10573,9 +13394,9 @@ "dev": true }, "eslint-plugin-cypress": { - "version": "2.11.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.11.1.tgz", - "integrity": "sha512-MxMYoReSO5+IZMGgpBZHHSx64zYPSPTpXDwsgW7ChlJTF/sA+obqRbHplxD6sBStE+g4Mi0LCLkG4t9liu//mQ==", + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-cypress/-/eslint-plugin-cypress-2.11.2.tgz", + "integrity": "sha512-1SergF1sGbVhsf7MYfOLiBhdOg6wqyeV9pXUAIDIffYTGMN3dTBQS9nFAzhLsHhO+Bn0GaVM1Ecm71XUidQ7VA==", "dev": true, "requires": { "globals": "^11.12.0" @@ -10602,21 +13423,21 @@ } }, "eslint-plugin-react": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.20.6.tgz", - "integrity": "sha512-kidMTE5HAEBSLu23CUDvj8dc3LdBU0ri1scwHBZjI41oDv4tjsWZKU7MQccFzH1QYPYhsnTF2ovh7JlcIcmxgg==", + "version": "7.22.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.22.0.tgz", + "integrity": "sha512-p30tuX3VS+NWv9nQot9xIGAHBXR0+xJVaZriEsHoJrASGCJZDJ8JLNM0YqKqI0AKm6Uxaa1VUHoNEibxRCMQHA==", "dev": true, "requires": { "array-includes": "^3.1.1", "array.prototype.flatmap": "^1.2.3", "doctrine": "^2.1.0", "has": "^1.0.3", - "jsx-ast-utils": "^2.4.1", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", "object.entries": "^1.1.2", "object.fromentries": "^2.0.2", "object.values": "^1.1.1", "prop-types": "^15.7.2", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "string.prototype.matchall": "^4.0.2" }, "dependencies": { @@ -10630,20 +13451,21 @@ } }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } } } }, "eslint-plugin-react-hooks": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.1.2.tgz", - "integrity": "sha512-ykUeqkGyUGgwTtk78C0o8UG2fzwmgJ0qxBGPp2WqRKsTwcLuVf01kTDRAtOsd4u6whX2XOC8749n2vPydP82fg==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.2.0.tgz", + "integrity": "sha512-623WEiZJqxR7VdxFCKLI6d6LLpwJkGPYKODnkH3D7WpOG5KM8yWueBd8TLsNAetEJNF5iJmolaAKO3F8yzyVBQ==", "dev": true }, "eslint-scope": { @@ -10691,13 +13513,13 @@ "dev": true }, "espree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz", - "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "dev": true, "requires": { "acorn": "^7.4.0", - "acorn-jsx": "^5.2.0", + "acorn-jsx": "^5.3.1", "eslint-visitor-keys": "^1.3.0" } }, @@ -10725,12 +13547,20 @@ } }, "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", "dev": true, "requires": { - "estraverse": "^4.1.0" + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } } }, "esrever": { @@ -10767,9 +13597,9 @@ "dev": true }, "eventemitter3": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", - "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "dev": true }, "events": { @@ -10835,6 +13665,11 @@ } } }, + "exenv": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz", + "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50=" + }, "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", @@ -10907,23 +13742,23 @@ } }, "expect": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-26.4.2.tgz", - "integrity": "sha512-IlJ3X52Z0lDHm7gjEp+m76uX46ldH5VpqmU0006vqDju/285twh7zaWMRhs67VpQhBwjjMchk+p5aA0VkERCAA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/expect/-/expect-26.6.2.tgz", + "integrity": "sha512-9/hlOBkQl2l/PLHJx6JjoDF6xPKcJEsUlWKb23rKE7KzeDqUZKXKNMW27KIue5JMdBV9HgmoJPcc8HtO85t9IA==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-styles": "^4.0.0", "jest-get-type": "^26.3.0", - "jest-matcher-utils": "^26.4.2", - "jest-message-util": "^26.3.0", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", "jest-regex-util": "^26.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -10943,12 +13778,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -10990,9 +13824,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -11349,28 +14183,34 @@ } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "dev": true, "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-loader": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.1.0.tgz", - "integrity": "sha512-26qPdHyTsArQ6gU4P1HJbAbnFTyT2r0pG7czh1GFAd9TZbj0n94wWbupgixZH/ET/meqi2/5+F7DhW4OAXD+Lg==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "schema-utils": "^2.7.1" + "schema-utils": "^3.0.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -11398,9 +14238,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -11418,22 +14258,22 @@ } }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } } } }, "file-saver": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.2.tgz", - "integrity": "sha512-Wz3c3XQ5xroCxd1G8b7yL0Ehkf0TC9oYC6buPFkNnU9EnaPlifeAFCyCh+iewXTyFRcg0a6j3J7FmJsIhlhBdw==" + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" }, "file-uri-to-path": { "version": "1.0.0", @@ -11551,20 +14391,20 @@ } }, "firebase": { - "version": "7.22.1", - "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.22.1.tgz", - "integrity": "sha512-pMx+Wg6Bl74PNdWxjGLrFxLqtmIB/Ggl8oYQZLl1baa9xPcb9rxut5ZgDcLZlFERBL6vNRhLEszv/+3H827m9A==", + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.24.0.tgz", + "integrity": "sha512-j6jIyGFFBlwWAmrlUg9HyQ/x+YpsPkc/TTkbTyeLwwAJrpAmmEHNPT6O9xtAnMV4g7d3RqLL/u9//aZlbY4rQA==", "requires": { - "@firebase/analytics": "0.5.0", + "@firebase/analytics": "0.6.0", "@firebase/app": "0.6.11", "@firebase/app-types": "0.6.1", - "@firebase/auth": "0.14.9", + "@firebase/auth": "0.15.0", "@firebase/database": "0.6.13", - "@firebase/firestore": "1.17.2", + "@firebase/firestore": "1.18.0", "@firebase/functions": "0.5.1", "@firebase/installations": "0.4.17", "@firebase/messaging": "0.7.1", - "@firebase/performance": "0.4.1", + "@firebase/performance": "0.4.2", "@firebase/polyfill": "0.3.36", "@firebase/remote-config": "0.1.28", "@firebase/storage": "0.3.43", @@ -11572,47 +14412,86 @@ } }, "firebase-admin": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.2.0.tgz", - "integrity": "sha512-LhnMYl71B4gP1FlTLfwaYlOWhBCAcNF+byb2CPTfaW/T4hkp4qlXOgo2bws/zbAv5X9GTFqGir3KexMslVGsIA==", + "version": "9.4.2", + "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.4.2.tgz", + "integrity": "sha512-mRnBJbW6BAz6DJkZ0GOUTkmnmCrwVzMreMc6O+RXWukFydOzi5Xr6TKSiPKxoOQw41r9IluP2AZ3Qzvlx2SR+g==", "dev": true, "requires": { - "@firebase/database": "^0.6.10", - "@firebase/database-types": "^0.5.2", - "@google-cloud/firestore": "^4.0.0", + "@firebase/database": "^0.8.1", + "@firebase/database-types": "^0.6.1", + "@google-cloud/firestore": "^4.5.0", "@google-cloud/storage": "^5.3.0", "@types/node": "^10.10.0", "dicer": "^0.3.0", "jsonwebtoken": "^8.5.1", "node-forge": "^0.10.0" - } - }, - "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" }, "dependencies": { - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "@firebase/component": { + "version": "0.1.21", + "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.1.21.tgz", + "integrity": "sha512-kd5sVmCLB95EK81Pj+yDTea8pzN2qo/1yr0ua9yVi6UgMzm6zAeih73iVUkaat96MAHy26yosMufkvd3zC4IKg==", "dev": true, "requires": { - "glob": "^7.1.3" + "@firebase/util": "0.3.4", + "tslib": "^1.11.1" + } + }, + "@firebase/database": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.8.3.tgz", + "integrity": "sha512-i29rr3kcPltIkA8La9M1lgsSxx9bfu5lCQ0T+tbJptZ3UpqpcL1NzCcZa24cJjiLgq3HQNPyLvUvCtcPSFDlRg==", + "dev": true, + "requires": { + "@firebase/auth-interop-types": "0.1.5", + "@firebase/component": "0.1.21", + "@firebase/database-types": "0.6.1", + "@firebase/logger": "0.2.6", + "@firebase/util": "0.3.4", + "faye-websocket": "0.11.3", + "tslib": "^1.11.1" + } + }, + "@firebase/database-types": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.6.1.tgz", + "integrity": "sha512-JtL3FUbWG+bM59iYuphfx9WOu2Mzf0OZNaqWiQ7lJR8wBe7bS9rIm9jlBFtksB7xcya1lZSQPA/GAy2jIlMIkA==", + "dev": true, + "requires": { + "@firebase/app-types": "0.6.1" + } + }, + "@firebase/util": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@firebase/util/-/util-0.3.4.tgz", + "integrity": "sha512-VwjJUE2Vgr2UMfH63ZtIX9Hd7x+6gayi6RUXaTqEYxSbf/JmehLmAEYSuxS/NckfzAXWeGnKclvnXVibDgpjQQ==", + "dev": true, + "requires": { + "tslib": "^1.11.1" } + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true } } }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", "dev": true }, "flush-write-stream": { @@ -11652,37 +14531,17 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" + "safe-buffer": "~5.1.0" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, + "follow-redirects": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.2.tgz", + "integrity": "sha512-6mPTgLxYm3r6Bkkg0vNM0HTjfGrOEtsfbhagQvbxDEsEkpNhw582upBaoRZylzen6krEmxXJgt9Ju6HiI4O7BA==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -11888,33 +14747,37 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "function.prototype.name": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.2.tgz", - "integrity": "sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.3.tgz", + "integrity": "sha512-H51qkbNSp8mtkJt+nyW1gyStBiKZxfRqySNUR99ylq6BPXHKI4SEvIlTKp4odLfjRKJV04DFWMU3G/YRlQOsag==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1", - "functions-have-names": "^1.2.0" + "es-abstract": "^1.18.0-next.1", + "functions-have-names": "^1.2.1" }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -11935,25 +14798,58 @@ "dev": true }, "is-callable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.1.tgz", - "integrity": "sha512-wliAfSzx6V+6WfMOmus1xy0XvSgf/dlStkvTfq7F0g4bOIW0PSUbnyse3NhDwdyYS1ozfUtAAySqTws3z9Eqgg==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } } } }, @@ -11964,9 +14860,9 @@ "dev": true }, "functions-have-names": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.1.tgz", - "integrity": "sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.2.tgz", + "integrity": "sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA==", "dev": true }, "gauge": { @@ -11986,9 +14882,9 @@ } }, "gaxios": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-3.2.0.tgz", - "integrity": "sha512-+6WPeVzPvOshftpxJwRi2Ozez80tn/hdtOUag7+gajDHRJvAblKxTFSSMPtr2hmnLy7p0mvYz0rMXLBl8pSO7Q==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.1.0.tgz", + "integrity": "sha512-vb0to8xzGnA2qcgywAjtshOKKVDf2eQhJoiL6fHhgW5tVN7wNk7egnYIO9zotfn3lQ3De1VPdf7V5/BWfCtCmg==", "requires": { "abort-controller": "^3.0.0", "extend": "^3.0.2", @@ -12014,25 +14910,25 @@ } }, "gcp-metadata": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.0.tgz", - "integrity": "sha512-vQZD57cQkqIA6YPGXM/zc+PIZfNRFdukWGsGZ5+LcJzesi5xp6Gn7a02wRJi4eXPyArNMIYpPET4QMxGqtlk6Q==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.2.1.tgz", + "integrity": "sha512-tSk+REe5iq/N+K+SK1XjZJUrFPuDqGZVzCy2vocIHIGmPlTGsa8owXMJwGkrXr73NO0AzhPW4MF2DEHz7P2AVw==", "requires": { - "gaxios": "^3.0.0", + "gaxios": "^4.0.0", "json-bigint": "^1.0.0" } }, "gcs-resumable-upload": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.1.tgz", - "integrity": "sha512-RS1osvAicj9+MjCc6jAcVL1Pt3tg7NK2C2gXM5nqD1Gs0klF2kj5nnAFSBy97JrtslMIQzpb7iSuxaG8rFWd2A==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/gcs-resumable-upload/-/gcs-resumable-upload-3.1.2.tgz", + "integrity": "sha512-VKWP3Xju1JmNX3N4ossnGp3DfIRZjOsMj8sDGPBGnvn8YSruCOVGQBvELfStfIFPybScv/e5sEdWx/qzfnS3+w==", "dev": true, "optional": true, "requires": { "abort-controller": "^3.0.0", "configstore": "^5.0.0", "extend": "^3.0.2", - "gaxios": "^3.0.0", + "gaxios": "^4.0.0", "google-auth-library": "^6.0.0", "pumpify": "^2.0.0", "stream-events": "^1.0.4" @@ -12047,13 +14943,33 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true }, "get-document": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-document/-/get-document-1.0.0.tgz", "integrity": "sha1-SCG85m8cJMsDMWAr5strEsTwHEs=" }, + "get-intrinsic": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.0.tgz", + "integrity": "sha512-M11rgtQp5GZMZzDL7jLTNxbDfurpzuau5uqRWDPvlHjfvg3TdScAZo96GLvhMjImrmR8uAt0FS2RLoMrfWGKlg==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + } + } + }, "get-package-type": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", @@ -12141,12 +15057,20 @@ } }, "global-dirs": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz", - "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz", + "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==", "dev": true, "requires": { - "ini": "^1.3.5" + "ini": "1.3.7" + }, + "dependencies": { + "ini": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", + "dev": true + } } }, "global-modules": { @@ -12215,16 +15139,16 @@ } }, "google-auth-library": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.1.tgz", - "integrity": "sha512-0WfExOx3FrLYnY88RICQxvpaNzdwjz44OsHqHkIoAJfjY6Jck6CZRl1ASWadk+wbJ0LhkQ8rNY4zZebKml4Ghg==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-6.1.6.tgz", + "integrity": "sha512-Q+ZjUEvLQj/lrVHF/IQwRo6p3s8Nc44Zk/DALsN+ac3T4HY/g/3rrufkgtl+nZ1TW7DNAw5cTChdVp4apUXVgQ==", "requires": { "arrify": "^2.0.0", "base64-js": "^1.3.0", "ecdsa-sig-formatter": "^1.0.11", "fast-text-encoding": "^1.0.0", - "gaxios": "^3.0.0", - "gcp-metadata": "^4.1.0", + "gaxios": "^4.0.0", + "gcp-metadata": "^4.2.0", "gtoken": "^5.0.4", "jws": "^4.0.0", "lru-cache": "^6.0.0" @@ -12252,21 +15176,22 @@ } }, "google-gax": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.9.0.tgz", - "integrity": "sha512-MFMwA7Fb8PEwjnYwfGXjZMidCNyMl3gSnvS/+kS8TQioJZQDpzK+W3dmwyNyig/U13+kbABqDnbkkAXJ5NiUkw==", + "version": "2.10.2", + "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.10.2.tgz", + "integrity": "sha512-adECud3d5jsk24SvPkKQG3Kw1szpy4We0OqKfsdBHKWlSWhdY4hVQEOG7iBBp469Zm327fzz7NZz8BMLOYZJHg==", "dev": true, "optional": true, "requires": { - "@grpc/grpc-js": "~1.1.1", + "@grpc/grpc-js": "~1.2.0", "@grpc/proto-loader": "^0.5.1", "@types/long": "^4.0.0", "abort-controller": "^3.0.0", "duplexify": "^4.0.0", - "google-auth-library": "^6.0.0", + "fast-text-encoding": "^1.0.3", + "google-auth-library": "^6.1.3", "is-stream-ended": "^0.1.4", "node-fetch": "^2.6.1", - "protobufjs": "^6.9.0", + "protobufjs": "^6.10.2", "retry-request": "^4.0.0" }, "dependencies": { @@ -12307,14 +15232,13 @@ "optional": true }, "gtoken": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.0.4.tgz", - "integrity": "sha512-U9wnSp4GZ7ov6zRdPuRHG4TuqEWqRRgT1gfXGNArhzBUn9byrPeH8uTmBWU/ZiWJJvTEmkjhDIC3mqHWdVi3xQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.2.1.tgz", + "integrity": "sha512-OY0BfPKe3QnMsY9MzTHTSKn+Vl2l1CcLe6BwDEQj00mbbkl5nyQ/7EUREstg4fQNZ8iYE7br4JJ7TdKeDOPWmw==", "requires": { - "gaxios": "^3.0.0", + "gaxios": "^4.0.0", "google-p12-pem": "^3.0.3", - "jws": "^4.0.0", - "mime": "^2.2.0" + "jws": "^4.0.0" }, "dependencies": { "jwa": { @@ -12572,9 +15496,9 @@ } }, "html-entities": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", - "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.4.0.tgz", + "integrity": "sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA==", "dev": true }, "html-escaper": { @@ -12599,9 +15523,9 @@ } }, "html-webpack-plugin": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.4.1.tgz", - "integrity": "sha512-nEtdEIsIGXdXGG7MjTTZlmhqhpHU9pJFc1OYxcP36c5/ZKP6b0BJMww2QTvJGQYA9aMxUnjDujpZdYcVOXiBCQ==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.5.1.tgz", + "integrity": "sha512-yzK7RQZwv9xB+pcdHNTjcqbaaDZ+5L0zJHXfi89iWIZmb/FtzxhLk0635rmJihcQbs3ZUF27Xp4oWGx6EK56zg==", "dev": true, "requires": { "@types/html-minifier-terser": "^5.0.0", @@ -12609,7 +15533,7 @@ "@types/webpack": "^4.41.8", "html-minifier-terser": "^5.0.1", "loader-utils": "^1.2.3", - "lodash": "^4.17.15", + "lodash": "^4.17.20", "pretty-error": "^2.1.1", "tapable": "^1.1.3", "util.promisify": "1.0.0" @@ -12685,9 +15609,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "optional": true, "requires": { @@ -12735,9 +15659,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { "ms": "2.1.2" } @@ -12750,6 +15674,15 @@ "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", "dev": true }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "icss-utils": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-4.1.1.tgz", @@ -12765,9 +15698,9 @@ "integrity": "sha512-+FLa/0sTXqyux0o6C+i2lOR0VoS60LU/jzUo5xjfY6+7sEEgy4Gz1O7yFBXvjd7N0NyIGWIRg8DcQSLEG+VSPw==" }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "iferr": { @@ -12933,73 +15866,14 @@ } }, "internal-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.2.tgz", - "integrity": "sha512-2cQNfwhAfJIkU4KZPkDI+Gj5yNNnbqi40W9Gge6dfnk4TocEVm00B3bdiL+JINrbGJil2TeHvM4rETGzk/f/0g==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", + "get-intrinsic": "^1.1.0", "has": "^1.0.3", - "side-channel": "^1.0.2" - }, - "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, - "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", - "dev": true - } + "side-channel": "^1.0.4" } }, "interpret": { @@ -13102,6 +15976,15 @@ "ci-info": "^2.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -13196,9 +16079,9 @@ } }, "is-hotkey": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.6.tgz", - "integrity": "sha512-1+hMr0GLPM0M49UDRt9RgE8i+SM29UY4AGRP6sGz6fThOVXqSrEvTMakolhHMcVizJnPNAoMpEmE+Oi1k2NrZQ==", + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/is-hotkey/-/is-hotkey-0.1.8.tgz", + "integrity": "sha512-qs3NZ1INIS+H+yeo7cD9pDfwYV/jqRh1JG9S9zYrNudkoUQg7OL7ziXqRKu+InFjUIDoP2o6HIkLYMh1pcWgyQ==", "dev": true }, "is-in-browser": { @@ -13216,6 +16099,12 @@ "is-path-inside": "^3.0.1" } }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, "is-number": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", @@ -13467,9 +16356,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -13489,12 +16378,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "source-map": { @@ -13516,20 +16405,20 @@ } }, "jest": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-26.4.2.tgz", - "integrity": "sha512-LLCjPrUh98Ik8CzW8LLVnSCfLaiY+wbK53U7VxnFSX7Q+kWC4noVeDvGWIFw0Amfq1lq2VfGm7YHWSLBV62MJw==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest/-/jest-26.6.3.tgz", + "integrity": "sha512-lGS5PXGAzR4RF7V5+XObhqz2KZIDUA1yD0DG6pBVmy10eh0ZIXQImRuzocsI/N2XZ1GrLFwTS27In2i2jlpq1Q==", "dev": true, "requires": { - "@jest/core": "^26.4.2", + "@jest/core": "^26.6.3", "import-local": "^3.0.2", - "jest-cli": "^26.4.2" + "jest-cli": "^26.6.3" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13549,15 +16438,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -13583,6 +16480,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -13595,53 +16501,92 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "jest-cli": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.4.2.tgz", - "integrity": "sha512-zb+lGd/SfrPvoRSC/0LWdaWCnscXc1mGYW//NP4/tmBvRPT3VntZ2jtKUONsRi59zc5JqmsSajA9ewJKFYp8Cw==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-26.6.3.tgz", + "integrity": "sha512-GF9noBSa9t08pSyl3CY4frMrqp+aQXFGFkf5hEPbh/pIUFYWMK6ZLTfbmadxJVcJrdRoChlWQsA2VkJcDFK8hg==", "dev": true, "requires": { - "@jest/core": "^26.4.2", - "@jest/test-result": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/core": "^26.6.3", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.4", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^26.4.2", - "jest-util": "^26.3.0", - "jest-validate": "^26.4.2", + "jest-config": "^26.6.3", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "prompts": "^2.0.1", - "yargs": "^15.3.1" + "yargs": "^15.4.1" + } + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-changed-files": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.3.0.tgz", - "integrity": "sha512-1C4R4nijgPltX6fugKxM4oQ18zimS7LqQ+zTTY8lMCMFPrxqBFb7KJH0Z2fRQJvw2Slbaipsqq7s1mgX5Iot+g==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-26.6.2.tgz", + "integrity": "sha512-fDS7szLcY9sCtIip8Fjry9oGf3I2ht/QT21bAHm5Dmf0mD4X3ReNUf17y+bO6fR8WgbIZTlbyG1ak/53cbRzKQ==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "execa": "^4.0.0", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13661,12 +16606,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -13707,9 +16651,9 @@ } }, "execa": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", - "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -13784,9 +16728,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -13804,35 +16748,35 @@ } }, "jest-config": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.4.2.tgz", - "integrity": "sha512-QBf7YGLuToiM8PmTnJEdRxyYy3mHWLh24LJZKVdXZ2PNdizSe1B/E8bVm+HYcjbEzGuVXDv/di+EzdO/6Gq80A==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-26.6.3.tgz", + "integrity": "sha512-t5qdIj/bCj2j7NFVHb2nFB4aUdfucDn3JRKgrZnplb8nieAirAzRSHP8uDEd+qV6ygzg9Pz4YG7UTJf94LPSyg==", "dev": true, "requires": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^26.4.2", - "@jest/types": "^26.3.0", - "babel-jest": "^26.3.0", + "@jest/test-sequencer": "^26.6.3", + "@jest/types": "^26.6.2", + "babel-jest": "^26.6.3", "chalk": "^4.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", "graceful-fs": "^4.2.4", - "jest-environment-jsdom": "^26.3.0", - "jest-environment-node": "^26.3.0", + "jest-environment-jsdom": "^26.6.2", + "jest-environment-node": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-jasmine2": "^26.4.2", + "jest-jasmine2": "^26.6.3", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.4.0", - "jest-util": "^26.3.0", - "jest-validate": "^26.4.2", + "jest-resolve": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "micromatch": "^4.0.2", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -13858,12 +16802,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -13934,6 +16877,20 @@ "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -13945,27 +16902,27 @@ } }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -13983,31 +16940,30 @@ } }, "jest-diff": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-25.5.0.tgz", - "integrity": "sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { - "chalk": "^3.0.0", - "diff-sequences": "^25.2.6", - "jest-get-type": "^25.2.6", - "pretty-format": "^25.5.0" + "chalk": "^4.0.0", + "diff-sequences": "^26.6.2", + "jest-get-type": "^26.3.0", + "pretty-format": "^26.6.2" }, "dependencies": { "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -14056,22 +17012,22 @@ } }, "jest-each": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.4.2.tgz", - "integrity": "sha512-p15rt8r8cUcRY0Mvo1fpkOGYm7iI8S6ySxgIdfh3oOIv+gHwrHTy5VWCGOecWUhDsit4Nz8avJWdT07WLpbwDA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-26.6.2.tgz", + "integrity": "sha512-Mer/f0KaATbjl8MCJ+0GEpNdqmnVmDYqCTJYTvoo7rqmRiDllmp2AYN+06F93nXcY3ur9ShIjS+CO/uD+BbH4A==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "jest-get-type": "^26.3.0", - "jest-util": "^26.3.0", - "pretty-format": "^26.4.2" + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14097,15 +17053,23 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -14131,66 +17095,120 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, "jest-get-type": { "version": "26.3.0", "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-environment-jsdom": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.3.0.tgz", - "integrity": "sha512-zra8He2btIMJkAzvLaiZ9QwEPGEetbxqmjEBQwhH3CA+Hhhu0jSiEJxnJMbX28TGUvPLxBt/zyaTLrOPF4yMJA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-26.6.2.tgz", + "integrity": "sha512-jgPqCruTlt3Kwqg5/WVFyHIOJHsiAvhcp2qiR2QQstuG9yWox5+iHpU3ZrcBxW14T4fe5Z68jAfLRh7joCSP2Q==", "dev": true, "requires": { - "@jest/environment": "^26.3.0", - "@jest/fake-timers": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "jest-mock": "^26.3.0", - "jest-util": "^26.3.0", - "jsdom": "^16.2.2" + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2", + "jsdom": "^16.4.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14210,15 +17228,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -14244,41 +17270,95 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-environment-node": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.3.0.tgz", - "integrity": "sha512-c9BvYoo+FGcMj5FunbBgtBnbR5qk3uky8PKyRVpSfe2/8+LrNQMiXX53z6q2kY+j15SkjQCOSL/6LHnCPLVHNw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-26.6.2.tgz", + "integrity": "sha512-zhtMio3Exty18dy8ee8eJ9kjnRyZC1N4C1Nt/VShN1apyXc8rWGtJ9lI7vqiWcyyXS4BVSEn9lxAM2D+07/Tag==", "dev": true, "requires": { - "@jest/environment": "^26.3.0", - "@jest/fake-timers": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", - "jest-mock": "^26.3.0", - "jest-util": "^26.3.0" + "jest-mock": "^26.6.2", + "jest-util": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14298,15 +17378,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -14332,36 +17420,90 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", + "version": "26.3.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.3.0.tgz", + "integrity": "sha512-TpfaviN1R2pQWkIihlfEanwOXK0zcxrKEE4MlU6Tn7keoXdN6/3gK/xl0yEh8DOunn5pOVGKf8hB4R9gVh04ig==", "dev": true }, "jest-haste-map": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.3.0.tgz", - "integrity": "sha512-DHWBpTJgJhLLGwE5Z1ZaqLTYqeODQIZpby0zMBsCU9iRFHYyhklYqP4EiG73j5dkbaAdSZhgB938mL51Q5LeZA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-26.6.2.tgz", + "integrity": "sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "@types/graceful-fs": "^4.1.2", "@types/node": "*", "anymatch": "^3.0.3", @@ -14369,18 +17511,18 @@ "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", - "jest-serializer": "^26.3.0", - "jest-util": "^26.3.0", - "jest-worker": "^26.3.0", + "jest-serializer": "^26.6.2", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14400,12 +17542,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -14470,6 +17611,20 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -14481,9 +17636,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -14501,35 +17656,35 @@ } }, "jest-jasmine2": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.4.2.tgz", - "integrity": "sha512-z7H4EpCldHN1J8fNgsja58QftxBSL+JcwZmaXIvV9WKIM+x49F4GLHu/+BQh2kzRKHAgaN/E82od+8rTOBPyPA==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-26.6.3.tgz", + "integrity": "sha512-kPKUrQtc8aYwBV7CqBg5pu+tmYXlvFlSFYn18ev4gPFtrRzB15N2gW/Roew3187q2w2eHuu0MU9TJz6w0/nPEg==", "dev": true, "requires": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^26.3.0", - "@jest/source-map": "^26.3.0", - "@jest/test-result": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/environment": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "expect": "^26.4.2", + "expect": "^26.6.2", "is-generator-fn": "^2.0.0", - "jest-each": "^26.4.2", - "jest-matcher-utils": "^26.4.2", - "jest-message-util": "^26.3.0", - "jest-runtime": "^26.4.2", - "jest-snapshot": "^26.4.2", - "jest-util": "^26.3.0", - "pretty-format": "^26.4.2", + "jest-each": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "pretty-format": "^26.6.2", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14555,15 +17710,23 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -14589,55 +17752,109 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-leak-detector": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.4.2.tgz", - "integrity": "sha512-akzGcxwxtE+9ZJZRW+M2o+nTNnmQZxrHJxX/HjgDaU5+PLmY1qnQPnMjgADPGCRPhB+Yawe1iij0REe+k/aHoA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-26.6.2.tgz", + "integrity": "sha512-i4xlXpsVSMeKvg2cEKdfhh0H39qlJlP5Ex1yQxwF9ubahboQYMgTtz5oML35AVA3B4Eu+YsmwaiKVev9KCvLxg==", "dev": true, "requires": { "jest-get-type": "^26.3.0", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14663,12 +17880,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -14710,27 +17926,27 @@ "dev": true }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -14739,21 +17955,21 @@ } }, "jest-matcher-utils": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.4.2.tgz", - "integrity": "sha512-KcbNqWfWUG24R7tu9WcAOKKdiXiXCbMvQYT6iodZ9k1f7065k0keUOW6XpJMMvah+hTfqkhJhRXmA3r3zMAg0Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-26.6.2.tgz", + "integrity": "sha512-llnc8vQgYcNqDrqRDXWwMr9i7rS5XFiCwvh6DTP7Jqa2mqpcCBBlpCbn+trkG0KNhPu/h8rzyBkriOtBstvWhw==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^26.4.2", + "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14779,12 +17995,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -14814,9 +18029,9 @@ "dev": true }, "diff-sequences": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", - "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "has-flag": { @@ -14826,15 +18041,15 @@ "dev": true }, "jest-diff": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz", - "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.3.0", + "diff-sequences": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" } }, "jest-get-type": { @@ -14844,27 +18059,27 @@ "dev": true }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -14873,25 +18088,26 @@ } }, "jest-message-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.3.0.tgz", - "integrity": "sha512-xIavRYqr4/otGOiLxLZGj3ieMmjcNE73Ui+LdSW/Y790j5acqCsAdDiLIbzHCZMpN07JOENRWX5DcU+OQ+TjTA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-26.6.2.tgz", + "integrity": "sha512-rGiLePzQ3AzwUshu2+Rn+UMFk0pHN58sOG+IaJbk5Jxuqo3NYO1U2/MIR4S1sKgsoYSXSzdtSa0TgrmtUwEbmA==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^26.3.0", - "@types/stack-utils": "^1.0.1", + "@jest/types": "^26.6.2", + "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "micromatch": "^4.0.2", + "pretty-format": "^26.6.2", "slash": "^3.0.0", "stack-utils": "^2.0.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -14910,13 +18126,18 @@ "@types/istanbul-lib-report": "*" } }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -14991,10 +18212,28 @@ "picomatch": "^2.0.5" } }, + "pretty-format": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "ansi-regex": "^5.0.0", + "ansi-styles": "^4.0.0", + "react-is": "^17.0.1" + } + }, + "react-is": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", + "dev": true + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15012,19 +18251,19 @@ } }, "jest-mock": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.3.0.tgz", - "integrity": "sha512-PeaRrg8Dc6mnS35gOo/CbZovoDPKAeB1FICZiuagAgGvbWdNNyjQjkOaGUa/3N3JtpQ/Mh9P4A2D4Fv51NnP8Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-26.6.2.tgz", + "integrity": "sha512-YyFjePHHp1LzpzYcmgqkJ0nm0gg/lJx2aZFzFy1S6eUqNjXsOqTK10zNRff2dNfssgokjkG65OlWNcIlgd3zew==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "@types/node": "*" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15044,12 +18283,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -15085,9 +18323,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15108,25 +18346,25 @@ "dev": true }, "jest-resolve": { - "version": "26.4.0", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.4.0.tgz", - "integrity": "sha512-bn/JoZTEXRSlEx3+SfgZcJAVuTMOksYq9xe9O6s4Ekg84aKBObEaVXKOEilULRqviSLAYJldnoWV9c07kwtiCg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-26.6.2.tgz", + "integrity": "sha512-sOxsZOq25mT1wRsfHcbtkInS+Ek7Q8jCHUB0ZUTP0tc/c41QHriU/NunqMfCUWsL4H3MHpvQD4QR9kSYhS7UvQ==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^26.3.0", + "jest-util": "^26.6.2", "read-pkg-up": "^7.0.1", - "resolve": "^1.17.0", + "resolve": "^1.18.1", "slash": "^3.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15146,15 +18384,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -15180,6 +18426,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -15192,41 +18447,81 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "dev": true, "requires": { + "is-core-module": "^2.1.0", "path-parse": "^1.0.6" } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-resolve-dependencies": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.4.2.tgz", - "integrity": "sha512-ADHaOwqEcVc71uTfySzSowA/RdxUpCxhxa2FNLiin9vWLB1uLPad3we+JSSROq5+SrL9iYPdZZF8bdKM7XABTQ==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-26.6.3.tgz", + "integrity": "sha512-pVwUjJkxbhe4RY8QEWzN3vns2kqyuldKpxlxJlzEYfKSvY6/bMvxoFrYYzUO1Gx28yKWN37qyV7rIoIp2h8fTg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-snapshot": "^26.4.2" + "jest-snapshot": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15246,12 +18541,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -15287,9 +18581,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15298,37 +18592,37 @@ } }, "jest-runner": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.4.2.tgz", - "integrity": "sha512-FgjDHeVknDjw1gRAYaoUoShe1K3XUuFMkIaXbdhEys+1O4bEJS8Avmn4lBwoMfL8O5oFTdWYKcf3tEJyyYyk8g==", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-26.6.3.tgz", + "integrity": "sha512-atgKpRHnaA2OvByG/HpGA4g6CSPS/1LK0jK3gATJAoptC1ojltpmVlYC3TYgdmGp+GLuhzpH30Gvs36szSL2JQ==", "dev": true, "requires": { - "@jest/console": "^26.3.0", - "@jest/environment": "^26.3.0", - "@jest/test-result": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.7.1", "exit": "^0.1.2", "graceful-fs": "^4.2.4", - "jest-config": "^26.4.2", + "jest-config": "^26.6.3", "jest-docblock": "^26.0.0", - "jest-haste-map": "^26.3.0", - "jest-leak-detector": "^26.4.2", - "jest-message-util": "^26.3.0", - "jest-resolve": "^26.4.0", - "jest-runtime": "^26.4.2", - "jest-util": "^26.3.0", - "jest-worker": "^26.3.0", + "jest-haste-map": "^26.6.2", + "jest-leak-detector": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", + "jest-runtime": "^26.6.3", + "jest-util": "^26.6.2", + "jest-worker": "^26.6.2", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15348,15 +18642,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -15382,6 +18684,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -15394,55 +18705,95 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-runtime": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.4.2.tgz", - "integrity": "sha512-4Pe7Uk5a80FnbHwSOk7ojNCJvz3Ks2CNQWT5Z7MJo4tX0jb3V/LThKvD9tKPNVNyeMH98J/nzGlcwc00R2dSHQ==", - "dev": true, - "requires": { - "@jest/console": "^26.3.0", - "@jest/environment": "^26.3.0", - "@jest/fake-timers": "^26.3.0", - "@jest/globals": "^26.4.2", - "@jest/source-map": "^26.3.0", - "@jest/test-result": "^26.3.0", - "@jest/transform": "^26.3.0", - "@jest/types": "^26.3.0", + "version": "26.6.3", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-26.6.3.tgz", + "integrity": "sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==", + "dev": true, + "requires": { + "@jest/console": "^26.6.2", + "@jest/environment": "^26.6.2", + "@jest/fake-timers": "^26.6.2", + "@jest/globals": "^26.6.2", + "@jest/source-map": "^26.6.2", + "@jest/test-result": "^26.6.2", + "@jest/transform": "^26.6.2", + "@jest/types": "^26.6.2", "@types/yargs": "^15.0.0", "chalk": "^4.0.0", + "cjs-module-lexer": "^0.6.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.4", - "jest-config": "^26.4.2", - "jest-haste-map": "^26.3.0", - "jest-message-util": "^26.3.0", - "jest-mock": "^26.3.0", + "jest-config": "^26.6.3", + "jest-haste-map": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-mock": "^26.6.2", "jest-regex-util": "^26.0.0", - "jest-resolve": "^26.4.0", - "jest-snapshot": "^26.4.2", - "jest-util": "^26.3.0", - "jest-validate": "^26.4.2", + "jest-resolve": "^26.6.2", + "jest-snapshot": "^26.6.2", + "jest-util": "^26.6.2", + "jest-validate": "^26.6.2", "slash": "^3.0.0", "strip-bom": "^4.0.0", - "yargs": "^15.3.1" + "yargs": "^15.4.1" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15462,15 +18813,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -15496,6 +18855,15 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "graceful-fs": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", @@ -15508,6 +18876,36 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -15515,20 +18913,29 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } } } }, "jest-serializer": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.3.0.tgz", - "integrity": "sha512-IDRBQBLPlKa4flg77fqg0n/pH87tcRKwe8zxOVTWISxGpPHYkRZ1dXKyh04JOja7gppc60+soKVZ791mruVdow==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-26.6.2.tgz", + "integrity": "sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==", "dev": true, "requires": { "@types/node": "*", @@ -15544,32 +18951,33 @@ } }, "jest-snapshot": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.4.2.tgz", - "integrity": "sha512-N6Uub8FccKlf5SBFnL2Ri/xofbaA68Cc3MGjP/NuwgnsvWh+9hLIR/DhrxbSiKXMY9vUW5dI6EW1eHaDHqe9sg==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz", + "integrity": "sha512-OLhxz05EzUtsAmOMzuupt1lHYXCNib0ECyuZ/PZOx9TrZcC8vL0x+DUG3TL+GLX3yHG45e6YGjIm0XwDc3q3og==", "dev": true, "requires": { "@babel/types": "^7.0.0", - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", + "@types/babel__traverse": "^7.0.4", "@types/prettier": "^2.0.0", "chalk": "^4.0.0", - "expect": "^26.4.2", + "expect": "^26.6.2", "graceful-fs": "^4.2.4", - "jest-diff": "^26.4.2", + "jest-diff": "^26.6.2", "jest-get-type": "^26.3.0", - "jest-haste-map": "^26.3.0", - "jest-matcher-utils": "^26.4.2", - "jest-message-util": "^26.3.0", - "jest-resolve": "^26.4.0", + "jest-haste-map": "^26.6.2", + "jest-matcher-utils": "^26.6.2", + "jest-message-util": "^26.6.2", + "jest-resolve": "^26.6.2", "natural-compare": "^1.4.0", - "pretty-format": "^26.4.2", + "pretty-format": "^26.6.2", "semver": "^7.3.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15595,12 +19003,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -15630,9 +19037,9 @@ "dev": true }, "diff-sequences": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.3.0.tgz", - "integrity": "sha512-5j5vdRcw3CNctePNYN0Wy2e/JbWT6cAYnXv5OuqPhDpyCGc0uLu2TK0zOCJWNB9kOIfYMSpIulRaDgIi4HJ6Ig==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-26.6.2.tgz", + "integrity": "sha512-Mv/TDa3nZ9sbc5soK+OoA74BsS3mL37yixCvUAQkiuA4Wz6YtwP/K47n2rv2ovzHZvoiQeA5FTQOschKkEwB0Q==", "dev": true }, "graceful-fs": { @@ -15648,15 +19055,15 @@ "dev": true }, "jest-diff": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.4.2.tgz", - "integrity": "sha512-6T1XQY8U28WH0Z5rGpQ+VqZSZz8EN8rZcBtfvXaOkbwxIEeRre6qnuZQlbY1AJ4MKDxQF8EkrCvK+hL/VkyYLQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-26.6.2.tgz", + "integrity": "sha512-6m+9Z3Gv9wN0WFVasqjCL/06+EFCMTqDEUl/b87HYK2rAPTyfz4ZIuSlPhY51PIQRWx5TaxeF1qmXKe9gfN3sA==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^26.3.0", + "diff-sequences": "^26.6.2", "jest-get-type": "^26.3.0", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" } }, "jest-get-type": { @@ -15666,33 +19073,36 @@ "dev": true }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15701,12 +19111,12 @@ } }, "jest-util": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.3.0.tgz", - "integrity": "sha512-4zpn6bwV0+AMFN0IYhH/wnzIQzRaYVrz1A8sYnRnj4UXDXbOVtWmlaZkO9mipFqZ13okIfN87aDoJWB7VH6hcw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "@types/node": "*", "chalk": "^4.0.0", "graceful-fs": "^4.2.4", @@ -15715,9 +19125,9 @@ }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15737,12 +19147,11 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -15818,9 +19227,9 @@ } }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15838,23 +19247,23 @@ } }, "jest-validate": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.4.2.tgz", - "integrity": "sha512-blft+xDX7XXghfhY0mrsBCYhX365n8K5wNDC4XAcNKqqjEzsRUSXP44m6PL0QJEW2crxQFLLztVnJ4j7oPlQrQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-26.6.2.tgz", + "integrity": "sha512-NEYZ9Aeyj0i5rQqbq+tpIOom0YS1u2MVu6+euBsvpgIme+FOfRmoC4R5p0JiAUpaFvFy24xgrpMknarR/93XjQ==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "camelcase": "^6.0.0", "chalk": "^4.0.0", "jest-get-type": "^26.3.0", "leven": "^3.1.0", - "pretty-format": "^26.4.2" + "pretty-format": "^26.6.2" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -15880,19 +19289,18 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "camelcase": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", - "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", "dev": true }, "chalk": { @@ -15933,27 +19341,27 @@ "dev": true }, "pretty-format": { - "version": "26.4.2", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.4.2.tgz", - "integrity": "sha512-zK6Gd8zDsEiVydOCGLkoBoZuqv8VTiHyAbKznXe/gaph/DAeZOmit9yMfgIz5adIgAMMs5XfoYSwAX3jcCO1tA==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^26.3.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" } }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -15962,24 +19370,24 @@ } }, "jest-watcher": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.3.0.tgz", - "integrity": "sha512-XnLdKmyCGJ3VoF6G/p5ohbJ04q/vv5aH9ENI+i6BL0uu9WWB6Z7Z2lhQQk0d2AVZcRGp1yW+/TsoToMhBFPRdQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-26.6.2.tgz", + "integrity": "sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==", "dev": true, "requires": { - "@jest/test-result": "^26.3.0", - "@jest/types": "^26.3.0", + "@jest/test-result": "^26.6.2", + "@jest/types": "^26.6.2", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "jest-util": "^26.3.0", + "jest-util": "^26.6.2", "string-length": "^4.0.1" }, "dependencies": { "@jest/types": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.3.0.tgz", - "integrity": "sha512-BDPG23U0qDeAvU4f99haztXwdAg3hz4El95LkAM+tHAqqhiVzRpEGHHU8EDxT/AnxOrA65YjLBwDahdJ9pTLJQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-26.6.2.tgz", + "integrity": "sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.0", @@ -16008,15 +19416,23 @@ } }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "chalk": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", @@ -16042,21 +19458,75 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "jest-util": { + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-26.6.2.tgz", + "integrity": "sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==", + "dev": true, + "requires": { + "@jest/types": "^26.6.2", + "@types/node": "*", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.4", + "is-ci": "^2.0.0", + "micromatch": "^4.0.2" + } + }, + "micromatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.0.5" + } + }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", @@ -16066,9 +19536,9 @@ } }, "jest-worker": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.3.0.tgz", - "integrity": "sha512-Vmpn2F6IASefL+DVBhPzI2J9/GJUsqzomdeN+P+dK8/jKxbh8R3BtFnx3FIta7wYlPU62cpJMJQo4kuOowcMnw==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-26.6.2.tgz", + "integrity": "sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==", "dev": true, "requires": { "@types/node": "*", @@ -16083,9 +19553,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -16291,13 +19761,33 @@ } }, "jsx-ast-utils": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz", - "integrity": "sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz", + "integrity": "sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==", "dev": true, "requires": { - "array-includes": "^3.1.1", - "object.assign": "^4.1.0" + "array-includes": "^3.1.2", + "object.assign": "^4.1.2" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + } } }, "jwa": { @@ -16338,9 +19828,9 @@ "dev": true }, "klona": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.3.tgz", - "integrity": "sha512-CgPOT3ZadDpXxKcfV56lEQ9OQSZ42Mk26gnozI+uN/k39vzD8toUhRQoqsX0m9Q3eMPEfsLWmtyUpK/yqST4yg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", "dev": true }, "koalas": { @@ -16370,15 +19860,6 @@ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true }, - "levenary": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", - "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", - "dev": true, - "requires": { - "leven": "^3.1.0" - } - }, "levn": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", @@ -16649,12 +20130,6 @@ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "dev": true - }, "lodash.once": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", @@ -16883,9 +20358,9 @@ } }, "loglevel": { - "version": "1.6.8", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", - "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.7.1.tgz", + "integrity": "sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==", "dev": true }, "long": { @@ -16912,12 +20387,20 @@ } }, "lower-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.1.tgz", - "integrity": "sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "dev": true, "requires": { - "tslib": "^1.10.0" + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "lru-cache": { @@ -16928,6 +20411,12 @@ "yallist": "^4.0.0" } }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true + }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -17173,85 +20662,6 @@ "is-what": "^3.3.1" } }, - "merge-deep": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/merge-deep/-/merge-deep-3.0.2.tgz", - "integrity": "sha512-T7qC8kg4Zoti1cFd8Cr0M+qaZfOwjlPDEdZIIPPB2JZctjaPM4fX+i7HOId69tAti2fvO6X5ldfYUONDODsrkA==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "clone-deep": "^0.2.4", - "kind-of": "^3.0.2" - }, - "dependencies": { - "clone-deep": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-0.2.4.tgz", - "integrity": "sha1-TnPdCen7lxzDhnDF3O2cGJZIHMY=", - "dev": true, - "requires": { - "for-own": "^0.1.3", - "is-plain-object": "^2.0.1", - "kind-of": "^3.0.2", - "lazy-cache": "^1.0.3", - "shallow-clone": "^0.1.2" - } - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "^1.0.1" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "shallow-clone": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-0.1.2.tgz", - "integrity": "sha1-WQnodLp3EG1zrEFM/sH/yofZcGA=", - "dev": true, - "requires": { - "is-extendable": "^0.1.1", - "kind-of": "^2.0.1", - "lazy-cache": "^0.2.3", - "mixin-object": "^2.0.1" - }, - "dependencies": { - "kind-of": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-2.0.1.tgz", - "integrity": "sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU=", - "dev": true, - "requires": { - "is-buffer": "^1.0.2" - } - }, - "lazy-cache": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.7.tgz", - "integrity": "sha1-f+3fLctu23fRHvHRF6tf/fCrG2U=", - "dev": true - } - } - } - } - }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -17348,9 +20758,9 @@ } }, "mini-css-extract-plugin": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.2.tgz", - "integrity": "sha512-h2LknfX4U1kScXxH8xE9LCOqT5B+068EAj36qicMb8l4dqdJoyHcmWmpd+ueyZfgu/POvIn+teoUnTtei2ikug==", + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", + "integrity": "sha512-n9BA8LonkOkW1/zn+IbLPQmovsL0wMb9yx75fMJQZf2X1Zoec9yTZtyMePcyu19wPkmFbzZZA6fLTotpFhQsOA==", "dev": true, "requires": { "loader-utils": "^1.1.0", @@ -17472,46 +20882,6 @@ } } } - }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } } } }, @@ -17564,27 +20934,27 @@ } }, "mobx": { - "version": "5.15.6", - "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.6.tgz", - "integrity": "sha512-U5nnx3UNdRkUjntpwzO060VWifGVx/JZeu/aMw4y28dTjDNjoY3vNKs6tFNm7z1qIfcPInsd9L9HIm8H0zTDqg==" + "version": "5.15.7", + "resolved": "https://registry.npmjs.org/mobx/-/mobx-5.15.7.tgz", + "integrity": "sha512-wyM3FghTkhmC+hQjyPGGFdpehrcX1KOXsDuERhfK2YbJemkUhEB+6wzEN639T21onxlfYBmriA1PFnvxTUhcKw==" }, "mobx-react": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.3.0.tgz", - "integrity": "sha512-C14yya2nqEBRSEiJjPkhoWJLlV8pcCX3m2JRV7w1KivwANJqipoiPx9UMH4pm6QNMbqDdvJqoyl+LqNu9AhvEQ==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/mobx-react/-/mobx-react-6.3.1.tgz", + "integrity": "sha512-IOxdJGnRSNSJrL2uGpWO5w9JH5q5HoxEqwOF4gye1gmZYdjoYkkMzSGMDnRCUpN/BNzZcFoMdHXrjvkwO7KgaQ==", "requires": { - "mobx-react-lite": ">=2.2.0" + "mobx-react-lite": "^2.2.0" } }, "mobx-react-lite": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-2.2.1.tgz", - "integrity": "sha512-SxOuV7Q1MLdj9uRUG8N1x9lBa4cS9c+YwlcrvrBVuCTlNrgRrrHuydfBHW/0f3pALhvGhcg+JEvf1gMWOuej4A==" + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/mobx-react-lite/-/mobx-react-lite-2.2.2.tgz", + "integrity": "sha512-2SlXALHIkyUPDsV4VTKVR9DW7K3Ksh1aaIv3NrNJygTbhXe2A9GrcKHZ2ovIiOp/BXilOcTYemfHHZubP431dg==" }, "mobx-state-tree": { - "version": "3.17.2", - "resolved": "https://registry.npmjs.org/mobx-state-tree/-/mobx-state-tree-3.17.2.tgz", - "integrity": "sha512-X0+xO7yEvBvPmLU2Z6cp81sD0xQaMXgLD4lGZoKSasOhNJSQPyKlu/LFxJTS6Wgw7J3gkWq9MMfQ4pO6wGMVfw==" + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/mobx-state-tree/-/mobx-state-tree-3.17.3.tgz", + "integrity": "sha512-ph4ee/Lh1qUJqHEGkfdWdBAUGdG+VAu7xZbYX/+4qem5hSSpdeZYAJOcN3bhtgEH8Wh/ZxRpQVOLM0aMFXfBSw==" }, "moment": { "version": "2.29.1", @@ -17657,9 +21027,9 @@ "dev": true }, "nanoid": { - "version": "3.1.12", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==" + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==" }, "nanomatch": { "version": "1.2.13", @@ -17726,19 +21096,27 @@ "dev": true }, "no-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.3.tgz", - "integrity": "sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "dev": true, "requires": { - "lower-case": "^2.0.1", - "tslib": "^1.10.0" + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "nock": { - "version": "13.0.4", - "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.4.tgz", - "integrity": "sha512-alqTV8Qt7TUbc74x1pKRLSENzfjp4nywovcJgi/1aXDiUxXdt7TkruSTF5MDWPP7UoPVgea4F9ghVdmX0xxnSA==", + "version": "13.0.7", + "resolved": "https://registry.npmjs.org/nock/-/nock-13.0.7.tgz", + "integrity": "sha512-WBz73VYIjdbO6BwmXODRQLtn7B5tldA9pNpWJe5QTtTEscQlY5KXU4srnGzBOK2fWakkXj69gfTnXGzmrsaRWw==", "dev": true, "requires": { "debug": "^4.1.0", @@ -17748,12 +21126,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } @@ -17900,9 +21278,9 @@ "dev": true }, "node-notifier": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.0.tgz", - "integrity": "sha512-46z7DUmcjoYdaWyXouuFNNfUo6eFa94t23c53c+lG/9Cvauk4a98rAUp9672X5dxGdQmLpPzTxzu8f/OeEPaFA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", + "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", "dev": true, "optional": true, "requires": { @@ -17915,11 +21293,14 @@ }, "dependencies": { "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", "dev": true, - "optional": true + "optional": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "which": { "version": "2.0.2", @@ -18636,9 +22017,9 @@ "dev": true }, "p-each-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", - "integrity": "sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.2.0.tgz", + "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true }, "p-finally": { @@ -18651,6 +22032,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, "requires": { "p-try": "^2.0.0" } @@ -18682,7 +22064,8 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true }, "pako": { "version": "1.0.11", @@ -18734,13 +22117,21 @@ } }, "param-case": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.3.tgz", - "integrity": "sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "dev": true, "requires": { - "dot-case": "^3.0.3", - "tslib": "^1.10.0" + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "parent-module": { @@ -18797,13 +22188,21 @@ "dev": true }, "pascal-case": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.1.tgz", - "integrity": "sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "dev": true, "requires": { - "no-case": "^3.0.3", - "tslib": "^1.10.0" + "no-case": "^3.0.4", + "tslib": "^2.0.3" + }, + "dependencies": { + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==", + "dev": true + } } }, "pascalcase": { @@ -18965,14 +22364,14 @@ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" }, "portfinder": { - "version": "1.0.27", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.27.tgz", - "integrity": "sha512-bJ3U3MThKnyJ9Dx1Idtm5pQmxXqw08+XOHhi/Lie8OF1OlhVaBFhsntAIhkZYjfDcCzszSr0w1yCbccThhzgxQ==", + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", "dev": true, "requires": { "async": "^2.6.2", "debug": "^3.1.1", - "mkdirp": "^0.5.1" + "mkdirp": "^0.5.5" }, "dependencies": { "async": { @@ -19021,22 +22420,28 @@ } }, "postcss-loader": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.0.1.tgz", - "integrity": "sha512-m+2fe21cs/1Oz4Yds90al5uqVSc0yJRhYSfCRnsnVLt3z0QoNPpqLdgW7CGVWmlUlKEGL9vmq+P4hHS6Orb5DA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-4.2.0.tgz", + "integrity": "sha512-mqgScxHqbiz1yxbnNcPdKYo/6aVt+XExURmEbQlviFVWogDbM4AJ0A/B+ZBpYsJrTRxKw7HyRazg9x0Q9SWwLA==", "dev": true, "requires": { "cosmiconfig": "^7.0.0", - "klona": "^2.0.3", + "klona": "^2.0.4", "loader-utils": "^2.0.0", - "schema-utils": "^2.7.1", - "semver": "^7.3.2" + "schema-utils": "^3.0.0", + "semver": "^7.3.4" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -19064,9 +22469,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -19084,21 +22489,24 @@ } }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -19173,31 +22581,31 @@ "dev": true }, "pretty-bytes": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.4.1.tgz", - "integrity": "sha512-s1Iam6Gwz3JI5Hweaz4GoCD1WUNUIyzePFy5+Js2hjwGVt2Z79wNN+ZKOZ2vB6C+Xs6njyB84Z1IthQg8d9LxA==", + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.5.0.tgz", + "integrity": "sha512-p+T744ZyjjiaFlMUZZv6YPC5JrkNj8maRmPaQCWFJFplUAzpIUTRaTcS+7wmZtUoFXHtESJb23ISliaWyz3SHA==", "dev": true }, "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.2.tgz", + "integrity": "sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==", "dev": true, "requires": { - "renderkid": "^2.0.1", - "utila": "~0.4" + "lodash": "^4.17.20", + "renderkid": "^2.0.4" } }, "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.6.2.tgz", + "integrity": "sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg==", "dev": true, "requires": { - "@jest/types": "^25.5.0", + "@jest/types": "^26.6.2", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" + "react-is": "^17.0.1" }, "dependencies": { "ansi-regex": { @@ -19207,12 +22615,11 @@ "dev": true }, "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, "requires": { - "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, @@ -19232,9 +22639,9 @@ "dev": true }, "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.1.tgz", + "integrity": "sha512-NAnt2iGDXohE5LI7uBnLnqvLQMtzhkiAOLXTmv+qnF9Ky7xAPcX8Up/xWIhxvLVGJvuLiNc4xQLtuqDRzb4fSA==", "dev": true } } @@ -19465,13 +22872,13 @@ } }, "prompts": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.3.2.tgz", - "integrity": "sha512-Q06uKs2CkNYVID0VqwfAl9mipo99zkBv/n2JtWY89Yxa3ZabWSrs0e2KTudKVa3peLUvYXMefDqIleLPVUBZMA==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.0.tgz", + "integrity": "sha512-awZAKrk3vN6CroQukBL+R9051a4R3zCZBlJm/HBfrSZ8iTpYix3VX1vU4mveiLpiwmOJT4wokTF9m6HUk4KqWQ==", "dev": true, "requires": { "kleur": "^3.0.3", - "sisteransi": "^1.0.4" + "sisteransi": "^1.0.5" } }, "prop-types": { @@ -19502,9 +22909,9 @@ "dev": true }, "protobufjs": { - "version": "6.10.1", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.1.tgz", - "integrity": "sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ==", + "version": "6.10.2", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz", + "integrity": "sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ==", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -19522,9 +22929,9 @@ }, "dependencies": { "@types/node": { - "version": "13.13.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.23.tgz", - "integrity": "sha512-L31WmMJYKb15PDqFWutn8HNwrNK6CE6bkWgSB0dO1XpNoHrszVKV1Clcnfgd6c/oG54TVF8XQEvY2gQrW8K6Mw==" + "version": "13.13.40", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.40.tgz", + "integrity": "sha512-eKaRo87lu1yAXrzEJl0zcJxfUMDT5/mZalFyOkT44rnQps41eS2pfWzbaulSPpQLFNy29bFqn+Y5lOTL8ATlEQ==" } } }, @@ -19634,9 +23041,9 @@ "dev": true }, "query-string": { - "version": "6.13.2", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.2.tgz", - "integrity": "sha512-BMmDaUiLDFU1hlM38jTFcRt7HYiGP/zt1sRzrIWm5zpeEuO1rkbPS0ELI3uehoLuuhHDCS8u8lhFN3fEN4JzPQ==", + "version": "6.13.8", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.8.tgz", + "integrity": "sha512-jxJzQI2edQPE/NPUOusNjO/ZOGqr1o2OBa/3M00fU76FsLXDVbJDv/p7ng5OdQyorKrkRz1oqfwmbe5MAMePQg==", "requires": { "decode-uri-component": "^0.2.0", "split-on-first": "^1.0.0", @@ -19656,9 +23063,9 @@ "dev": true }, "querystringify": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", - "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", "dev": true }, "radio-symbol": { @@ -19745,15 +23152,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } } } }, @@ -19764,35 +23162,32 @@ "dev": true }, "react": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", - "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", + "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" } }, + "react-data-grid": { + "version": "7.0.0-canary.34", + "resolved": "https://registry.npmjs.org/react-data-grid/-/react-data-grid-7.0.0-canary.34.tgz", + "integrity": "sha512-ZBWb4uH2lSmDEf0SofOrJGt8hplHLgbppKGec0fJcVQHPATEFaLscyFI2Ki0aQSJYWvKCJDwyvJgEVkwqY7jUQ==", + "requires": { + "clsx": "^1.1.1" + } + }, "react-dom": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.13.1.tgz", - "integrity": "sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.19.1" - }, - "dependencies": { - "scheduler": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", - "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "requires": { - "loose-envify": "^1.1.0", - "object-assign": "^4.1.1" - } - } } }, "react-dom-factories": { @@ -19815,6 +23210,22 @@ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, + "react-modal": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.12.1.tgz", + "integrity": "sha512-WGuXn7Fq31PbFJwtWmOk+jFtGC7E9tJVbFX0lts8ZoS5EPi9+WWylUJWLKKVm3H4GlQ7ZxY7R6tLlbSIBQ5oZA==", + "requires": { + "exenv": "^1.2.0", + "prop-types": "^15.5.10", + "react-lifecycles-compat": "^3.0.0", + "warning": "^4.0.3" + } + }, + "react-modal-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-modal-hook/-/react-modal-hook-3.0.0.tgz", + "integrity": "sha512-mNkJwgEtOoIabuILlWnGAto993WVkimZASBWk/rAGZ6tNIqjx4faQtNdr/X31vw+QGfKhspXc4vPi1jbfkk2Yg==" + }, "react-popper": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.3.7.tgz", @@ -19856,18 +23267,18 @@ } }, "react-tabs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-3.1.1.tgz", - "integrity": "sha512-HpySC29NN1BkzBAnOC+ajfzPbTaVZcSWzMSjk56uAhPC/rBGtli8lTysR4CfPAyEE/hfweIzagOIoJ7nu80yng==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-3.1.2.tgz", + "integrity": "sha512-OKS1l7QzSNcn+L2uFsxyGFHdXp9YsPGf/YOURWcImp7xLN36n0Wz+/j9HwlwGtlXCZexwshScR5BrcFbw/3P9Q==", "requires": { "clsx": "^1.1.0", "prop-types": "^15.5.0" } }, "react-test-renderer": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz", - "integrity": "sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ==", + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.14.0.tgz", + "integrity": "sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg==", "dev": true, "requires": { "object-assign": "^4.1.1", @@ -19946,9 +23357,9 @@ } }, "parse-json": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", - "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -19997,9 +23408,9 @@ } }, "readdirp": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", - "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", "dev": true, "optional": true, "requires": { @@ -20272,16 +23683,46 @@ "dev": true }, "renderkid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.3.tgz", - "integrity": "sha512-z8CLQp7EZBPCwCnncgf9C4XAi3WR0dv+uWu/PjIyhhAb5d6IJ/QZqlHFprHeKT+59//V6BNUsLbvN8+2LarxGA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.5.tgz", + "integrity": "sha512-ccqoLg+HLOHq1vdfYNm4TBeaCDIi1FLt3wGojTDSvdewUv65oTmI3cnT2E4hRjl1gzKZIPK+KZrXzlUYKnR+vQ==", "dev": true, "requires": { - "css-select": "^1.1.0", + "css-select": "^2.0.2", "dom-converter": "^0.2", - "htmlparser2": "^3.3.0", - "strip-ansi": "^3.0.0", - "utila": "^0.4.0" + "htmlparser2": "^3.10.1", + "lodash": "^4.17.20", + "strip-ansi": "^3.0.0" + }, + "dependencies": { + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-what": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", + "dev": true + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + } } }, "repeat-element": { @@ -20420,12 +23861,20 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true }, "requirejs": { "version": "2.3.6", @@ -20537,9 +23986,9 @@ }, "dependencies": { "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "optional": true, "requires": { @@ -20574,9 +24023,9 @@ } }, "rollbar": { - "version": "2.19.3", - "resolved": "https://registry.npmjs.org/rollbar/-/rollbar-2.19.3.tgz", - "integrity": "sha512-SBGEN999+wAlE2Q25pfzqUCqNiplpRPbgv/oYn4eW3Kk4CJox/mMGaSB9BWidX2Vep5TGpxxuyWCHrqklS+s/w==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/rollbar/-/rollbar-2.20.0.tgz", + "integrity": "sha512-xPSJIfkP4scBCpt1gEiFAcaeAHutvGbz0xF7Kr7JS2bloBC3G8ufua9iKXu8cpATPD4rFDqCWD7cngPaICCTwA==", "requires": { "async": "~1.2.1", "console-polyfill": "0.3.0", @@ -20638,9 +24087,9 @@ } }, "rxjs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.0.tgz", - "integrity": "sha512-3HMA8z/Oz61DUHe+SdOiQyzIf4tOx5oQHmMir7IZEu6TMqCLHT4LRcmNaUS0NwOz8VLvmmBduMsoaUvMaIiqzg==", + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", "dev": true, "requires": { "tslib": "^1.9.0" @@ -20807,22 +24256,28 @@ } }, "sass-loader": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.0.2.tgz", - "integrity": "sha512-wV6NDUVB8/iEYMalV/+139+vl2LaRFlZGEd5/xmdcdzQcgmis+npyco6NsDTVOlNA3y2NV9Gcz+vHyFMIT+ffg==", + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-10.1.1.tgz", + "integrity": "sha512-W6gVDXAd5hR/WHsPicvZdjAWHBcEJ44UahgxcIE196fW2ong0ZHMPO1kZuI5q0VlvMQZh32gpv69PLWQm70qrw==", "dev": true, "requires": { - "klona": "^2.0.3", + "klona": "^2.0.4", "loader-utils": "^2.0.0", "neo-async": "^2.6.2", - "schema-utils": "^2.7.1", + "schema-utils": "^3.0.0", "semver": "^7.3.2" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.5", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.5.tgz", - "integrity": "sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -20849,15 +24304,21 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" } }, + "klona": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.4.tgz", + "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", + "dev": true + }, "loader-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", @@ -20870,21 +24331,24 @@ } }, "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", "ajv-keywords": "^3.5.2" } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } } } }, @@ -20907,7 +24371,6 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -21111,7 +24574,8 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true }, "set-getter": { "version": "0.1.0", @@ -21220,70 +24684,20 @@ "optional": true }, "side-channel": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.2.tgz", - "integrity": "sha512-7rL9YlPHg7Ancea1S96Pa8/QWb4BtXL/TZvS6B8XFetGBeuhAsfmUspK6DokBeZ64+Kj9TCNRD/30pVz1BvQNA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", "dev": true, "requires": { - "es-abstract": "^1.17.0-next.1", - "object-inspect": "^1.7.0" + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" }, "dependencies": { - "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", - "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "has-symbols": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", - "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", - "dev": true - }, - "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", - "dev": true - }, - "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.1" - } - }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true } } @@ -21565,54 +24979,36 @@ } }, "sockjs": { - "version": "0.3.20", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", - "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz", + "integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==", "dev": true, "requires": { - "faye-websocket": "^0.10.0", + "faye-websocket": "^0.11.3", "uuid": "^3.4.0", - "websocket-driver": "0.6.5" + "websocket-driver": "^0.7.4" }, "dependencies": { - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true - }, - "websocket-driver": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", - "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", - "dev": true, - "requires": { - "websocket-extensions": ">=0.1.1" - } } } }, "sockjs-client": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", - "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.5.0.tgz", + "integrity": "sha512-8Dt3BDi4FYNrCFGTL/HtwVzkARrENdwOUf1ZoW/9p3M8lZdFT35jVdrHza+qgxuG9H3/shR4cuX/X9umUrjP8Q==", "dev": true, "requires": { - "debug": "^3.2.5", + "debug": "^3.2.6", "eventsource": "^1.0.7", - "faye-websocket": "~0.11.1", - "inherits": "^2.0.3", - "json3": "^3.3.2", - "url-parse": "^1.4.3" + "faye-websocket": "^0.11.3", + "inherits": "^2.0.4", + "json3": "^3.3.3", + "url-parse": "^1.4.7" } }, "sort-keys": { @@ -21718,12 +25114,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } @@ -21743,12 +25139,12 @@ }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } } } @@ -21791,9 +25187,9 @@ } }, "ssri": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", - "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", + "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", "dev": true, "requires": { "minipass": "^3.1.1" @@ -21806,9 +25202,9 @@ "dev": true }, "stack-utils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.2.tgz", - "integrity": "sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-gL//fkxfWUsIlFL2Tl42Cl6+HFALEaB1FU76I/Fy+oZjRreP7OPMXFlGbxM7NQsI0ZpUfw76sHnv0WNYuTb7Iw==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -22111,36 +25507,40 @@ } }, "string.prototype.matchall": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz", - "integrity": "sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz", + "integrity": "sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0", + "es-abstract": "^1.18.0-next.1", "has-symbols": "^1.0.1", "internal-slot": "^1.0.2", "regexp.prototype.flags": "^1.3.0", - "side-channel": "^1.0.2" + "side-channel": "^1.0.3" }, "dependencies": { "es-abstract": { - "version": "1.17.6", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", - "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "version": "1.18.0-next.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.2.tgz", + "integrity": "sha512-Ih4ZMFHEtZupnUh6497zEL4y2+w8+1ljnCyaTa+adcoafI1GOvMwFlDjBLfWR7y9VLfrjRJe9ocuHY1PSR9jjw==", "dev": true, "requires": { + "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2", "has": "^1.0.3", "has-symbols": "^1.0.1", - "is-callable": "^1.2.0", - "is-regex": "^1.1.0", - "object-inspect": "^1.7.0", + "is-callable": "^1.2.2", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.1", + "object-inspect": "^1.9.0", "object-keys": "^1.1.1", - "object.assign": "^4.1.0", - "string.prototype.trimend": "^1.0.1", - "string.prototype.trimstart": "^1.0.1" + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.3", + "string.prototype.trimstart": "^1.0.3" } }, "es-to-primitive": { @@ -22161,34 +25561,67 @@ "dev": true }, "is-callable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", - "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", "dev": true }, "is-regex": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", - "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.2.tgz", + "integrity": "sha512-axvdhb5pdhEVThqJzYXwMlVuZwC+FF2DpcOhTS+y/8jVq4trxyPgfcwIxIKiyeuLlSQYKkmUaPQJ8ZE4yNKXDg==", "dev": true, "requires": { + "call-bind": "^1.0.2", "has-symbols": "^1.0.1" } }, "object-inspect": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.8.0.tgz", - "integrity": "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", + "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", "dev": true }, - "regexp.prototype.flags": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", - "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", "dev": true, "requires": { + "call-bind": "^1.0.0", "define-properties": "^1.1.3", - "es-abstract": "^1.17.0-next.1" + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "regexp.prototype.flags": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz", + "integrity": "sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimend": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", + "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", + "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" } } } @@ -22516,19 +25949,19 @@ "optional": true }, "style-loader": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.2.1.tgz", - "integrity": "sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-1.3.0.tgz", + "integrity": "sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "schema-utils": "^2.6.6" + "schema-utils": "^2.7.0" }, "dependencies": { "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -22537,6 +25970,12 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -22550,9 +25989,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -22569,21 +26008,15 @@ "json5": "^2.1.2" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", "dev": true, "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" } } } @@ -22704,9 +26137,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -22754,9 +26187,9 @@ } }, "css-what": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", - "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz", + "integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==", "dev": true }, "domutils": { @@ -22784,64 +26217,106 @@ "dev": true }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", "dev": true, "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "dependencies": { + "ajv": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.4.tgz", + "integrity": "sha512-xzzzaqgEQfmuhbhAoqjJ8T/1okb6gAzXn/eQRNpAN1AEUoHJTNF9xCDRTtf/s3SKldtZfa+RJeTs+BQq+eZ/sw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" } }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } @@ -22853,9 +26328,9 @@ "dev": true }, "tar": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.5.tgz", - "integrity": "sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", + "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -23104,6 +26579,48 @@ "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", "dev": true }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -23117,9 +26634,9 @@ "dev": true }, "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -23260,28 +26777,28 @@ } }, "ts-jest": { - "version": "26.3.0", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.3.0.tgz", - "integrity": "sha512-Jq2uKfx6bPd9+JDpZNMBJMdMQUC3sJ08acISj8NXlVgR2d5OqslEHOR2KHMgwymu8h50+lKIm0m0xj/ioYdW2Q==", + "version": "26.5.0", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-26.5.0.tgz", + "integrity": "sha512-Ya4IQgvIFNa2Mgq52KaO8yBw2W8tWp61Ecl66VjF0f5JaV8u50nGoptHVILOPGoI7SDnShmEqnYQEmyHdQ+56g==", "dev": true, "requires": { "@types/jest": "26.x", "bs-logger": "0.x", "buffer-from": "1.x", "fast-json-stable-stringify": "2.x", - "jest-util": "26.x", + "jest-util": "^26.1.0", "json5": "2.x", - "lodash.memoize": "4.x", + "lodash": "4.x", "make-error": "1.x", "mkdirp": "1.x", "semver": "7.x", - "yargs-parser": "18.x" + "yargs-parser": "20.x" }, "dependencies": { "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -23294,26 +26811,44 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", "dev": true } } }, "ts-loader": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.3.tgz", - "integrity": "sha512-wsqfnVdB7xQiqhqbz2ZPLGHLPZbHVV5Qn/MNFZkCFxRU1miDyxKORucDGxKtsQJ63Rfza0udiUxWF5nHY6bpdQ==", + "version": "8.0.14", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.14.tgz", + "integrity": "sha512-Jt/hHlUnApOZjnSjTmZ+AbD5BGlQFx3f1D0nYuNKwz0JJnuDGHJas6az+FlWKwwRTu+26GXpv249A8UAnYUpqA==", "dev": true, "requires": { - "chalk": "^2.3.0", + "chalk": "^4.1.0", "enhanced-resolve": "^4.0.0", - "loader-utils": "^1.0.2", + "loader-utils": "^2.0.0", "micromatch": "^4.0.0", - "semver": "^6.0.0" + "semver": "^7.3.4" }, "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", @@ -23323,6 +26858,37 @@ "fill-range": "^7.0.1" } }, + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -23332,12 +26898,38 @@ "to-regex-range": "^5.0.1" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "loader-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.0.tgz", + "integrity": "sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, "micromatch": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", @@ -23349,10 +26941,22 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } }, "to-regex-range": { "version": "5.0.1", @@ -23366,12 +26970,13 @@ } }, "ts-node": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.0.0.tgz", - "integrity": "sha512-/TqB4SnererCDR/vb4S/QvSZvzQMJN8daAslg7MeaiHvD8rDZsSfXmNeNumyZZzMned72Xoq/isQljYSt8Ynfg==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz", + "integrity": "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg==", "dev": true, "requires": { "arg": "^4.1.0", + "create-require": "^1.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.17", @@ -23479,9 +27084,9 @@ } }, "typescript": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.2.tgz", - "integrity": "sha512-e4ERvRV2wb+rRZ/IQeb3jm2VxBsirQLpQhdxplZ2MEzGvDkkMmPglecnNDfSUBivMjP93vRbngYYDQqQ/78bcQ==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", + "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", "dev": true }, "unicode-canonical-property-names-ecmascript": { @@ -23662,20 +27267,26 @@ } }, "url-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.0.tgz", - "integrity": "sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m+RyM5N3mLx5BqJKccgxJS+W3kqw==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", "dev": true, "requires": { "loader-utils": "^2.0.0", - "mime-types": "^2.1.26", - "schema-utils": "^2.6.5" + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" }, "dependencies": { + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==", + "dev": true + }, "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -23684,6 +27295,12 @@ "uri-js": "^4.2.2" } }, + "ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true + }, "emojis-list": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", @@ -23697,9 +27314,9 @@ "dev": true }, "json5": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", - "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", "dev": true, "requires": { "minimist": "^1.2.5" @@ -23717,35 +27334,29 @@ } }, "mime-db": { - "version": "1.44.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", - "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "version": "1.45.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", + "integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "dev": true }, "mime-types": { - "version": "2.1.27", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", - "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "version": "2.1.28", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", + "integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", "dev": true, "requires": { - "mime-db": "1.44.0" + "mime-db": "1.45.0" } }, - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - }, "schema-utils": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", - "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.0.0.tgz", + "integrity": "sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==", "dev": true, "requires": { - "@types/json-schema": "^7.0.4", - "ajv": "^6.12.2", - "ajv-keywords": "^3.4.1" + "@types/json-schema": "^7.0.6", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" } } } @@ -23817,9 +27428,9 @@ "dev": true }, "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==" + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" }, "v8-compile-cache": { "version": "2.1.1", @@ -23828,9 +27439,9 @@ "dev": true }, "v8-to-istanbul": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-5.0.1.tgz", - "integrity": "sha512-mbDNjuDajqYe3TXFk5qxcQy8L1msXNE37WTlLoqqpBfRsimbNcrlhQlDPntmECEcUvdC+AQ8CyMMf6EUx1r74Q==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-7.1.0.tgz", + "integrity": "sha512-uXUVqNUCLa0AH1vuVxzi+MI4RfxEOKt9pBgKwHbgH7st8Kv2P1m+jvWNnektzBh5QShF3ODgKmUFCf38LnVz1g==", "dev": true, "requires": { "@types/istanbul-lib-coverage": "^2.0.1", @@ -23982,21 +27593,21 @@ "dev": true }, "watchpack": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.4.tgz", - "integrity": "sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg==", + "version": "1.7.5", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz", + "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "requires": { "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.0" + "watchpack-chokidar2": "^2.0.1" } }, "watchpack-chokidar2": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", - "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz", + "integrity": "sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==", "dev": true, "optional": true, "requires": { @@ -24161,9 +27772,9 @@ "dev": true }, "webpack": { - "version": "4.44.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.44.1.tgz", - "integrity": "sha512-4UOGAohv/VGUNQJstzEywwNxqX417FnjZgZJpJQegddzPmTvph37eBIRbRTfdySXzVtJXLJfbMN3mMYhM6GdmQ==", + "version": "4.46.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.46.0.tgz", + "integrity": "sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q==", "dev": true, "requires": { "@webassemblyjs/ast": "1.9.0", @@ -24174,7 +27785,7 @@ "ajv": "^6.10.2", "ajv-keywords": "^3.4.1", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.3.0", + "enhanced-resolve": "^4.5.0", "eslint-scope": "^4.0.3", "json-parse-better-errors": "^1.0.2", "loader-runner": "^2.4.0", @@ -24192,11 +27803,34 @@ }, "dependencies": { "acorn": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", - "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==", "dev": true }, + "enhanced-resolve": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz", + "integrity": "sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", @@ -24404,9 +28038,9 @@ } }, "webpack-dev-middleware": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", - "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz", + "integrity": "sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==", "dev": true, "requires": { "memory-fs": "^0.4.1", @@ -24459,9 +28093,9 @@ } }, "webpack-dev-server": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", - "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "version": "3.11.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz", + "integrity": "sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ==", "dev": true, "requires": { "ansi-html": "0.0.7", @@ -24484,11 +28118,11 @@ "p-retry": "^3.0.1", "portfinder": "^1.0.26", "schema-utils": "^1.0.0", - "selfsigned": "^1.10.7", + "selfsigned": "^1.10.8", "semver": "^6.3.0", "serve-index": "^1.9.1", - "sockjs": "0.3.20", - "sockjs-client": "1.4.0", + "sockjs": "^0.3.21", + "sockjs-client": "^1.5.0", "spdy": "^4.0.2", "strip-ansi": "^3.0.1", "supports-color": "^6.1.0", @@ -24575,12 +28209,12 @@ } }, "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, "emoji-regex": { @@ -24852,23 +28486,12 @@ "dev": true, "requires": { "iconv-lite": "0.4.24" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } } }, "whatwg-fetch": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz", - "integrity": "sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ==" + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz", + "integrity": "sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==" }, "whatwg-mimetype": { "version": "2.3.0", @@ -24877,9 +28500,9 @@ "dev": true }, "whatwg-url": { - "version": "8.2.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.2.1.tgz", - "integrity": "sha512-ZmVCr6nfBeaMxEHALLEGy0LszYjpJqf6PVNQUQ1qd9Et+q7Jpygd4rGGDXgHjD8e99yLFseD69msHDM4YwPZ4A==", + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.4.0.tgz", + "integrity": "sha512-vwTUFf6V4zhcPkWp/4CQPr1TW9Ml6SF4lVyaIMBdJw5i6qUUJ1QWM4Z6YYVkfka0OUIzVo/0aNtGVGk256IKWw==", "dev": true, "requires": { "lodash.sortby": "^4.7.0", @@ -24899,7 +28522,8 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true }, "wide-align": { "version": "1.1.3", @@ -24929,6 +28553,7 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", @@ -24938,12 +28563,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -24953,6 +28580,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "requires": { "color-name": "~1.1.4" } @@ -24960,17 +28588,20 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -24981,6 +28612,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -24993,15 +28625,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", @@ -25015,9 +28638,9 @@ } }, "ws": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", - "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==", + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.2.tgz", + "integrity": "sha512-T4tewALS3+qsrpGI/8dqNMLIVdq/g/85U98HPMa6F0m6xTbvhXU6RCQLqPH3+SlomNV/LdY6RXEbBpMH6EOJnA==", "dev": true }, "xdg-basedir": { @@ -25063,7 +28686,8 @@ "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true }, "yallist": { "version": "4.0.0", @@ -25080,6 +28704,7 @@ "version": "15.4.1", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", @@ -25097,12 +28722,14 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -25111,12 +28738,14 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -25125,6 +28754,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -25132,12 +28762,14 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -25148,6 +28780,7 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, "requires": { "ansi-regex": "^5.0.0" } @@ -25158,6 +28791,7 @@ "version": "18.1.3", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -25178,6 +28812,12 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true } } } diff --git a/package.json b/package.json index 6ae7ca2358..bdabd67fa7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "collaborative-learning", - "version": "1.5.4", + "version": "1.6.0", "description": "Collaborative Learning environment", "main": "index.js", "config": { @@ -60,6 +60,7 @@ "test:cypress": "cypress run --config video=false,defaultCommandTimeout=10000 --env testEnv=local", "test:cypress:ci": "cypress run --config video=false,defaultCommandTimeout=10000 --env testEnv=local --record", "test:cypress:open": "cypress open --env testEnv=local", + "test:cypress:open:disable-gpu": "cross-env ELECTRON_EXTRA_LAUNCH_ARGS=--disable-gpu cypress open --env testEnv=local", "test:cypress:smoke": "cypress run --spec 'cypress/integration/clue/smoke/single_student_canvas_test.js' --config video=false,defaultCommandTimeout=10000 --env testEnv=local", "test:cypress:branch": "cypress run --spec 'cypress/integration/clue/branch/**/*' --config video=false,defaultCommandTimeout=10000 --env testEnv=local --record", "test:full": "npm-run-all test test:cypress", @@ -79,111 +80,112 @@ }, "homepage": "https://github.com/concord-consortium/collaborative-learning#readme", "devDependencies": { - "@babel/preset-env": "^7.11.5", - "@cypress/webpack-preprocessor": "^5.4.5", + "@babel/preset-env": "^7.12.11", + "@cypress/webpack-preprocessor": "^5.5.0", "@firebase/app-types": "^0.6.1", - "@svgr/webpack": "^5.4.0", - "@testing-library/react": "^11.0.4", - "@types/classnames": "^2.2.10", + "@svgr/webpack": "^5.5.0", + "@testing-library/react": "^11.2.5", + "@types/classnames": "^2.2.11", "@types/color-string": "^1.5.0", - "@types/d3-format": "^1.3.1", - "@types/enzyme": "^3.10.6", + "@types/d3-format": "^1.4.1", + "@types/enzyme": "^3.10.8", "@types/enzyme-adapter-react-16": "^1.0.6", "@types/file-saver": "^2.0.1", "@types/is-hotkey": "^0.1.2", - "@types/jest": "^26.0.13", + "@types/jest": "^26.0.20", "@types/jsonwebtoken": "^8.5.0", - "@types/lodash": "^4.14.161", + "@types/lodash": "^4.14.168", "@types/nanoid": "^2.0.0", "@types/query-string": "^6.3.0", - "@types/react": "^16.9.49", - "@types/react-dom": "^16.9.8", + "@types/react": "^16.9.56", + "@types/react-dom": "^16.9.9", + "@types/react-modal": "^3.10.6", "@types/react-tabs": "^2.3.2", - "@types/slate": "^0.47.7", + "@types/slate": "^0.47.8", "@types/slate-html-serializer": "^0.6.4", "@types/slate-plain-serializer": "^0.7.0", "@types/slate-react": "^0.22.9", "@types/superagent": "^4.1.10", "@types/uuid": "^8.3.0", - "@typescript-eslint/eslint-plugin": "^4.6.0", - "@typescript-eslint/parser": "^4.6.0", + "@typescript-eslint/eslint-plugin": "^4.14.2", + "@typescript-eslint/parser": "^4.14.2", "autoprefixer": "^9.8.6", - "babel-loader": "^8.1.0", - "copy-webpack-plugin": "^6.1.0", - "cross-env": "^7.0.2", + "babel-loader": "^8.2.2", + "copy-webpack-plugin": "^6.4.1", + "cross-env": "^7.0.3", "css-loader": "^4.3.0", - "cypress": "^5.6.0", + "cypress": "^6.3.0", "cypress-commands": "^1.1.0", "cypress-file-upload": "^4.1.1", "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.4", - "eslint": "^7.12.1", + "enzyme-adapter-react-16": "^1.15.6", + "eslint": "^7.19.0", "eslint-config-react": "^1.1.7", "eslint-loader": "^4.0.2", "eslint-plugin-chai-friendly": "^0.6.0", - "eslint-plugin-cypress": "^2.11.1", + "eslint-plugin-cypress": "^2.11.2", "eslint-plugin-eslint-comments": "^3.2.0", "eslint-plugin-json": "^2.1.2", - "eslint-plugin-react": "^7.20.6", - "eslint-plugin-react-hooks": "^4.1.2", - "file-loader": "^6.1.0", - "firebase-admin": "^9.2.0", - "html-webpack-plugin": "^4.4.1", - "is-hotkey": "^0.1.6", - "jest": "^26.4.2", - "mini-css-extract-plugin": "^0.11.2", - "nock": "^13.0.4", + "eslint-plugin-react": "^7.22.0", + "eslint-plugin-react-hooks": "^4.2.0", + "file-loader": "^6.2.0", + "firebase-admin": "^9.4.2", + "html-webpack-plugin": "^4.5.1", + "is-hotkey": "^0.1.8", + "jest": "^26.6.3", + "mini-css-extract-plugin": "^0.11.3", + "nock": "^13.0.7", "node-sass": "^4.14.1", "npm-run-all": "^4.1.5", - "postcss-loader": "^4.0.1", + "postcss-loader": "^4.2.0", "prompt-confirm": "^2.0.4", "rimraf": "^3.0.2", - "sass-loader": "^10.0.2", + "sass-loader": "^10.1.1", "script-loader": "^0.7.2", "string-replace-loader": "^2.3.0", - "style-loader": "^1.2.1", - "ts-jest": "^26.3.0", - "ts-loader": "^8.0.3", - "ts-node": "^9.0.0", - "typescript": "^4.0.2", - "url-loader": "^4.1.0", + "style-loader": "^1.3.0", + "ts-jest": "^26.5.0", + "ts-loader": "^8.0.14", + "ts-node": "^9.1.1", + "typescript": "^4.1.3", + "url-loader": "^4.1.1", "utility-types": "^3.10.0", "wait-on": "^5.2.1", - "webpack": "^4.44.1", + "webpack": "^4.46.0", "webpack-cli": "^3.3.12", - "webpack-dev-server": "^3.11.0", + "webpack-dev-server": "^3.11.2", "xhr-mock": "^2.5.1" }, "dependencies": { - "@ag-grid-community/client-side-row-model": "^22.1.1", - "@ag-grid-community/core": "^22.1.1", - "@ag-grid-community/react": "^22.1.2", - "@blueprintjs/core": "^3.31.0", + "@blueprintjs/core": "^3.38.2", "@concord-consortium/jsxgraph": "^0.99.8-cc.1", "@concord-consortium/react-components": "^0.1.14", "classnames": "^2.2.6", "color-string": "^1.5.4", "d3-format": "^2.0.0", "expr-eval": "^2.0.2", - "file-saver": "^2.0.2", - "firebase": "^7.22.1", + "file-saver": "^2.0.5", + "firebase": "^7.24.0", "immutable": "^3.8.2", "initials": "^3.1.1", "jsonwebtoken": "^8.5.0", "lodash": "^4.17.20", - "mobx": "^5.15.6", - "mobx-react": "^6.3.0", - "mobx-state-tree": "^3.17.2", - "nanoid": "^3.1.12", - "query-string": "^6.13.2", - "react": "^16.13.1", - "react-dom": "^16.13.1", + "mobx": "^5.15.7", + "mobx-react": "^6.3.1", + "mobx-state-tree": "^3.17.3", + "nanoid": "^3.1.20", + "query-string": "^6.13.8", + "react": "^16.14.0", + "react-data-grid": "^7.0.0-canary.34", + "react-dom": "^16.14.0", "react-dom-factories": "^1.0.2", + "react-modal": "^3.12.1", + "react-modal-hook": "^3.0.0", "react-sizeme": "^2.6.12", - "react-tabs": "^3.1.1", + "react-tabs": "^3.1.2", "react-tippy": "^1.4.0", "resize-observer-polyfill": "^1.5.1", - "rollbar": "^2.19.3", + "rollbar": "^2.20.0", "slate": "^0.47.9", "slate-html-serializer": "^0.8.13", "slate-md-serializer": "^5.5.4", @@ -191,7 +193,7 @@ "slate-react": "^0.22.10", "superagent": "^6.1.0", "ts-polyfill": "^3.8.2", - "uuid": "^8.3.0", - "whatwg-fetch": "^3.4.1" + "uuid": "^8.3.2", + "whatwg-fetch": "^3.5.0" } } diff --git a/src/assets/icons/add/add.nosvgo.svg b/src/assets/icons/add/add.nosvgo.svg new file mode 100644 index 0000000000..dce7b74242 --- /dev/null +++ b/src/assets/icons/add/add.nosvgo.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/assets/icons/caution.svg b/src/assets/icons/caution.svg new file mode 100644 index 0000000000..9f0f6ef44d --- /dev/null +++ b/src/assets/icons/caution.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/src/assets/icons/error.svg b/src/assets/icons/error.svg new file mode 100644 index 0000000000..8182aec944 --- /dev/null +++ b/src/assets/icons/error.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/src/assets/icons/remove/remove.nosvgo.svg b/src/assets/icons/remove/remove.nosvgo.svg new file mode 100644 index 0000000000..1a447219ad --- /dev/null +++ b/src/assets/icons/remove/remove.nosvgo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/assets/icons/text-input.svg b/src/assets/icons/text-input.svg new file mode 100644 index 0000000000..287bf8b8c6 --- /dev/null +++ b/src/assets/icons/text-input.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/src/clue/app-config.json b/src/clue/app-config.json index 48c3f007d2..deed129ab6 100644 --- a/src/clue/app-config.json +++ b/src/clue/app-config.json @@ -2,22 +2,49 @@ "appName": "CLUE", "pageTitle": "CLUE: %problemTitle%", "units": { - "cr": "curriculum/completely-rational/completely-rational.json", - "cas": "curriculum/comparing-and-scaling/comparing-and-scaling.json", - "faw": "curriculum/filling-and-wrapping/filling-and-wrapping.json", - "ffpc": "curriculum/frogs-fleas-and-painted-cubes/frogs-fleas-and-painted-cubes.json", - "ggg": "curriculum/growing-growing-growing/growing-growing-growing.json", - "hlit": "curriculum/how-likely-is-it/how-likely-is-it.json", - "help": "curriculum/help/help.json", - "lfp": "curriculum/looking-for-pythagoras/looking-for-pythagoras.json", - "msa": "curriculum/moving-straight-ahead/moving-straight-ahead.json", - "sad": "curriculum/shapes-and-designs/shapes-and-designs.json", - "sap": "curriculum/samples-and-populations/samples-and-populations.json", - "sas": "curriculum/stretching-and-shrinking/stretching-and-shrinking.json", - "s+s": "curriculum/stretching-and-shrinking/stretching-and-shrinking.json", - "s s": "curriculum/stretching-and-shrinking/stretching-and-shrinking.json", - "sws": "curriculum/say-it-with-symbols/say-it-with-symbols.json", - "twmm": "curriculum/thinking-with-math-models/thinking-with-math-models.json" + "cr": { + "content": "curriculum/completely-rational/completely-rational.json" + }, + "cas": { + "content": "curriculum/comparing-and-scaling/comparing-and-scaling.json" + }, + "faw": { + "content": "curriculum/filling-and-wrapping/filling-and-wrapping.json" + }, + "ffpc": { + "content": "curriculum/frogs-fleas-and-painted-cubes/frogs-fleas-and-painted-cubes.json" + }, + "ggg": { + "content": "curriculum/growing-growing-growing/growing-growing-growing.json" + }, + "hlit": { + "content": "curriculum/how-likely-is-it/how-likely-is-it.json" + }, + "help": { + "content": "curriculum/help/help.json" + }, + "lfp": { + "content": "curriculum/looking-for-pythagoras/looking-for-pythagoras.json" + }, + "msa": { + "content": "curriculum/moving-straight-ahead/moving-straight-ahead.json", + "guide": "curriculum/moving-straight-ahead/msa-teacher-guide.json" + }, + "sad": { + "content": "curriculum/shapes-and-designs/shapes-and-designs.json" + }, + "sap": { + "content": "curriculum/samples-and-populations/samples-and-populations.json" + }, + "sas": { + "content": "curriculum/stretching-and-shrinking/stretching-and-shrinking.json" + }, + "sws": { + "content": "curriculum/say-it-with-symbols/say-it-with-symbols.json" + }, + "twmm": { + "content": "curriculum/thinking-with-math-models/thinking-with-math-models.json" + } }, "unitCodeMap": { "s s": "sas", @@ -60,6 +87,12 @@ "label": "Problem", "sections": [] }, + { + "tab": "teacher-guide", + "label": "Teacher Guide", + "teacherOnly": true, + "sections": [] + }, { "tab": "student-work", "label": "Student Workspaces", diff --git a/src/clue/assets/icons/table/link-graph-icon.svg b/src/clue/assets/icons/table/link-graph-icon.svg new file mode 100644 index 0000000000..06764e1868 --- /dev/null +++ b/src/clue/assets/icons/table/link-graph-icon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/clue/assets/icons/table/row-labels-hidden-icon.svg b/src/clue/assets/icons/table/row-labels-hidden-icon.svg new file mode 100644 index 0000000000..7b4edccd90 --- /dev/null +++ b/src/clue/assets/icons/table/row-labels-hidden-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/clue/assets/icons/table/row-labels-shown-icon.svg b/src/clue/assets/icons/table/row-labels-shown-icon.svg new file mode 100644 index 0000000000..5066c3d1d7 --- /dev/null +++ b/src/clue/assets/icons/table/row-labels-shown-icon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/src/clue/assets/icons/table/set-expression-icon.svg b/src/clue/assets/icons/table/set-expression-icon.svg new file mode 100644 index 0000000000..1cead8eaaf --- /dev/null +++ b/src/clue/assets/icons/table/set-expression-icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/clue/clue.sass b/src/clue/clue.sass index a3e1182b99..7568f7fd67 100644 --- a/src/clue/clue.sass +++ b/src/clue/clue.sass @@ -8,6 +8,13 @@ &:active, &.selected background-color: $problem-orange-light-4 font-weight: bold +.tab-teacher-guide + background-color: $learninglog-green-light-7 + &:hover + background-color: $learninglog-green-light-5 + &:active, &.selected + background-color: $learninglog-green-light-4 + font-weight: bold .tab-student-work background-color: $charcoal-light-7 &:hover diff --git a/src/components/app.tsx b/src/components/app.tsx index 13ba7b7d06..62ea7be209 100644 --- a/src/components/app.tsx +++ b/src/components/app.tsx @@ -1,6 +1,7 @@ import { inject, observer } from "mobx-react"; import React from "react"; -import { Alert } from "@blueprintjs/core"; +import Modal from "react-modal"; +import { ModalProvider } from "react-modal-hook"; import { authenticate } from "../lib/auth"; import { AppContentContainerComponent } from "./app-content"; import { BaseComponent, IBaseProps } from "./base"; @@ -11,6 +12,8 @@ import { GroupChooserComponent } from "./group/group-chooser"; import { IStores, setAppMode, setUnitAndProblem } from "../models/stores/stores"; import { isDifferentUnitAndProblem } from "../models/curriculum/unit"; import { updateProblem } from "../lib/misc"; +import ErrorAlert from "./utilities/error-alert"; + import "./app.sass"; interface IProps extends IBaseProps {} @@ -124,6 +127,10 @@ export class AppComponent extends BaseComponent { }); } + public componentDidMount() { + Modal.setAppElement(".app"); + } + public componentWillUnmount() { this.stores.db.disconnect(); } @@ -168,10 +175,16 @@ export class AppComponent extends BaseComponent { } private renderApp(children: JSX.Element | JSX.Element[]) { + // We use the ModalProvider from react-modal-hook to place modals at the top of + // the React component tree to minimize the potential that events propagating + // up the tree from modal dialogs will interact adversely with other content. + // cf. https://github.com/reactjs/react-modal/issues/699#issuecomment-496685847 return ( -
- {children} -
+ +
+ {children} +
+
); } @@ -187,16 +200,12 @@ export class AppComponent extends BaseComponent { private renderError(error: string) { return (
- -

{error.toString()}

-
+
); } diff --git a/src/components/document/canvas.tsx b/src/components/document/canvas.tsx index 4b359876e9..c835607212 100644 --- a/src/components/document/canvas.tsx +++ b/src/components/document/canvas.tsx @@ -1,24 +1,23 @@ +import { each } from "lodash"; import { observer } from "mobx-react"; import React from "react"; -import { IBaseProps } from "../base"; import { DocumentContentComponent } from "./document-content"; import { DocumentModelType } from "../../models/document/document"; import { DocumentContentModelType } from "../../models/document/document-content"; -import { IToolApiInterface } from "../tools/tool-tile"; +import { IToolApiMap, IToolApiInterface, IToolApi, ToolApiInterfaceContext } from "../tools/tool-api"; import { DEBUG_CANVAS } from "../../lib/debug"; import "./canvas.sass"; export type EditabilityLocation = "north east" | "north west" | "south east" | "south west"; -interface IProps extends IBaseProps { +interface IProps { context: string; scale?: number; readOnly?: boolean; document?: DocumentModelType; content?: DocumentContentModelType; editabilityLocation?: EditabilityLocation; - toolApiInterface?: IToolApiInterface; overlayMessage?: string; selectedSectionId?: string | null; viaTeacherDashboard?: boolean; @@ -27,14 +26,38 @@ interface IProps extends IBaseProps { @observer export class CanvasComponent extends React.Component { + private toolApiMap: IToolApiMap = {}; + private toolApiInterface: IToolApiInterface; + + constructor(props: IProps) { + super(props); + + this.toolApiInterface = { + register: (id: string, toolApi: IToolApi) => { + this.toolApiMap[id] = toolApi; + }, + unregister: (id: string) => { + delete this.toolApiMap[id]; + }, + getToolApi: (id: string) => { + return this.toolApiMap[id]; + }, + forEach: (callback: (api: IToolApi) => void) => { + each(this.toolApiMap, api => callback(api)); + } + }; + } + public render() { return ( -
- {this.renderContent()} - {this.renderEditability()} - {this.renderDebugInfo()} - {this.renderOverlayMessage()} -
+ +
+ {this.renderContent()} + {this.renderEditability()} + {this.renderDebugInfo()} + {this.renderOverlayMessage()} +
+
); } @@ -54,10 +77,11 @@ export class CanvasComponent extends React.Component { private renderContent() { const {content, document, ...others} = this.props; const documentContent = document ? document.content : content; + const documentId = document?.key; if (documentContent) { return ( - + ); } else { diff --git a/src/components/document/document-content.tsx b/src/components/document/document-content.tsx index 6e8fbc1b10..80e3389128 100644 --- a/src/components/document/document-content.tsx +++ b/src/components/document/document-content.tsx @@ -5,19 +5,21 @@ import { throttle } from "lodash"; import { BaseComponent, IBaseProps } from "../base"; import { TileRowComponent, kDragResizeRowId, extractDragResizeRowId, extractDragResizeY, extractDragResizeModelHeight, extractDragResizeDomHeight } from "../document/tile-row"; -import { DocumentContentModelType, IDropRowInfo } from "../../models/document/document-content"; -import { DocumentTool } from "../../models/document/document"; +import { DocumentContentModelType, IDragToolCreateInfo, IDropRowInfo } from "../../models/document/document-content"; +import { getToolContentInfoById } from "../../models/tools/tool-content-info"; import { IDragTiles } from "../../models/tools/tool-tile"; -import { dragTileSrcDocId, IToolApiInterface, kDragTileCreate, kDragTiles } from "../tools/tool-tile"; +import { ToolApiInterfaceContext } from "../tools/tool-api"; +import { dragTileSrcDocId, kDragTileCreate, kDragTiles } from "../tools/tool-tile"; +import { safeJsonParse } from "../../utilities/js-utils"; import "./document-content.sass"; interface IProps extends IBaseProps { context: string; + documentId?: string; content?: DocumentContentModelType; readOnly?: boolean; scale?: number; - toolApiInterface?: IToolApiInterface; selectedSectionId?: string | null; viaTeacherDashboard?: boolean; } @@ -40,6 +42,9 @@ const kDragUpdateInterval = 50; @observer export class DocumentContentComponent extends BaseComponent { + static contextType = ToolApiInterfaceContext; + declare context: React.ContextType; + public state: IState = {}; private domElement: HTMLElement | null; @@ -56,6 +61,9 @@ export class DocumentContentComponent extends BaseComponent { this.mutationObserver = new MutationObserver(this.handleRowElementsChanged); this.mutationObserver.observe(this.domElement, { childList: true }); } + // We pass the domElement to our children, but it's undefined during the first render, + // so we force an update to make sure we draw at least once after we have our domElement. + this.forceUpdate(); } } @@ -126,7 +134,7 @@ export class DocumentContentComponent extends BaseComponent { if (ref) { // eslint-disable-next-line react/no-find-dom-node const rowNode = findDOMNode(ref); - if (isElementInViewport(rowNode as Element)) { + if (rowNode && isElementInViewport(rowNode as Element)) { visibleRowIds.push(ref.props.model.id); } } @@ -140,9 +148,9 @@ export class DocumentContentComponent extends BaseComponent { const { rowMap } = content; const row = rowMap.get(rowId); const { dragResizeRow } = this.state; - const dragResizeRowId = dragResizeRow && dragResizeRow.id; - if (rowId !== dragResizeRowId) { - return row && row.height; + // must match lower-case for ids stored in DataTransfer key + if (rowId.toLowerCase() !== dragResizeRow?.id) { + return row?.height; } const rowHeight = dragResizeRow && (dragResizeRow.domHeight || dragResizeRow.modelHeight); if (!dragResizeRow || !rowHeight) return; @@ -176,6 +184,8 @@ export class DocumentContentComponent extends BaseComponent { documentContent={this.domElement} rowIndex={index} height={rowHeight} tileMap={tileMap} dropHighlight={dropHighlight} + onRequestTilesOfType={this.handleRequestTilesOfType} + onRequestUniqueTitle={this.handleRequestUniqueTitle} ref={(elt) => this.rowRefs.push(elt)} {...others} /> : null; }); @@ -187,11 +197,29 @@ export class DocumentContentComponent extends BaseComponent { } private handleScroll = throttle((e: React.UIEvent) => { + const toolApiInterface = this.context; const xScroll = this.domElement?.scrollLeft || 0; const yScroll = this.domElement?.scrollTop || 0; - this.props.toolApiInterface?.forEach(api => api.handleDocumentScroll?.(xScroll, yScroll)); + toolApiInterface?.forEach(api => api.handleDocumentScroll?.(xScroll, yScroll)); }, 50) + private handleRequestTilesOfType = (tileType: string) => { + const { content } = this.props; + const toolApiInterface = this.context; + if (!content || !tileType || !toolApiInterface) return []; + const tilesOfType = content.getTilesOfType(tileType); + return tilesOfType.map(id => ({ id, title: toolApiInterface.getToolApi(id)?.getTitle?.() })); + } + + private handleRequestUniqueTitle = (tileId: string) => { + const { content } = this.props; + const toolApiInterface = this.context; + const tileType = content?.getTile(tileId)?.content.type; + const titleBase = tileType && getToolContentInfoById(tileType)?.titleBase; + const getTileTitle = (_tileId: string) => toolApiInterface?.getToolApi?.(_tileId)?.getTitle?.(); + return tileType && titleBase && content?.getUniqueTitle(tileType, titleBase, getTileTitle); + } + private handleClick = (e: React.MouseEvent) => { const { ui } = this.stores; // deselect tiles on click on document background @@ -273,7 +301,7 @@ export class DocumentContentComponent extends BaseComponent { } else if (withinDocument && this.hasDragType(e.dataTransfer, kDragResizeRowId)) { const dragResizeRow = this.getDragResizeRowInfo(e); - if (dragResizeRow && dragResizeRow.id && dragResizeRow.newHeight != null) { + if (dragResizeRow?.id && dragResizeRow.newHeight != null) { this.setState({ dragResizeRow }); } // indicate we'll accept the drop @@ -355,9 +383,9 @@ export class DocumentContentComponent extends BaseComponent { private handleRowResizeDrop = (e: React.DragEvent) => { const { content } = this.props; const dragResizeRow = this.getDragResizeRowInfo(e); - if (content && dragResizeRow && dragResizeRow.id && dragResizeRow.newHeight != null) { + if (content && dragResizeRow?.id && dragResizeRow.newHeight != null) { const row = content.rowMap.get(dragResizeRow.id); - row && row.setRowHeight(dragResizeRow.newHeight); + row?.setRowHeight(dragResizeRow.newHeight); this.setState({ dragResizeRow: undefined }); } } @@ -374,17 +402,20 @@ export class DocumentContentComponent extends BaseComponent { const { content } = this.props; const { ui } = this.stores; - const createTileType = e.dataTransfer.getData(kDragTileCreate) as DocumentTool; - if (!content || !createTileType) return; + const createTileInfoStr = e.dataTransfer.getData(kDragTileCreate); + const createTileInfo = createTileInfoStr + ? safeJsonParse(createTileInfoStr) as IDragToolCreateInfo + : undefined; + if (!content || !createTileInfo) return; + const { tool, title } = createTileInfo; const insertRowInfo = this.getDropRowInfo(e); - - const isInsertingInExistingRow = insertRowInfo && insertRowInfo.rowDropLocation && + const isInsertingInExistingRow = insertRowInfo?.rowDropLocation && (["left", "right"].indexOf(insertRowInfo.rowDropLocation) >= 0); - const addSidecarNotes = (createTileType === "geometry") && !isInsertingInExistingRow; - const rowTile = content.userAddTile(createTileType, {addSidecarNotes, insertRowInfo}); + const addSidecarNotes = (tool === "geometry") && !isInsertingInExistingRow; + const rowTile = content.userAddTile(tool, {title, addSidecarNotes, insertRowInfo}); - if (rowTile && rowTile.tileId) { + if (rowTile?.tileId) { ui.setSelectedTileId(rowTile.tileId); } } diff --git a/src/components/document/document-workspace.tsx b/src/components/document/document-workspace.tsx index a264e78077..97cffb6f10 100644 --- a/src/components/document/document-workspace.tsx +++ b/src/components/document/document-workspace.tsx @@ -36,10 +36,10 @@ export class DocumentWorkspaceComponent extends BaseComponent { } public render() { - const { appConfig : { navTabs: { tabSpecs } }, user } = this.stores; + const { appConfig : { navTabs: { tabSpecs } }, teacherGuide, user: { isTeacher } } = this.stores; const studentTabs = tabSpecs.filter((t) => !t.teacherOnly); - const isTeacher = user.isTeacher; - const tabsToDisplay = isTeacher ? tabSpecs : studentTabs; + const teacherTabs = tabSpecs.filter(t => (t.tab !== "teacher-guide") || teacherGuide); + const tabsToDisplay = isTeacher ? teacherTabs : studentTabs; // NOTE: the drag handlers are in three different divs because we cannot overlay // the renderDocuments() div otherwise the Cypress tests will fail because none // of the html elements in the documents will be visible to it. The first div acts diff --git a/src/components/document/editable-document-content.tsx b/src/components/document/editable-document-content.tsx index 7eec65337a..cb8b548ad2 100644 --- a/src/components/document/editable-document-content.tsx +++ b/src/components/document/editable-document-content.tsx @@ -5,9 +5,7 @@ import { DocumentContextReact } from "./document-context"; import { FourUpComponent } from "../four-up"; import { useDocumentContext } from "../../hooks/use-document-context"; import { useGroupsStore } from "../../hooks/use-stores"; -import { useToolApiInterface } from "../../hooks/use-tool-api-interface"; import { ToolbarComponent, ToolbarConfig } from "../toolbar"; -import { IToolApiInterface, IToolApiMap } from "../tools/tool-tile"; import { DocumentModelType } from "../../models/document/document"; import { ProblemDocument } from "../../models/document/document-types"; import { WorkspaceMode } from "../../models/stores/workspace"; @@ -17,36 +15,33 @@ import "./editable-document-content.scss"; interface IToolbarProps { document: DocumentModelType; toolbar?: ToolbarConfig; - toolApiMap: IToolApiMap; } -const DocumentToolbar: React.FC = ({ document, toolbar, toolApiMap }) => { +const DocumentToolbar: React.FC = ({ toolbar, ...others }) => { const appConfig = useContext(AppConfigContext); const toolbarConfig = toolbar?.map(tool => ({ icon: appConfig.appIcons?.[tool.iconId], ...tool })); return toolbarConfig - ? + ? : null; }; interface IOneUpCanvasProps { document: DocumentModelType; readOnly: boolean; - toolApiInterface: IToolApiInterface; } -const OneUpCanvas: React.FC = ({ document, readOnly, toolApiInterface}) => { +const OneUpCanvas: React.FC = props => { return ( - + ); }; interface IEditableFourUpCanvasProps { userId: string; - toolApiInterface: IToolApiInterface; } -const EditableFourUpCanvas: React.FC = ({ userId, toolApiInterface}) => { +const EditableFourUpCanvas: React.FC = props => { const groups = useGroupsStore(); - const group = groups.groupForUser(userId); + const group = groups.groupForUser(props.userId); return ( - + ); }; @@ -55,16 +50,15 @@ interface IDocumentCanvasProps { isPrimary: boolean; document: DocumentModelType; readOnly: boolean; - toolApiInterface: IToolApiInterface; } const DocumentCanvas: React.FC = props => { - const { mode, isPrimary, document, readOnly, toolApiInterface } = props; + const { mode, isPrimary, document, readOnly } = props; const isFourUp = (document.type === ProblemDocument) && (isPrimary && (mode === "4-up")); return (
{isFourUp - ? - : } + ? + : }
); @@ -81,7 +75,6 @@ export const EditableDocumentContent: React.FC = props => { const { mode, isPrimary, document, toolbar, readOnly } = props; const documentContext = useDocumentContext(document); - const [toolApiMap, toolApiInterface] = useToolApiInterface(); const isReadOnly = !isPrimary || readOnly || document.isPublished; const isShowingToolbar = !!toolbar && !isReadOnly; @@ -89,10 +82,9 @@ export const EditableDocumentContent: React.FC = props => { return (
- {isShowingToolbar && } + {isShowingToolbar && } {isShowingToolbar &&
} - +
); diff --git a/src/components/document/tile-row.sass b/src/components/document/tile-row.sass index 60e69c166a..1459748650 100644 --- a/src/components/document/tile-row.sass +++ b/src/components/document/tile-row.sass @@ -7,6 +7,9 @@ flex-direction: row align-content: flex-start + &.has-teacher-tiles + margin-bottom: 5px + .drop-feedback position: absolute pointer-events: none diff --git a/src/components/document/tile-row.tsx b/src/components/document/tile-row.tsx index 8f3cff9e52..6f09dbf2d5 100644 --- a/src/components/document/tile-row.tsx +++ b/src/components/document/tile-row.tsx @@ -1,10 +1,14 @@ +import classNames from "classnames"; import React from "react"; import { observer, inject } from "mobx-react"; -import { TileRowModelType } from "../../models/document/tile-row"; import { BaseComponent } from "../base"; -import { ToolTileComponent, dragTileSrcDocId, IToolApiInterface } from "../tools/tool-tile"; +import { TileLayoutModelType, TileRowModelType } from "../../models/document/tile-row"; +import { isShowingTeacherContent } from "../../models/stores/stores"; import { ToolTileModelType } from "../../models/tools/tool-tile"; import { SectionHeader } from "../tools/section-header"; +import { ToolApiInterfaceContext } from "../tools/tool-api"; +import { ToolTileComponent, dragTileSrcDocId } from "../tools/tool-tile"; + import "./tile-row.sass"; export const kDragResizeRowId = "org.concord.clue.row-resize.id"; @@ -18,6 +22,11 @@ export const dragResizeRowDomHeight = (domHeight: number) => `org.concord.clue.row-resize.dom-height.${domHeight}`; export function extractDragResizeRowId(dataTransfer: DataTransfer) { + // get the actual rowId from contents if possible (e.g. on drop) + const dragRowId = dataTransfer.getData(kDragResizeRowId); + if (dragRowId) return dragRowId; + + // if not, extract the toLowerCase() version from the key (e.g. on over) for (const type of dataTransfer.types) { const result = /org\.concord\.clue\.row-resize\.id\.(.*)$/.exec(type); if (result) return result[1]; @@ -47,7 +56,8 @@ export function extractDragResizeDomHeight(dataTransfer: DataTransfer) { interface IProps { context: string; - docId: string; + documentId?: string; // permanent id (key) of the containing document + docId: string; // ephemeral contentId for the DocumentContent documentContent: HTMLElement | null; scale?: number; model: TileRowModelType; @@ -56,7 +66,8 @@ interface IProps { tileMap: any; readOnly?: boolean; dropHighlight?: string; - toolApiInterface?: IToolApiInterface; + onRequestTilesOfType: (tileType: string) => Array<{ id: string, title?: string }>; + onRequestUniqueTitle: (tileId: string) => string | undefined; } interface IState { @@ -67,38 +78,69 @@ interface IState { @observer export class TileRowComponent extends BaseComponent { + static contextType = ToolApiInterfaceContext; + declare context: React.ContextType; + public state: IState = {}; private tileRowDiv: HTMLElement | null; public render() { const { model } = this.props; - const { isSectionHeader, sectionId } = model; + const { isSectionHeader, sectionId, tiles } = model; // ignore height setting for section header rows const height = !isSectionHeader - ? this.props.height || model.height + ? this.props.height || model.height || this.getContentHeight() : undefined; const style = height ? { height } : undefined; + const renderableTiles = tiles?.filter(tile => this.isTileRenderable(tile.tileId)); + const hasTeacherTiles = tiles.some(tile => this.getTile(tile.tileId)?.display === "teacher"); + const classes = classNames("tile-row", { "has-teacher-tiles": hasTeacherTiles }); + if (!isSectionHeader && !renderableTiles.length) return null; return ( -
this.tileRowDiv = elt}> { isSectionHeader && sectionId ? - : this.renderTiles(height) + : this.renderTiles(renderableTiles, height) } {!this.props.readOnly && this.renderDragDropHandles()}
); } - private renderTiles(rowHeight?: number) { + private getTile(tileId: string) { + return this.props.tileMap.get(tileId) as ToolTileModelType | undefined; + } + + private isTileRenderable(tileId: string) { + const tile = this.getTile(tileId); + return !!tile && (!tile.display || isShowingTeacherContent(this.stores)); + } + + private getTileWidth(tileId: string, tiles: TileLayoutModelType[]) { + // for now, distribute tiles evenly + return 100 / (tiles.length || 1); + } + + private getContentHeight() { + const { model: { tiles } } = this.props; + const toolApiInterface = this.context; + let rowHeight: number | undefined; + tiles.forEach(tile => { + const toolApi = toolApiInterface?.getToolApi(tile.tileId); + const tileHeight = toolApi?.getContentHeight?.(); + tileHeight && (rowHeight = Math.max(tileHeight, rowHeight || 0)); + }); + return rowHeight; + } + + private renderTiles(tiles: TileLayoutModelType[], rowHeight?: number) { const { model, tileMap, ...others } = this.props; - const { tiles } = model; - if (!tiles) { return null; } return tiles.map((tileRef, index) => { - const tileModel: ToolTileModelType = tileMap.get(tileRef.tileId); - const tileWidthPct = model.renderWidth(tileRef.tileId); + const tileModel = this.getTile(tileRef.tileId); + const tileWidthPct = this.getTileWidth(tileRef.tileId, tiles); return tileModel ? { private renderTabContent = (tabSpec: NavTabSpec) => { switch (tabSpec.tab) { case ENavTab.kProblems: - return this.renderProblems(); + return this.renderProblem(); + case ENavTab.kTeacherGuide: + return this.renderTeacherGuide(); case ENavTab.kStudentWork: return ; case ENavTab.kClassWork: @@ -91,11 +93,18 @@ export class NavTabPanel extends BaseComponent { ); } - private renderProblems = () => { - const { problem } = this.stores; - const { sections } = problem; + private renderProblem = () => { + const { user: { isTeacher }, problem: { sections } } = this.stores; return ( - + + ); + } + + private renderTeacherGuide = () => { + const { user: { isTeacher }, teacherGuide } = this.stores; + const sections = teacherGuide?.sections; + return isTeacher && sections && ( + ); } diff --git a/src/components/navigation/problem-tab-content.sass b/src/components/navigation/problem-tab-content.sass index 323d6a61ed..b33cdcb1cc 100644 --- a/src/components/navigation/problem-tab-content.sass +++ b/src/components/navigation/problem-tab-content.sass @@ -4,11 +4,16 @@ border-color: $problem-orange-light-3 border-width: 0 $tab-section-border-width $tab-section-border-width 0 border-style: solid - .tab-list + .tab-header-row + display: flex + flex-direction: row + align-items: center background-color: $problem-orange-light-7 + height: $nav-tab-height + .tab-list + flex: 1 1 auto margin: 0 padding: 0 - height: $nav-tab-height display: flex .prob-tab flex-grow: 1 @@ -23,3 +28,43 @@ &:active, &.selected background-color: $problem-orange-light-3 font-weight: bold + + &.teacher-guide + background-color: $learninglog-green-light-7 + &:hover + background-color: $learninglog-green-light-5 + &:active, &.selected + background-color: $learninglog-green-light-4 + + .solutions-switch + display: flex + align-items: center + width: 116px + height: 100% + border-top: 2px solid white + .solutions-separator + width: 1px + height: 24px + margin: 0 3px + background-color: $problem-orange-light-2 + border: 0.5px solid $problem-orange-light-2 + .solutions-button.toggle-control + flex: 0 0 auto + margin: 0 4px + .track + &.toggle-on + background-color: $problem-orange + .ball + background-color: $problem-orange-light-6 + &:hover + background-color: $problem-orange-light-4 + &:active + background-color: $problem-orange + &.toggle-on + background-color: $problem-orange + &:hover.toggle-on + background-color: $problem-orange-light-4 + &:active.toggle-on + background-color: $problem-orange-light-6 + .solutions-label + margin: 0 7px 0 3px diff --git a/src/components/navigation/problem-tab-content.tsx b/src/components/navigation/problem-tab-content.tsx index 9b67feff02..273d0920ec 100644 --- a/src/components/navigation/problem-tab-content.tsx +++ b/src/components/navigation/problem-tab-content.tsx @@ -1,17 +1,24 @@ +import classNames from "classnames"; +import { observer } from "mobx-react"; import React from "react"; import { Tab, Tabs, TabList, TabPanel } from "react-tabs"; +import { useUIStore, useUserStore } from "../../hooks/use-stores"; import { getSectionTitle, SectionModelType } from "../../models/curriculum/section"; import { ProblemPanelComponent } from "./problem-panel"; import { Logger, LogEventName } from "../../lib/logger"; +import ToggleControl from "../utilities/toggle-control"; import "./problem-tab-content.sass"; interface IProps { + context?: string; sections: SectionModelType[]; + showSolutionsSwitch: boolean; } -export const ProblemTabContent: React.FC = (props) => { - const { sections } = props; +export const ProblemTabContent: React.FC = observer(({ context, sections, showSolutionsSwitch}: IProps) => { + const { isTeacher } = useUserStore(); + const { showTeacherContent, toggleShowTeacherContent } = useUIStore(); const handleTabClick = (title: string, type: string) => { Logger.log(LogEventName.SHOW_TAB_SECTION, { @@ -20,20 +27,28 @@ export const ProblemTabContent: React.FC = (props) => { }); }; + const handleToggleSolutions = () => { + toggleShowTeacherContent(!showTeacherContent); + Logger.log(showTeacherContent ? LogEventName.HIDE_SOLUTIONS : LogEventName.SHOW_SOLUTIONS); + }; + return ( - - - {sections.map((section) => { - const sectionTitle = getSectionTitle(section.type); - return ( - handleTabClick(section.type, sectionTitle)} - > - {sectionTitle} - - ); - })} - + +
+ + {sections.map((section) => { + const sectionTitle = getSectionTitle(section.type); + return ( + handleTabClick(section.type, sectionTitle)} > + {sectionTitle} + + ); + })} + + {isTeacher && showSolutionsSwitch && + } +
{sections.map((section) => { return ( @@ -43,4 +58,19 @@ export const ProblemTabContent: React.FC = (props) => { })}
); +}); + +const SolutionsButton = ({ onClick, isToggled }: { onClick: () => void, isToggled: boolean }) => { + const classes = classNames("solutions-button", { toggled: isToggled }); + return ( +
+ {
} + +
Solutions
+
+ ); }; diff --git a/src/components/toolbar.tsx b/src/components/toolbar.tsx index 77ee686df5..f69c96dd6e 100644 --- a/src/components/toolbar.tsx +++ b/src/components/toolbar.tsx @@ -5,10 +5,11 @@ import classNames from "classnames"; import { IconComponent } from "../app-config-context"; import { BaseComponent, IBaseProps } from "./base"; import { DocumentModelType, DocumentTool } from "../models/document/document"; -import { IDocumentContentAddTileOptions } from "../models/document/document-content"; -import { getToolContentInfoByTool } from "../models/tools/tool-content-info"; +import { IDocumentContentAddTileOptions, IDragToolCreateInfo } from "../models/document/document-content"; +import { getToolContentInfoByTool, IToolContentInfo } from "../models/tools/tool-content-info"; import { ToolButtonSnapshot } from "../models/tools/tool-types"; -import { IToolApiMap, kDragTileCreate } from "./tools/tool-tile"; +import { ToolApiInterfaceContext } from "./tools/tool-api"; +import { kDragTileCreate } from "./tools/tool-tile"; import "./toolbar.sass"; @@ -21,7 +22,6 @@ export type ToolbarConfig = IToolButtonConfig[]; interface IProps extends IBaseProps { document: DocumentModelType; config: ToolbarConfig; - toolApiMap: IToolApiMap; } interface IState { @@ -90,6 +90,9 @@ const ToolButtonComponent: React.FC = @observer export class ToolbarComponent extends BaseComponent { + static contextType = ToolApiInterfaceContext; + declare context: React.ContextType; + state = { defaultTool: "", activeTool: "" @@ -157,11 +160,20 @@ export class ToolbarComponent extends BaseComponent { document.content.showPendingInsertHighlight(false); } + private getUniqueTitle(toolContentInfo: IToolContentInfo) { + const toolApiInterface = this.context; + const { document } = this.props; + const { id, titleBase } = toolContentInfo; + const getTileTitle = (tileId: string) => toolApiInterface?.getToolApi(tileId)?.getTitle?.(); + return titleBase && document.getUniqueTitle(id, titleBase, getTileTitle); + } + private handleAddToolTile(tool: DocumentTool) { const { document } = this.props; const { ui } = this.stores; const toolContentInfo = getToolContentInfoByTool(tool); const newTileOptions: IDocumentContentAddTileOptions = { + title: this.getUniqueTitle(toolContentInfo), addSidecarNotes: !!toolContentInfo?.addSidecarNotes, insertRowInfo: { rowInsertIndex: document.content.defaultInsertRow } }; @@ -177,10 +189,11 @@ export class ToolbarComponent extends BaseComponent { } private handleDelete() { + const toolApiInterface = this.context; const { document } = this.props; const { ui } = this.stores; ui.selectedTileIds.forEach(tileId => { - const toolApi = this.props.toolApiMap[tileId]; + const toolApi = toolApiInterface?.getToolApi(tileId); // if there is selected content inside the selected tile, delete it first if (toolApi?.hasSelection?.()) { toolApi.deleteSelection?.(); @@ -196,6 +209,9 @@ export class ToolbarComponent extends BaseComponent { private handleDragNewToolTile = (tool: DocumentTool, e: React.DragEvent) => { // remove hover-insert highlight when we start a tile drag this.removeDropRowHighlight(); - e.dataTransfer.setData(kDragTileCreate, tool); + + const toolContentInfo = getToolContentInfoByTool(tool); + const dragInfo: IDragToolCreateInfo = { tool, title: this.getUniqueTitle(toolContentInfo) }; + e.dataTransfer.setData(kDragTileCreate, JSON.stringify(dragInfo)); } } diff --git a/src/components/tools/drawing-tool/drawing-tool.tsx b/src/components/tools/drawing-tool/drawing-tool.tsx index 209891c351..b6f3b4f24a 100644 --- a/src/components/tools/drawing-tool/drawing-tool.tsx +++ b/src/components/tools/drawing-tool/drawing-tool.tsx @@ -11,7 +11,7 @@ import "./drawing-tool.sass"; type IProps = IToolTileProps; const DrawingToolComponent: React.FC = (props) => { - const { documentContent, toolTile, model, readOnly, onRegisterToolApi, onUnregisterToolApi } = props; + const { documentContent, toolTile, model, readOnly, scale, onRegisterToolApi, onUnregisterToolApi } = props; useEffect(() => { if (!readOnly) { @@ -26,6 +26,7 @@ const DrawingToolComponent: React.FC = (props) => {
diff --git a/src/components/tools/drawing-tool/drawing-toolbar.tsx b/src/components/tools/drawing-tool/drawing-toolbar.tsx index 43f4428694..229b27d0de 100644 --- a/src/components/tools/drawing-tool/drawing-toolbar.tsx +++ b/src/components/tools/drawing-tool/drawing-toolbar.tsx @@ -7,7 +7,7 @@ import { import { StampsPalette } from "./stamps-palette"; import { StrokeColorPalette } from "./stroke-color-palette"; import { FillColorPalette } from "./fill-color-palette"; -import { useFloatingToolbarLocation } from "../hooks/use-floating-toolbar-location"; +import { IFloatingToolbarProps, useFloatingToolbarLocation } from "../hooks/use-floating-toolbar-location"; import { useForceUpdate } from "../hooks/use-force-update"; import { useMobXOnChange } from "../hooks/use-mobx-on-change"; import { IRegisterToolApiProps } from "../tool-tile"; @@ -24,11 +24,8 @@ interface IPaletteState { type PaletteKey = keyof IPaletteState; const kClosedPalettesState = { showStamps: false, showStroke: false, showFill: false }; -interface IProps extends IRegisterToolApiProps { - documentContent?: HTMLElement | null; - toolTile?: HTMLElement | null; +interface IProps extends IFloatingToolbarProps, IRegisterToolApiProps { model: ToolTileModelType; - onIsEnabled: () => boolean; } export const ToolbarView: React.FC = ( { documentContent, model, onIsEnabled, ...others }: IProps) => { diff --git a/src/components/tools/geometry-tool/editable-geometry-title.tsx b/src/components/tools/geometry-tool/editable-geometry-title.tsx new file mode 100644 index 0000000000..cc0eb65249 --- /dev/null +++ b/src/components/tools/geometry-tool/editable-geometry-title.tsx @@ -0,0 +1,72 @@ +import classNames from "classnames"; +import { observer } from "mobx-react"; +import React, { useState } from "react"; +import { SizeMeProps } from "react-sizeme"; +import { GeometryLabelInput } from "./geometry-label-input"; + +import "./geometry-title.scss"; + +interface IProps extends SizeMeProps { + className?: string; + readOnly?: boolean; + getTitle: () => string | undefined; + measureText: (text: string) => number; + onBeginEdit?: () => void; + onEndEdit?: (title?: string) => void; +} +export const EditableGeometryTitle: React.FC = observer(({ + className, readOnly, size: contentSize, getTitle, measureText, onBeginEdit, onEndEdit +}) => { + // getTitle() and observer() allow this component to re-render + // when the title changes without re-rendering the entire Geometry + const title = getTitle() || "Graph"; + const kTitlePadding = 30; + const kCenteringCorrection = 11; // so it's centered w.r.t. the document title + // There can be one render before we know our container size, which will then be + // immediately replaced by a subsequent render with a known container size. + // Place it roughly in the middle of the screen until we have a proper position. + const kContainerlessPosition = 450; + const width = Math.ceil(measureText(title)) + kTitlePadding; + const left = contentSize.width ? (contentSize.width - width) / 2 - kCenteringCorrection : kContainerlessPosition; + const [isEditing, setIsEditing] = useState(false); + const [editingTitle, setEditingTitle] = useState(title); + const handleClick = () => { + if (!readOnly && !isEditing) { + onBeginEdit?.(); + setEditingTitle(title); + setIsEditing(true); + } + }; + const handleKeyDown = (e: React.KeyboardEvent) => { + const { key } = e; + switch (key) { + case "Escape": + handleClose(false); + break; + case "Enter": + case "Tab": + handleClose(true); + break; + } + }; + const handleClose = (accept: boolean) => { + const trimTitle = editingTitle?.trim(); + onEndEdit?.(accept && trimTitle ? trimTitle : undefined); + setIsEditing(false); + }; + const isDefaultTitle = title && /Graph\s+(\d+)\s*$/.test(title); + const classes = classNames("geometry-title", className, + { "geometry-title-editing": isEditing, "geometry-title-default": isDefaultTitle }); + const containerStyle: React.CSSProperties = { left, width }; + const kMinInputWidth = 200; // so there's room to expand very short titles + const inputWidth = width >= kMinInputWidth ? "100%" : kMinInputWidth; + const inputStyle: React.CSSProperties = { width: inputWidth }; + return ( +
+ {isEditing + ? handleClose(true)} /> + :
{title}
} +
+ ); +}); diff --git a/src/components/tools/geometry-tool/geometry-content-wrapper.tsx b/src/components/tools/geometry-tool/geometry-content-wrapper.tsx index bcd6d04122..1cb2595e68 100644 --- a/src/components/tools/geometry-tool/geometry-content-wrapper.tsx +++ b/src/components/tools/geometry-tool/geometry-content-wrapper.tsx @@ -1,21 +1,21 @@ import classNames from "classnames"; import React from "react"; import { SizeMe, SizeMeProps } from "react-sizeme"; +import { useMeasureText } from "../hooks/use-measure-text"; import { GeometryContentComponent, IGeometryContentProps } from "./geometry-content"; interface IProps extends IGeometryContentProps{ readOnly?: boolean; } -export const GeometryContentWrapper: React.FC = ({ - readOnly, ...others -}) => { +export const GeometryContentWrapper: React.FC = (props) => { + const measureLabelText = useMeasureText("italic 14px Lato, sans-serif"); return ( -
+
{({ size }: SizeMeProps) => { return (
- +
); }} diff --git a/src/components/tools/geometry-tool/geometry-content.tsx b/src/components/tools/geometry-tool/geometry-content.tsx index b272e4c8f9..b285034f80 100644 --- a/src/components/tools/geometry-tool/geometry-content.tsx +++ b/src/components/tools/geometry-tool/geometry-content.tsx @@ -2,7 +2,6 @@ import React from "react"; import { inject, observer } from "mobx-react"; import { SizeMeProps } from "react-sizeme"; import { BaseComponent } from "../../base"; -import { Alert, Intent } from "@blueprintjs/core"; import { DocumentContentModelType } from "../../../models/document/document-content"; import { getLinkedTableIndex, getTableLinkColors } from "../../../models/tools/table-links"; import { getTableContent } from "../../../models/tools/table/table-content"; @@ -12,15 +11,19 @@ import { GeometryContentModelType, GeometryMetadataModelType, setElementColor, g import { copyCoords, getEventCoords, getAllObjectsUnderMouse, getClickableObjectUnderMouse, isDragTargetOrAncestor } from "../../../models/tools/geometry/geometry-utils"; import { RotatePolygonIcon } from "./rotate-polygon-icon"; -import { kGeometryDefaultPixelsPerUnit, isAxis, isAxisLabel } from "../../../models/tools/geometry/jxg-board"; +import { getPointsByCaseId, kGeometryDefaultPixelsPerUnit } from "../../../models/tools/geometry/jxg-board"; import { ESegmentLabelOption, ILinkProperties, JXGChange, JXGCoordPair } from "../../../models/tools/geometry/jxg-changes"; -import { isPoint, isFreePoint, isVisiblePoint, kSnapUnit } from "../../../models/tools/geometry/jxg-point"; -import { getAssociatedPolygon, getPointsForVertexAngle, getPolygonEdges, isPolygon, isVisibleEdge - } from "../../../models/tools/geometry/jxg-polygon"; -import { isComment } from "../../../models/tools/geometry/jxg-types"; -import { getVertexAngle, isVertexAngle, updateVertexAngle, updateVertexAnglesFromObjects - } from "../../../models/tools/geometry/jxg-vertex-angle"; +import { kSnapUnit } from "../../../models/tools/geometry/jxg-point"; +import { + getAssociatedPolygon, getPointsForVertexAngle, getPolygonEdges +} from "../../../models/tools/geometry/jxg-polygon"; +import { + isAxis, isAxisLabel, isComment, isFreePoint, isPoint, isPolygon, isVertexAngle, isVisibleEdge, isVisiblePoint +} from "../../../models/tools/geometry/jxg-types"; +import { + getVertexAngle, updateVertexAngle, updateVertexAnglesFromObjects +} from "../../../models/tools/geometry/jxg-vertex-angle"; import { isFeatureSupported } from "../../../models/stores/stores"; import { injectGetTableLinkColorsFunction } from "../../../models/tools/geometry/jxg-table-link"; import { extractDragTileType, kDragTileContent, kDragTileId, dragTileSrcDocId } from "../tool-tile"; @@ -30,15 +33,17 @@ import { getUrlFromImageContent } from "../../../utilities/image-utils"; import { safeJsonParse, uniqueId } from "../../../utilities/js-utils"; import { hasSelectionModifier } from "../../../utilities/event-utils"; import { assign, castArray, debounce, each, filter, find, keys as _keys, throttle, values } from "lodash"; -import { isVisibleMovableLine, isMovableLine, isMovableLineControlPoint, isMovableLineLabel, - handleControlPointClick} from "../../../models/tools/geometry/jxg-movable-line"; -import { v4 as uuid } from "uuid"; +import { + isVisibleMovableLine, isMovableLine, isMovableLineControlPoint, isMovableLineLabel, +} from "../../../models/tools/geometry/jxg-movable-line"; import { Logger, LogEventName, LogEventMethod } from "../../../lib/logger"; import { getDataSetBounds, IDataSet } from "../../../models/data/data-set"; import AxisSettingsDialog from "./axis-settings-dialog"; +import { EditableGeometryTitle } from "./editable-geometry-title"; import LabelSegmentDialog from "./label-segment-dialog"; import MovableLineDialog from "./movable-line-dialog"; import placeholderImage from "../../../assets/image_placeholder.png"; +import ErrorAlert from "../../utilities/error-alert"; import SingleStringDialog from "../../utilities/single-string-dialog"; import { autorun } from "mobx"; @@ -49,7 +54,9 @@ export interface IGeometryContentProps extends IGeometryProps { onSetActionHandlers: (handlers: IActionHandlers) => void; onContentChange: () => void; } -export type IProps = IGeometryContentProps & SizeMeProps; +export interface IProps extends IGeometryContentProps, SizeMeProps { + measureText: (text: string) => number; +} // cf. https://mariusschulz.com/blog/mapped-type-modifiers-in-typescript#removing-the-readonly-mapped-type-modifier type Mutable = { @@ -249,6 +256,7 @@ export class GeometryContentComponent extends BaseComponent { const metadata = this.getContent().metadata; this.props.onRegisterToolApi({ + getTitle: () => metadata.title, hasSelection: () => { const geometryContent = this.props.model.content as GeometryContentModelType; // Note: hasSelection() returns true when there is a selection whether or not @@ -267,8 +275,9 @@ export class GeometryContentComponent extends BaseComponent { } }, getSelectionInfo: () => { + const { board } = this.state; const geometryContent = this.props.model.content as GeometryContentModelType; - const selectedIds = geometryContent ? geometryContent.selectedIds : []; + const selectedIds = board && geometryContent?.getSelectedIds(board) || []; return JSON.stringify(selectedIds); }, setSelectionHighlight: (selectionInfo: string, isHighlighted: boolean) => { @@ -404,6 +413,7 @@ export class GeometryContentComponent extends BaseComponent { onDragLeave={this.handleDragLeave} onDrop={this.handleDrop} />, this.renderRotateHandle(), + this.renderTitle(), this.renderInvalidTableDataAlert() ]); } @@ -501,24 +511,28 @@ export class GeometryContentComponent extends BaseComponent { ); } + private handleTitleChange = (title?: string) => { + title && this.getContent().updateTitle(this.state.board, title); + } + + private renderTitle() { + const getTitle = () => this.getContent().title || ""; + const { measureText, size } = this.props; + return ( + + ); + } + private renderInvalidTableDataAlert() { const { showInvalidTableDataAlert } = this.state; if (!showInvalidTableDataAlert) return; return ( - -

- Linked data must be numeric. Please edit the table values so that all cells contain numbers. -

-
+ ); } @@ -552,6 +566,13 @@ export class GeometryContentComponent extends BaseComponent { } this.syncedChanges = content.changes.length; } + // if we haven't been assigned a title already, request one now + // we set the title without updating the content, so the title is ephemeral + if (!content.metadata.title) { + const { model: { id }, onRequestUniqueTitle } = this.props; + const title = onRequestUniqueTitle(id); + title && content.metadata.setTitle(title); + } } private getBackgroundImage(_board?: JXG.Board) { @@ -893,7 +914,7 @@ export class GeometryContentComponent extends BaseComponent { case "create": // map ids of newly create object if (change.properties && change.properties.id) { - idMap[change.properties.id] = uuid(); + idMap[change.properties.id] = uniqueId(); change.properties.id = idMap[change.properties.id]; } // after the first paste, names/labels are auto-generated @@ -989,7 +1010,7 @@ export class GeometryContentComponent extends BaseComponent { this.handleImageTileDrop(e, parsedContent); } else if (tileType === "table") { - this.handleTableTileDrop(e, parsedContent); + this.handleTableTileDrop(e); } e.preventDefault(); e.stopPropagation(); @@ -1049,13 +1070,19 @@ export class GeometryContentComponent extends BaseComponent { return { id: links.id, tileIds: [this.props.model.id] }; } - private handleTableTileDrop(e: React.DragEvent, parsedContent: any) { - const { board } = this.state; + private handleTableTileDrop(e: React.DragEvent) { const dragTileId = e.dataTransfer.getData(kDragTileId); - if (this.getContent().isLinkedToTable(dragTileId)) return; + if (dragTileId) { + this.handleTableTileLinkRequest(dragTileId); + } + } + + private handleTableTileLinkRequest(tableTileId: string) { + const { board } = this.state; + if (this.getContent().isLinkedToTable(tableTileId)) return; - const tableContent = this.getTableContent(dragTileId); - if (tableContent && parsedContent && board) { + const tableContent = this.getTableContent(tableTileId); + if (tableContent && board) { if (!tableContent.isValidForGeometryLink()) { this.setState({ showInvalidTableDataAlert: true }); return; @@ -1063,15 +1090,15 @@ export class GeometryContentComponent extends BaseComponent { const dataSet = tableContent.getSharedData(); this.autoRescaleBoardAndAxes(dataSet); - const geomActionLinks = tableContent.getClientLinks(uniqueId(), dataSet, true); + const geomActionLinks = tableContent.getClientLinks(uniqueId(), dataSet); this.applyChange(() => { - const pts = this.getContent().addTableLink(board, dragTileId, dataSet, geomActionLinks); + const pts = this.getContent().addTableLink(board, tableTileId, dataSet, geomActionLinks); pts.forEach((pt: JXG.Point) => { this.handleCreatePoint(pt); }); }); - const _tableContent = this.getTableContent(dragTileId); + const _tableContent = this.getTableContent(tableTileId); const tableActionLinks = this.getTableActionLinks(geomActionLinks); _tableContent && _tableContent.addGeometryLink(this.props.model.id, tableActionLinks); } @@ -1361,8 +1388,11 @@ export class GeometryContentComponent extends BaseComponent { // synchronize selection changes this.disposers.push(content.metadata.selection.observe((change: any) => { - if (this.state.board) { - setElementColor(this.state.board, change.name, (change as any).newValue.value); + const { board: _board } = this.state; + if (_board) { + // this may be a shared selection change; get all points associated with it + const objs = getPointsByCaseId(_board, change.name); + objs.forEach(obj => setElementColor(_board, obj.id, change.newValue.value)); } })); @@ -1392,12 +1422,13 @@ export class GeometryContentComponent extends BaseComponent { if (!board) return; const id = point.id; const coords = copyCoords(point.coords); - const linkedTableId = point.getAttribute("linkedTableId"); + const tableId = point.getAttribute("linkedTableId"); + const columnId = point.getAttribute("linkedColId"); const isPointDraggable = !this.props.readOnly && !point.getAttribute("fixed"); if (isFreePoint(point) && this.isDoubleClick(this.lastPointDown, { evt, coords })) { if (board) { this.applyChange(() => { - const polygon = geometryContent.createPolygonFromFreePoints(board, linkedTableId) as JXG.Polygon; + const polygon = geometryContent.createPolygonFromFreePoints(board, tableId, columnId) as JXG.Polygon; if (polygon) { this.handleCreatePolygon(polygon); this.props.onContentChange(); @@ -1417,7 +1448,16 @@ export class GeometryContentComponent extends BaseComponent { } if (isMovableLineControlPoint(point)) { - handleControlPointClick(point, geometryContent); + // When a control point is clicked, deselect the rest of the line so the line slope can be changed + const line = find(point.descendants, el => isMovableLine(el)); + if (line) { + geometryContent.deselectElement(undefined, line.id); + each(line.ancestors, (parentPoint, parentId) => { + if (parentId !== point.id) { + geometryContent.deselectElement(undefined, parentId); + } + }); + } } } // click on unselected element diff --git a/src/components/tools/geometry-tool/geometry-label-input.tsx b/src/components/tools/geometry-tool/geometry-label-input.tsx new file mode 100644 index 0000000000..064461c98d --- /dev/null +++ b/src/components/tools/geometry-tool/geometry-label-input.tsx @@ -0,0 +1,29 @@ +import React from "react"; + +function autoFocusAndSelect(input: HTMLInputElement | null) { + input?.focus(); + input?.select(); +} + +interface IProps { + style?: React.CSSProperties; + value: string; + onKeyDown: (e: React.KeyboardEvent) => void; + onChange: (value: string) => void; + onBlur: (value: string) => void; +} +export const GeometryLabelInput: React.FC = ({ style, value, onKeyDown, onChange, onBlur }) => { + return ( +
+ onChange(event.target.value)} + onBlur={event => onBlur(event.target.value)} + /> +
+ ); +}; diff --git a/src/components/tools/geometry-tool/geometry-title.scss b/src/components/tools/geometry-tool/geometry-title.scss new file mode 100644 index 0000000000..b8e6c714e3 --- /dev/null +++ b/src/components/tools/geometry-tool/geometry-title.scss @@ -0,0 +1,24 @@ +@import "../../vars.sass"; + +.geometry-title { + position: absolute; + top: 6px; + height: 26px; + display: flex; + align-items: center; + justify-content: center; + color: $charcoal-dark-2; + background-color: white; + border: 1.5px solid $charcoal-light-1; + border-radius: 5px; + text-align: center; + z-index: 10; // has to be higher than JSXGraph entities that should be below it + + input { + text-align: center; + } + + .geometry-title-text { + font-style: italic; + } +} diff --git a/src/components/tools/geometry-tool/geometry-tool.sass b/src/components/tools/geometry-tool/geometry-tool.sass index c41fd57d0c..88fb6cd404 100644 --- a/src/components/tools/geometry-tool/geometry-tool.sass +++ b/src/components/tools/geometry-tool/geometry-tool.sass @@ -7,6 +7,7 @@ $toolbar-width: 44px width: 100% height: 100% min-height: 52px + outline: none !important // counteract blueprint.js :focus rule .geometry-wrapper position: absolute diff --git a/src/components/tools/geometry-tool/geometry-tool.tsx b/src/components/tools/geometry-tool/geometry-tool.tsx index d6929312ca..c13f63f6cd 100644 --- a/src/components/tools/geometry-tool/geometry-tool.tsx +++ b/src/components/tools/geometry-tool/geometry-tool.tsx @@ -15,7 +15,7 @@ import "./geometry-tool.sass"; const GeometryToolComponent: React.FC = ({ model, readOnly, ...others }) => { - const { documentContent, toolTile, onRegisterToolApi, onUnregisterToolApi } = others; + const { documentContent, toolTile, scale, onRegisterToolApi, onUnregisterToolApi } = others; const modelRef = useCurrent(model); const domElement = useRef(null); const content = model.content as GeometryContentModelType; @@ -63,7 +63,7 @@ const GeometryToolComponent: React.FC = ({ onMouseUpCapture={handlePointerUp} onKeyDown={e => hotKeys.current.dispatch(e)} > - diff --git a/src/components/tools/geometry-tool/geometry-toolbar.tsx b/src/components/tools/geometry-tool/geometry-toolbar.tsx index d4105b9e32..26bbf69ca5 100644 --- a/src/components/tools/geometry-tool/geometry-toolbar.tsx +++ b/src/components/tools/geometry-tool/geometry-toolbar.tsx @@ -3,7 +3,7 @@ import { observer } from "mobx-react"; import React from "react"; import ReactDOM from "react-dom"; import { GeometryContentModelType } from "../../../models/tools/geometry/geometry-content"; -import { isPoint } from "../../../models/tools/geometry/jxg-point"; +import { isPoint } from "../../../models/tools/geometry/jxg-types"; import { canSupportVertexAngle, getVertexAngle } from "../../../models/tools/geometry/jxg-vertex-angle"; import { IFloatingToolbarProps, useFloatingToolbarLocation } from "../hooks/use-floating-toolbar-location"; import { IToolbarActionHandlers } from "./geometry-shared"; diff --git a/src/components/tools/geometry-tool/use-tile-selection-pointer-events.ts b/src/components/tools/geometry-tool/use-tile-selection-pointer-events.ts index bce770ce50..6ccacda80f 100644 --- a/src/components/tools/geometry-tool/use-tile-selection-pointer-events.ts +++ b/src/components/tools/geometry-tool/use-tile-selection-pointer-events.ts @@ -8,6 +8,12 @@ export const useTileSelectionPointerEvents = ( const didLastMouseDownSelectTile = useRef(false); const handlePointerDown = useCallback((e: React.MouseEvent) => { + + // if the clicked element is focusable, let it handle the event + const target = e.target as HTMLElement; + const classList = target.classList; + if (classList?.contains("focusable")) return; + // clicked tile gets keyboard focus if (focusableElement.current) { // requires non-empty tabIndex diff --git a/src/components/tools/hooks/use-floating-toolbar-location.ts b/src/components/tools/hooks/use-floating-toolbar-location.ts index b64ae38d96..cd8cf62bbe 100644 --- a/src/components/tools/hooks/use-floating-toolbar-location.ts +++ b/src/components/tools/hooks/use-floating-toolbar-location.ts @@ -7,6 +7,7 @@ import { useForceUpdate } from "./use-force-update"; export interface IFloatingToolbarProps extends IRegisterToolApiProps { documentContent?: HTMLElement | null; toolTile?: HTMLElement | null; + scale?: number; onIsEnabled: () => boolean; } diff --git a/src/components/tools/hooks/use-measure-text.ts b/src/components/tools/hooks/use-measure-text.ts new file mode 100644 index 0000000000..94735fb8a3 --- /dev/null +++ b/src/components/tools/hooks/use-measure-text.ts @@ -0,0 +1,15 @@ +import { useCallback, useRef } from "react"; + +export const useMeasureText = (font: string) => { + const cache = useRef>({}); + const canvas = useRef(document.createElement("canvas")); + const context = canvas.current.getContext("2d"); + context && font && (context.font = font); + return useCallback((text: string) => { + const _context = canvas.current.getContext("2d"); + return cache.current[text] || + (_context + ? cache.current[text] = Math.ceil(10 * _context.measureText(text).width) / 10 + : 0); + }, []); +}; diff --git a/src/components/tools/hooks/use-toolbar-tool-api.ts b/src/components/tools/hooks/use-toolbar-tool-api.ts index 4fcc27e063..fcbe3d21fa 100644 --- a/src/components/tools/hooks/use-toolbar-tool-api.ts +++ b/src/components/tools/hooks/use-toolbar-tool-api.ts @@ -1,7 +1,7 @@ import { useEffect, useMemo, useRef } from "react"; import { useCurrent } from "../../../hooks/use-current"; import { useUIStore } from "../../../hooks/use-stores"; -import { IToolApi } from "../tool-tile"; +import { IToolApi } from "../tool-api"; export interface IUseToolbarToolApi { id: string; diff --git a/src/components/tools/image-tool.tsx b/src/components/tools/image-tool.tsx index e490ac6737..a717b3cd67 100644 --- a/src/components/tools/image-tool.tsx +++ b/src/components/tools/image-tool.tsx @@ -8,7 +8,8 @@ import { BaseComponent } from "../base"; import { EmptyImagePrompt } from "./image/empty-image-prompt"; import { ImageToolbar } from "./image/image-toolbar"; import { ImageComponent } from "./image-component"; -import { IToolApi, IToolTileProps } from "./tool-tile"; +import { IToolApi } from "./tool-api"; +import { IToolTileProps } from "./tool-tile"; import { IDocumentContext } from "../../models/document/document-types"; import { debouncedSelectTile } from "../../models/stores/ui"; import { gImageMap, IImageContext, ImageMapEntryType } from "../../models/image-map"; @@ -131,7 +132,7 @@ export default class ImageToolComponent extends BaseComponent { } public render() { - const { documentContent, toolTile, readOnly } = this.props; + const { documentContent, toolTile, readOnly, scale } = this.props; const { isLoading, imageEntry } = this.state; const showEmptyImagePrompt = !this.getContent().hasValidImage; @@ -157,6 +158,7 @@ export default class ImageToolComponent extends BaseComponent { onUnregisterToolApi={() => this.toolbarToolApi = undefined} documentContent={documentContent} toolTile={toolTile} + scale={scale} onIsEnabled={this.handleIsEnabled} onUploadImageFile={this.handleUploadImageFile} /> diff --git a/src/components/tools/table-tool/cell-formatter.tsx b/src/components/tools/table-tool/cell-formatter.tsx new file mode 100644 index 0000000000..aebed9a1d0 --- /dev/null +++ b/src/components/tools/table-tool/cell-formatter.tsx @@ -0,0 +1,14 @@ +import { TFormatterProps } from "./table-types"; +import { useNumberFormat } from "./use-number-format"; + +export const formatValue = (formatter: (n: number | { valueOf(): number }) => string, value: any) => { + if ((value == null) || (value === "")) return ""; + const num = Number(value); + if (!isFinite(num)) return value; + return formatter(num); +}; + +export const CellFormatter: React.FC = ({ column, row }) => { + const formatter = useNumberFormat(); + return formatValue(formatter, row[column.key]); +}; diff --git a/src/components/tools/table-tool/cell-text-editor.tsx b/src/components/tools/table-tool/cell-text-editor.tsx new file mode 100644 index 0000000000..637bc61075 --- /dev/null +++ b/src/components/tools/table-tool/cell-text-editor.tsx @@ -0,0 +1,36 @@ +import React, { useEffect } from "react"; +import { EditorProps } from "react-data-grid"; +import { TColumn } from "./table-types"; + +function autoFocusAndSelect(input: HTMLInputElement | null) { + input?.focus(); + input?.select(); +} + +// patterned after TextEditor from "react-data-grid" +export default function CellTextEditor({ + row, column, onRowChange, onClose +}: EditorProps) { + const _column: TColumn = column as unknown as TColumn; + + useEffect(() => { + _column.appData?.onBeginBodyCellEdit?.(); + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + const handleBlur = (e: React.FocusEvent) => { + onClose(true); + _column.appData?.onEndBodyCellEdit?.(e.target.value); + }; + + const raw = row[column.key as keyof TRow]; + const value = raw == null ? "" : raw; + return ( + onRowChange({ ...row, [column.key]: event.target.value })} + onBlur={handleBlur} + /> + ); +} diff --git a/src/components/tools/table-tool/column-header-cell.scss b/src/components/tools/table-tool/column-header-cell.scss new file mode 100644 index 0000000000..c1432e6af8 --- /dev/null +++ b/src/components/tools/table-tool/column-header-cell.scss @@ -0,0 +1,90 @@ +@import "../../vars.sass"; + +$column-header-padding: 10px; + +.column-header-cell { + position: relative; + width: 100%; + height: 100%; + + .flex-container { + display: flex; + flex-direction: column; + + .editable-header-cell { + width: 100%; + height: var(--row-height); + line-height: var(--row-height); // https://tutorialdeep.com/knowhow/align-text-vertically-center-css/ + + &.table-title-editing { + padding: 0 !important; + + .rdg-text-editor:focus { + border-color: $highlight-blue; + outline: 0 + } + + input { + text-align: center; + } + } + } + + .expression-cell { + width: 100%; + height: var(--row-height); + line-height: var(--row-height); // https://tutorialdeep.com/knowhow/align-text-vertically-center-css/ + font-style: italic; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + } + + .remove-column-button { + position: absolute; + left: -$column-header-padding; + top: 0; + width: 36px; + height: 34px; + display: none; // overridden when tile is selected + justify-content: center; + align-items: center; + svg { + fill: var(--header-background-color); + stroke: $highlight-blue; + } + &:hover { + svg { + fill: $highlight-blue-25; + stroke: $highlight-blue; + } + } + &:active { + svg { + fill: $highlight-blue; + stroke: var(--header-background-color); + } + } + } + + .expression-divider { + position: absolute; + left: -$column-header-padding; + right: -$column-header-padding; + top: var(--row-height); + height: 1px; + background-color: white; + } +} + +.tool-tile.selected { + .table-tool { + .selected-column { + .remove-column-button { + // show buttons only when tile and column are selected + display: flex !important; + } + } + } +} diff --git a/src/components/tools/table-tool/column-header-cell.tsx b/src/components/tools/table-tool/column-header-cell.tsx new file mode 100644 index 0000000000..701e83d30d --- /dev/null +++ b/src/components/tools/table-tool/column-header-cell.tsx @@ -0,0 +1,67 @@ +import classNames from "classnames"; +import React from "react"; +import { EditableHeaderCell } from "./editable-header-cell"; +import { THeaderRendererProps, TColumn } from "./table-types"; +import { useCautionAlert } from "../../utilities/use-caution-alert"; +import RemoveColumnSvg from "../../../assets/icons/remove/remove.nosvgo.svg"; + +import "./column-header-cell.scss"; + +interface IProps extends THeaderRendererProps { +} +export const ColumnHeaderCell: React.FC = (props: IProps) => { + const column = props.column as unknown as TColumn; + const { readOnly, isEditing, isRemovable, showExpressions, expression, onRemoveColumn } = column.appData || {}; + const hasExpression = showExpressions && !!expression; + const classes = classNames("column-header-cell", { "show-expression": showExpressions }); + return ( +
+
+ + {showExpressions && } +
+ {!isEditing && isRemovable && + } + {hasExpression &&
} +
+ ); +}; + +interface IRemoveColumnButtonProps { + colId: string; + colName: string; + onRemoveColumn?: (colId: string) => void; +} +const RemoveColumnButton: React.FC = ({ colId, colName, onRemoveColumn }) => { + const AlertContent = () => { + return

Remove column {colName as string} and its contents from the table?

; + }; + const [showAlert] = useCautionAlert({ + title: "Remove Column", + content: AlertContent, + confirmLabel: "Remove Column", + onConfirm: () => onRemoveColumn?.(colId) + }); + return ( +
+ +
+ ); +}; +RemoveColumnButton.displayName = "RemoveColumnButton"; + +interface IExpressionCellProps { + readOnly?: boolean; + column: TColumn; +} +export const ExpressionCell: React.FC = ({ readOnly, column }) => { + const { expression, onShowExpressionsDialog } = column?.appData || {}; + const expressionStr = expression ? `= ${expression}` : ""; + const classes = classNames("expression-cell", { "has-expression": !!expression }); + const handleClick = () => !readOnly && expression && onShowExpressionsDialog?.(column.key); + return ( +
+ {expressionStr} +
+ ); +}; diff --git a/src/components/tools/table-tool/data-table.css b/src/components/tools/table-tool/data-table.css index 43c49eafc1..e7af459ccb 100644 --- a/src/components/tools/table-tool/data-table.css +++ b/src/components/tools/table-tool/data-table.css @@ -1,4 +1,4 @@ -.neo-codap-case-table { +/* .neo-codap-case-table { width: 100%; height: 100%; box-sizing: border-box; @@ -22,7 +22,7 @@ } .ag-theme-fresh .cdp-case-index-cell, -.ag-theme-fresh .cdp-case-index-cell.ag-cell-data-changed { /* .cdp-case-index-cell.ag-cell-data-changed is to prevent flashing during sort */ +.ag-theme-fresh .cdp-case-index-cell.ag-cell-data-changed { /* .cdp-case-index-cell.ag-cell-data-changed is to prevent flashing during sort background-color: #EEE !important; } @@ -45,4 +45,4 @@ .cdp-row-data-cell.has-expression { background-color: #DDD; -} +} */ diff --git a/src/components/tools/table-tool/data-table.tsx b/src/components/tools/table-tool/data-table.tsx index 5ef22b255b..d548a78dac 100644 --- a/src/components/tools/table-tool/data-table.tsx +++ b/src/components/tools/table-tool/data-table.tsx @@ -1,928 +1,929 @@ -import React from "react"; -import { onSnapshot, getSnapshot, types } from "mobx-state-tree"; -import { ISerializedActionCall } from "mobx-state-tree/dist/middlewares/on-action"; -import { IMenuItemFlags, IProps as ITableHeaderMenuProps, TableHeaderMenu } from "./table-header-menu"; -import { - addAttributeToDataSet, addCanonicalCasesToDataSet, - ICase, ICaseCreation, IDataSet -} from "../../../models/data/data-set"; -import { IAttribute } from "../../../models/data/attribute"; -import { emitTableEvent } from "../../../models/tools/table/table-events"; -import { AgGridReact } from "@ag-grid-community/react"; -import { ClientSideRowModelModule } from "@ag-grid-community/client-side-row-model"; -import { - CellEditingStartedEvent, CellEditingStoppedEvent, CellPosition, ColDef, ColGroupDef, - Column, ColumnApi, GridApi, GridReadyEvent, ICellEditorComp, SelectionChangedEvent, RowNode, - SortChangedEvent, TabToNextCellParams, ValueGetterParams, ValueFormatterParams, ValueSetterParams -} from "@ag-grid-community/core"; -import { RowDataTransaction } from "@ag-grid-community/core/dist/es6/interfaces/rowDataTransaction"; -import { assign, cloneDeep, findIndex, isEqual, sortedIndexBy } from "lodash"; -import "@ag-grid-community/core/dist/styles/ag-grid.css"; -import "@ag-grid-community/core/dist/styles/ag-theme-fresh.css"; - -import "./data-table.css"; - -type ColDefArray = Array; - -export const TableComponentSortModelData = types.model("TableComponentSortModelData", { - colId: types.string, - sort: types.string -}); -export type ITableSortModelData = typeof TableComponentSortModelData.Type; - -export const TableComponentData = types.model("TableComponentData", - { - sortModel: types.array(TableComponentSortModelData) - }) - .actions(self => ({ - setSortModel(sortModel: any) { - self.sortModel = sortModel; - } - })); -export type ITableComponentData = typeof TableComponentData.Type; - -interface IPos { - left: number; - top: number; -} - -interface IProps { - expressions?: Map; - rawExpressions?: Map; - dataSet?: IDataSet; - changeCount: number; - readOnly?: boolean; - indexValueGetter?: (params: ValueGetterParams) => string; - attrValueFormatter?: (params: ValueFormatterParams) => string; - cellEditorComponent?: new () => ICellEditorComp; - cellEditorParams?: any; - autoSizeColumns?: boolean; - defaultPrecision?: number; - itemFlags?: IMenuItemFlags; - tableComponentData?: ITableComponentData | null; - onGridReady?: (gridReadyParams: GridReadyEvent) => void; - onRowSelectionChange?: (e: SelectionChangedEvent) => void; - onSetTableName?: (name: string) => void; - onSetAttributeName?: (colId: string, name: string) => void; - onSetExpression?: (colId: string, expression: string, rawExpression: string) => void; - onAddCanonicalCases?: (cases: ICaseCreation[], beforeID?: string | string[]) => void; - onSetCanonicalCaseValues?: (aCase: ICase) => void; - onRemoveCases?: (ids: string[]) => void; - onGetLinkedGeometries?: () => string[]; - onUnlinkGeometry?: () => void; - onSampleData?: (name: string) => void; -} - -interface IState { - rowSelection: string; - addAttributeButtonPos: IPos | null; -} - -export const LOCAL_ROW_ID = "__local__"; -// const LOCAL_ROW_STYLE = { backgroundColor: "#cfc" }; - -interface IRowStyleParams { - data: { - id: string; - }; -} - -interface IGridRow { - id: string; -} - -interface IGridCellDef { - rowIndex?: number; - column?: Column; - floating?: string; -} - -interface ICellIDs { - colID?: string; - rowID?: string; - floating?: string; -} - -// default widths for sample data sets -const kRowIndexColumnWidth = 50; -const kDefaultColumnMinWidth = 65; -const kDefaultColumnWidth = 80; -const kTableNameMargins = 30; - -export default class DataTableComponent extends React.Component { - - private gridApi?: GridApi | null; - private gridColumnApi?: ColumnApi | null; - - private gridColumnDefs: ColDefArray = []; - private gridRowData: IGridRow[] = []; - private components = this.props.cellEditorComponent - ? { clientCellEditor: this.props.cellEditorComponent } - : undefined; - private localRow: ICaseCreation = {}; - private checkForEnterAfterCellEditingStopped = false; - private localRowChangeTimer?: any; - - private prevEditCell?: CellPosition; - private editCellEvent?: CellEditingStartedEvent; - private savedFocusedCell?: ICellIDs; - private savedEditCell?: ICellIDs; - private savedEditContent?: string; - private isProcessingEnterKey?: boolean; - - private gridElement: HTMLDivElement | null; - private headerElement: HTMLDivElement | null; - private headerRulerElement: HTMLDivElement | null; - - private sortedRowNodes: RowNode[]; - - // we don't need to refresh for changes the table already knows about - private localChanges: ICaseCreation[] = []; - - constructor(props: IProps) { - super(props); - - const { dataSet } = this.props; - this.attachDataSet(dataSet); - - this.state = { - rowSelection: "multiple", - addAttributeButtonPos: null - }; - - this.gridElement = null; - this.headerElement = null; - - this.updateGridState(dataSet); - - this.sortedRowNodes = []; - } - - public onGridReady = (gridReadyParams: GridReadyEvent) => { - this.gridApi = gridReadyParams.api; - this.gridColumnApi = gridReadyParams.columnApi; - - if (this.props.autoSizeColumns) { - this.gridColumnApi?.autoSizeAllColumns(); - } - - const { tableComponentData: caseTableComponentData } = this.props; - if (caseTableComponentData && this.gridApi) { - this.gridApi.setSortModel(getSnapshot(caseTableComponentData.sortModel)); - - onSnapshot(caseTableComponentData, (snapshot: ITableComponentData) => { - if (this.gridApi) { - this.gridApi.setSortModel(snapshot.sortModel); - } - }); - } - - if (this.props.onGridReady) { - this.props.onGridReady(gridReadyParams); - } - } - - public getRowNodeId = (data: { id: string }) => data.id; - - public getRowIndexColumnDef(): ColDef { - const { itemFlags, readOnly } = this.props; - - function defaultIndexValueGetter(params: ValueGetterParams) { - // default just returns a row/case index - return params.node.rowIndex + 1; - } - - return ({ - headerName: "", - headerComponentFramework: TableHeaderMenu, - headerComponentParams: { - api: this.gridApi, - expressions: this.props.expressions, - rawExpressions: this.props.rawExpressions, - dataSet: this.props.dataSet, - readOnly, - itemFlags, - onSetTableName: (name: string) => { - if (this.props.onSetTableName) { - this.props.onSetTableName(name); - } - else { - this.props.dataSet?.setName(name); - } - }, - onNewAttribute: (name: string) => { - const { dataSet } = this.props; - dataSet && addAttributeToDataSet(dataSet, { name }); - }, - onRenameAttribute: (id: string, name: string) => { - if (this.props.onSetAttributeName) { - this.props.onSetAttributeName(id, name); - } - else { - const { dataSet } = this.props; - dataSet && dataSet.setAttributeName(id, name); - } - setTimeout(() => this.gridColumnApi?.autoSizeAllColumns(), 10); - }, - onUpdateExpression: (id: string, expression: string, rawExpression: string) => { - if (this.props.onSetExpression) { - this.props.onSetExpression(id, expression, rawExpression); - } - }, - onNewCase: () => { - const newCases = [{}]; - if (this.props.onAddCanonicalCases) { - this.props.onAddCanonicalCases(newCases); - } - else { - const { dataSet } = this.props; - dataSet && addCanonicalCasesToDataSet(dataSet, newCases); - } - }, - onRemoveAttribute: (id: string) => { - const { dataSet } = this.props; - dataSet && dataSet.removeAttribute(id); - }, - onRemoveCases: (ids: string[]) => { - if (this.props.onRemoveCases) { - this.props.onRemoveCases(ids); - } - else { - const { dataSet } = this.props; - dataSet && dataSet.removeCases(ids); - } - }, - onGetLinkedGeometries: () => { - return this.props.onGetLinkedGeometries && this.props.onGetLinkedGeometries(); - }, - onUnlinkGeometry: () => { - this.props.onUnlinkGeometry && this.props.onUnlinkGeometry(); - } - } as ITableHeaderMenuProps, - headerClass: "cdp-column-header cdp-case-index-header", - cellClass: "cdp-case-index-cell", - colId: "__CASE_INDEX__", - width: kRowIndexColumnWidth, - // Note that pinned columns can't be grouped with unpinned columns. - // Given that we're using grouped columns to present the table title, we can - // either pin the index column and have the title cover the remaining columns, - // or not pin the index column and have the title cover all the columns. - // Since we currently only support two columns and horizontal scrolling is - // rare, we don't pin the column for now, but this can be revisited. - // pinned: "left", - lockPosition: true, - valueGetter: this.props.indexValueGetter || defaultIndexValueGetter, - suppressMovable: true, - resizable: false, - suppressNavigable: true - }); - } - - public addLocalCaseToTable() { - const { dataSet } = this.props; - if (!dataSet) return; - - // clear local case before adding so that the update caused by addCanonicalCasesToDataSet() - // shows an empty row for the local case - const newCases: ICaseCreation[] = [cloneDeep(this.localRow)]; - this.localRow = {}; - if (this.props.onAddCanonicalCases) { - this.props.onAddCanonicalCases(newCases); - } - else { - addCanonicalCasesToDataSet(dataSet, newCases); - } - this.updateGridState(this.props.dataSet); - } - - public getAttributeColumnDef(attribute: IAttribute): ColDef { - const { readOnly, expressions } = this.props; - const expression = expressions && expressions.get(attribute.id); - const editable = !readOnly && !expression; - - const defaultAttrValueFormatter = (params: ValueFormatterParams) => { - const colName = params.colDef.field || params.colDef.headerName || ""; - const colPlaces: { [key: string]: number } = { - day: 0, - distance: 1, - speed: 2 - }; - let places = colPlaces[colName]; - if ((places == null) && (this.props.defaultPrecision != null)) { - places = this.props.defaultPrecision; - } - return (places != null) && (typeof params.value === "number") - ? params.value.toFixed(places) - : params.value; - }; - - return ({ - headerClass: "cdp-column-header cdp-attr-column-header", - cellClass: `cdp-row-data-cell ${expression ? "has-expression" : ""}`, - headerName: attribute.name, - field: attribute.name, - tooltipField: attribute.name, - colId: attribute.id, - editable, - width: kDefaultColumnWidth, - resizable: true, - lockPosition: true, - valueGetter: (params: ValueGetterParams) => { - const { dataSet } = this.props; - const caseID = params.node.id; - const attrID = params.colDef.colId; - if (params.data.id === LOCAL_ROW_ID) { - return attrID ? this.localRow[attrID] : undefined; - } - let value = dataSet && attrID ? dataSet.getValue(caseID, attrID) : undefined; - if (Number.isNaN(value as any)) { - value = "#ERR"; - } - // The purpose of the code below was to get recently changed cells in case - // they've been updated but not yet received from Firebase. It was removed as - // it overwrites updates from expressions and it is not clear that it remains necessary. - // However, if changes are failing to appear across tables, it would be worth reconsidering this logic. - // this.localChanges.forEach((change) => { - // if ((change.__id__ === caseID) && (attrID != null)) { - // if (change[attrID] != null) { - // value = change[attrID] as IValueType; - // } - // } - // }); - return value; - }, - valueFormatter: this.props.attrValueFormatter || defaultAttrValueFormatter, - valueSetter: (params: ValueSetterParams) => { - const { dataSet } = this.props; - if (!dataSet || (params.newValue === params.oldValue)) { return false; } - if (params.data.id === LOCAL_ROW_ID) { - if (params.colDef.colId) { - this.localRow[params.colDef.colId] = params.newValue; - } - return !!params.colDef.colId; - } - const str = (params.newValue != null) && (typeof params.newValue === "string") - ? params.newValue.trim() : undefined; - const num = str ? Number(str) : undefined; - const attrID = attribute.id; - const caseID = dataSet && dataSet.cases[params.node.rowIndex].__id__; - const caseValues = { - __id__: caseID, - [attrID]: (num != null) && isFinite(num) ? num : str - }; - if (caseValues[attrID] === params.oldValue) { return false; } - // track in-flight changes - this.localChanges.push(cloneDeep(caseValues)); - if (this.props.onSetCanonicalCaseValues) { - this.props.onSetCanonicalCaseValues(caseValues); - } - else { - dataSet.setCanonicalCaseValues([caseValues]); - } - return true; - }, - comparator(valueA: any, valueB: any, nodeA: RowNode, nodeB: RowNode, descending: boolean) { - const floatA = parseFloat(valueA); - const floatB = parseFloat(valueB); - if (isNaN(floatA) || isNaN(floatB)) { - if (valueA < valueB) { return -1; } - if (valueA > valueB) { return 1; } - return 0; - } - return floatA - floatB; - }, - cellEditor: this.props.cellEditorComponent ? "clientCellEditor" : undefined, - cellEditorParams: this.props.cellEditorParams, - }); - } - - public getColumnDefs(dataSet: IDataSet): ColDefArray { - - let minColumnWidth = 0; - if (dataSet.name) { - // adjust the minimum column width to accommodate the table header - const tableNameWidth = this.measureHeaderLabelWidth(dataSet.name); - if (tableNameWidth) { - const tableHeaderWidth = tableNameWidth + kTableNameMargins; - minColumnWidth = Math.max(kDefaultColumnMinWidth, - Math.ceil((tableHeaderWidth - kRowIndexColumnWidth) / 2)); - } - } - - const cols = dataSet.attributes.map(attr => { - const colDef = this.getAttributeColumnDef(attr); - minColumnWidth && (colDef.minWidth = minColumnWidth); - return colDef; - }); - cols.unshift(this.getRowIndexColumnDef()); - - // if the table has a name/title, group the columns under it - return dataSet.name - ? [{ headerName: dataSet.name, children: cols }] - : cols; - } - - public getRowData(dataSet?: IDataSet): IGridRow[] { - const rows = []; - if (dataSet) { - for (const aCase of dataSet.cases) { - // just need the ID; everything else comes from valueGetter - rows.push({ id: aCase.__id__ }); - } - } - if (!this.props.readOnly) { - rows.push({ id: LOCAL_ROW_ID }); - } - return rows; - } - - public updateGridState(dataSet?: IDataSet) { - this.updateGridColState(dataSet); - this.updateGridRowState(dataSet); - } - - public updateGridColState(dataSet?: IDataSet) { - this.gridColumnDefs = dataSet ? this.getColumnDefs(dataSet) : []; - if (this.gridApi) { - // recent versions of ag-grid require manual column header synchronization - // cf. https://github.com/ag-grid/ag-grid/issues/2771#issuecomment-441576761 - // cf. https://github.com/ag-grid/ag-grid/issues/2771#issuecomment-509981799 - this.gridApi.setColumnDefs([]); - this.gridApi.setColumnDefs(this.gridColumnDefs); - } - } - - public updateGridRowState(dataSet?: IDataSet) { - this.gridRowData = this.getRowData(dataSet); - if (this.gridApi) { - this.gridApi.setRowData(this.gridRowData); - setTimeout(() => this.ensureFocus(dataSet)); - } - } - - public ensureFocus = (dataSet?: IDataSet) => { - if (!this.gridApi) return; - const currentCell = this.gridApi.getFocusedCell(); - const lastRowIndex = this.gridApi.paginationGetRowCount() - 1; - if (!currentCell && (lastRowIndex >= 0) && dataSet && (dataSet.attributes.length > 0)) { - const firstColId = dataSet.attributes[0].id; - this.gridApi.setFocusedCell(lastRowIndex, firstColId); - } - } - - public startEditingCell = (rowIndex: number, colKey: string) => { - if (this.gridApi && (rowIndex != null) && colKey) { - this.gridApi.setFocusedCell(rowIndex, colKey); - this.gridApi.startEditingCell({ rowIndex, colKey }); - } - } - - public startEditingSameColumnOfNextRow = (backwards: boolean) => { - if (this.gridApi && this.prevEditCell) { - const rowIndex = this.prevEditCell.rowIndex + (backwards ? -1 : 1); - const colKey = this.prevEditCell.column.getColId(); - if ((rowIndex >= 0) && colKey) { - this.startEditingCell(rowIndex, colKey); - } - } - } - - public startEditingFirstColumnOfNextRow = () => { - if (this.gridApi && this.gridColumnApi && this.prevEditCell) { - const rowIndex = this.prevEditCell.rowIndex + 1; - const columns = this.gridColumnApi.getAllDisplayedColumns(); - const colKey = columns[1].getColId(); - this.startEditingCell(rowIndex, colKey); - } - } - - public getRowStyle(params: IRowStyleParams) { - // if (params.data.id === LOCAL_ROW_ID) { - // return LOCAL_ROW_STYLE; - // } - return undefined; - } - - public isIgnorableChange(action: ISerializedActionCall) { - switch (action.name) { - case "setCaseValues": - case "setCanonicalCaseValues": { - const cases = action.args && action.args[0]; - if (!cases) { return true; } - let ignoredChanges = 0; - cases.forEach((aCase: ICaseCreation) => { - const index = findIndex(this.localChanges, (change) => isEqual(assign({}, aCase, change), aCase)); - if (index >= 0) { - // ignoring local change - this.localChanges.splice(index, 1); - ++ignoredChanges; - } - }); - return ignoredChanges >= cases.length; - } - case "addActionListener": - case "removeActionListener": - return true; - default: - return false; - } - } - - public getCellIDsFromGridCell(cell: IGridCellDef): ICellIDs | undefined { - if (!cell) { return; } - const { rowIndex, column, floating } = cell; - const attrID = column && column.getColId(); - const aCase = rowIndex != null ? this.gridRowData[rowIndex] : undefined; - const caseID = aCase && aCase.id; - return attrID && caseID ? { colID: attrID, rowID: caseID, floating } : undefined; - } - - public getGridCellFromCellIDs(cellIDs: ICellIDs): IGridCellDef | undefined { - if (!this.gridApi || !this.gridColumnApi || !cellIDs || !cellIDs.rowID) return; - const rowNode = this.gridApi.getRowNode(cellIDs.rowID); - return rowNode && { - rowIndex: rowNode.rowIndex, - column: this.gridColumnApi.getColumn(cellIDs.colID) - }; - } - - public saveCellEditState() { - if (!this.gridApi) return; - const focusedCell = this.gridApi.getFocusedCell(); - const rowIndex = this.editCellEvent && this.editCellEvent.rowIndex; - const column = this.editCellEvent && this.editCellEvent.column; - this.savedFocusedCell = this.getCellIDsFromGridCell(focusedCell); - this.savedEditCell = this.getCellIDsFromGridCell({ rowIndex, column }); - if (this.editCellEvent) { - const cellInputElts = document.getElementsByClassName("ag-cell-edit-input"); - const cellInputElt: HTMLInputElement = cellInputElts && (cellInputElts[0] as HTMLInputElement); - this.savedEditContent = cellInputElt ? cellInputElt.value : undefined; - } - this.gridApi.stopEditing(true); - this.gridApi.clearFocusedCell(); - } - - public restoreCellEditState() { - if (!this.gridApi) return; - if (this.savedFocusedCell) { - const focusedGridCell = this.getGridCellFromCellIDs(this.savedFocusedCell); - if (focusedGridCell) { - const { rowIndex, column, floating } = focusedGridCell; - if ((rowIndex != null) && column) { - this.gridApi.setFocusedCell(rowIndex, column, floating); - } - } - this.savedFocusedCell = undefined; - } - if (this.savedEditCell) { - const editRowColumn = this.getGridCellFromCellIDs(this.savedEditCell); - if (editRowColumn) { - const { rowIndex, column } = editRowColumn; - if ((rowIndex != null) && column) { - this.gridApi.startEditingCell({ rowIndex, colKey: column }); - } - } - this.savedEditCell = undefined; - } - if (this.savedEditContent != null) { - const cellInputElts = document.getElementsByClassName("ag-cell-edit-input"); - const cellInputElt: HTMLInputElement = cellInputElts && (cellInputElts[0] as HTMLInputElement); - if (cellInputElt) { - cellInputElt.value = this.savedEditContent; - } - this.savedEditContent = undefined; - } - } - - public handleAction = (action: ISerializedActionCall) => { - const { dataSet } = this.props; - if (!this.isIgnorableChange(action)) { - let columnDefs = null; - let rowTransaction: RowDataTransaction | null = null; - let shouldSaveEditState = true; - const attributeChanged = () => { - if (dataSet) { - columnDefs = this.getColumnDefs(dataSet); - setTimeout(() => this.handleSetAddAttributePos(), 1); - } - }; - switch (action.name) { - case "@APPLY_SNAPSHOT": - if (/^\/attributes\//.test(action.path || "")) { - attributeChanged(); - } - break; - case "addAttributeWithID": - case "removeAttribute": - case "setAttributeName": - attributeChanged(); - break; - case "addCasesWithIDs": - case "addCanonicalCasesWithIDs": - case "setCaseValues": - case "setCanonicalCaseValues": - if (action.args && action.args.length) { - const cases = action.args[0].map((aCase: ICase) => ({ id: aCase.__id__ })); - if (action.name.substr(0, 3) === "add") { - interface IRowData { id: string; } - const addIndex = sortedIndexBy(this.gridRowData, cases[0], (value: IRowData) => value.id); - rowTransaction = { add: cases, addIndex: Math.min(addIndex, this.gridRowData.length - 1) }; - } - else { - rowTransaction = { update: cases }; - // don't need to save/restore cell edit if only changing existing values - shouldSaveEditState = false; - } - } - break; - case "removeCases": - if (action.args && action.args.length) { - const casesToRemove = action.args[0].map((id: string) => ({ id })); - rowTransaction = { remove: casesToRemove }; - } - break; - default: - } - if (shouldSaveEditState) { - this.saveCellEditState(); - } - if (columnDefs && this.gridApi) { - this.gridApi.setColumnDefs(columnDefs); - } - if (rowTransaction && this.gridApi) { - this.gridApi.updateRowData(rowTransaction); - this.gridRowData = this.getRowData(dataSet); - } - if (shouldSaveEditState) { - this.restoreCellEditState(); - } - } - } - - public attachDataSet(dataSet?: IDataSet) { - if (dataSet) { - dataSet.addActionListener("case-table", this.handleAction); - } - } - - public detachDataSet(dataSet?: IDataSet) { - if (dataSet) { - dataSet.removeActionListener("case-table"); - } - } - - public handleRowSelectionChanged = (e: SelectionChangedEvent) => { - e.api.refreshHeader(); - this.props.onRowSelectionChange && this.props.onRowSelectionChange(e); - } - - public handleCellEditingStarted = (event: CellEditingStartedEvent) => { - this.prevEditCell = this.gridApi && this.gridApi.getEditingCells()[0] || undefined; - this.editCellEvent = event; - - if (this.localRowChangeTimer) { - // The user stopped editing a cell in the local/input row, but started - // editing another cell before the timer expired. We cancel the timer - // and then decide whether to create a new case depending on whether - // the new cell being edited is in the local/input row or not. - clearTimeout(this.localRowChangeTimer); - this.localRowChangeTimer = undefined; - - if (event.node.id !== LOCAL_ROW_ID) { - // If the new cell being edited is not in the local/input row, then - // we should add the new case, but also save/restore the edit state - // for the cell now being edited. - this.saveCellEditState(); - this.addLocalCaseToTable(); - setTimeout(() => { - this.restoreCellEditState(); - }); - } - } - } - - public hasCellEditValueChanged(startEvent: CellEditingStartedEvent | undefined, stopEvent: CellEditingStoppedEvent) { - const orgValue = startEvent && startEvent.value || ""; - const newValue = stopEvent && stopEvent.value || ""; - // eslint-disable-next-line eqeqeq - return newValue != orgValue; - } - - public handleCellEditingStopped = (event: CellEditingStoppedEvent) => { - this.checkForEnterAfterCellEditingStopped = true; - - // When the user stops editing a cell in the local/input row, we want to add - // the new case to the dataset, as long as the user has actually edited the - // value or explicitly requested the new row (by pressing the enter key). - if (event.node.id === LOCAL_ROW_ID) { - if (this.isProcessingEnterKey || this.hasCellEditValueChanged(this.editCellEvent, event)) { - // We set a timeout so that this can be canceled. If the user immediately starts - // editing another cell in the local/input row, then we do _not_ want to add the - // new case to the dataset until the user stops editing the row entirely. - // We assume that 10 ms is sufficient to allow the next cell edit to begin, - // if there is one starting up immediately, e.g. when tabbing to the next cell. - this.localRowChangeTimer = setTimeout(() => { - this.localRowChangeTimer = undefined; - this.addLocalCaseToTable(); - }, 10); - } - } - this.editCellEvent = undefined; - this.checkForEnterAfterCellEditingStopped = true; - } - - public handleTabToNextCell = (params: TabToNextCellParams) => { - this.prevEditCell = params.previousCellPosition; - if (params.editing && !params.backwards && !params.nextCellPosition) { - setTimeout(() => { - this.startEditingFirstColumnOfNextRow(); - }, 100); - } - return params.nextCellPosition; - } - - public handleKeyDownCapture = (e: KeyboardEvent) => { - // Track whether or not we are processing an enter key event, because - // we use that information to decide when/whether to create a new case. - // We use a browser event handler because the corresponding React event - // handler didn't work as expected. - if ((e.keyCode === 13) && !e.shiftKey) { - this.isProcessingEnterKey = true; - } - } - - public handleKeyUp = (e: React.KeyboardEvent) => { - const startEditingNextRow = this.startEditingSameColumnOfNextRow.bind(this, e.shiftKey); - - if (e.keyCode === 13) { - if (this.checkForEnterAfterCellEditingStopped) { - setTimeout(startEditingNextRow, 100); - } - this.isProcessingEnterKey = false; - } - - this.checkForEnterAfterCellEditingStopped = false; - } - - public handlePostSort = (rowNodes: RowNode[]) => { - // move the entry row to the bottom - const localRow = rowNodes.find((rowNode) => rowNode.data.id === LOCAL_ROW_ID); - if (localRow) { - rowNodes.splice(rowNodes.indexOf(localRow), 1); - rowNodes.push(localRow); - } - - // keep reference so we can keep index in ascending order - this.sortedRowNodes = rowNodes; - if (this.gridApi) { - // force update of the case index - this.gridApi.refreshCells({ - columns: ["__CASE_INDEX__"], - force: true - }); - } - } - - public handleSortChanged = (event: SortChangedEvent) => { - const { tableComponentData: caseTableComponentData } = this.props; - if (caseTableComponentData) { - const currentSortModel = getSnapshot(caseTableComponentData.sortModel); - const newSortModel = event.api && event.api.getSortModel(); - if (!isEqual(currentSortModel, newSortModel)) { - caseTableComponentData.setSortModel(newSortModel); - } - } - } - - public componentDidMount() { - if (this.gridElement) { - this.gridElement.addEventListener("keydown", this.handleKeyDownCapture, true); - } - } - - public componentWillUnmount() { - if (this.gridElement) { - this.gridElement.removeEventListener("keydown", this.handleKeyDownCapture, true); - } - } - - public UNSAFE_componentWillReceiveProps(nextProps: IProps) { - const { changeCount, dataSet } = nextProps; - if (dataSet !== this.props.dataSet) { - this.detachDataSet(this.props.dataSet); - this.attachDataSet(dataSet); - this.updateGridState(dataSet); - } - else if (changeCount !== this.props.changeCount) { - this.updateGridState(dataSet); - } - } - - public handleSetAddAttributePos = () => { - if (this.gridElement) { - const classes = this.gridElement.getElementsByClassName("ag-header-row"); - this.headerElement = classes.item(classes.length - 1) as HTMLDivElement; - if (this.headerElement) { - const gridRect = this.gridElement.getBoundingClientRect(); - const headerRect = this.headerElement.getBoundingClientRect(); - const left = headerRect.right - gridRect.left; - const top = headerRect.top - gridRect.top; - const { addAttributeButtonPos } = this.state; - if (!addAttributeButtonPos || (addAttributeButtonPos.top !== top) || (addAttributeButtonPos.left !== left)) { - this.setState({ addAttributeButtonPos: { top, left } }); - } - } - } - } - - public componentWillReact() { - this.updateGridState(this.props.dataSet); - } - - public handleAddAttributeButton = () => { - emitTableEvent({ type: "add-column" }); - } - - public renderAddAttributeButtonPos() { - const { addAttributeButtonPos } = this.state; - if (addAttributeButtonPos !== null) { - const { top, left } = addAttributeButtonPos; - return ( - - + - - ); - } - return null; - } - - public render() { - return ( -
this.gridElement = el} - draggable={true} - onDragStart={this.handleDragStart} - onKeyUp={this.handleKeyUp}> - - {/* hidden ruler div for measuring header text width */} -
this.headerRulerElement = el} - style={{ display: "inline", visibility: "hidden" }} /> -
- ); - } - - private measureHeaderLabelWidth(label: string) { - if (this.headerRulerElement) { - this.headerRulerElement.innerText = label; - const width = Math.ceil(this.headerRulerElement.offsetWidth); - this.headerRulerElement.innerText = ""; - return width; - } - } - - private handleDragStart = (evt: React.DragEvent) => { - // ag-grid adds "ag-column-resizing" class to columns being actively resized - if (this.gridElement?.getElementsByClassName("ag-column-resizing").length) { - // if we're column resizing, prevent other drags above (e.g. tile drags) - evt.preventDefault(); - evt.stopPropagation(); - } - } -} +// import React from "react"; +// import { onSnapshot, getSnapshot, types } from "mobx-state-tree"; +// import { ISerializedActionCall } from "mobx-state-tree/dist/middlewares/on-action"; +// import { IMenuItemFlags, IProps as ITableHeaderMenuProps, TableHeaderMenu } from "./table-header-menu"; +// import { +// addAttributeToDataSet, addCanonicalCasesToDataSet, +// ICase, ICaseCreation, IDataSet +// } from "../../../models/data/data-set"; +// import { IAttribute } from "../../../models/data/attribute"; +// import { emitTableEvent } from "../../../models/tools/table/table-events"; +// import { AgGridReact } from "@ag-grid-community/react"; +// import { ClientSideRowModelModule } from "@ag-grid-community/client-side-row-model"; +// import { +// CellEditingStartedEvent, CellEditingStoppedEvent, CellPosition, ColDef, ColGroupDef, +// Column, ColumnApi, GridApi, GridReadyEvent, ICellEditorComp, SelectionChangedEvent, RowNode, +// SortChangedEvent, TabToNextCellParams, ValueGetterParams, ValueFormatterParams, ValueSetterParams +// } from "@ag-grid-community/core"; +// import { RowDataTransaction } from "@ag-grid-community/core/dist/es6/interfaces/rowDataTransaction"; +// import { assign, cloneDeep, findIndex, isEqual, sortedIndexBy } from "lodash"; +// import "@ag-grid-community/core/dist/styles/ag-grid.css"; +// import "@ag-grid-community/core/dist/styles/ag-theme-fresh.css"; + +// import "./data-table.css"; + +// type ColDefArray = Array; + +// export const TableComponentSortModelData = types.model("TableComponentSortModelData", { +// colId: types.string, +// sort: types.string +// }); +// export type ITableSortModelData = typeof TableComponentSortModelData.Type; + +// export const TableComponentData = types.model("TableComponentData", +// { +// sortModel: types.array(TableComponentSortModelData) +// }) +// .actions(self => ({ +// setSortModel(sortModel: any) { +// self.sortModel = sortModel; +// } +// })); +// export type ITableComponentData = typeof TableComponentData.Type; + +// interface IPos { +// left: number; +// top: number; +// } + +// interface IProps { +// expressions?: Map; +// rawExpressions?: Map; +// dataSet?: IDataSet; +// changeCount: number; +// readOnly?: boolean; +// indexValueGetter?: (params: ValueGetterParams) => string; +// attrValueFormatter?: (params: ValueFormatterParams) => string; +// cellEditorComponent?: new () => ICellEditorComp; +// cellEditorParams?: any; +// autoSizeColumns?: boolean; +// defaultPrecision?: number; +// itemFlags?: IMenuItemFlags; +// tableComponentData?: ITableComponentData | null; +// onGridReady?: (gridReadyParams: GridReadyEvent) => void; +// onRowSelectionChange?: (e: SelectionChangedEvent) => void; +// onSetTableName?: (name: string) => void; +// onSetAttributeName?: (colId: string, name: string) => void; +// onSetExpression?: (colId: string, expression: string, rawExpression: string) => void; +// onAddCanonicalCases?: (cases: ICaseCreation[], beforeID?: string | string[]) => void; +// onSetCanonicalCaseValues?: (aCase: ICase) => void; +// onRemoveCases?: (ids: string[]) => void; +// onGetLinkedGeometries?: () => string[]; +// onUnlinkGeometry?: () => void; +// onSampleData?: (name: string) => void; +// } + +// interface IState { +// rowSelection: string; +// addAttributeButtonPos: IPos | null; +// } + +// export const LOCAL_ROW_ID = "__local__"; +// // const LOCAL_ROW_STYLE = { backgroundColor: "#cfc" }; + +// interface IRowStyleParams { +// data: { +// id: string; +// }; +// } + +// interface IGridRow { +// id: string; +// } + +// interface IGridCellDef { +// rowIndex?: number; +// column?: Column; +// floating?: string; +// } + +// interface ICellIDs { +// colID?: string; +// rowID?: string; +// floating?: string; +// } + +// // default widths for sample data sets +// const kRowIndexColumnWidth = 50; +// const kDefaultColumnMinWidth = 65; +// const kDefaultColumnWidth = 80; +// const kTableNameMargins = 30; + +// export default class DataTableComponent extends React.Component { + +// private gridApi?: GridApi | null; +// private gridColumnApi?: ColumnApi | null; + +// private gridColumnDefs: ColDefArray = []; +// private gridRowData: IGridRow[] = []; +// private components = this.props.cellEditorComponent +// ? { clientCellEditor: this.props.cellEditorComponent } +// : undefined; +// private localRow: ICaseCreation = {}; +// private checkForEnterAfterCellEditingStopped = false; +// private localRowChangeTimer?: any; + +// private prevEditCell?: CellPosition; +// private editCellEvent?: CellEditingStartedEvent; +// private savedFocusedCell?: ICellIDs; +// private savedEditCell?: ICellIDs; +// private savedEditContent?: string; +// private isProcessingEnterKey?: boolean; + +// private gridElement: HTMLDivElement | null; +// private headerElement: HTMLDivElement | null; +// private headerRulerElement: HTMLDivElement | null; + +// private sortedRowNodes: RowNode[]; + +// // we don't need to refresh for changes the table already knows about +// private localChanges: ICaseCreation[] = []; + +// constructor(props: IProps) { +// super(props); + +// const { dataSet } = this.props; +// this.attachDataSet(dataSet); + +// this.state = { +// rowSelection: "multiple", +// addAttributeButtonPos: null +// }; + +// this.gridElement = null; +// this.headerElement = null; + +// this.updateGridState(dataSet); + +// this.sortedRowNodes = []; +// } + +// public onGridReady = (gridReadyParams: GridReadyEvent) => { +// this.gridApi = gridReadyParams.api; +// this.gridColumnApi = gridReadyParams.columnApi; + +// if (this.props.autoSizeColumns) { +// this.gridColumnApi?.autoSizeAllColumns(); +// } + +// const { tableComponentData: caseTableComponentData } = this.props; +// if (caseTableComponentData && this.gridApi) { +// this.gridApi.setSortModel(getSnapshot(caseTableComponentData.sortModel)); + +// onSnapshot(caseTableComponentData, (snapshot: ITableComponentData) => { +// if (this.gridApi) { +// this.gridApi.setSortModel(snapshot.sortModel); +// } +// }); +// } + +// if (this.props.onGridReady) { +// this.props.onGridReady(gridReadyParams); +// } +// } + +// public getRowNodeId = (data: { id: string }) => data.id; + +// public getRowIndexColumnDef(): ColDef { +// const { itemFlags, readOnly } = this.props; + +// function defaultIndexValueGetter(params: ValueGetterParams) { +// // default just returns a row/case index +// return params.node.rowIndex + 1; +// } + +// return ({ +// headerName: "", +// headerComponentFramework: TableHeaderMenu, +// headerComponentParams: { +// api: this.gridApi, +// expressions: this.props.expressions, +// rawExpressions: this.props.rawExpressions, +// dataSet: this.props.dataSet, +// readOnly, +// itemFlags, +// onSetTableName: (name: string) => { +// if (this.props.onSetTableName) { +// this.props.onSetTableName(name); +// } +// else { +// this.props.dataSet?.setName(name); +// } +// }, +// onNewAttribute: (name: string) => { +// const { dataSet } = this.props; +// dataSet && addAttributeToDataSet(dataSet, { name }); +// }, +// onRenameAttribute: (id: string, name: string) => { +// if (this.props.onSetAttributeName) { +// this.props.onSetAttributeName(id, name); +// } +// else { +// const { dataSet } = this.props; +// dataSet && dataSet.setAttributeName(id, name); +// } +// setTimeout(() => this.gridColumnApi?.autoSizeAllColumns(), 10); +// }, +// onUpdateExpression: (id: string, expression: string, rawExpression: string) => { +// if (this.props.onSetExpression) { +// this.props.onSetExpression(id, expression, rawExpression); +// } +// }, +// onNewCase: () => { +// const newCases = [{}]; +// if (this.props.onAddCanonicalCases) { +// this.props.onAddCanonicalCases(newCases); +// } +// else { +// const { dataSet } = this.props; +// dataSet && addCanonicalCasesToDataSet(dataSet, newCases); +// } +// }, +// onRemoveAttribute: (id: string) => { +// const { dataSet } = this.props; +// dataSet && dataSet.removeAttribute(id); +// }, +// onRemoveCases: (ids: string[]) => { +// if (this.props.onRemoveCases) { +// this.props.onRemoveCases(ids); +// } +// else { +// const { dataSet } = this.props; +// dataSet && dataSet.removeCases(ids); +// } +// }, +// onGetLinkedGeometries: () => { +// return this.props.onGetLinkedGeometries && this.props.onGetLinkedGeometries(); +// }, +// onUnlinkGeometry: () => { +// this.props.onUnlinkGeometry && this.props.onUnlinkGeometry(); +// } +// } as ITableHeaderMenuProps, +// headerClass: "cdp-column-header cdp-case-index-header", +// cellClass: "cdp-case-index-cell", +// colId: "__CASE_INDEX__", +// width: kRowIndexColumnWidth, +// // Note that pinned columns can't be grouped with unpinned columns. +// // Given that we're using grouped columns to present the table title, we can +// // either pin the index column and have the title cover the remaining columns, +// // or not pin the index column and have the title cover all the columns. +// // Since we currently only support two columns and horizontal scrolling is +// // rare, we don't pin the column for now, but this can be revisited. +// // pinned: "left", +// lockPosition: true, +// valueGetter: this.props.indexValueGetter || defaultIndexValueGetter, +// suppressMovable: true, +// resizable: false, +// suppressNavigable: true +// }); +// } + +// public addLocalCaseToTable() { +// const { dataSet } = this.props; +// if (!dataSet) return; + +// // clear local case before adding so that the update caused by addCanonicalCasesToDataSet() +// // shows an empty row for the local case +// const newCases: ICaseCreation[] = [cloneDeep(this.localRow)]; +// this.localRow = {}; +// if (this.props.onAddCanonicalCases) { +// this.props.onAddCanonicalCases(newCases); +// } +// else { +// addCanonicalCasesToDataSet(dataSet, newCases); +// } +// this.updateGridState(this.props.dataSet); +// } + +// public getAttributeColumnDef(attribute: IAttribute): ColDef { +// const { readOnly, expressions } = this.props; +// const expression = expressions && expressions.get(attribute.id); +// const editable = !readOnly && !expression; + +// const defaultAttrValueFormatter = (params: ValueFormatterParams) => { +// const colName = params.colDef.field || params.colDef.headerName || ""; +// const colPlaces: { [key: string]: number } = { +// day: 0, +// distance: 1, +// speed: 2 +// }; +// let places = colPlaces[colName]; +// if ((places == null) && (this.props.defaultPrecision != null)) { +// places = this.props.defaultPrecision; +// } +// return (places != null) && (typeof params.value === "number") +// ? params.value.toFixed(places) +// : params.value; +// }; + +// return ({ +// headerClass: "cdp-column-header cdp-attr-column-header", +// cellClass: `cdp-row-data-cell ${expression ? "has-expression" : ""}`, +// headerName: attribute.name, +// field: attribute.name, +// tooltipField: attribute.name, +// colId: attribute.id, +// editable, +// width: kDefaultColumnWidth, +// resizable: true, +// lockPosition: true, +// valueGetter: (params: ValueGetterParams) => { +// const { dataSet } = this.props; +// const caseID = params.node.id; +// const attrID = params.colDef.colId; +// if (params.data.id === LOCAL_ROW_ID) { +// return attrID ? this.localRow[attrID] : undefined; +// } +// let value = dataSet && attrID ? dataSet.getValue(caseID, attrID) : undefined; +// if (Number.isNaN(value as any)) { +// value = "#ERR"; +// } +// // The purpose of the code below was to get recently changed cells in case +// // they've been updated but not yet received from Firebase. It was removed as +// // it overwrites updates from expressions and it is not clear that it remains necessary. +// // However, if changes are failing to appear across tables, it would be worth reconsidering this logic. +// // this.localChanges.forEach((change) => { +// // if ((change.__id__ === caseID) && (attrID != null)) { +// // if (change[attrID] != null) { +// // value = change[attrID] as IValueType; +// // } +// // } +// // }); +// return value; +// }, +// valueFormatter: this.props.attrValueFormatter || defaultAttrValueFormatter, +// valueSetter: (params: ValueSetterParams) => { +// const { dataSet } = this.props; +// if (!dataSet || (params.newValue === params.oldValue)) { return false; } +// if (params.data.id === LOCAL_ROW_ID) { +// if (params.colDef.colId) { +// this.localRow[params.colDef.colId] = params.newValue; +// } +// return !!params.colDef.colId; +// } +// const str = (params.newValue != null) && (typeof params.newValue === "string") +// ? params.newValue.trim() : undefined; +// const num = str ? Number(str) : undefined; +// const attrID = attribute.id; +// const caseID = dataSet && dataSet.cases[params.node.rowIndex].__id__; +// const caseValues = { +// __id__: caseID, +// [attrID]: (num != null) && isFinite(num) ? num : str +// }; +// if (caseValues[attrID] === params.oldValue) { return false; } +// // track in-flight changes +// this.localChanges.push(cloneDeep(caseValues)); +// if (this.props.onSetCanonicalCaseValues) { +// this.props.onSetCanonicalCaseValues(caseValues); +// } +// else { +// dataSet.setCanonicalCaseValues([caseValues]); +// } +// return true; +// }, +// comparator(valueA: any, valueB: any, nodeA: RowNode, nodeB: RowNode, descending: boolean) { +// const floatA = parseFloat(valueA); +// const floatB = parseFloat(valueB); +// if (isNaN(floatA) || isNaN(floatB)) { +// if (valueA < valueB) { return -1; } +// if (valueA > valueB) { return 1; } +// return 0; +// } +// return floatA - floatB; +// }, +// cellEditor: this.props.cellEditorComponent ? "clientCellEditor" : undefined, +// cellEditorParams: this.props.cellEditorParams, +// }); +// } + +// public getColumnDefs(dataSet: IDataSet): ColDefArray { + +// let minColumnWidth = 0; +// if (dataSet.name) { +// // adjust the minimum column width to accommodate the table header +// const tableNameWidth = this.measureHeaderLabelWidth(dataSet.name); +// if (tableNameWidth) { +// const tableHeaderWidth = tableNameWidth + kTableNameMargins; +// minColumnWidth = Math.max(kDefaultColumnMinWidth, +// Math.ceil((tableHeaderWidth - kRowIndexColumnWidth) / 2)); +// } +// } + +// const cols = dataSet.attributes.map(attr => { +// const colDef = this.getAttributeColumnDef(attr); +// minColumnWidth && (colDef.minWidth = minColumnWidth); +// return colDef; +// }); +// cols.unshift(this.getRowIndexColumnDef()); + +// // if the table has a name/title, group the columns under it +// return dataSet.name +// ? [{ headerName: dataSet.name, children: cols }] +// : cols; +// } + +// public getRowData(dataSet?: IDataSet): IGridRow[] { +// const rows = []; +// if (dataSet) { +// for (const aCase of dataSet.cases) { +// // just need the ID; everything else comes from valueGetter +// rows.push({ id: aCase.__id__ }); +// } +// } +// if (!this.props.readOnly) { +// rows.push({ id: LOCAL_ROW_ID }); +// } +// return rows; +// } + +// public updateGridState(dataSet?: IDataSet) { +// this.updateGridColState(dataSet); +// this.updateGridRowState(dataSet); +// } + +// public updateGridColState(dataSet?: IDataSet) { +// this.gridColumnDefs = dataSet ? this.getColumnDefs(dataSet) : []; +// if (this.gridApi) { +// // recent versions of ag-grid require manual column header synchronization +// // cf. https://github.com/ag-grid/ag-grid/issues/2771#issuecomment-441576761 +// // cf. https://github.com/ag-grid/ag-grid/issues/2771#issuecomment-509981799 +// this.gridApi.setColumnDefs([]); +// this.gridApi.setColumnDefs(this.gridColumnDefs); +// } +// } + +// public updateGridRowState(dataSet?: IDataSet) { +// this.gridRowData = this.getRowData(dataSet); +// if (this.gridApi) { +// this.gridApi.setRowData(this.gridRowData); +// setTimeout(() => this.ensureFocus(dataSet)); +// } +// } + +// public ensureFocus = (dataSet?: IDataSet) => { +// if (!this.gridApi) return; +// const currentCell = this.gridApi.getFocusedCell(); +// const lastRowIndex = this.gridApi.paginationGetRowCount() - 1; +// if (!currentCell && (lastRowIndex >= 0) && dataSet && (dataSet.attributes.length > 0)) { +// const firstColId = dataSet.attributes[0].id; +// this.gridApi.setFocusedCell(lastRowIndex, firstColId); +// } +// } + +// public startEditingCell = (rowIndex: number, colKey: string) => { +// if (this.gridApi && (rowIndex != null) && colKey) { +// this.gridApi.setFocusedCell(rowIndex, colKey); +// this.gridApi.startEditingCell({ rowIndex, colKey }); +// } +// } + +// public startEditingSameColumnOfNextRow = (backwards: boolean) => { +// if (this.gridApi && this.prevEditCell) { +// const rowIndex = this.prevEditCell.rowIndex + (backwards ? -1 : 1); +// const colKey = this.prevEditCell.column.getColId(); +// if ((rowIndex >= 0) && colKey) { +// this.startEditingCell(rowIndex, colKey); +// } +// } +// } + +// public startEditingFirstColumnOfNextRow = () => { +// if (this.gridApi && this.gridColumnApi && this.prevEditCell) { +// const rowIndex = this.prevEditCell.rowIndex + 1; +// const columns = this.gridColumnApi.getAllDisplayedColumns(); +// const colKey = columns[1].getColId(); +// this.startEditingCell(rowIndex, colKey); +// } +// } + +// public getRowStyle(params: IRowStyleParams) { +// // if (params.data.id === LOCAL_ROW_ID) { +// // return LOCAL_ROW_STYLE; +// // } +// return undefined; +// } + +// public isIgnorableChange(action: ISerializedActionCall) { +// switch (action.name) { +// case "setCaseValues": +// case "setCanonicalCaseValues": { +// const cases = action.args && action.args[0]; +// if (!cases) { return true; } +// let ignoredChanges = 0; +// cases.forEach((aCase: ICaseCreation) => { +// const index = findIndex(this.localChanges, (change) => isEqual(assign({}, aCase, change), aCase)); +// if (index >= 0) { +// // ignoring local change +// this.localChanges.splice(index, 1); +// ++ignoredChanges; +// } +// }); +// return ignoredChanges >= cases.length; +// } +// case "addActionListener": +// case "removeActionListener": +// return true; +// default: +// return false; +// } +// } + +// public getCellIDsFromGridCell(cell: IGridCellDef): ICellIDs | undefined { +// if (!cell) { return; } +// const { rowIndex, column, floating } = cell; +// const attrID = column && column.getColId(); +// const aCase = rowIndex != null ? this.gridRowData[rowIndex] : undefined; +// const caseID = aCase && aCase.id; +// return attrID && caseID ? { colID: attrID, rowID: caseID, floating } : undefined; +// } + +// public getGridCellFromCellIDs(cellIDs: ICellIDs): IGridCellDef | undefined { +// if (!this.gridApi || !this.gridColumnApi || !cellIDs || !cellIDs.rowID) return; +// const rowNode = this.gridApi.getRowNode(cellIDs.rowID); +// return rowNode && { +// rowIndex: rowNode.rowIndex, +// column: this.gridColumnApi.getColumn(cellIDs.colID) +// }; +// } + +// public saveCellEditState() { +// if (!this.gridApi) return; +// const focusedCell = this.gridApi.getFocusedCell(); +// const rowIndex = this.editCellEvent && this.editCellEvent.rowIndex; +// const column = this.editCellEvent && this.editCellEvent.column; +// this.savedFocusedCell = this.getCellIDsFromGridCell(focusedCell); +// this.savedEditCell = this.getCellIDsFromGridCell({ rowIndex, column }); +// if (this.editCellEvent) { +// const cellInputElts = document.getElementsByClassName("ag-cell-edit-input"); +// const cellInputElt: HTMLInputElement = cellInputElts && (cellInputElts[0] as HTMLInputElement); +// this.savedEditContent = cellInputElt ? cellInputElt.value : undefined; +// } +// this.gridApi.stopEditing(true); +// this.gridApi.clearFocusedCell(); +// } + +// public restoreCellEditState() { +// if (!this.gridApi) return; +// if (this.savedFocusedCell) { +// const focusedGridCell = this.getGridCellFromCellIDs(this.savedFocusedCell); +// if (focusedGridCell) { +// const { rowIndex, column, floating } = focusedGridCell; +// if ((rowIndex != null) && column) { +// this.gridApi.setFocusedCell(rowIndex, column, floating); +// } +// } +// this.savedFocusedCell = undefined; +// } +// if (this.savedEditCell) { +// const editRowColumn = this.getGridCellFromCellIDs(this.savedEditCell); +// if (editRowColumn) { +// const { rowIndex, column } = editRowColumn; +// if ((rowIndex != null) && column) { +// this.gridApi.startEditingCell({ rowIndex, colKey: column }); +// } +// } +// this.savedEditCell = undefined; +// } +// if (this.savedEditContent != null) { +// const cellInputElts = document.getElementsByClassName("ag-cell-edit-input"); +// const cellInputElt: HTMLInputElement = cellInputElts && (cellInputElts[0] as HTMLInputElement); +// if (cellInputElt) { +// cellInputElt.value = this.savedEditContent; +// } +// this.savedEditContent = undefined; +// } +// } + +// public handleAction = (action: ISerializedActionCall) => { +// const { dataSet } = this.props; +// if (!this.isIgnorableChange(action)) { +// let columnDefs = null; +// let rowTransaction: RowDataTransaction | null = null; +// let shouldSaveEditState = true; +// const attributeChanged = () => { +// if (dataSet) { +// columnDefs = this.getColumnDefs(dataSet); +// setTimeout(() => this.handleSetAddAttributePos(), 1); +// } +// }; +// switch (action.name) { +// case "@APPLY_SNAPSHOT": +// if (/^\/attributes\//.test(action.path || "")) { +// attributeChanged(); +// } +// break; +// case "addAttributeWithID": +// case "removeAttribute": +// case "setAttributeName": +// attributeChanged(); +// break; +// case "addCasesWithIDs": +// case "addCanonicalCasesWithIDs": +// case "setCaseValues": +// case "setCanonicalCaseValues": +// if (action.args && action.args.length) { +// const cases = action.args[0].map((aCase: ICase) => ({ id: aCase.__id__ })); +// if (action.name.substr(0, 3) === "add") { +// interface IRowData { id: string; } +// const addIndex = sortedIndexBy(this.gridRowData, cases[0], (value: IRowData) => value.id); +// rowTransaction = { add: cases, addIndex: Math.min(addIndex, this.gridRowData.length - 1) }; +// } +// else { +// rowTransaction = { update: cases }; +// // don't need to save/restore cell edit if only changing existing values +// shouldSaveEditState = false; +// } +// } +// break; +// case "removeCases": +// if (action.args && action.args.length) { +// const casesToRemove = action.args[0].map((id: string) => ({ id })); +// rowTransaction = { remove: casesToRemove }; +// } +// break; +// default: +// } +// if (shouldSaveEditState) { +// this.saveCellEditState(); +// } +// if (columnDefs && this.gridApi) { +// this.gridApi.setColumnDefs(columnDefs); +// } +// if (rowTransaction && this.gridApi) { +// this.gridApi.updateRowData(rowTransaction); +// this.gridRowData = this.getRowData(dataSet); +// } +// if (shouldSaveEditState) { +// this.restoreCellEditState(); +// } +// } +// } + +// public attachDataSet(dataSet?: IDataSet) { +// if (dataSet) { +// dataSet.addActionListener("case-table", this.handleAction); +// } +// } + +// public detachDataSet(dataSet?: IDataSet) { +// if (dataSet) { +// dataSet.removeActionListener("case-table"); +// } +// } + +// public handleRowSelectionChanged = (e: SelectionChangedEvent) => { +// e.api.refreshHeader(); +// this.props.onRowSelectionChange && this.props.onRowSelectionChange(e); +// } + +// public handleCellEditingStarted = (event: CellEditingStartedEvent) => { +// this.prevEditCell = this.gridApi && this.gridApi.getEditingCells()[0] || undefined; +// this.editCellEvent = event; + +// if (this.localRowChangeTimer) { +// // The user stopped editing a cell in the local/input row, but started +// // editing another cell before the timer expired. We cancel the timer +// // and then decide whether to create a new case depending on whether +// // the new cell being edited is in the local/input row or not. +// clearTimeout(this.localRowChangeTimer); +// this.localRowChangeTimer = undefined; + +// if (event.node.id !== LOCAL_ROW_ID) { +// // If the new cell being edited is not in the local/input row, then +// // we should add the new case, but also save/restore the edit state +// // for the cell now being edited. +// this.saveCellEditState(); +// this.addLocalCaseToTable(); +// setTimeout(() => { +// this.restoreCellEditState(); +// }); +// } +// } +// } + +// public hasCellEditValueChanged(startEvent: CellEditingStartedEvent | undefined, +// stopEvent: CellEditingStoppedEvent) { +// const orgValue = startEvent && startEvent.value || ""; +// const newValue = stopEvent && stopEvent.value || ""; +// // eslint-disable-next-line eqeqeq +// return newValue != orgValue; +// } + +// public handleCellEditingStopped = (event: CellEditingStoppedEvent) => { +// this.checkForEnterAfterCellEditingStopped = true; + +// // When the user stops editing a cell in the local/input row, we want to add +// // the new case to the dataset, as long as the user has actually edited the +// // value or explicitly requested the new row (by pressing the enter key). +// if (event.node.id === LOCAL_ROW_ID) { +// if (this.isProcessingEnterKey || this.hasCellEditValueChanged(this.editCellEvent, event)) { +// // We set a timeout so that this can be canceled. If the user immediately starts +// // editing another cell in the local/input row, then we do _not_ want to add the +// // new case to the dataset until the user stops editing the row entirely. +// // We assume that 10 ms is sufficient to allow the next cell edit to begin, +// // if there is one starting up immediately, e.g. when tabbing to the next cell. +// this.localRowChangeTimer = setTimeout(() => { +// this.localRowChangeTimer = undefined; +// this.addLocalCaseToTable(); +// }, 10); +// } +// } +// this.editCellEvent = undefined; +// this.checkForEnterAfterCellEditingStopped = true; +// } + +// public handleTabToNextCell = (params: TabToNextCellParams) => { +// this.prevEditCell = params.previousCellPosition; +// if (params.editing && !params.backwards && !params.nextCellPosition) { +// setTimeout(() => { +// this.startEditingFirstColumnOfNextRow(); +// }, 100); +// } +// return params.nextCellPosition; +// } + +// public handleKeyDownCapture = (e: KeyboardEvent) => { +// // Track whether or not we are processing an enter key event, because +// // we use that information to decide when/whether to create a new case. +// // We use a browser event handler because the corresponding React event +// // handler didn't work as expected. +// if ((e.keyCode === 13) && !e.shiftKey) { +// this.isProcessingEnterKey = true; +// } +// } + +// public handleKeyUp = (e: React.KeyboardEvent) => { +// const startEditingNextRow = this.startEditingSameColumnOfNextRow.bind(this, e.shiftKey); + +// if (e.keyCode === 13) { +// if (this.checkForEnterAfterCellEditingStopped) { +// setTimeout(startEditingNextRow, 100); +// } +// this.isProcessingEnterKey = false; +// } + +// this.checkForEnterAfterCellEditingStopped = false; +// } + +// public handlePostSort = (rowNodes: RowNode[]) => { +// // move the entry row to the bottom +// const localRow = rowNodes.find((rowNode) => rowNode.data.id === LOCAL_ROW_ID); +// if (localRow) { +// rowNodes.splice(rowNodes.indexOf(localRow), 1); +// rowNodes.push(localRow); +// } + +// // keep reference so we can keep index in ascending order +// this.sortedRowNodes = rowNodes; +// if (this.gridApi) { +// // force update of the case index +// this.gridApi.refreshCells({ +// columns: ["__CASE_INDEX__"], +// force: true +// }); +// } +// } + +// public handleSortChanged = (event: SortChangedEvent) => { +// const { tableComponentData: caseTableComponentData } = this.props; +// if (caseTableComponentData) { +// const currentSortModel = getSnapshot(caseTableComponentData.sortModel); +// const newSortModel = event.api && event.api.getSortModel(); +// if (!isEqual(currentSortModel, newSortModel)) { +// caseTableComponentData.setSortModel(newSortModel); +// } +// } +// } + +// public componentDidMount() { +// if (this.gridElement) { +// this.gridElement.addEventListener("keydown", this.handleKeyDownCapture, true); +// } +// } + +// public componentWillUnmount() { +// if (this.gridElement) { +// this.gridElement.removeEventListener("keydown", this.handleKeyDownCapture, true); +// } +// } + +// public UNSAFE_componentWillReceiveProps(nextProps: IProps) { +// const { changeCount, dataSet } = nextProps; +// if (dataSet !== this.props.dataSet) { +// this.detachDataSet(this.props.dataSet); +// this.attachDataSet(dataSet); +// this.updateGridState(dataSet); +// } +// else if (changeCount !== this.props.changeCount) { +// this.updateGridState(dataSet); +// } +// } + +// public handleSetAddAttributePos = () => { +// if (this.gridElement) { +// const classes = this.gridElement.getElementsByClassName("ag-header-row"); +// this.headerElement = classes.item(classes.length - 1) as HTMLDivElement; +// if (this.headerElement) { +// const gridRect = this.gridElement.getBoundingClientRect(); +// const headerRect = this.headerElement.getBoundingClientRect(); +// const left = headerRect.right - gridRect.left; +// const top = headerRect.top - gridRect.top; +// const { addAttributeButtonPos } = this.state; +// if (!addAttributeButtonPos || (addAttributeButtonPos.top !== top) || (addAttributeButtonPos.left !== left)) { +// this.setState({ addAttributeButtonPos: { top, left } }); +// } +// } +// } +// } + +// public componentWillReact() { +// this.updateGridState(this.props.dataSet); +// } + +// public handleAddAttributeButton = () => { +// emitTableEvent({ type: "add-column" }); +// } + +// public renderAddAttributeButtonPos() { +// const { addAttributeButtonPos } = this.state; +// if (addAttributeButtonPos !== null) { +// const { top, left } = addAttributeButtonPos; +// return ( +// +// + +// +// ); +// } +// return null; +// } + +// public render() { +// return ( +//
this.gridElement = el} +// draggable={true} +// onDragStart={this.handleDragStart} +// onKeyUp={this.handleKeyUp}> +// +// {/* hidden ruler div for measuring header text width */} +//
this.headerRulerElement = el} +// style={{ display: "inline", visibility: "hidden" }} /> +//
+// ); +// } + +// private measureHeaderLabelWidth(label: string) { +// if (this.headerRulerElement) { +// this.headerRulerElement.innerText = label; +// const width = Math.ceil(this.headerRulerElement.offsetWidth); +// this.headerRulerElement.innerText = ""; +// return width; +// } +// } + +// private handleDragStart = (evt: React.DragEvent) => { +// // ag-grid adds "ag-column-resizing" class to columns being actively resized +// if (this.gridElement?.getElementsByClassName("ag-column-resizing").length) { +// // if we're column resizing, prevent other drags above (e.g. tile drags) +// evt.preventDefault(); +// evt.stopPropagation(); +// } +// } +// } diff --git a/src/components/tools/table-tool/editable-header-cell.tsx b/src/components/tools/table-tool/editable-header-cell.tsx new file mode 100644 index 0000000000..725e4f8f36 --- /dev/null +++ b/src/components/tools/table-tool/editable-header-cell.tsx @@ -0,0 +1,49 @@ +import React, { useState } from "react"; +import { TColumn, THeaderRendererProps } from "./table-types"; +import { HeaderCellInput } from "./header-cell-input"; + +interface IProps extends THeaderRendererProps { +} +export const EditableHeaderCell: React.FC = ({ column: _column }) => { + const column = _column as unknown as TColumn; + const { name, appData } = column; + const { + gridContext, editableName, isEditing, + onBeginHeaderCellEdit, onHeaderCellEditKeyDown, onEndHeaderCellEdit + } = appData || {}; + const [nameValue, setNameValue] = useState(editableName ? name as string : ""); + const handleClick = () => { + !isEditing && gridContext?.onSelectColumn(column.key); + }; + const handleDoubleClick = () => { + editableName && !isEditing && onBeginHeaderCellEdit?.(); + }; + const handleKeyDown = (e: React.KeyboardEvent) => { + const { key } = e; + switch (key) { + case "Escape": + handleClose(false); + break; + case "Enter": + case "Tab": + handleClose(true); + onHeaderCellEditKeyDown?.(e); + break; + } + }; + const handleChange = (value: string) => { + setNameValue(value); + }; + const handleClose = (accept: boolean) => { + onEndHeaderCellEdit?.(accept ? nameValue : undefined); + }; + const style = { width: column.width }; + return ( +
+ {isEditing + ? + : name} +
+ ); +}; diff --git a/src/components/tools/table-tool/editable-table-title.tsx b/src/components/tools/table-tool/editable-table-title.tsx new file mode 100644 index 0000000000..d997398742 --- /dev/null +++ b/src/components/tools/table-tool/editable-table-title.tsx @@ -0,0 +1,67 @@ +import classNames from "classnames"; +import { observer } from "mobx-react"; +import React, { useState } from "react"; +import { HeaderCellInput } from "./header-cell-input"; +import { LinkGeometryButton } from "./link-geometry-button"; + +interface IProps { + className?: string; + readOnly?: boolean; + showLinkButton: boolean; + linkIndex: number; + isLinkEnabled?: boolean; + titleCellWidth: number; + getTitle: () => string | undefined; + onBeginEdit?: () => void; + onEndEdit?: (title?: string) => void; + onLinkGeometryClick?: () => void; +} +export const EditableTableTitle: React.FC = observer(({ + className, readOnly, showLinkButton, linkIndex, isLinkEnabled, titleCellWidth, + getTitle, onBeginEdit, onEndEdit, onLinkGeometryClick +}) => { + // getTitle() and observer() allow this component to re-render + // when the title changes without re-rendering the entire TableTool + const title = getTitle(); + const [isEditing, setIsEditing] = useState(false); + const [editingTitle, setEditingTitle] = useState(title); + const handleClick = () => { + if (!readOnly && !isEditing) { + onBeginEdit?.(); + setEditingTitle(title); + setIsEditing(true); + } + }; + const handleKeyDown = (e: React.KeyboardEvent) => { + const { key } = e; + switch (key) { + case "Escape": + handleClose(false); + break; + case "Enter": + case "Tab": + handleClose(true); + break; + } + }; + const handleClose = (accept: boolean) => { + const trimTitle = editingTitle?.trim(); + onEndEdit?.(accept && trimTitle ? trimTitle : undefined); + setIsEditing(false); + }; + const isDefaultTitle = title && /Table\s+(\d+)\s*$/.test(title); + const classes = classNames("editable-header-cell", className, + { "table-title-editing": isEditing, "table-title-default": isDefaultTitle }); + const style = { width: titleCellWidth }; + return ( +
+ {isEditing + ? + : title} + {showLinkButton && !isEditing && + } +
+ ); +}); diff --git a/src/components/tools/table-tool/expression-utils.ts b/src/components/tools/table-tool/expression-utils.ts new file mode 100644 index 0000000000..36e60c1952 --- /dev/null +++ b/src/components/tools/table-tool/expression-utils.ts @@ -0,0 +1,52 @@ +import { Parser } from "expr-eval"; +import { kSerializedXKey } from "../../../models/tools/table/table-model-types"; + +export const getEditableExpression = ( + rawExpression: string | undefined, canonicalExpression: string, xName: string +) => { + // Raw expressions are cleared when x attribute is renamed, in which case + // we regenerate the "raw" expression from the canonical expression. + return rawExpression || prettifyExpression(canonicalExpression, xName); +}; + +export const canonicalizeExpression = (displayExpression: string, xName: string) => { + if (xName && displayExpression) { + const parser = new Parser(); + const canonicalExpression = parser.parse(displayExpression).substitute(xName, kSerializedXKey); + return canonicalExpression.toString(); + } else { + return displayExpression; + } +}; + +export const prettifyExpression = (canonicalExpression: string | undefined, xName: string) => { + if (xName && canonicalExpression) { + const parser = new Parser(); + let expression = parser.parse(canonicalExpression).substitute(kSerializedXKey, xName).toString(); + if (expression.charAt(0) === "(" && expression.charAt(expression.length - 1) === ")") { + expression = expression.substring(1, expression.length - 1); + } + return expression; + } else { + return canonicalExpression; + } +}; + +export const validateExpression = (expressionStr: string, xName: string) => { + if (!expressionStr || !xName) return; + const parser = new Parser(); + try { + const expression = parser.parse(expressionStr); + const unknownVar = expression.variables().find(variable => variable !== xName); + if (unknownVar) { + return `Unrecognized variable "${unknownVar}" in expression.`; + } + if (xName) { + // Attempt an evaluation to check for errors e.g. invalid function names + expression.evaluate({[xName]: 1}); + } + } catch { + return "Could not understand expression. Make sure you supply all operands " + + "and use a multiplication sign where necessary, e.g. 3 * x + 4 instead of 3x + 4."; + } +}; diff --git a/src/components/tools/table-tool/expressions-dialog.scss b/src/components/tools/table-tool/expressions-dialog.scss new file mode 100644 index 0000000000..1d9367856f --- /dev/null +++ b/src/components/tools/table-tool/expressions-dialog.scss @@ -0,0 +1,57 @@ +@import "../../../components/vars.sass"; + +.custom-modal.set-expression { + width: 512px; + height: 237px; + outline: none; + + .modal-content { + justify-content: flex-start; + + .prompt { + margin-top: 15px; + + select { + margin: 0 3px; + padding: 0 3px; + font-weight: bold; + } + + .attr-name { + font-weight: bold; + + &.y { + margin: 0 3px; + } + + &.x { + margin-left: 3px; + } + } + } + + .expression { + margin-top: 20px; + height: 30px; + display: flex; + align-items: center; + + label { + display: inline-block; + flex: 0 0 auto; + + .equals { + margin: 0 6px 0 3px; + } + } + input { + height: 100%; + flex: 1 1 auto; + } + } + + .error { + margin-top: 15px; + } + } +} diff --git a/src/components/tools/table-tool/header-cell-input.tsx b/src/components/tools/table-tool/header-cell-input.tsx new file mode 100644 index 0000000000..f8ac4ab1b8 --- /dev/null +++ b/src/components/tools/table-tool/header-cell-input.tsx @@ -0,0 +1,28 @@ +import React from "react"; + +function autoFocusAndSelect(input: HTMLInputElement | null) { + input?.focus(); + input?.select(); +} + +interface IProps { + style?: React.CSSProperties; + value: string; + onKeyDown: (e: React.KeyboardEvent) => void; + onChange: (value: string) => void; + onClose: (accept: boolean) => void; +} +export const HeaderCellInput: React.FC = ({ style, value, onKeyDown, onChange, onClose }) => { + return ( +
+ onChange(event.target.value)} + onBlur={() => onClose(true)} + /> +
+ ); +}; diff --git a/src/components/tools/table-tool/link-geometry-button.tsx b/src/components/tools/table-tool/link-geometry-button.tsx new file mode 100644 index 0000000000..4321e4c181 --- /dev/null +++ b/src/components/tools/table-tool/link-geometry-button.tsx @@ -0,0 +1,21 @@ +import classNames from "classnames"; +import React from "react"; +import LinkGraphIcon from "../../../clue/assets/icons/table/link-graph-icon.svg"; + +interface IProps { + linkIndex: number; + isEnabled?: boolean; + onClick?: () => void; +} +export const LinkGeometryButton: React.FC = ({ isEnabled, linkIndex, onClick }) => { + const classes = classNames("link-geometry-button", `link-color-${linkIndex}`, { disabled: !isEnabled }); + const handleClick = (e: React.MouseEvent) => { + isEnabled && onClick?.(); + e.stopPropagation(); + }; + return ( +
+ +
+ ); +}; diff --git a/src/components/tools/table-tool/link-geometry-dialog.scss b/src/components/tools/table-tool/link-geometry-dialog.scss new file mode 100644 index 0000000000..d33b3a0979 --- /dev/null +++ b/src/components/tools/table-tool/link-geometry-dialog.scss @@ -0,0 +1,24 @@ +@import "../../../components/vars.sass"; + +.custom-modal.link-geometry { + width: 420px; + height: 200px; + outline: none; + + .modal-content { + justify-content: flex-start; + + .prompt { + margin-top: 15px; + } + } + + select { + margin: 15px 20px; + font-style: italic; + } + + .modal-button.disabled { + opacity: 35%; + } +}; diff --git a/src/components/tools/table-tool/linked-table-cell-editor.tsx b/src/components/tools/table-tool/linked-table-cell-editor.tsx index 83573219f3..3edffa4bd4 100644 --- a/src/components/tools/table-tool/linked-table-cell-editor.tsx +++ b/src/components/tools/table-tool/linked-table-cell-editor.tsx @@ -1,56 +1,56 @@ -import { ICellEditorParams, TextCellEditor } from "@ag-grid-community/core"; -import { TableMetadataModelType } from "../../../models/tools/table/table-content"; - -interface ILinkedTableCellEditorParams extends ICellEditorParams { - metadata: TableMetadataModelType; -} - -export class LinkedTableCellEditor extends TextCellEditor { - - private domInput: HTMLInputElement; - private metadata: TableMetadataModelType; - - constructor() { - super(); - this.domInput = this.getGui().querySelector("input") as HTMLInputElement; - } - - public init(params: ICellEditorParams) { - super.init(params as any); - const _params = params as ILinkedTableCellEditorParams; - this.metadata = _params.metadata; - } - - public afterGuiAttached() { - super.afterGuiAttached(); - const eInput = this.domInput; - eInput && eInput.addEventListener("input", this.handleInputChange); - } - - public destroy() { - const eInput = this.domInput; - eInput && eInput.removeEventListener("input", this.handleInputChange); - } - - public handleInputChange = (e: any) => { - const value = e.target.value; - if (!this.isValid(value)) { - this.domInput.classList.add("invalid-cell"); - } else { - this.domInput.classList.remove("invalid-cell"); - } - } - - public isValid = (value: string) => { - // don't apply validation unless the table is linked - if (!this.metadata || !this.metadata.isLinked) return true; - // allow empty values - if ((value == null) || (value === "")) return true; - // non-empty values must be numeric - return isFinite(Number(value)); - } - - public isCancelAfterEnd = () => { - return !this.isValid(this.getValue()); - } -} +// import { ICellEditorParams, TextCellEditor } from "@ag-grid-community/core"; +// import { TableMetadataModelType } from "../../../models/tools/table/table-content"; + +// interface ILinkedTableCellEditorParams extends ICellEditorParams { +// metadata: TableMetadataModelType; +// } + +// export class LinkedTableCellEditor extends TextCellEditor { + +// private domInput: HTMLInputElement; +// private metadata: TableMetadataModelType; + +// constructor() { +// super(); +// this.domInput = this.getGui().querySelector("input") as HTMLInputElement; +// } + +// public init(params: ICellEditorParams) { +// super.init(params as any); +// const _params = params as ILinkedTableCellEditorParams; +// this.metadata = _params.metadata; +// } + +// public afterGuiAttached() { +// super.afterGuiAttached(); +// const eInput = this.domInput; +// eInput && eInput.addEventListener("input", this.handleInputChange); +// } + +// public destroy() { +// const eInput = this.domInput; +// eInput && eInput.removeEventListener("input", this.handleInputChange); +// } + +// public handleInputChange = (e: any) => { +// const value = e.target.value; +// if (!this.isValid(value)) { +// this.domInput.classList.add("invalid-cell"); +// } else { +// this.domInput.classList.remove("invalid-cell"); +// } +// } + +// public isValid = (value: string) => { +// // don't apply validation unless the table is linked +// if (!this.metadata || !this.metadata.isLinked) return true; +// // allow empty values +// if ((value == null) || (value === "")) return true; +// // non-empty values must be numeric +// return isFinite(Number(value)); +// } + +// public isCancelAfterEnd = () => { +// return !this.isValid(this.getValue()); +// } +// } diff --git a/src/components/tools/table-tool/new-column-dialog.tsx b/src/components/tools/table-tool/new-column-dialog.tsx deleted file mode 100644 index 5aea3b09ca..0000000000 --- a/src/components/tools/table-tool/new-column-dialog.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import React from "react"; -import { Button, Dialog } from "@blueprintjs/core"; - -interface IProps { - isOpen: boolean; - onNewAttribute: (name: string) => void; - onClose: () => void; -} - -interface IState { - name: string; -} - -export default -class NewColumnDialog extends React.Component { - - constructor(props: IProps) { - super(props); - - this.state = { - name: "" - }; - } - - public render() { - const capitalizedAttribute = "Attribute"; - return ( - - -
Enter a name for the new column:
- input && input.focus()} - /> -
-
-
- ); - } - - private handleNameChange = (evt: React.FormEvent) => { - this.setState({ name: (evt.target as HTMLInputElement).value }); - } - - private handleNewAttribute = () => { - if (this.props.onNewAttribute) { - this.props.onNewAttribute(this.state.name); - } - } - - private handleKeyDown = (evt: React.KeyboardEvent) => { - if (evt.keyCode === 13) { - this.handleNewAttribute(); - } - } - -} diff --git a/src/components/tools/table-tool/rename-column-dialog.sass b/src/components/tools/table-tool/rename-column-dialog.sass deleted file mode 100644 index 97aa7fd306..0000000000 --- a/src/components/tools/table-tool/rename-column-dialog.sass +++ /dev/null @@ -1,4 +0,0 @@ -.bp3-dialog.rename-column-dialog - - .nc-dialog-error - height: 36px \ No newline at end of file diff --git a/src/components/tools/table-tool/rename-column-dialog.tsx b/src/components/tools/table-tool/rename-column-dialog.tsx deleted file mode 100644 index 9d38cd206a..0000000000 --- a/src/components/tools/table-tool/rename-column-dialog.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React from "react"; -import { Button, Dialog } from "@blueprintjs/core"; - -import "./rename-column-dialog.sass"; - -interface IProps { - id: string; - isOpen: boolean; - onRenameAttribute: (id: string, name: string) => void; - onClose: () => void; - name: string; - columnNameValidator?: (name: string) => string | undefined; -} - -interface IState { - name: string; -} - -export default -class RenameColumnDialog extends React.Component { - - public state = { - name: this.props.name || "" - }; - - public render() { - const prompt = `Enter a new name for column "${this.props.name}"`; - const errorMessage = this.getValidationError(); - return ( - -
{prompt}:
- input && input.focus()} - /> -
- {errorMessage} -
-
-
-
- ); - } - - private getValidationError = () => { - const { columnNameValidator: validator } = this.props; - const { name } = this.state; - return validator && validator(name); - } - - private handleNameChange = (evt: React.FormEvent) => { - this.setState({ name: (evt.target as HTMLInputElement).value }); - } - - private handleRenameAttribute = () => { - if (this.props.onRenameAttribute && !this.getValidationError()) { - this.props.onRenameAttribute(this.props.id, this.state.name); - } - } - - private handleKeyDown = (evt: React.KeyboardEvent) => { - if (evt.keyCode === 13) { - this.handleRenameAttribute(); - } - } - -} diff --git a/src/components/tools/table-tool/set-table-name-dialog.tsx b/src/components/tools/table-tool/set-table-name-dialog.tsx deleted file mode 100644 index 331dda4c8f..0000000000 --- a/src/components/tools/table-tool/set-table-name-dialog.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import * as React from "react"; -const { useState } = React; -import { Button, Dialog } from "@blueprintjs/core"; - -interface IProps { - isOpen: boolean; - tableName?: string; - maxLength?: number; - onSetTableName: (name: string) => void; - onClose: () => void; -} - -const kDefaultMaxLength = 60; - -export const SetTableNameDialog: React.FC = ({ isOpen, tableName, maxLength, onSetTableName, onClose }) => { - - const [name, setName] = useState(tableName || ""); - - const handleChange = (e: React.FormEvent) => { - setName((e.target as HTMLInputElement).value); - }; - - const handleKeyDown = (e: React.KeyboardEvent) => { - (e.keyCode === 13) && onSetTableName(name); - }; - - const handleOkClick = () => { - onSetTableName(name); - }; - - return ( - - -
Enter a title for the table:
- input?.focus()} - /> -
-
-
- ); -}; diff --git a/src/components/tools/table-tool/table-header-menu.tsx b/src/components/tools/table-tool/table-header-menu.tsx deleted file mode 100644 index 126c04fdb5..0000000000 --- a/src/components/tools/table-tool/table-header-menu.tsx +++ /dev/null @@ -1,380 +0,0 @@ -import React from "react"; -import NewColumnDialog from "./new-column-dialog"; -import RenameColumnDialog from "./rename-column-dialog"; -import { SetTableNameDialog } from "./set-table-name-dialog"; -import { IDataSet } from "../../../models/data/data-set"; -import { GridApi } from "@ag-grid-community/core"; -import { Icon, Menu, Popover, Position, MenuDivider, MenuItem, Alert, Intent } from "@blueprintjs/core"; -import { listenForTableEvents } from "../../../models/tools/table/table-events"; -import UpdateExpressionDialog from "./update-expression-dialog"; - -export interface IMenuItemFlags { - addAttribute?: boolean; - addCase?: boolean; - addRemoveDivider?: boolean; - setTableName?: boolean; - renameAttribute?: boolean; - removeAttribute?: boolean; - removeCases?: boolean; - unlinkGeometry?: boolean; -} - -export interface IProps { - api: GridApi; - expressions?: Map; - rawExpressions?: Map; - dataSet?: IDataSet; - readOnly?: boolean; - itemFlags?: IMenuItemFlags; - onSetTableName: (name: string) => void; - onNewAttribute: (name: string) => void; - onRenameAttribute: (id: string, name: string) => void; - onUpdateExpression: (id: string, expression: string, rawExpression: string) => void; - onNewCase: () => void; - onRemoveAttribute: (id: string) => void; - onRemoveCases: (ids: string[]) => void; - onGetLinkedGeometries: () => string[]; - onUnlinkGeometry: () => void; - onSampleData?: (name: string) => void; -} - -interface IState { - isNewAttributeDialogOpen?: boolean; - isTableNameDialogOpen?: boolean; - tableName?: string; - isRenameAttributeDialogOpen?: boolean; - renameAttributeId?: string; - renameAttributeName?: string; - - isUpdateExpressionDialogOpen?: boolean; - updateExpressionAttributeId?: string; - showInvalidVariableAlert?: boolean; -} - -export class TableHeaderMenu extends React.Component { - - public state: IState = {}; - - constructor(props: IProps) { - super(props); - - listenForTableEvents((event) => { - switch (event.type) { - case "rename-column": - this.setState({ - isRenameAttributeDialogOpen: true, - renameAttributeId: event.id, - renameAttributeName: event.name - }); - break; - case "add-column": - this.setState({ - isNewAttributeDialogOpen: true - }); - break; - default: - break; - } - }); - } - - public buildColumnNameValidator(columnHasExpression: boolean): (name: string) => string | undefined { - return (name: string) => { - if (!name) { - return "Column must have a non-empty name"; - } - // TODO: Expand valid variable names to include additional character sets - if (columnHasExpression && !/^[a-z]+$/i.test(name)) { - return "Columns with expressions must have single-word names"; - } - }; - } - - public render() { - if (this.props.readOnly) return null; - return ( -
- - - - - - {this.renderRenameColumnDialog()} - {this.renderUpdateExpressionDialog()} - {this.renderInvalidVariableAlert()} -
- ); - } - - private renderRenameColumnDialog() { - const { expressions } = this.props; - const nonNullExpression = !!expressions && Array.from(expressions.values()).some(expr => !!expr); - return this.state.isRenameAttributeDialogOpen && this.state.renameAttributeId - ? - : null; - } - - private renderUpdateExpressionDialog() { - const id = this.state.updateExpressionAttributeId; - const { dataSet, expressions, rawExpressions } = this.props; - if (!id || !dataSet || !this.state.isUpdateExpressionDialogOpen) return null; - const xName = dataSet.attributes[0].name; - const yName = dataSet.attrFromID(id).name; - return ; - } - - private openNewAttributeDialog = () => { - this.setState({ isNewAttributeDialogOpen: true }); - } - - private closeNewAttributeDialog = () => { - this.setState({ isNewAttributeDialogOpen: false }); - } - - private closeRenameAttributeDialog = () => { - this.setState({ isRenameAttributeDialogOpen: false }); - } - - private handleRenameAttributeCallback = (id: string, name: string) => { - this.props.onRenameAttribute(id, name); - this.closeRenameAttributeDialog(); - } - - private handleRenameAttribute = (evt: React.MouseEvent, attrID: string, name?: string) => { - this.setState({ - isRenameAttributeDialogOpen: true, - renameAttributeId: attrID, - renameAttributeName: name || "" - }); - } - - private handleSetTableName = () => { - this.setState({ isTableNameDialogOpen: true }); - } - - private handleCloseTableNameDialog = () => { - this.setState({ isTableNameDialogOpen: false }); - } - - private closeUpdateExpressionDialog = () => { - this.setState({ isUpdateExpressionDialogOpen: false }); - } - - private handleUpdateExpressionCallback = (id: string, expression: string, rawExpression: string) => { - this.props.onUpdateExpression(id, expression, rawExpression); - this.closeUpdateExpressionDialog(); - } - - private handleUpdateExpression = (evt: React.MouseEvent) => { - const { dataSet } = this.props; - const xAttr = dataSet && dataSet.attributes[0]; - const yAttr = dataSet && dataSet.attributes[1]; - if (xAttr && yAttr) { - if (this.buildColumnNameValidator(true)(xAttr.name) || this.buildColumnNameValidator(true)(yAttr.name)) { - this.setState({ - showInvalidVariableAlert: true - }); - } else { - this.setState({ - isUpdateExpressionDialogOpen: true, - updateExpressionAttributeId: yAttr.id - }); - } - } - } - - private handleNewCase = () => { - if (this.props.onNewCase) { - this.props.onNewCase(); - } - } - - private handleRemoveAttribute = (evt: React.MouseEvent, attrID: string) => { - if (this.props.onRemoveAttribute) { - this.props.onRemoveAttribute(attrID); - } - } - - private getSelectedRowNodes() { - return this.props.api && this.props.api.getSelectedNodes(); - } - - private getSelectedRowNodeCount() { - const selectedNodes = this.getSelectedRowNodes(); - return selectedNodes ? selectedNodes.length : 0; - } - - private handleRemoveCases = (evt: React.MouseEvent) => { - if (this.props.onRemoveCases) { - const selectedRows = this.getSelectedRowNodes() || []; - this.props.onRemoveCases(selectedRows.map(row => row.id)); - } - } - - private handleUnlinkGeometry = () => { - this.props.onUnlinkGeometry && this.props.onUnlinkGeometry(); - } - - private renderAttributeSubMenuItems(onClick: (evt: React.MouseEvent, - attrID: string, name?: string) => void) { - if (!this.props.dataSet || !this.props.dataSet.attributes.length) { return null; } - return this.props.dataSet.attributes.map((attr) => { - function handleClick(evt: React.MouseEvent) { - return onClick(evt, attr.id, attr.name); - } - return ( - - ); - }); - } - - private renderInvalidVariableAlert() { - const { showInvalidVariableAlert } = this.state; - if (!showInvalidVariableAlert) return; - - return ( - -

- The names of all columns must be a single word to create expressions. -

-
- ); - } - - private handleCloseInvalidVariableAlert = () => { - this.setState({ showInvalidVariableAlert: false }); - } - - private renderMenu() { - const itemFlags = this.props.itemFlags || {}; - const addColumn = itemFlags.addAttribute !== false - ? - : null; - const addRow = itemFlags.addCase !== false - ? - : null; - const addRemoveDivider = itemFlags.addRemoveDivider && ; - const setTableName = itemFlags.setTableName && - ; - const renameColumn = itemFlags.renameAttribute !== false - ? - {this.renderAttributeSubMenuItems(this.handleRenameAttribute)} - - : null; - const updateExpression = itemFlags.renameAttribute !== false - ? - : null; - const removeColumn = itemFlags.removeAttribute !== false - ? - {this.renderAttributeSubMenuItems(this.handleRemoveAttribute)} - - : null; - const removeRows = itemFlags.removeCases !== false - ? - : null; - const linkedGeometryCount = this.props.onGetLinkedGeometries - ? this.props.onGetLinkedGeometries().length - : 0; - const unlinkGeometry = itemFlags.unlinkGeometry !== false - ? - : null; - return ( - - {addColumn} - {addRow} - {addRemoveDivider} - {setTableName} - {renameColumn} - {removeColumn} - {removeRows} - {updateExpression} - {unlinkGeometry} - - ); - } - -} diff --git a/src/components/tools/table-tool/table-tool.sass b/src/components/tools/table-tool/table-tool.sass deleted file mode 100644 index 40bde5b016..0000000000 --- a/src/components/tools/table-tool/table-tool.sass +++ /dev/null @@ -1,22 +0,0 @@ -@import ../../../models/tools/table-links - -.table-tool - height: 100% - -.link-color-0 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-0-light - -.link-color-1 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-1-light - -.link-color-2 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-2-light - -.link-color-3 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-3-light - -.link-color-4 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-4-light - -.link-color-5 > .ag-theme-fresh .ag-row-selected - background-color: $link-color-5-light diff --git a/src/components/tools/table-tool/table-tool.scss b/src/components/tools/table-tool/table-tool.scss new file mode 100644 index 0000000000..82eddf35af --- /dev/null +++ b/src/components/tools/table-tool/table-tool.scss @@ -0,0 +1,294 @@ +@import "../../vars.sass"; +@import "../../../models/tools/table-links"; + +$table-padding: 10px; +$row-height: 34px; +$index-column-width: 34px; +$controls-column-width: 36px; +$platform-scrollbar-width: 16px; +$header-color: $workspace-teal-light-5; +$header-input-color: #eef9fb; +$border-style: 1px solid $charcoal-light-1; +$border-input-style: 1px solid #dadada; +$border-radius: 3px; +$controls-hover-background: #c0dfe7; + +.table-tool { + position: relative; + height: 100%; + padding: $table-padding; + + .table-grid-container { + position: relative; + height: 100%; + + .table-title { + position: absolute; + left: $index-column-width - 1px; + max-width: calc(100% - #{$index-column-width} + #{$table-padding}); + height: $row-height; + color: $charcoal-dark-2; + background-color: $workspace-teal-light-7; + border-left: $border-style; + border-top: $border-style; + border-right: $border-style; + border-radius: $border-radius $border-radius 0 0; + font-weight: bold; + padding: 8px; + + &.table-title-default { + font-style: italic; + } + + &.table-title-editing { + padding: 0; + + input { + text-align: center; + border: solid 1.5px $charcoal-light-1; + + &:focus { + border: solid 2px $highlight-blue; + } + } + } + + .link-geometry-button { + position: absolute; + right: 3.5px; + top: 3px; + width: 26px; + height: 26px; + border-radius: 5px; + border: solid 1.5px $charcoal-light-1; + background-color: $workspace-teal-light-9; + display: flex; + justify-content: center; + align-items: center; + + &.disabled { + opacity: 35%; + } + + &:hover:not(.disabled) { + background-color: $workspace-teal-light-4; + } + + &:active:not(.disabled) { + background-color: $workspace-teal-light-2; + } + } + } + } + + .rdg { + --color: #{$charcoal-dark-2}; + --border-color: #{$charcoal-light-1}; + --header-background-color: #{$header-color}; + --header-selected-background-color: #{$highlight-blue-50}; + --row-selected-background-color: #{$highlight-blue-25}; + --selection-color: #{$highlight-blue}; + + position: absolute; + top: $row-height; + width: calc(var(--row-width) + #{$platform-scrollbar-width}); + max-width: calc(100% + #{$table-padding}); + height: calc(100% - #{$row-height}); + border: none; + overflow: auto !important; + + &.show-expressions { + .index-column-header { + .show-hide-row-labels-button { + top: $row-height; + } + } + } + + .rdg-header-row { + .index-column-header { + min-width: $index-column-width; + padding: 0; + border-left: $border-style; + border-top-left-radius: $border-radius; + .show-hide-row-labels-button { + width: $index-column-width; + height: $row-height; + position: relative; + .hide-row-labels-icon, .show-row-labels-icon { + position: absolute; + left: 4px; + top: 4px; + } + &.shown { + .hide-row-labels-icon { opacity: 35% } + .show-row-labels-icon { opacity: 0% } + } + &.hidden { + .hide-row-labels-icon { opacity: 0% } + .show-row-labels-icon { opacity: 35% } + } + &:hover { + &.shown { + .hide-row-labels-icon { opacity: 0% } + .show-row-labels-icon { opacity: 100% } + } + &.hidden { + .hide-row-labels-icon { opacity: 100% } + .show-row-labels-icon { opacity: 0% } + } + } + } + } + .rdg-cell { + border-top: $border-style; + &.selected-column { + background-color: var(--header-selected-background-color); + } + input { + background-color: inherit; + } + } + .controls-column-header { + background-color: white; + border: none; + padding: 0; + .add-column-button { + width: $controls-column-width; + height: $row-height; + display: none; // overridden when tile is selected + justify-content: center; + align-items: center; + svg { + fill: white; + stroke: $workspace-teal-light-3; + } + &:hover { + svg { + fill: $workspace-teal-light-4; + stroke: $workspace-teal-dark-1; + } + } + &:active { + svg { + fill: $workspace-teal-dark-1; + stroke: white; + } + } + } + } + } + .rdg-row { + &.rdg-row-selected { + background-color: var(--row-selected-background-color); + .index-column { + background-color: var(--header-selected-background-color); + } + .has-expression { + background-color: var(--row-selected-background-color); + } + &.input-row { + .index-column { + background-color: $highlight-blue-50-35; + } + } + } + &.input-row { + .index-column { + background-color: $header-input-color; + border-left: $border-input-style; + } + .rdg-cell { + border-right: $border-input-style; + border-bottom: $border-input-style; + } + .controls-column { + border: none; + } + } + .index-column { + border-left: $border-style; + } + .controls-column { + background-color: white; + border: none; + box-shadow: none; + padding: 0; + .remove-row-button { + width: $controls-column-width; + height: $row-height; + display: none; // overridden when tile is selected + justify-content: center; + align-items: center; + svg { + fill: white; + stroke: $highlight-blue; + } + &:hover { + svg { + fill: $highlight-blue-25; + stroke: $highlight-blue; + } + } + &:active { + svg { + fill: $highlight-blue; + stroke: white; + } + } + } + } + } + .index-column { + width: $index-column-width; + min-width: $index-column-width; + padding: 0; + background-color: var(--header-background-color); + font-weight: bold; + font-style: italic; + .index-cell-contents { + width: 100%; + height: 100%; + } + } + .rdg-cell { + input { + text-align: center; + } + + &.has-expression { + background-color: $charcoal-light-5; + } + &.selected-column { + background-color: var(--row-selected-background-color); + } + } + } +} + +.tool-tile.selected { + .table-tool { + .add-column-button, .remove-row-button { + // show buttons only when tile is selected + display: flex !important; + } + } +} + +// .link-color-0 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-0-light + +// .link-color-1 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-1-light + +// .link-color-2 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-2-light + +// .link-color-3 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-3-light + +// .link-color-4 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-4-light + +// .link-color-5 > .ag-theme-fresh .ag-row-selected +// background-color: $link-color-5-light diff --git a/src/components/tools/table-tool/table-tool.tsx b/src/components/tools/table-tool/table-tool.tsx index 62c182cc00..f9fd3167d1 100644 --- a/src/components/tools/table-tool/table-tool.tsx +++ b/src/components/tools/table-tool/table-tool.tsx @@ -1,446 +1,597 @@ -import React from "react"; -import { observer, inject } from "mobx-react"; -import { Alert, Intent } from "@blueprintjs/core"; -import { BaseComponent } from "../../base"; -import DataTableComponent, { LOCAL_ROW_ID } from "./data-table"; -import { LinkedTableCellEditor } from "./linked-table-cell-editor"; -import { IMenuItemFlags } from "./table-header-menu"; +import { observer } from "mobx-react"; +import React, { useCallback, useEffect, useRef, useState } from "react"; +import ReactDataGrid from "react-data-grid"; +import { getTableContentHeight, TableContentModelType } from "../../../models/tools/table/table-content"; import { IToolTileProps } from "../tool-tile"; -import { GridApi, GridReadyEvent, SelectionChangedEvent, ValueGetterParams, ValueFormatterParams - } from "@ag-grid-community/core"; -import { DataSet, IDataSet, ICase, ICaseCreation } from "../../../models/data/data-set"; -import { getSettingFromStores } from "../../../models/stores/stores"; -import { addTable, getLinkedTableIndex } from "../../../models/tools/table-links"; -import { canonicalizeValue, getRowLabel, isLinkableValue, ILinkProperties, ITableLinkProperties, - TableContentModelType } from "../../../models/tools/table/table-content"; -import { getGeometryContent } from "../../../models/tools/geometry/geometry-content"; -import { JXGCoordPair, JXGProperties, JXGUnsafeCoordPair } from "../../../models/tools/geometry/jxg-changes"; -import { HotKeys } from "../../../utilities/hot-keys"; -import { uniqueId } from "../../../utilities/js-utils"; -import { format } from "d3-format"; -import { each, memoize, sortedIndexOf } from "lodash"; -import { autorun, IReactionDisposer, Lambda } from "mobx"; -type MobXDisposer = IReactionDisposer | Lambda; - -import "./table-tool.sass"; - -const memoizedFormat = memoize(format); - -interface IClipboardCases { - attrs: Array<{ id: string, name: string }>; - cases: ICase[]; -} - -interface IState { - dataSet: IDataSet; - showInvalidPasteAlert?: boolean; -} - -@inject("stores") -@observer -export default class TableToolComponent extends BaseComponent { - - public static tileHandlesSelection = true; - - public state: IState = { - dataSet: DataSet.create() - }; - - private modelId: string; - private domRef: React.RefObject = React.createRef(); - private hotKeys: HotKeys = new HotKeys(); - private syncedChanges: number; - private disposers: MobXDisposer[]; - - private gridApi?: GridApi; - - public componentDidMount() { - this.initializeHotKeys(); - this.syncedChanges = 0; - this.disposers = []; - - this.modelId = this.props.model.id; - addTable(this.props.docId, this.modelId); - - if (this.domRef.current) { - this.domRef.current.addEventListener("mousedown", this.handleMouseDown); - } - - const metadata = this.getContent().metadata; - this.props.onRegisterToolApi({ - isLinked: () => { - return metadata.isLinked; - }, - getLinkIndex: (index?: number) => { - return metadata.isLinked - ? getLinkedTableIndex(this.modelId) - : -1; - } - }); - - const { selection } = this.stores; - this.disposers.push(selection.observe(this.props.model.id, change => { - const rowId = change.name; - const isSharedRowSelected = change.type === "delete" - ? false - : (change.newValue as any).storedValue; - const rowNode = this.gridApi && this.gridApi.getRowNode(rowId); - const isRowNodeSelected = rowNode ? rowNode.isSelected() : false; - if (rowNode && (isSharedRowSelected !== isRowNodeSelected)) { - rowNode.setSelected(isSharedRowSelected, false); - } - })); - - this.disposers.push(autorun(() => { - const { model: { content } } = this.props; - const tableContent = content as TableContentModelType; - if (this.syncedChanges < tableContent.changes.length) { - tableContent.applyChanges(this.state.dataSet, this.syncedChanges); - this.syncedChanges = tableContent.changes.length; - // The state updates in applyChanges aren't picked up by React, so we force a render - this.forceUpdate(); - } - })); - } - - public componentWillUnmount() { - if (this.domRef.current) { - this.domRef.current.removeEventListener("mousedown", this.handleMouseDown); - } - - this.props.onUnregisterToolApi(); - - this.disposers.forEach(disposer => disposer()); - - this.gridApi = undefined; - } - - public render() { - const { model, readOnly } = this.props; - const content = this.getContent(); - const metadata = content.metadata; - const itemFlags: IMenuItemFlags = { - addAttribute: false, - addCase: true, - addRemoveDivider: false, - setTableName: true, - renameAttribute: true, - removeAttribute: false, - removeCases: true, - unlinkGeometry: true - }; - const linkIndex = getLinkedTableIndex(model.id); - const linkClass = metadata.isLinked ? `is-linked link-color-${linkIndex}` : ""; - return ( -
- - {this.renderInvalidPasteAlert()} -
- ); - } - - private renderInvalidPasteAlert() { - return this.state.showInvalidPasteAlert && ( - -

- Linked data must be numeric. Please edit the table values so that all pasted cells contain numbers. -

-
- ); - } - - private handleCloseInvalidPasteAlert = () => { - this.setState({ showInvalidPasteAlert: false }); - } - - private getContent() { - return this.props.model.content as TableContentModelType; - } - - private initializeHotKeys() { - this.hotKeys.register({ - "cmd-c": this.handleCopy, - "cmd-v": this.handlePaste +import { EditableTableTitle } from "./editable-table-title"; +import { TableToolbar } from "./table-toolbar"; +import { useColumnWidths } from "./use-column-widths"; +import { useContentChangeHandlers } from "./use-content-change-handlers"; +import { useDataSet } from "./use-data-set"; +import { useExpressionsDialog } from "./use-expressions-dialog"; +import { useGeometryLinking } from "./use-geometry-linking"; +import { useGridContext } from "./use-grid-context"; +import { useModelDataSet } from "./use-model-data-set"; +import { useRowLabelColumn } from "./use-row-label-column"; +import { useTableTitle } from "./use-table-title"; +import { useToolApi } from "./use-tool-api"; +import { useCurrent } from "../../../hooks/use-current"; +import { useMeasureText } from "../hooks/use-measure-text"; +import { useToolbarToolApi } from "../hooks/use-toolbar-tool-api"; +import { lightenColor } from "../../../utilities/color-utils"; + +import "react-data-grid/dist/react-data-grid.css"; +import "./table-tool.scss"; + +// observes row selection from shared selection store +const TableToolComponent: React.FC = observer(({ + documentId, documentContent, toolTile, model, readOnly, height, scale, + onRequestRowHeight, onRequestTilesOfType, onRequestUniqueTitle, onRegisterToolApi, onUnregisterToolApi +}) => { + const modelRef = useCurrent(model); + const getContent = useCallback(() => modelRef.current.content as TableContentModelType, [modelRef]); + const metadata = getContent().metadata; + + const { + dataSet, columnChanges, triggerColumnChange, rowChanges, triggerRowChange, ...gridModelProps + } = useModelDataSet(model); + + const handleRequestUniqueTitle = useCallback(() => { + return onRequestUniqueTitle(modelRef.current.id); + }, [modelRef, onRequestUniqueTitle]); + + const getContentHeight = useCallback(() => { + return getTableContentHeight({ + readOnly, + dataRows: dataSet.current.cases.length, + hasExpressions: getContent().hasExpressions, + padding: 10 + (modelRef.current.display === "teacher" ? 20 : 0) }); - } - - private handleGridReady = (gridReadyParams: GridReadyEvent) => { - this.gridApi = gridReadyParams.api || undefined; - } - - private handleRowSelectionChange = (e: SelectionChangedEvent) => { - const { selection } = this.stores; - const nodes = e.api.getSelectedNodes(); - selection.setSelected(this.props.model.id, nodes.map(n => n.id)); - } - - private handleMouseDown = (e: MouseEvent) => { - const target: HTMLElement = e.target as HTMLElement; - const targetClasses = target && target.className; - // don't mess with focus if this looks like something ag-grid has handled - if (typeof targetClasses !== "string") return; - if (targetClasses.includes("ag-cell") || targetClasses.includes("ag-header-cell")) { - return; + }, [dataSet, getContent, modelRef, readOnly]); + + const heightRef = useCurrent(height); + const handleRequestRowHeight = useCallback((options: { height?: number, deltaHeight?: number }) => { + // increase row height automatically but require manual shrinking + if (!heightRef.current || + (options?.height && (options.height > heightRef.current)) || + (options?.deltaHeight && (options.deltaHeight > 0))) { + onRequestRowHeight(modelRef.current.id, options?.height, options?.deltaHeight); } - - // table tile should have keyboard focus -- requires tabIndex - this.domRef.current?.focus(); - - // clicking on table background clears selection - this.gridApi?.deselectAll(); - this.gridApi?.refreshCells(); - } - - private handleKeyDown = (e: React.KeyboardEvent) => { - this.hotKeys.dispatch(e); - } - - private handleCopy = () => { - const { dataSet } = this.state; - if (this.gridApi && dataSet) { - const sortedRowIds = this.gridApi.getSelectedNodes().map(row => row.id).sort(); - const rowIds = dataSet.cases.map(aCase => aCase.__id__).filter(id => sortedIndexOf(sortedRowIds, id) >= 0); - if (rowIds && rowIds.length) { - const { clipboard } = this.stores; - const clipData = { - attrs: dataSet.attributes.map(attr => ({ id: attr.id, name: attr.name })), - cases: dataSet.getCanonicalCases(rowIds) - }; - clipboard.clear(); - clipboard.addTileContent(this.props.model.id, this.getContent().type, clipData, this.stores); - } + }, [heightRef, modelRef, onRequestRowHeight]); + + const changeHandlers = useContentChangeHandlers({ + model, dataSet: dataSet.current, + onRequestRowHeight: handleRequestRowHeight, triggerColumnChange, triggerRowChange + }); + const { onSetTableTitle, onSetColumnExpressions, onLinkGeometryTile } = changeHandlers; + + const [showRowLabels, setShowRowLabels] = useState(false); + const { + ref: gridRef, gridContext, inputRowId, selectedCell, getSelectedRows, ...gridProps + } = useGridContext({ modelId: model.id, showRowLabels, triggerColumnChange }); + const measureHeaderText = useMeasureText("bold 14px Lato, sans-serif"); + // const measureBodyText = useMeasureText("14px Lato, sans-serif"); + const { getTitle, onBeginTitleEdit, onEndTitleEdit } = useTableTitle({ + gridContext, dataSet: dataSet.current, readOnly, + onSetTableTitle, onRequestUniqueTitle: handleRequestUniqueTitle + }); + + useToolApi({ metadata, getTitle, getContentHeight, onRegisterToolApi, onUnregisterToolApi }); + + const rowLabelProps = useRowLabelColumn({ + inputRowId: inputRowId.current, selectedCell, showRowLabels, setShowRowLabels + }); + + const handleSubmitExpressions = (expressions: Map) => { + if (dataSet.current.attributes.length && expressions.size) { + onSetColumnExpressions(expressions, dataSet.current.attributes[0].name); } - } - - private handlePaste = () => { - const content = this.getContent(); - const { readOnly } = this.props; - if (!readOnly && this.gridApi) { - const { clipboard } = this.stores; - const clipData: IClipboardCases = clipboard.getTileContent(content.type); - if (clipData && clipData.cases && clipData.cases.length) { - const attrCount = Math.min(this.state.dataSet.attributes.length, clipData.attrs.length); - const attrMap: { [id: string]: string } = {}; - clipData.attrs.forEach((attr, i) => { - if (i < attrCount) { - attrMap[attr.id] = this.state.dataSet.attributes[i].id; - } - }); - let doesTableContainUnlinkableValues = false; - const cases = clipData.cases.map(srcCase => { - const dstCase: ICase = { __id__: uniqueId() }; - each(srcCase, (value, attrID) => { - const dstAttrID = attrMap[attrID]; - if (dstAttrID) { - dstCase[dstAttrID] = value; - if (!isLinkableValue(value)) { - doesTableContainUnlinkableValues = true; - } - } - }); - return dstCase; - }); - if (content.isLinked && doesTableContainUnlinkableValues) { - this.setState({ showInvalidPasteAlert: true }); - } - else { - this.handleAddCanonicalCases(cases); - } - } + }; + const [showExpressionsDialog, , setCurrYAttrId] = useExpressionsDialog({ + metadata, dataSet: dataSet.current, onSubmit: handleSubmitExpressions + }); + + const handleShowExpressionsDialog = (attrId?: string) => { + attrId && setCurrYAttrId(attrId); + showExpressionsDialog(); + }; + const { hasLinkableRows, ...dataGridProps } = useDataSet({ + gridRef, gridContext, model, dataSet: dataSet.current, columnChanges, triggerColumnChange, + rowChanges, readOnly: !!readOnly, changeHandlers, measureText: measureHeaderText, + selectedCell, inputRowId, ...rowLabelProps, onShowExpressionsDialog: handleShowExpressionsDialog }); + + const { showLinkButton, isLinkEnabled, linkIndex, linkColors, showLinkGeometryDialog } = + useGeometryLinking({ documentId, model, hasLinkableRows, onRequestTilesOfType, onLinkGeometryTile }); + + const { titleCellWidth } = + useColumnWidths({ readOnly, getTitle, columns: dataGridProps.columns, measureText: measureHeaderText }); + + const containerRef = useRef(null); + const handleBackgroundClick = (e: React.MouseEvent) => { + // clear any selection on background click + (e.target === containerRef.current) && gridContext.onClearSelection(); + }; + + useEffect(() => { + if (containerRef.current && linkColors) { + // override the CSS variables controlling selection color for linked tables + const dataGrid = containerRef.current.getElementsByClassName("rdg")[0] as HTMLDivElement | undefined; + dataGrid?.style.setProperty("--header-selected-background-color", lightenColor(linkColors.stroke)); + dataGrid?.style.setProperty("--row-selected-background-color", lightenColor(linkColors.fill)); } - } - - private indexValueGetter = (params: ValueGetterParams) => { - const metadata = this.getContent().metadata; - return metadata && metadata.isLinked && (params.data.id !== LOCAL_ROW_ID) - ? getRowLabel(params.node.rowIndex) - : ""; - } - - private attrValueFormatter = (params: ValueFormatterParams) => { - if ((params.value == null) || (params.value === "")) return params.value; - const num = Number(params.value); - if (!isFinite(num)) return params.value; - const kDefaultFormatStr = ".1~f"; // one decimal place, remove trailing zero - const formatStr = getSettingFromStores(this.stores, "numFormat", "table") as string | undefined || - kDefaultFormatStr; - return memoizedFormat(formatStr)(num); - } - - private getGeometryContent(geometryId: string) { - return getGeometryContent(this.getContent(), geometryId); - } - - private getPositionOfPoint(caseId: string): JXGUnsafeCoordPair { - const { dataSet } = this.state; - const attrCount = dataSet.attributes.length; - const xAttr = attrCount > 0 ? dataSet.attributes[0] : undefined; - const yAttr = attrCount > 1 ? dataSet.attributes[1] : undefined; - // convert non-numeric values to 0 - const xValue = xAttr ? dataSet.getValue(caseId, xAttr.id) : 0; - const yValue = yAttr ? dataSet.getValue(caseId, yAttr.id) : 0; - return [canonicalizeValue(xValue), canonicalizeValue(yValue)]; - } - - private getTableActionLinks(): ILinkProperties | undefined { - const linkedGeometries = this.getContent().metadata.linkedGeometries; - if (!linkedGeometries || !linkedGeometries.length) return; - const actionId = uniqueId(); - return { id: actionId, tileIds: [...linkedGeometries] }; - } - - private getGeometryActionLinks(links?: ILinkProperties, addLabelMap = false): ITableLinkProperties | undefined { - if (!links || !links.id) return; - return this.getContent().getClientLinks(links.id, this.state.dataSet, addLabelMap); - } - - private getGeometryActionLinksWithLabels(links?: ILinkProperties) { - return this.getGeometryActionLinks(links, true); - } - - private handleSetTableName = (name: string) => { - // const shouldExpandTable = name && !this.state.dataSet?.name; - this.getContent().setTableName(name); - const kTableNameHeight = 25; - this.props.onRequestRowHeight(this.props.model.id, undefined, kTableNameHeight); - } - - private handleSetAttributeName = (attributeId: string, name: string) => { - const tableActionLinks = this.getTableActionLinks(); - this.getContent().setAttributeName(attributeId, name); - const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); - this.getContent().metadata.linkedGeometries.forEach(id => { - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.updateAxisLabels(undefined, this.props.model.id, geomActionLinks); - } - }); - } - - private handleSetExpression = (attributeId: string, expression: string, rawExpression: string) => { - this.getContent().setExpression(attributeId, expression, rawExpression); - const dataSet = this.state.dataSet; - const tableActionLinks = this.getTableActionLinks(); - const geomActionLinks = this.getGeometryActionLinks(tableActionLinks); - const ids: string[] = []; - const props: JXGProperties[] = []; - dataSet.cases.forEach(aCase => { - const caseId = aCase.__id__; - ids.push(caseId); - const position = this.getPositionOfPoint(caseId) as JXGCoordPair; - props.push({ position }); - }); - this.getContent().metadata.linkedGeometries.forEach(id => { - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.updateObjects(undefined, ids, props, geomActionLinks); - } - }); - } - - private handleAddCanonicalCases = (newCases: ICaseCreation[]) => { - const validateCase = (aCase: ICaseCreation) => { - const newCase: ICaseCreation = { __id__: uniqueId() }; - if (this.getContent().isLinked) { - // validate linkable values - this.state.dataSet.attributes.forEach(attr => { - const value = aCase[attr.id]; - newCase[attr.id] = isLinkableValue(value) ? value : 0; - }); - return newCase; - } - return { ...newCase, ...aCase }; - }; - const cases = newCases.map(aCase => validateCase(aCase)); - const selectedRowIds = this.gridApi && this.gridApi.getSelectedNodes().map(row => row.id); - const firstSelectedRowId = selectedRowIds && selectedRowIds.length && selectedRowIds[0] || undefined; - const tableActionLinks = this.getTableActionLinks(); - this.getContent().addCanonicalCases(cases, firstSelectedRowId, tableActionLinks); - const parents = cases.map(aCase => this.getPositionOfPoint(aCase.__id__ as string)); - const props = cases.map(aCase => ({ id: aCase.__id__ })); - const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); - this.getContent().metadata.linkedGeometries.forEach(id => { - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.addPoints(undefined, parents, props, geomActionLinks); - } - }); - } - - private handleSetCanonicalCaseValues = (caseValues: ICase) => { - const caseId = caseValues.__id__; - const tableActionLinks = this.getTableActionLinks(); - this.getContent().setCanonicalCaseValues([caseValues], tableActionLinks); - const geomActionLinks = this.getGeometryActionLinks(tableActionLinks); - this.getContent().metadata.linkedGeometries.forEach(id => { - const newPosition = this.getPositionOfPoint(caseId); - const position = newPosition as JXGCoordPair; - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.updateObjects(undefined, caseId, { position }, geomActionLinks); - } - }); - } - - private handleRemoveCases = (ids: string[]) => { - const tableActionLinks = this.getTableActionLinks(); - this.getContent().removeCases(ids, tableActionLinks); - const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); - this.getContent().metadata.linkedGeometries.forEach(id => { - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.removeObjects(undefined, ids, geomActionLinks); - } - }); - } - - private handleGetLinkedGeometries = () => { - return this.getContent().metadata.linkedGeometries.toJS(); - } - - private handleUnlinkGeometry = () => { - const geometryIds = this.getContent().metadata.linkedGeometries.toJS(); - const tableActionLinks = this.getTableActionLinks(); - this.getContent().removeGeometryLinks(geometryIds, tableActionLinks); - const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); - geometryIds.forEach(id => { - const geometryContent = this.getGeometryContent(id); - if (geometryContent) { - geometryContent.removeTableLink(undefined, this.props.model.id, geomActionLinks); - } - }); - } -} + }); + + const toolbarProps = useToolbarToolApi({ id: model.id, enabled: !readOnly, onRegisterToolApi, onUnregisterToolApi }); + return ( +
+ +
+ + +
+
+ ); +}); +export default TableToolComponent; +(TableToolComponent as any).tileHandlesSelection = true; + +// import { observer, inject } from "mobx-react"; +// import { Alert, Intent } from "@blueprintjs/core"; +// import { BaseComponent } from "../../base"; +// import DataTableComponent, { LOCAL_ROW_ID } from "./data-table"; +// import { LinkedTableCellEditor } from "./linked-table-cell-editor"; +// import { IMenuItemFlags } from "./table-header-menu"; +// import { IToolTileProps } from "../tool-tile"; +// import { GridApi, GridReadyEvent, SelectionChangedEvent, ValueGetterParams, ValueFormatterParams +// } from "@ag-grid-community/core"; +// import { DataSet, IDataSet, ICase, ICaseCreation } from "../../../models/data/data-set"; +// import { getSettingFromStores } from "../../../models/stores/stores"; +// import { addTable, getLinkedTableIndex } from "../../../models/tools/table-links"; +// import { canonicalizeValue, getRowLabel, isLinkableValue, ILinkProperties, ITableLinkProperties, +// TableContentModelType } from "../../../models/tools/table/table-content"; +// import { getGeometryContent } from "../../../models/tools/geometry/geometry-content"; +// import { JXGCoordPair, JXGProperties, JXGUnsafeCoordPair } from "../../../models/tools/geometry/jxg-changes"; +// import { HotKeys } from "../../../utilities/hot-keys"; +// import { uniqueId } from "../../../utilities/js-utils"; +// import { format } from "d3-format"; +// import { each, memoize, sortedIndexOf } from "lodash"; +// import { autorun, IReactionDisposer, Lambda } from "mobx"; +// type MobXDisposer = IReactionDisposer | Lambda; + +// import "./table-tool.sass"; + +// const memoizedFormat = memoize(format); + +// interface IClipboardCases { +// attrs: Array<{ id: string, name: string }>; +// cases: ICase[]; +// } + +// interface IState { +// dataSet: IDataSet; +// showInvalidPasteAlert?: boolean; [TODO] +// } + +// @inject("stores") +// @observer +// export default class TableToolComponent extends BaseComponent { + +// public static tileHandlesSelection = true; + +// public state: IState = { +// dataSet: DataSet.create() +// }; + +// private modelId: string; +// private domRef: React.RefObject = React.createRef(); +// private hotKeys: HotKeys = new HotKeys(); +// private syncedChanges: number; +// private disposers: MobXDisposer[]; + +// private gridApi?: GridApi; + +// public componentDidMount() { +// this.initializeHotKeys(); [TODO] +// this.syncedChanges = 0; +// this.disposers = []; + +// this.modelId = this.props.model.id; +// addTable(this.props.docId, this.modelId); + +// if (this.domRef.current) { +// this.domRef.current.addEventListener("mousedown", this.handleMouseDown); +// } + +// const metadata = this.getContent().metadata; +// this.props.onRegisterToolApi({ +// isLinked: () => { +// return metadata.isLinked; +// }, +// getLinkIndex: (index?: number) => { +// return metadata.isLinked +// ? getLinkedTableIndex(this.modelId) +// : -1; +// } +// }); + +// const { selection } = this.stores; +// this.disposers.push(selection.observe(this.props.model.id, change => { [TODO] +// const rowId = change.name; +// const isSharedRowSelected = change.type === "delete" +// ? false +// : (change.newValue as any).storedValue; +// const rowNode = this.gridApi && this.gridApi.getRowNode(rowId); +// const isRowNodeSelected = rowNode ? rowNode.isSelected() : false; +// if (rowNode && (isSharedRowSelected !== isRowNodeSelected)) { +// rowNode.setSelected(isSharedRowSelected, false); +// } +// })); + +// this.disposers.push(autorun(() => { +// const { model: { content } } = this.props; +// const tableContent = content as TableContentModelType; +// if (this.syncedChanges < tableContent.changes.length) { +// tableContent.applyChanges(this.state.dataSet, this.syncedChanges); +// this.syncedChanges = tableContent.changes.length; +// // The state updates in applyChanges aren't picked up by React, so we force a render +// this.forceUpdate(); +// } +// })); +// } + +// public componentWillUnmount() { +// if (this.domRef.current) { +// this.domRef.current.removeEventListener("mousedown", this.handleMouseDown); +// } + +// this.props.onUnregisterToolApi(); + +// this.disposers.forEach(disposer => disposer()); + +// this.gridApi = undefined; +// } + +// public render() { +// const { model, readOnly } = this.props; +// const content = this.getContent(); +// const metadata = content.metadata; +// const itemFlags: IMenuItemFlags = { +// addAttribute: false, +// addCase: true, +// addRemoveDivider: false, +// setTableName: true, +// renameAttribute: true, +// removeAttribute: false, +// removeCases: true, +// unlinkGeometry: true +// }; +// const linkIndex = getLinkedTableIndex(model.id); +// const linkClass = metadata.isLinked ? `is-linked link-color-${linkIndex}` : ""; +// return ( +//
+// +// {this.renderInvalidPasteAlert()} +//
+// ); +// } + +// private renderInvalidPasteAlert() { [TODO] +// return this.state.showInvalidPasteAlert && ( +// +//

+// Linked data must be numeric. Please edit the table values so that all pasted cells contain numbers. +//

+//
+// ); +// } + +// private handleCloseInvalidPasteAlert = () => { +// this.setState({ showInvalidPasteAlert: false }); +// } + +// private getContent() { +// return this.props.model.content as TableContentModelType; +// } + +// private initializeHotKeys() { [TODO] +// this.hotKeys.register({ +// "cmd-c": this.handleCopy, +// "cmd-v": this.handlePaste +// }); +// } + +// private handleGridReady = (gridReadyParams: GridReadyEvent) => { +// this.gridApi = gridReadyParams.api || undefined; +// } + +// private handleRowSelectionChange = (e: SelectionChangedEvent) => { [TODO] +// const { selection } = this.stores; +// const nodes = e.api.getSelectedNodes(); +// selection.setSelected(this.props.model.id, nodes.map(n => n.id)); [TODO] sync row selection back to model +// } + +// private handleMouseDown = (e: MouseEvent) => { [TODO] +// const target: HTMLElement = e.target as HTMLElement; +// const targetClasses = target && target.className; +// // don't mess with focus if this looks like something ag-grid has handled +// if (typeof targetClasses !== "string") return; +// if (targetClasses.includes("ag-cell") || targetClasses.includes("ag-header-cell")) { +// return; +// } + +// // table tile should have keyboard focus -- requires tabIndex +// this.domRef.current?.focus(); [TODO?] + +// // clicking on table background clears selection [TODO] +// this.gridApi?.deselectAll(); +// this.gridApi?.refreshCells(); +// } + +// private handleKeyDown = (e: React.KeyboardEvent) => { [TODO] +// this.hotKeys.dispatch(e); +// } + +// private handleCopy = () => { [TODO] +// const { dataSet } = this.state; +// if (this.gridApi && dataSet) { +// const sortedRowIds = this.gridApi.getSelectedNodes().map(row => row.id).sort(); +// const rowIds = dataSet.cases.map(aCase => aCase.__id__).filter(id => sortedIndexOf(sortedRowIds, id) >= 0); +// if (rowIds && rowIds.length) { +// const { clipboard } = this.stores; +// const clipData = { +// attrs: dataSet.attributes.map(attr => ({ id: attr.id, name: attr.name })), +// cases: dataSet.getCanonicalCases(rowIds) +// }; +// clipboard.clear(); +// clipboard.addTileContent(this.props.model.id, this.getContent().type, clipData, this.stores); +// } +// } +// } + +// private handlePaste = () => { [TODO] +// const content = this.getContent(); +// const { readOnly } = this.props; +// if (!readOnly && this.gridApi) { +// const { clipboard } = this.stores; +// const clipData: IClipboardCases = clipboard.getTileContent(content.type); +// if (clipData && clipData.cases && clipData.cases.length) { +// const attrCount = Math.min(this.state.dataSet.attributes.length, clipData.attrs.length); +// const attrMap: { [id: string]: string } = {}; +// clipData.attrs.forEach((attr, i) => { +// if (i < attrCount) { +// attrMap[attr.id] = this.state.dataSet.attributes[i].id; +// } +// }); +// let doesTableContainUnlinkableValues = false; +// const cases = clipData.cases.map(srcCase => { +// const dstCase: ICase = { __id__: uniqueId() }; +// each(srcCase, (value, attrID) => { +// const dstAttrID = attrMap[attrID]; +// if (dstAttrID) { +// dstCase[dstAttrID] = value; +// if (!isLinkableValue(value)) { +// doesTableContainUnlinkableValues = true; +// } +// } +// }); +// return dstCase; +// }); +// if (content.isLinked && doesTableContainUnlinkableValues) { +// this.setState({ showInvalidPasteAlert: true }); +// } +// else { +// this.handleAddCanonicalCases(cases); +// } +// } +// } +// } + +// private indexValueGetter = (params: ValueGetterParams) => { +// const metadata = this.getContent().metadata; +// return metadata && metadata.isLinked && (params.data.id !== LOCAL_ROW_ID) +// ? getRowLabel(params.node.rowIndex) +// : ""; +// } + +// private attrValueFormatter = (params: ValueFormatterParams) => { +// if ((params.value == null) || (params.value === "")) return params.value; +// const num = Number(params.value); +// if (!isFinite(num)) return params.value; +// const kDefaultFormatStr = ".1~f"; // one decimal place, remove trailing zero +// const formatStr = getSettingFromStores(this.stores, "numFormat", "table") as string | undefined || +// kDefaultFormatStr; +// return memoizedFormat(formatStr)(num); +// } + +// private getGeometryContent(geometryId: string) { +// return getGeometryContent(this.getContent(), geometryId); +// } + +// => useContentChangeHandlers [getPositionOfPoint] +// private getPositionOfPoint(caseId: string): JXGUnsafeCoordPair { +// const { dataSet } = this.state; +// const attrCount = dataSet.attributes.length; +// const xAttr = attrCount > 0 ? dataSet.attributes[0] : undefined; +// const yAttr = attrCount > 1 ? dataSet.attributes[1] : undefined; +// // convert non-numeric values to 0 +// const xValue = xAttr ? dataSet.getValue(caseId, xAttr.id) : 0; +// const yValue = yAttr ? dataSet.getValue(caseId, yAttr.id) : 0; +// return [canonicalizeValue(xValue), canonicalizeValue(yValue)]; +// } + +// => useContentChangeHandlers [getTableActionLinks] +// private getTableActionLinks(): ILinkProperties | undefined { +// const linkedGeometries = this.getContent().metadata.linkedGeometries; +// if (!linkedGeometries || !linkedGeometries.length) return; +// const actionId = uniqueId(); +// return { id: actionId, tileIds: [...linkedGeometries] }; +// } + +// => useContentChangeHandlers [getGeometryActionLinks] +// private getGeometryActionLinks(links?: ILinkProperties, addLabelMap = false): ITableLinkProperties | undefined { +// if (!links || !links.id) return; +// return this.getContent().getClientLinks(links.id, this.state.dataSet, addLabelMap); +// } + +// => useContentChangeHandlers [getGeometryActionLinksWithLabels] +// private getGeometryActionLinksWithLabels(links?: ILinkProperties) { +// return this.getGeometryActionLinks(links, true); +// } + +// => useContentChangeHandlers [setTableName] +// private handleSetTableName = (name: string) => { +// // const shouldExpandTable = name && !this.state.dataSet?.name; +// this.getContent().setTableName(name); +// const kTableNameHeight = 25; +// this.props.onRequestRowHeight(this.props.model.id, undefined, kTableNameHeight); +// } + +// => useContentChangeHandlers [setColumnName] +// private handleSetAttributeName = (attributeId: string, name: string) => { +// const tableActionLinks = this.getTableActionLinks(); +// this.getContent().setAttributeName(attributeId, name); +// const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); +// this.getContent().metadata.linkedGeometries.forEach(id => { +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.updateAxisLabels(undefined, this.props.model.id, geomActionLinks); +// } +// }); +// } + +// => useContentChangeHandlers [setColumnExpressions] +// private handleSetExpression = (attributeId: string, expression: string, rawExpression: string) => { +// this.getContent().setExpression(attributeId, expression, rawExpression); +// const dataSet = this.state.dataSet; +// const tableActionLinks = this.getTableActionLinks(); +// const geomActionLinks = this.getGeometryActionLinks(tableActionLinks); +// const ids: string[] = []; +// const props: JXGProperties[] = []; +// dataSet.cases.forEach(aCase => { +// const caseId = aCase.__id__; +// ids.push(caseId); +// const position = this.getPositionOfPoint(caseId) as JXGCoordPair; +// props.push({ position }); +// }); +// this.getContent().metadata.linkedGeometries.forEach(id => { +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.updateObjects(undefined, ids, props, geomActionLinks); +// } +// }); +// } + +// => useContentChangeHandlers [addRows] +// private handleAddCanonicalCases = (newCases: ICaseCreation[]) => { +// const validateCase = (aCase: ICaseCreation) => { +// const newCase: ICaseCreation = { __id__: uniqueId() }; +// if (this.getContent().isLinked) { +// // validate linkable values +// this.state.dataSet.attributes.forEach(attr => { +// const value = aCase[attr.id]; +// newCase[attr.id] = isLinkableValue(value) ? value : 0; +// }); +// return newCase; +// } +// return { ...newCase, ...aCase }; +// }; +// const cases = newCases.map(aCase => validateCase(aCase)); +// const selectedRowIds = this.gridApi && this.gridApi.getSelectedNodes().map(row => row.id); +// const firstSelectedRowId = selectedRowIds && selectedRowIds.length && selectedRowIds[0] || undefined; +// const tableActionLinks = this.getTableActionLinks(); +// this.getContent().addCanonicalCases(cases, firstSelectedRowId, tableActionLinks); +// const parents = cases.map(aCase => this.getPositionOfPoint(aCase.__id__ as string)); +// const props = cases.map(aCase => ({ id: aCase.__id__ })); +// const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); +// this.getContent().metadata.linkedGeometries.forEach(id => { +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.addPoints(undefined, parents, props, geomActionLinks); +// } +// }); +// } + +// => useContentChangeHandlers [updateRow] +// private handleSetCanonicalCaseValues = (caseValues: ICase) => { +// const caseId = caseValues.__id__; +// const tableActionLinks = this.getTableActionLinks(); +// this.getContent().setCanonicalCaseValues([caseValues], tableActionLinks); +// const geomActionLinks = this.getGeometryActionLinks(tableActionLinks); +// this.getContent().metadata.linkedGeometries.forEach(id => { +// const newPosition = this.getPositionOfPoint(caseId); +// const position = newPosition as JXGCoordPair; +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.updateObjects(undefined, caseId, { position }, geomActionLinks); +// } +// }); +// } + +// => useContentChangeHandlers [removeRows] +// private handleRemoveCases = (ids: string[]) => { +// const tableActionLinks = this.getTableActionLinks(); +// this.getContent().removeCases(ids, tableActionLinks); +// const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); +// this.getContent().metadata.linkedGeometries.forEach(id => { +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.removeObjects(undefined, ids, geomActionLinks); +// } +// }); +// } + +// private handleGetLinkedGeometries = () => { [TODO?] +// return this.getContent().metadata.linkedGeometries.toJS(); +// } + +// private handleUnlinkGeometry = () => { [TODO] +// const geometryIds = this.getContent().metadata.linkedGeometries.toJS(); +// const tableActionLinks = this.getTableActionLinks(); +// this.getContent().removeGeometryLinks(geometryIds, tableActionLinks); +// const geomActionLinks = this.getGeometryActionLinksWithLabels(tableActionLinks); +// geometryIds.forEach(id => { +// const geometryContent = this.getGeometryContent(id); +// if (geometryContent) { +// geometryContent.removeTableLink(undefined, this.props.model.id, geomActionLinks); +// } +// }); +// } +// } diff --git a/src/components/tools/table-tool/table-toolbar.scss b/src/components/tools/table-tool/table-toolbar.scss new file mode 100644 index 0000000000..8c7d442833 --- /dev/null +++ b/src/components/tools/table-tool/table-toolbar.scss @@ -0,0 +1,35 @@ +@import "../../vars.sass"; + +.table-toolbar { + position: absolute; + border: $toolbar-border; + border-radius: 0 0 $toolbar-border-radius $toolbar-border-radius; + z-index: $toolbar-z-index; + + &.disabled { + display: none; + } + + .toolbar-button { + position: relative; + width: $toolbar-button-width; + height: $toolbar-button-height; + background-color: $workspace-teal-light-9; + + &:hover { + background-color: $workspace-teal-light-6; + } + + &:active { + background-color: $workspace-teal-light-4; + } + } + + .toolbar-button:first-child { + border-bottom-left-radius: 3px; + } + + .toolbar-button:last-child { + border-bottom-right-radius: 3px; + } +} diff --git a/src/components/tools/table-tool/table-toolbar.tsx b/src/components/tools/table-tool/table-toolbar.tsx new file mode 100644 index 0000000000..fcabd974e5 --- /dev/null +++ b/src/components/tools/table-tool/table-toolbar.tsx @@ -0,0 +1,46 @@ +import { observer } from "mobx-react"; +import React from "react"; +import ReactDOM from "react-dom"; +import { Tooltip } from "react-tippy"; +import SetExpressionIconSvg from "../../../clue/assets/icons/table/set-expression-icon.svg"; +import { useTooltipOptions } from "../../../hooks/use-tooltip-options"; +import { IFloatingToolbarProps, useFloatingToolbarLocation } from "../hooks/use-floating-toolbar-location"; + +import "./table-toolbar.scss"; + +interface ISetExpressionButtonProps { + onClick: () => void; +} +const SetExpressionButton: React.FC = ({ onClick }) => { + const tooltipOptions = useTooltipOptions({ title: "Set expression", distance: -34, offset: -19 }); + return ( + +
+ +
+
+ ); +}; + +interface IProps extends IFloatingToolbarProps { + onSetExpression: () => void; +} +export const TableToolbar: React.FC = observer(({ + documentContent, onIsEnabled, onSetExpression, ...others +}) => { + const enabled = onIsEnabled(); + const location = useFloatingToolbarLocation({ + documentContent, + toolbarHeight: 38, + toolbarTopOffset: 2, + enabled, + ...others + }); + return documentContent + ? ReactDOM.createPortal( +
e.stopPropagation()}> + +
, documentContent) + : null; +}); diff --git a/src/components/tools/table-tool/table-types.ts b/src/components/tools/table-tool/table-types.ts new file mode 100644 index 0000000000..c6460cec5e --- /dev/null +++ b/src/components/tools/table-tool/table-types.ts @@ -0,0 +1,52 @@ +import { Column, FormatterProps, HeaderRendererProps } from "react-data-grid"; + +export const kRowHeight = 34; +export const kIndexColumnWidth = 34; +export const kControlsColumnWidth = 36; +export const kHeaderCellPadding = 72; // half on either side of text +export const kExpressionCellPadding = 20; +export interface IGridContext { + showRowLabels: boolean; + isColumnSelected: (columnId: string) => boolean; + onSelectColumn: (columnId: string) => void; + isSelectedCellInRow: (rowIdx: number) => boolean; + onSelectRowById: (rowId: string, select: boolean) => void; + onSelectOneRow: (row: string) => void; + onClearSelection: (options?: { row?: boolean, column?: boolean, cell?: boolean }) => void; +} + +export const kIndexColumnKey = "__index__"; +export const kControlsColumnKey = "__controls__"; +export interface TRow extends Record { + __id__: string; + __index__?: number; + __context__: IGridContext; +} + +export interface TColumnAppData { + readOnly?: boolean; + gridContext: IGridContext; + editableName: boolean; + isEditing: boolean; + isRemovable: boolean; + showExpressions: boolean; + expression?: string; + onBeginHeaderCellEdit: () => boolean | undefined; + onHeaderCellEditKeyDown: (e: React.KeyboardEvent) => void; + onEndHeaderCellEdit: (value?: string) => void; + onShowExpressionsDialog?: (attrId?: string) => void; + onRemoveColumn?: (attrId: string) => void; + onBeginBodyCellEdit?: () => boolean | undefined; + onEndBodyCellEdit?: (value?: string) => void; +} +export interface TColumn extends Column { + appData?: TColumnAppData; +} +export interface TPosition { idx: number, rowIdx: number } +export type TFormatterProps = FormatterProps; +export type THeaderRendererProps = HeaderRendererProps; +export type OnRowSelectionChangeFn = (checked: boolean, isShiftClick: boolean) => void; + +export const isDataColumn = (column: TColumn) => { + return (column.key !== kIndexColumnKey) && (column.key !== kControlsColumnKey); +}; diff --git a/src/components/tools/table-tool/update-expression-dialog.sass b/src/components/tools/table-tool/update-expression-dialog.sass deleted file mode 100644 index ee94d97a8b..0000000000 --- a/src/components/tools/table-tool/update-expression-dialog.sass +++ /dev/null @@ -1,8 +0,0 @@ -.bp3-dialog.update-expression-dialog - width: 540px - - .nc-dialog-error - height: 56px - - .nc-dialog-buttons - margin: 1em 0 0 0 \ No newline at end of file diff --git a/src/components/tools/table-tool/update-expression-dialog.tsx b/src/components/tools/table-tool/update-expression-dialog.tsx deleted file mode 100644 index 3cffad178a..0000000000 --- a/src/components/tools/table-tool/update-expression-dialog.tsx +++ /dev/null @@ -1,147 +0,0 @@ -import React from "react"; -import { Button, Dialog } from "@blueprintjs/core"; -import { Parser } from "expr-eval"; - -import "./update-expression-dialog.sass"; - -interface IProps { - id: string; - isOpen: boolean; - onUpdateExpression: (id: string, expression: string, rawExpression: string) => void; - onClose: () => void; - expression: string; - rawExpression: string; - xName?: string; - yName?: string; -} - -interface IState { - expression: string; -} - -export const kSerializedXKey = "__x__"; - -export default class UpdateExpressionDialog extends React.Component { - - constructor(props: IProps) { - super(props); - this.state = { - expression: this.props.rawExpression || this.prettifyExpression(this.props.expression) || "" - }; - } - - public render() { - const { xName, yName } = this.props; - const prompt = `Enter an expression for "${yName}" in terms of "${xName}"`; - const errorMessage = this.getValidationError(); - return ( - -
{prompt}:
-
-
{`${yName} =`}
- input && input.focus()} - /> -
-
- {errorMessage} -
-
-
-
- ); - } - - private getValidationError = () => { - const { xName } = this.props; - const expressionStr = this.state.expression; - if (!expressionStr) return; - const parser = new Parser(); - try { - const expression = parser.parse(expressionStr); - const unknownVar = expression.variables().find(variable => variable !== xName); - if (unknownVar) { - return `Unrecognized variable "${unknownVar}" in expression.`; - } - if (xName) { - // Attempt an evaluation to check for errors e.g. invalid function names - expression.evaluate({[xName]: 1}); - } - } catch { - return "Could not understand expression. Make sure you supply all operands " + - "and use a multiplication sign where necessary, e.g. 3 * x + 4 instead of 3x + 4."; - } - } - - private handleExpressionChange = (evt: React.FormEvent) => { - this.setState({ expression: (evt.target as HTMLInputElement).value }); - } - - private handleClearExpression = () => { - if (this.props.onUpdateExpression) { - this.props.onUpdateExpression(this.props.id, "", ""); - } - } - - private handleSubmitExpression = () => { - if (this.props.onUpdateExpression && !this.getValidationError()) { - // Store a canonical version of the expression so it does not need to change on column renames - const canonicalExpression = this.canonicalizeExpression(this.state.expression); - this.props.onUpdateExpression(this.props.id, canonicalExpression, this.state.expression); - } - } - - private handleKeyDown = (evt: React.KeyboardEvent) => { - if (evt.keyCode === 13) { - this.handleSubmitExpression(); - } - } - - private canonicalizeExpression = (displayExpression: string) => { - const { xName } = this.props; - if (xName && displayExpression) { - const parser = new Parser(); - const subbedExpression = parser.parse(displayExpression).substitute(xName, kSerializedXKey); - return subbedExpression.toString(); - } else { - return displayExpression; - } - } - - private prettifyExpression = (canonicalExpression: string) => { - const { xName } = this.props; - if (xName && canonicalExpression) { - const parser = new Parser(); - let expression = parser.parse(canonicalExpression).substitute(kSerializedXKey, xName).toString(); - if (expression.charAt(0) === "(" && expression.charAt(expression.length - 1) === ")") { - expression = expression.substring(1, expression.length - 1); - } - return expression; - } else { - return canonicalExpression; - } - } - -} diff --git a/src/components/tools/table-tool/use-column-extensions.ts b/src/components/tools/table-tool/use-column-extensions.ts new file mode 100644 index 0000000000..cb9fda2cf3 --- /dev/null +++ b/src/components/tools/table-tool/use-column-extensions.ts @@ -0,0 +1,65 @@ +import { TableMetadataModelType } from "../../../models/tools/table/table-content"; +import { getEditableExpression } from "./expression-utils"; +import { IGridContext, isDataColumn, TColumn } from "./table-types"; +import { IContentChangeHandlers } from "./use-content-change-handlers"; + +interface IProps { + gridContext: IGridContext; + metadata: TableMetadataModelType; + readOnly?: boolean; + columns: TColumn[]; + columnEditingName?: string; + setColumnEditingName: (column?: TColumn) => void; + onShowExpressionsDialog?: (attrId?: string) => void; + changeHandlers: IContentChangeHandlers; +} +export const useColumnExtensions = ({ + gridContext, metadata, readOnly, columns, columnEditingName, + setColumnEditingName, onShowExpressionsDialog, changeHandlers +}: IProps) => { + const { onSetColumnName, onRemoveColumn } = changeHandlers; + const firstDataColumn = columns.find(col => isDataColumn(col)); + const xName = (firstDataColumn?.name || "") as string; + + columns.forEach((column, i) => { + column.appData = { + readOnly, + gridContext, + editableName: !readOnly && isDataColumn(column), + isEditing: column.key === columnEditingName, + isRemovable: !readOnly && isDataColumn(column) && (column.key !== firstDataColumn?.key), + showExpressions: metadata.hasExpressions, + expression: getEditableExpression( + metadata.rawExpressions.get(column.key), + metadata.expressions.get(column.key) || "", + xName), + onBeginHeaderCellEdit: (() => { + gridContext.onClearSelection(); + !readOnly && setColumnEditingName(column); + }) as any, + onHeaderCellEditKeyDown: (e: React.KeyboardEvent) => { + switch (e.key) { + case "Tab": { + const nextColumnToEdit = !e.shiftKey + ? (i < columns.length - 1 ? columns[i + 1] : undefined) + : (i > 1 ? columns[i - 1] : undefined); + !readOnly && nextColumnToEdit && + setTimeout(() => setColumnEditingName(nextColumnToEdit)); + break; + } + case "Enter": + break; + } + }, + onEndHeaderCellEdit: (value?: string) => { + !readOnly && !!value && (value !== column.name) && onSetColumnName(column, value); + setColumnEditingName(); + }, + onRemoveColumn, + onShowExpressionsDialog, + onBeginBodyCellEdit: (() => { + gridContext.onClearSelection({ cell: false }); + }) as any + }; + }); +}; diff --git a/src/components/tools/table-tool/use-column-widths.ts b/src/components/tools/table-tool/use-column-widths.ts new file mode 100644 index 0000000000..8d06a7b080 --- /dev/null +++ b/src/components/tools/table-tool/use-column-widths.ts @@ -0,0 +1,36 @@ +import { isDataColumn, kControlsColumnWidth, kHeaderCellPadding, TColumn } from "./table-types"; + +interface IProps { + readOnly?: boolean; + getTitle: () => string | undefined; + columns: TColumn[]; + measureText: (text: string) => number; +} +export const useColumnWidths = ({ readOnly, getTitle, columns, measureText }: IProps) => { + + const desiredTitleCellWidth = measureText(getTitle() || "Table 8") + kHeaderCellPadding; + + const kDefaultWidth = 80; + const columnWidth = (column: TColumn) => { + return Math.max(+(column.width || kDefaultWidth), column.maxWidth || kDefaultWidth); + }; + const getTitleCellWidthFromColumns = () => { + return columns.reduce( + (sum, col, i) => sum + (i ? columnWidth(col) : 0), + 1 - (readOnly ? 0 : kControlsColumnWidth)); + }; + + const titleCellWidthFromColumns = getTitleCellWidthFromColumns(); + let titleCellWidth = titleCellWidthFromColumns; + // if necessary, increase width of columns to accommodate longer titles + if (desiredTitleCellWidth > titleCellWidthFromColumns) { + // distribute the additional width equally among the data columns + const dataColumnCount = columns.reduce((count, col) => count + (isDataColumn(col) ? 1 : 0), 0); + const widthAdjustment = (desiredTitleCellWidth - titleCellWidthFromColumns) / dataColumnCount; + const roundedWidthAdjustment = Math.ceil(10 * widthAdjustment) / 10; + columns.forEach((col, i) => isDataColumn(col) && (col.width = columnWidth(col) + roundedWidthAdjustment)); + titleCellWidth = getTitleCellWidthFromColumns(); + } + + return { columns, titleCellWidth }; +}; diff --git a/src/components/tools/table-tool/use-columns-from-data-set.ts b/src/components/tools/table-tool/use-columns-from-data-set.ts new file mode 100644 index 0000000000..6a3e430b1e --- /dev/null +++ b/src/components/tools/table-tool/use-columns-from-data-set.ts @@ -0,0 +1,129 @@ +import classNames from "classnames"; +import { useCallback, useMemo, useRef, useState } from "react"; +import { IAttribute } from "../../../models/data/attribute"; +import { IDataSet } from "../../../models/data/data-set"; +import { TableMetadataModelType } from "../../../models/tools/table/table-content"; +import { CellFormatter } from "./cell-formatter"; +import CellTextEditor from "./cell-text-editor"; +import { ColumnHeaderCell } from "./column-header-cell"; +import { prettifyExpression } from "./expression-utils"; +import { + IGridContext, kControlsColumnKey, kControlsColumnWidth, kExpressionCellPadding, kHeaderCellPadding, + kIndexColumnKey, kIndexColumnWidth, TColumn +} from "./table-types"; +import { useColumnExtensions } from "./use-column-extensions"; +import { IContentChangeHandlers } from "./use-content-change-handlers"; +import { useControlsColumn } from "./use-controls-column"; + +interface IUseColumnsFromDataSet { + gridContext: IGridContext; + dataSet: IDataSet; + metadata: TableMetadataModelType; + readOnly?: boolean; + columnChanges: number; + RowLabelHeader: React.FC; + RowLabelFormatter: React.FC; + measureText: (text: string) => number; + onShowExpressionsDialog?: (attrId?: string) => void; + changeHandlers: IContentChangeHandlers; +} +export const useColumnsFromDataSet = ({ + gridContext, dataSet, metadata, readOnly, columnChanges, RowLabelHeader, RowLabelFormatter, + measureText, onShowExpressionsDialog, changeHandlers +}: IUseColumnsFromDataSet) => { + const { attributes } = dataSet; + const { onAddColumn, onRemoveRows } = changeHandlers; + const onRemoveRow = useCallback((rowId: string) => onRemoveRows([rowId]), [onRemoveRows]); + const { ControlsHeaderRenderer, ControlsRowFormatter } = useControlsColumn({ readOnly, onAddColumn, onRemoveRow }); + // user-modified column widths aren't currently saved + const userColumnWidths = useRef>({}); + const nameColumnWidths = useRef>({}); + const exprColumnWidths = useRef>({}); + + const [columnEditingName, setColumnEditingName] = useState(); + const handleSetColumnEditingName = (column?: TColumn) => { + setColumnEditingName(column?.key); + }; + + const cellClasses = useCallback((attrId: string) => { + const selectedColumnClass = { "selected-column": gridContext.isColumnSelected(attrId) }; + return { + cellClass: classNames({ "has-expression": metadata.hasExpression(attrId), ...selectedColumnClass }), + headerCellClass: classNames({ "rdg-cell-editing": columnEditingName === attrId, ...selectedColumnClass }) + }; + }, [columnEditingName, gridContext, metadata]); + + const measureColumnWidth = useCallback((attr: IAttribute) => { + const nameCellWidth = measureText(attr.name) + kHeaderCellPadding; + const xName = dataSet.attributes[0]?.name || "x"; + const expr = metadata.rawExpressions.get(attr.id) || + prettifyExpression(metadata.expressions.get(attr.id) || "", xName); + const exprCellWidth = (expr ? measureText(`= ${expr}`) : 0) + kExpressionCellPadding; + if ((nameCellWidth !== nameColumnWidths.current[attr.id]) || + (exprCellWidth !== exprColumnWidths.current[attr.id])) { + // autoWidth changes (e.g. name or formula changes), supercede user-set width + delete userColumnWidths.current[attr.id]; + nameColumnWidths.current[attr.id] = nameCellWidth; + exprColumnWidths.current[attr.id] = exprCellWidth; + } + return userColumnWidths.current[attr.id] || Math.max(nameCellWidth, exprCellWidth); + }, [dataSet.attributes, measureText, metadata.expressions, metadata.rawExpressions]); + + const columns = useMemo(() => { + const cols: TColumn[] = attributes.map(attr => ({ + ...cellClasses(attr.id), + name: attr.name, + key: attr.id, + width: measureColumnWidth(attr), + resizable: true, + headerRenderer: ColumnHeaderCell, + formatter: CellFormatter, + editor: !readOnly && !metadata.hasExpression(attr.id) ? CellTextEditor : undefined, + editorOptions: { + editOnClick: !readOnly + } + })); + cols.unshift({ + cellClass: "index-column", + headerCellClass: "index-column-header", + name: "Index", + key: kIndexColumnKey, + width: kIndexColumnWidth, + maxWidth: kIndexColumnWidth, + resizable: false, + editable: false, + frozen: true, + headerRenderer: RowLabelHeader, + formatter: RowLabelFormatter + }); + if (!readOnly) { + cols.push({ + cellClass: "controls-column", + headerCellClass: "controls-column-header", + name: "Controls", + key: kControlsColumnKey, + width: kControlsColumnWidth, + maxWidth: kControlsColumnWidth, + resizable: false, + editable: false, + frozen: false, + headerRenderer: ControlsHeaderRenderer, + formatter: ControlsRowFormatter + }); + } + columnChanges; // eslint-disable-line no-unused-expressions + return cols; + }, [attributes, RowLabelHeader, RowLabelFormatter, readOnly, columnChanges, + cellClasses, measureColumnWidth, metadata, ControlsHeaderRenderer, ControlsRowFormatter]); + + useColumnExtensions({ + gridContext, metadata, readOnly, columns, columnEditingName, changeHandlers, + setColumnEditingName: handleSetColumnEditingName, onShowExpressionsDialog + }); + + const onColumnResize = useCallback((idx: number, width: number) => { + userColumnWidths.current[columns[idx].key] = width; + }, [columns]); + + return { columns, onColumnResize }; +}; diff --git a/src/components/tools/table-tool/use-content-change-handlers.ts b/src/components/tools/table-tool/use-content-change-handlers.ts new file mode 100644 index 0000000000..7d93dca6e7 --- /dev/null +++ b/src/components/tools/table-tool/use-content-change-handlers.ts @@ -0,0 +1,175 @@ +import { useCallback } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { ICase, ICaseCreation, IDataSet } from "../../../models/data/data-set"; +import { getGeometryContent } from "../../../models/tools/geometry/geometry-content"; +import { + getTableContentHeight, ILinkProperties, ITableChange, TableContentModelType +} from "../../../models/tools/table/table-content"; +import { isLinkableValue, ITileLinkMetadata } from "../../../models/tools/table/table-model-types"; +import { ToolTileModelType } from "../../../models/tools/tool-tile"; +import { safeJsonParse, uniqueId, uniqueName } from "../../../utilities/js-utils"; +import { TColumn } from "./table-types"; + +export interface IContentChangeHandlers { + onSetTableTitle: (title: string) => void; + onSetColumnName: (column: TColumn, columnName: string) => void; + onSetColumnExpressions: (rawExpressions: Map, xName: string) => void; + onAddColumn: () => void; + onRemoveColumn: (colId: string) => void; + onAddRows: (newCases: ICaseCreation[]) => void; + onUpdateRow: (caseValues: ICase) => void; + onRemoveRows: (rowIds: string[]) => void; + onLinkGeometryTile: (geomTileInfo: ITileLinkMetadata) => void; + onUnlinkGeometryTiles: () => void; +} + +interface IProps { + model: ToolTileModelType; + dataSet: IDataSet; + readOnly?: boolean; + onRequestRowHeight: (options: { height?: number, deltaHeight?: number }) => void; + triggerColumnChange: () => void; + triggerRowChange: () => void; +} +export const useContentChangeHandlers = ({ + model, dataSet, readOnly, onRequestRowHeight, triggerColumnChange +}: IProps): IContentChangeHandlers => { + const modelRef = useCurrent(model); + const getContent = useCallback(() => modelRef.current.content as TableContentModelType, [modelRef]); + + /* + * helper functions + */ + // link information attached to individual table changes/actions + const getTableActionLinks = useCallback((newClientId?: string): ILinkProperties | undefined => { + const linkedClients = getContent().metadata.linkedGeometries; + // if there are no linked clients, then we don't need to attach link info to the action + if (!linkedClients?.length && !newClientId) return; + // id is used to link actions across tiles + const actionId = uniqueId(); + const newClientIds = newClientId ? [newClientId] : []; + return { id: actionId, tileIds: [...linkedClients, ...newClientIds] }; + }, [getContent]); + + const syncChangeToLinkedClient = useCallback((clientTileId: string, linkId: string) => { + const tableContent = getContent(); + const lastChange: ITableChange | undefined = safeJsonParse(tableContent.changes[tableContent.changes.length - 1]); + // eventually we'll presumably need to support other clients + const clientContent = getGeometryContent(getContent(), clientTileId); + // link information attached to individual client changes/actions + const clientActionLinks = getContent().getClientLinks(linkId, dataSet); + // synchronize the table change to the linked client + lastChange && clientContent?.syncLinkedChange(dataSet, lastChange, clientActionLinks); + }, [dataSet, getContent]); + + const syncLinkedClients = useCallback((tableActionLinks?: ILinkProperties) => { + tableActionLinks?.tileIds.forEach(tileId => { + syncChangeToLinkedClient(tileId, tableActionLinks.id); + }); + }, [syncChangeToLinkedClient]); + + const validateCase = useCallback((aCase: ICaseCreation) => { + const newCase: ICaseCreation = { __id__: uniqueId() }; + if (getContent().isLinked) { + // validate linkable values + dataSet.attributes.forEach(attr => { + const value = aCase[attr.id]; + newCase[attr.id] = isLinkableValue(value) ? value : 0; + }); + return newCase; + } + return { ...newCase, ...aCase }; + }, [dataSet.attributes, getContent]); + + const requestRowHeight = useCallback(() => { + const height = getTableContentHeight({ + dataRows: dataSet.cases.length, readOnly, hasExpressions: getContent().hasExpressions + }); + onRequestRowHeight({ height }); + }, [dataSet.cases.length, getContent, onRequestRowHeight, readOnly]); + + /* + * content change functions + */ + const setTableTitle = useCallback((title: string) => { + if (readOnly) return; + (title != null) && getContent().setTableName(title); + triggerColumnChange(); + }, [getContent, readOnly, triggerColumnChange]); + + const setColumnName = useCallback((column: TColumn, columnName: string) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + getContent().setAttributeName(column.key, columnName, tableActionLinks); + syncLinkedClients(tableActionLinks); + }, [readOnly, getTableActionLinks, getContent, syncLinkedClients]); + + const setColumnExpressions = useCallback((rawExpressions: Map, xName: string) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + getContent().setExpressions(rawExpressions, xName, tableActionLinks); + requestRowHeight(); + syncLinkedClients(tableActionLinks); + }, [readOnly, getTableActionLinks, getContent, requestRowHeight, syncLinkedClients]); + + const addColumn = useCallback(() => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + const attrId = uniqueId(); + const attrName = uniqueName("y", (name: string) => !dataSet.attrFromName(name)); + getContent().addAttribute(attrId, attrName, tableActionLinks); + syncLinkedClients(tableActionLinks); + }, [dataSet, getContent, getTableActionLinks, readOnly, syncLinkedClients]); + + const removeColumn = useCallback((colId: string) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + getContent().removeAttributes([colId], tableActionLinks); + syncLinkedClients(tableActionLinks); + }, [getContent, getTableActionLinks, readOnly, syncLinkedClients]); + + const addRows = useCallback((newCases: ICaseCreation[]) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + const cases = newCases.map(aCase => validateCase(aCase)); + getContent().addCanonicalCases(cases, undefined, tableActionLinks); + requestRowHeight(); + syncLinkedClients(tableActionLinks); + }, [readOnly, getTableActionLinks, getContent, requestRowHeight, syncLinkedClients, validateCase]); + + const updateRow = useCallback((caseValues: ICase) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + getContent().setCanonicalCaseValues([caseValues], tableActionLinks); + syncLinkedClients(tableActionLinks); + }, [readOnly, getTableActionLinks, getContent, syncLinkedClients]); + + const removeRows = useCallback((rowIds: string[]) => { + if (readOnly) return; + const tableActionLinks = getTableActionLinks(); + getContent().removeCases(rowIds, tableActionLinks); + syncLinkedClients(tableActionLinks); + }, [readOnly, getTableActionLinks, getContent, syncLinkedClients]); + + const linkGeometryTile = useCallback((geomTileInfo: ITileLinkMetadata) => { + if (!getContent().isValidForGeometryLink()) return; + + // add action to table content + const tableActionLinks = getTableActionLinks(geomTileInfo.id); + if (!tableActionLinks) return; + getContent().addGeometryLink(geomTileInfo.id, tableActionLinks); + // sync change to the newly linked client - not all linked clients + syncChangeToLinkedClient(geomTileInfo.id, tableActionLinks.id); + }, [getContent, getTableActionLinks, syncChangeToLinkedClient]); + + const unlinkGeometryTiles = useCallback(() => { + const geometryIds = getContent().metadata.linkedGeometries.toJS(); + const tableActionLinks = getTableActionLinks(); + getContent().removeGeometryLinks(geometryIds, tableActionLinks); + }, [getContent, getTableActionLinks]); + + return { onSetTableTitle: setTableTitle, onSetColumnName: setColumnName, onSetColumnExpressions: setColumnExpressions, + onAddColumn: addColumn, onRemoveColumn: removeColumn, + onAddRows: addRows, onUpdateRow: updateRow, onRemoveRows: removeRows, + onLinkGeometryTile: linkGeometryTile, onUnlinkGeometryTiles: unlinkGeometryTiles }; +}; diff --git a/src/components/tools/table-tool/use-controls-column.tsx b/src/components/tools/table-tool/use-controls-column.tsx new file mode 100644 index 0000000000..a844d54f81 --- /dev/null +++ b/src/components/tools/table-tool/use-controls-column.tsx @@ -0,0 +1,62 @@ +import React, { useCallback } from "react"; +import { Tooltip } from "react-tippy"; +import AddColumnSvg from "../../../assets/icons/add/add.nosvgo.svg"; +import RemoveRowSvg from "../../../assets/icons/remove/remove.nosvgo.svg"; +import { useTooltipOptions } from "../../../hooks/use-tooltip-options"; +import { TFormatterProps } from "./table-types"; + +interface IUseControlsColumn { + readOnly?: boolean; + onAddColumn?: () => void; + onRemoveRow?: (rowId: string) => void; +} +export const useControlsColumn = ({ readOnly, onAddColumn, onRemoveRow }: IUseControlsColumn) => { + + const kTooltipDistance = -35; // required to get tooltip to line up just below the cell + const addColumnTooltipOptions = useTooltipOptions({ title: "Add column", distance: kTooltipDistance }); + const ControlsHeaderRenderer: React.FC = useCallback(() => { + return !readOnly + ? + + + : null; + }, [addColumnTooltipOptions, onAddColumn, readOnly]); + + const removeRowTooltipOptions = useTooltipOptions({ title: "Remove row", distance: kTooltipDistance }); + const ControlsRowFormatter: React.FC = useCallback(({ rowIdx, row, isRowSelected }) => { + const showRemoveButton = !readOnly && (isRowSelected || row.__context__.isSelectedCellInRow(rowIdx)); + return showRemoveButton + ? + + + : null; + }, [onRemoveRow, readOnly, removeRowTooltipOptions]); + ControlsRowFormatter.displayName = "ControlsRowFormatter"; + + return { ControlsHeaderRenderer, ControlsRowFormatter }; +}; + +interface IAddColumnButtonProps { + onAddColumn?: () => void; +} +const AddColumnButton: React.FC = ({ onAddColumn }) => { + return ( +
onAddColumn?.()}> + +
+ ); +}; +AddColumnButton.displayName = "AddColumnButton"; + +interface IRemoveRowButtonProps { + rowId: string; + onRemoveRow?: (rowId: string) => void; +} +const RemoveRowButton: React.FC = ({ rowId, onRemoveRow }) => { + return ( +
onRemoveRow?.(rowId)}> + +
+ ); +}; +RemoveRowButton.displayName = "RemoveRowButton"; diff --git a/src/components/tools/table-tool/use-data-set.ts b/src/components/tools/table-tool/use-data-set.ts new file mode 100644 index 0000000000..9346e7a9ac --- /dev/null +++ b/src/components/tools/table-tool/use-data-set.ts @@ -0,0 +1,128 @@ +import { useCallback } from "react"; +import { DataGridHandle } from "react-data-grid"; +import { useCurrent } from "../../../hooks/use-current"; +import { ICase, IDataSet } from "../../../models/data/data-set"; +import { TableContentModelType } from "../../../models/tools/table/table-content"; +import { ToolTileModelType } from "../../../models/tools/tool-tile"; +import { uniqueId } from "../../../utilities/js-utils"; +import { formatValue } from "./cell-formatter"; +import { IGridContext, TColumn, TPosition, TRow } from "./table-types"; +import { useColumnsFromDataSet } from "./use-columns-from-data-set"; +import { IContentChangeHandlers } from "./use-content-change-handlers"; +import { useNumberFormat } from "./use-number-format"; +import { useRowsFromDataSet } from "./use-rows-from-data-set"; + +const isCellSelectable = (position: TPosition, columns: TColumn[]) => { + return (position.idx !== 0) && (position.idx !== columns.length - 1); +}; + +interface IUseDataSet { + gridRef: React.RefObject; + gridContext: IGridContext; + model: ToolTileModelType; + dataSet: IDataSet; + columnChanges: number; + triggerColumnChange: () => void; + rowChanges: number; + readOnly: boolean; + inputRowId: React.MutableRefObject; + selectedCell: React.MutableRefObject; + RowLabelHeader: React.FC; + RowLabelFormatter: React.FC; + changeHandlers: IContentChangeHandlers; + measureText: (text: string) => number; + onShowExpressionsDialog?: (attrId?: string) => void; +} +export const useDataSet = ({ + gridRef, gridContext, model, dataSet, columnChanges, triggerColumnChange, rowChanges, readOnly, inputRowId, + selectedCell, RowLabelHeader, RowLabelFormatter, changeHandlers, measureText, onShowExpressionsDialog +}: IUseDataSet) => { + const { onAddRows, onUpdateRow } = changeHandlers; + const modelRef = useCurrent(model); + const getContent = useCallback(() => modelRef.current.content as TableContentModelType, [modelRef]); + const metadata = getContent().metadata; + const { columns, onColumnResize } = useColumnsFromDataSet({ + gridContext, dataSet, metadata, readOnly, columnChanges, RowLabelHeader, RowLabelFormatter, + measureText, onShowExpressionsDialog, changeHandlers }); + const onSelectedCellChange = (position: TPosition) => { + const forward = (selectedCell.current.rowIdx < position.rowIdx) || + ((selectedCell.current.rowIdx === position.rowIdx) && + (selectedCell.current.idx < position.idx)); + selectedCell.current = position; + + if (!isCellSelectable(position, columns) && (columns.length > 2)) { + let newPosition = { ...position }; + if (forward) { + while (!isCellSelectable(newPosition, columns)) { + // move from last cell to { -1, -1 } + if ((newPosition.rowIdx >= rows.length) || + ((newPosition.rowIdx === rows.length - 1) && (newPosition.idx >= columns.length - 1))) { + newPosition = { rowIdx: -1, idx: -1 }; + } + // otherwise advance to next selectable cell + else if (++newPosition.idx >= columns.length) { + newPosition.idx = 1; + ++newPosition.rowIdx; + } + } + } + else { // backward + while (!isCellSelectable(newPosition, columns)) { + // move from first cell to { -1, -1 } + if ((newPosition.rowIdx <= -1) || ((newPosition.rowIdx === 0) && (newPosition.idx < 1))) { + newPosition = { rowIdx: -1, idx: -1 }; + } + // otherwise move to previous selectable cell + else if (--newPosition.idx < 1) { + newPosition.idx = columns.length - 2; + --newPosition.rowIdx; + } + } + } + if ((newPosition.rowIdx !== position.rowIdx) || (newPosition.idx !== position.idx)) { + gridRef.current?.selectCell(newPosition); + } + } + }; + + const hasLinkableRows = getContent().hasLinkableCases(dataSet); + + const { rows, rowKeyGetter, rowClass } = useRowsFromDataSet({ + dataSet, readOnly, inputRowId: inputRowId.current, + rowChanges, context: gridContext}); + const formatter = useNumberFormat(); + const onRowsChange = (_rows: TRow[]) => { + // for now, assume that all changes are single cell edits + const selectedCellRowIndex = selectedCell.current?.rowIdx; + const selectedCellColIndex = selectedCell.current?.idx; + const updatedRow = (selectedCellRowIndex != null) && (selectedCellRowIndex >= 0) + ? _rows[selectedCellRowIndex] : undefined; + const updatedColumn = (selectedCellColIndex != null) && (selectedCellColIndex >= 0) + ? columns[selectedCellColIndex] : undefined; + if (!readOnly && updatedRow && updatedColumn) { + const originalValue = dataSet.getValue(updatedRow.__id__, updatedColumn.key); + const originalStrValue = formatValue(formatter, originalValue); + // only make a change if the value has actually changed + if (updatedRow[updatedColumn.key] !== originalStrValue) { + const updatedCaseValues: ICase = { + __id__: updatedRow.__id__, + [updatedColumn.key]: updatedRow[updatedColumn.key] + }; + const inputRowIndex = _rows.findIndex(row => row.__id__ === inputRowId.current); + if ((inputRowIndex >= 0) && (selectedCellRowIndex === inputRowIndex)) { + onAddRows([updatedCaseValues]); + inputRowId.current = uniqueId(); + } + else { + onUpdateRow(updatedCaseValues); + } + } + } + }; + const handleColumnResize = useCallback((idx: number, width: number) => { + onColumnResize(idx, width); + triggerColumnChange(); + }, [onColumnResize, triggerColumnChange]); + return { hasLinkableRows, columns, rows, rowKeyGetter, rowClass, + onColumnResize: handleColumnResize, onRowsChange, onSelectedCellChange}; +}; diff --git a/src/components/tools/table-tool/use-editable-expressions.ts b/src/components/tools/table-tool/use-editable-expressions.ts new file mode 100644 index 0000000000..7cd738b0cd --- /dev/null +++ b/src/components/tools/table-tool/use-editable-expressions.ts @@ -0,0 +1,18 @@ +import { useLayoutEffect, useRef } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { TableMetadataModelType } from "../../../models/tools/table/table-content"; +import { getEditableExpression } from "./expression-utils"; + +export const useEditableExpressions = (metadata: TableMetadataModelType, xName: string) => { + const metadataRef = useCurrent(metadata); + const editExpressions = useRef>(new Map()); + useLayoutEffect(() => { + const rawExpressions = metadataRef.current.rawExpressions; + const canonicalExpressions = metadataRef.current.expressions; + canonicalExpressions.forEach((canonical, attrId) => { + const editExpr = getEditableExpression(rawExpressions.get(attrId), canonical, xName); + editExpr && editExpressions.current?.set(attrId, editExpr); + }); + }, [metadataRef, xName]); + return editExpressions; +}; diff --git a/src/components/tools/table-tool/use-expressions-dialog.tsx b/src/components/tools/table-tool/use-expressions-dialog.tsx new file mode 100644 index 0000000000..837ccd5a2e --- /dev/null +++ b/src/components/tools/table-tool/use-expressions-dialog.tsx @@ -0,0 +1,146 @@ +import React, { useCallback, useLayoutEffect, useRef, useState } from "react"; +import SetExpressionIconSvg from "../../../clue/assets/icons/table/set-expression-icon.svg"; +import { useCurrent } from "../../../hooks/use-current"; +import { kLeaveModalOpen, useCustomModal } from "../../../hooks/use-custom-modal"; +import { IDataSet } from "../../../models/data/data-set"; +import { TableMetadataModelType } from "../../../models/tools/table/table-content"; +import { validateExpression } from "./expression-utils"; +import { useEditableExpressions } from "./use-editable-expressions"; + +import "./expressions-dialog.scss"; + +interface IProps { + metadata: TableMetadataModelType; + dataSet: IDataSet; + onSubmit: (changedExpressions: Map) => void; +} +type IResult = [() => void, () => void, React.Dispatch>]; +export const useExpressionsDialog = ({ metadata, dataSet, onSubmit }: IProps): IResult => { + const metadataRef = useCurrent(metadata); + const xName = useCurrent(dataSet.attributes.length > 0 + ? dataSet.attributes[0].name + : "x"); + const [currYAttrId, setCurrYAttrId] = useState(); + // map of attribute ids to current editable expressions + const expressions = useEditableExpressions(metadata, xName.current); + // the currently edited expression (controlled input) + const [currentExpression, setCurrentExpression] = useState(""); + const [errorMessage, setErrorMessage] = useState(""); + const updateCurrentExpression = useCallback((expr: string) => { + setCurrentExpression(expr); + setErrorMessage(validateExpression(expr, xName.current) || ""); + }, [xName]); + const acceptExpression = useCallback((yAttrId: string, expr: string) => { + expressions.current.set(yAttrId, expr); + }, [expressions]); + const contentProps: IContentProps = { + dataSet, xName: xName.current, currYAttrId, setCurrYAttrId, + expressions, currentExpression, errorMessage, updateCurrentExpression, acceptExpression + }; + + const blurModalRef = useRef<() => void>(); + + const handleClear = useCallback(() => { + blurModalRef.current?.(); + updateCurrentExpression(""); + currYAttrId && acceptExpression(currYAttrId, ""); + return kLeaveModalOpen; + }, [acceptExpression, currYAttrId, updateCurrentExpression]); + + const handleSubmit = useCallback(() => { + blurModalRef.current?.(); + const rawExpressions = metadataRef.current.rawExpressions; + const changedExpressions: Map = new Map(); + expressions.current.forEach((expr, id) => { + if ((expr != null) && (expr !== rawExpressions.get(id))) { + changedExpressions.set(id, expr); + } + }); + onSubmit(changedExpressions); + }, [expressions, metadataRef, onSubmit]); + + const [showModal, hideModal, blurModal] = useCustomModal({ + className: "set-expression", + title: "Set Expression", + Icon: SetExpressionIconSvg, + Content, + contentProps, + focusElement: "#expression-input", + buttons: [ + { label: "Clear", onClick: handleClear }, + { label: "Cancel" }, + { label: "OK", isDefault: true, onClick: handleSubmit } + ] + }, [currYAttrId, errorMessage, currentExpression]); + blurModalRef.current = blurModal; + return [showModal, hideModal, setCurrYAttrId]; +}; + +interface IContentProps { + dataSet: IDataSet; + xName: string; + currYAttrId: string | undefined; + setCurrYAttrId: React.Dispatch>; + // map of attribute ids to editable expressions + expressions: React.MutableRefObject>; + // the currently edited expression (controlled input) + currentExpression: string; + errorMessage: string; + updateCurrentExpression: (expr: string, isInitializing?: boolean) => void; + acceptExpression: (yAttrId: string, expr: string) => void; +} +const Content: React.FC = ({ + dataSet, xName, currYAttrId, setCurrYAttrId, expressions, + currentExpression, errorMessage, updateCurrentExpression, acceptExpression +}) => { + const firstYAttr = useCurrent(dataSet.attributes.length > 1 ? dataSet.attributes[1] : undefined); + const currYAttr = currYAttrId ? dataSet.attrFromID(currYAttrId) : firstYAttr.current; + const selectElt = useRef(null); + const inputElt = useRef(null); + const yAttrs = dataSet.attributes.length <= 2 + ? {currYAttr?.name} + : ; + const placeholder = `e.g. 3*${xName}+2`; + useLayoutEffect(() => { + currYAttr && updateCurrentExpression(expressions.current.get(currYAttr.id) || ""); + }, [currYAttr]); // eslint-disable-line react-hooks/exhaustive-deps + + const handleInputChange = (e: React.ChangeEvent) => { + updateCurrentExpression(e.target.value); + }; + + const handleBlur = (e: React.FocusEvent) => { + currYAttr && acceptExpression(currYAttr.id, e.target.value); + }; + + return ( + <> +
+ Enter an expression for + {yAttrs} + in terms of + {xName} + : +
+
+ + +
+
+ {errorMessage} +
+ + ); +}; diff --git a/src/components/tools/table-tool/use-geometry-linking.ts b/src/components/tools/table-tool/use-geometry-linking.ts new file mode 100644 index 0000000000..d86a4aa68d --- /dev/null +++ b/src/components/tools/table-tool/use-geometry-linking.ts @@ -0,0 +1,51 @@ +import { useEffect } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { useFeatureFlag } from "../../../hooks/use-stores"; +import { kGeometryToolID } from "../../../models/tools/geometry/geometry-content"; +import { + addTableToDocumentMap, getLinkedTableIndex, getTableLinkColors, removeTableFromDocumentMap +} from "../../../models/tools/table-links"; +import { TableContentModelType } from "../../../models/tools/table/table-content"; +import { ITileLinkMetadata } from "../../../models/tools/table/table-model-types"; +import { ToolTileModelType } from "../../../models/tools/tool-tile"; +import { useLinkGeometryDialog } from "./use-link-geometry-dialog"; + +interface IProps { + documentId?: string; + model: ToolTileModelType; + hasLinkableRows: boolean; + onRequestTilesOfType: (tileType: string) => ITileLinkMetadata[]; + onLinkGeometryTile: (geomTileInfo: ITileLinkMetadata) => void; +} +export const useGeometryLinking = ({ + documentId, model, hasLinkableRows, onRequestTilesOfType, onLinkGeometryTile +}: IProps) => { + const modelId = model.id; + const showLinkButton = useFeatureFlag("GeometryLinkedTables"); + const linkIndex = showLinkButton ? getLinkedTableIndex(modelId) : -1; + const geometryTiles = useLinkableGeometryTiles({ model, onRequestTilesOfType }); + const isLinkEnabled = hasLinkableRows && (geometryTiles.length > 0); + const linkColors = getTableLinkColors(modelId); + + const [showLinkGeometryDialog] = useLinkGeometryDialog({ geometryTiles, onLinkGeometryTile }); + + useEffect(() => { + documentId && addTableToDocumentMap(documentId, modelId); + return () => removeTableFromDocumentMap(modelId); + }, [documentId, modelId]); + + return { showLinkButton, isLinkEnabled, linkIndex, linkColors, showLinkGeometryDialog }; +}; + +interface IUseLinkableGeometryTilesProps { + model: ToolTileModelType; + onRequestTilesOfType: (tileType: string) => ITileLinkMetadata[]; +} +const useLinkableGeometryTiles = ({ model, onRequestTilesOfType }: IUseLinkableGeometryTilesProps) => { + const geometryTiles = useCurrent(onRequestTilesOfType(kGeometryToolID)); + const content = model.content as TableContentModelType; + // add default title if there isn't a title; filter out tiles we're already linked to + return geometryTiles.current + .map((tileInfo, i) => ({ id: tileInfo.id, title: tileInfo.title || `Graph ${i + 1}` })) + .filter(tileInfo => content.metadata.linkedGeometries.indexOf(tileInfo.id) < 0); +}; diff --git a/src/components/tools/table-tool/use-grid-context.ts b/src/components/tools/table-tool/use-grid-context.ts new file mode 100644 index 0000000000..285c4ade48 --- /dev/null +++ b/src/components/tools/table-tool/use-grid-context.ts @@ -0,0 +1,86 @@ +import { useCallback, useMemo, useRef, useState } from "react"; +import { CellNavigationMode, DataGridHandle } from "react-data-grid"; +import { useCurrent } from "../../../hooks/use-current"; +import { useSharedSelectionStore } from "../../../hooks/use-stores"; +import { uniqueId } from "../../../utilities/js-utils"; +import { IGridContext, TPosition } from "./table-types"; + +interface IProps { + modelId: string; + showRowLabels: boolean; + triggerColumnChange: () => void; +} +export const useGridContext = ({ modelId, showRowLabels, triggerColumnChange }: IProps) => { + const gridRef = useRef(null); + const inputRowId = useRef(uniqueId()); + + // this tracks ReactDataGrid's notion of the selected cell + const selectedCell = useRef({ rowIdx: -1, idx: -1 }); + const isSelectedCellInRow = useCallback((rowIdx: number) => selectedCell.current.rowIdx === rowIdx, []); + // local since ReactDataGrid doesn't have a notion of column selection + const [selectedColumns, setSelectedColumns] = useState(new Set()); + const selectedColumnsRef = useCurrent(selectedColumns); + // we use a Set to eventually support multiple selected columns, but + // currently the API constrains to a single selected column. + const isColumnSelected = useCallback((columnId: string) => + selectedColumnsRef.current.has(columnId), [selectedColumnsRef]); + const sharedSelection = useSharedSelectionStore(); + const getSelectedRows = useCallback(() => { + // this is suitable for passing into ReactDataGrid + return new Set(Array.from(sharedSelection.getSelected(modelId)) as string[]); + }, [modelId, sharedSelection]); + + const clearRowSelection = useCallback(() => sharedSelection.clear(modelId), [modelId, sharedSelection]); + const clearColumnSelection = useCallback(() => setSelectedColumns(new Set([])), []); + const clearCellSelection = useCallback(() => gridRef.current?.selectCell({ idx: -1, rowIdx: -1 }), []); + + // clears all selection by default; options can be used to preserve particular forms of selection + const clearSelection = useCallback((options?: { row?: boolean, column?: boolean, cell?: boolean }) => { + const { row, column, cell } = options || {}; + (row !== false) && clearRowSelection(); + (column !== false) && clearColumnSelection(); + (cell !== false) && clearCellSelection(); + }, [clearCellSelection, clearColumnSelection, clearRowSelection]); + + const selectColumn = useCallback((columnId: string) => { + clearSelection({ column: false }); + setSelectedColumns(new Set([columnId])); + triggerColumnChange(); + }, [clearSelection, triggerColumnChange]); + + const selectRowById = useCallback((rowId: string, select: boolean) => { + if (select !== sharedSelection.isSelected(modelId, rowId)) { + sharedSelection.select(modelId, rowId, select); + } + }, [modelId, sharedSelection]); + + const selectOneRow = useCallback((rowId: string) => { + clearColumnSelection(); + sharedSelection.setSelected(modelId, [rowId]); + }, [clearColumnSelection, modelId, sharedSelection]); + + // Creating a new gridContext can result in focus change thus disrupting cell edits; + // therefore, it's important that all inputs to the gridContext be wrapped in useCallback() + // and that state references are mediated through useRef() (e.g. isColumnSelected()). + const gridContext: IGridContext = useMemo(() => ({ + showRowLabels, + isColumnSelected, + onSelectColumn: selectColumn, + isSelectedCellInRow, + onSelectRowById: selectRowById, + onSelectOneRow: selectOneRow, + onClearSelection: clearSelection + }), [clearSelection, isColumnSelected, isSelectedCellInRow, selectColumn, selectOneRow, selectRowById, + showRowLabels]); + + // called by ReactDataGrid when selected rows change + const onSelectedRowsChange = useCallback((_rows: Set) => { + _rows.delete(inputRowId.current); + sharedSelection.setSelected(modelId, Array.from(_rows) as string[]); + }, [modelId, sharedSelection]); + + const cellNavigationMode: CellNavigationMode = "CHANGE_ROW"; + return { + ref: gridRef, cellNavigationMode, inputRowId, selectedCell, getSelectedRows, gridContext, onSelectedRowsChange + }; +}; diff --git a/src/components/tools/table-tool/use-link-geometry-dialog.tsx b/src/components/tools/table-tool/use-link-geometry-dialog.tsx new file mode 100644 index 0000000000..af655416af --- /dev/null +++ b/src/components/tools/table-tool/use-link-geometry-dialog.tsx @@ -0,0 +1,55 @@ +import React, { useRef, useState } from "react"; +import LinkGraphIcon from "../../../clue/assets/icons/table/link-graph-icon.svg"; +import { useCustomModal } from "../../../hooks/use-custom-modal"; +import { ITileLinkMetadata } from "../../../models/tools/table/table-model-types"; + +import "./link-geometry-dialog.scss"; + +interface IContentProps { + geometryTiles: ITileLinkMetadata[]; + selectValue: string; + setSelectValue: React.Dispatch>; +} +const Content: React.FC = ({ geometryTiles, selectValue, setSelectValue }) => { + const selectElt = useRef(null); + return ( + <> +
+ To link this table to a graph, drag the table to a graph or select a graph from this list. +
+ + + ); +}; + +interface IProps { + geometryTiles: ITileLinkMetadata[]; + onLinkGeometryTile: (geomTileInfo: ITileLinkMetadata) => void; +} +export const useLinkGeometryDialog = ({ geometryTiles, onLinkGeometryTile }: IProps) => { + const [selectValue, setSelectValue] = useState(""); + const handleClick = () => { + const tileInfo = geometryTiles.find(tile => tile.id === selectValue); + tileInfo && onLinkGeometryTile(tileInfo); + }; + const [showModal, hideModal] = useCustomModal({ + className: "link-geometry", + Icon: LinkGraphIcon, + title: "Link Table to a Graph", + Content, + contentProps: { geometryTiles, selectValue, setSelectValue }, + buttons: [ + { label: "Cancel" }, + { label: "Link Table", isDefault: true, isDisabled: !selectValue, onClick: handleClick } + ] + }, [geometryTiles]); + + return [showModal, hideModal]; +}; diff --git a/src/components/tools/table-tool/use-model-data-set.ts b/src/components/tools/table-tool/use-model-data-set.ts new file mode 100644 index 0000000000..67d41bedcf --- /dev/null +++ b/src/components/tools/table-tool/use-model-data-set.ts @@ -0,0 +1,50 @@ +import classNames from "classnames"; +import { autorun } from "mobx"; +import { useCallback, useEffect, useRef, useState } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { DataSet } from "../../../models/data/data-set"; +import { TableContentModelType } from "../../../models/tools/table/table-content"; +import { ToolTileModelType } from "../../../models/tools/tool-tile"; +import { kRowHeight } from "./table-types"; + +/* + Table state is stored in content as a sequence of changes/actions. + This code is responsible for tracking changes in content and maintaining a + synchronized DataSet model for use by ReactDataGrid and other clients. + */ +export const useModelDataSet = (model: ToolTileModelType) => { + const modelRef = useCurrent(model); + const getContent = useCallback(() => modelRef.current.content as TableContentModelType, [modelRef]); + const dataSet = useRef(DataSet.create()); + const syncedChanges = useRef(0); + const [columnChanges, setColumnChanges] = useState(0); + const triggerColumnChange = useCallback(() => setColumnChanges(state => ++state), []); + const [rowChanges, setRowChanges] = useState(0); + const triggerRowChange = useCallback(() => setRowChanges(state => ++state), []); + + useEffect(() => { + // can't use getContent() here as then content changes don't trigger reinstallation of the autorun + const _content = model.content as TableContentModelType; + const disposer = autorun(() => { + if (syncedChanges.current < _content.changes.length) { + const [hasColumnChanges, hasRowChanges] = _content.applyChanges(dataSet.current, syncedChanges.current); + hasColumnChanges && triggerColumnChange(); + hasRowChanges && triggerRowChange(); + syncedChanges.current = _content.changes.length; + } + }); + return () => disposer(); + }, [model.content, triggerColumnChange, triggerRowChange]); + + const setTableTitle = useCallback((title: string) => { + (title != null) && getContent().setTableName(title); + triggerColumnChange(); + }, [getContent, triggerColumnChange]); + + const content = getContent(); + const className = classNames("rdg-light", { "show-expressions": content.hasExpressions }); + const rowHeight = kRowHeight; + const headerRowHeight = content.hasExpressions ? 2 * rowHeight : rowHeight; + return { dataSet, columnChanges, triggerColumnChange, rowChanges, triggerRowChange, + className, rowHeight, headerRowHeight, onSetTableTitle: setTableTitle }; +}; diff --git a/src/components/tools/table-tool/use-number-format.ts b/src/components/tools/table-tool/use-number-format.ts new file mode 100644 index 0000000000..ede3ddd23f --- /dev/null +++ b/src/components/tools/table-tool/use-number-format.ts @@ -0,0 +1,10 @@ +import { useSettingFromStores } from "../../../hooks/use-stores"; +import { format } from "d3-format"; +import { useMemo } from "react"; + +export function useNumberFormat() { + const kDefaultFormatStr = ".1~f"; // one decimal place, remove trailing zero + const formatStr = useSettingFromStores("numFormat", "table") as string | undefined || + kDefaultFormatStr; + return useMemo(() => format(formatStr), [formatStr]); +} diff --git a/src/components/tools/table-tool/use-row-label-column.tsx b/src/components/tools/table-tool/use-row-label-column.tsx new file mode 100644 index 0000000000..d1f2cd74e4 --- /dev/null +++ b/src/components/tools/table-tool/use-row-label-column.tsx @@ -0,0 +1,66 @@ +import React, { useCallback } from "react"; +import { Tooltip } from "react-tippy"; +import RowLabelsHiddenSvg from "../../../clue/assets/icons/table/row-labels-hidden-icon.svg"; +import RowLabelsShownSvg from "../../../clue/assets/icons/table/row-labels-shown-icon.svg"; +import { useTooltipOptions } from "../../../hooks/use-tooltip-options"; +import { TFormatterProps, TPosition } from "./table-types"; + +interface IProps { + inputRowId: string; + selectedCell: React.MutableRefObject; + showRowLabels: boolean; + setShowRowLabels: (show: boolean) => void; +} +export const useRowLabelColumn = ({ + inputRowId, selectedCell, showRowLabels, setShowRowLabels +}: IProps) => { + + const title = showRowLabels ? "Hide labels" : "Show labels"; + const tooltipOptions = useTooltipOptions({ title, distance: -2 }); + + const RowLabelHeader: React.FC = useCallback(() => { + return ( + +
setShowRowLabels(!showRowLabels)}> + + +
+
+ ); + }, [setShowRowLabels, showRowLabels, tooltipOptions]); + RowLabelHeader.displayName = "RowLabelHeader"; + + const RowLabelFormatter: React.FC = useCallback(({ + row, isRowSelected, onRowSelectionChange + }: TFormatterProps) => { + const { __id__, __index__, __context__ } = row; + const handleClick = (e: React.MouseEvent) => { + const hasModifier = e.ctrlKey || e.metaKey || e.shiftKey; + const selected = hasModifier ? !isRowSelected : true; + if (e.button === 0) { + // clear selection so navigation direction is always forward after click + selectedCell.current = { rowIdx: -1, idx: -1 }; + if (selected !== isRowSelected) { + if (hasModifier) { + onRowSelectionChange(selected, e.shiftKey); + } + else if (__id__ === inputRowId) { + __context__.onClearSelection({ cell: false }); + } + else { + __context__.onSelectOneRow(__id__); + } + } + } + }; + + return ( +
+ {showRowLabels ? __index__ : undefined} +
+ ); + }, [inputRowId, selectedCell, showRowLabels]); + + return { RowLabelHeader, RowLabelFormatter }; +}; diff --git a/src/components/tools/table-tool/use-rows-from-data-set.ts b/src/components/tools/table-tool/use-rows-from-data-set.ts new file mode 100644 index 0000000000..1ebde8f995 --- /dev/null +++ b/src/components/tools/table-tool/use-rows-from-data-set.ts @@ -0,0 +1,39 @@ +import { useMemo } from "react"; +import { IDataSet } from "../../../models/data/data-set"; +import { IGridContext, TRow } from "./table-types"; + +interface IUseRowsFromDataSet { + dataSet: IDataSet; + readOnly: boolean; + inputRowId: string; + rowChanges: number; + context: IGridContext; +} + +const canonicalize = (dataSet: IDataSet, row: TRow) => { + // ReactDataGrid currently doesn't like editing undefined values, + // so we convert them to empty strings when building rows. + if (row) { + dataSet.attributes.forEach(attr => { + if (row[attr.id] == null) { + row[attr.id] = ""; + } + }); + } + return row; +}; + +export const useRowsFromDataSet = ({ dataSet, readOnly, inputRowId, rowChanges, context }: IUseRowsFromDataSet) => { + return useMemo(() => { + const rowKeyGetter = (row: TRow) => row.__id__; + const rowClass = (row: TRow) => row.__id__ === inputRowId ? "input-row" : undefined; + const rows = dataSet.getCanonicalCasesAtIndices() + .map((_case, i) => canonicalize(dataSet, { + __index__: i + 1, + __context__: context, + ..._case } as TRow)); + !readOnly && rows.push(canonicalize(dataSet, { __id__: inputRowId, __context__: context })); + rowChanges; // eslint-disable-line no-unused-expressions + return { rows, rowKeyGetter, rowClass }; + }, [context, dataSet, inputRowId, readOnly, rowChanges]); +}; diff --git a/src/components/tools/table-tool/use-table-title.ts b/src/components/tools/table-tool/use-table-title.ts new file mode 100644 index 0000000000..47aaf41c1e --- /dev/null +++ b/src/components/tools/table-tool/use-table-title.ts @@ -0,0 +1,48 @@ +import { useCallback, useEffect, useRef } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { IDataSet } from "../../../models/data/data-set"; +import { IGridContext } from "./table-types"; + +interface IProps { + gridContext: IGridContext; + dataSet: IDataSet; + readOnly?: boolean; + onRequestUniqueTitle?: () => string | undefined; + onSetTableTitle?: (title: string) => void; +} +export const useTableTitle = ({ + gridContext, dataSet, readOnly, onRequestUniqueTitle, onSetTableTitle +}: IProps) => { + + const getTitle = useCallback(() => dataSet.name, [dataSet.name]); + const editingTitle = useCurrent(getTitle()); + + const onBeginTitleEdit = () => { + editingTitle.current = getTitle(); + gridContext.onClearSelection(); + return !readOnly; + }; + const onEndTitleEdit = (title?: string) => { + if (!readOnly && (title != null) && (title !== editingTitle.current)) { + onSetTableTitle?.(title); + } + }; + + // request a default title if we don't already have one + const onRequestUniqueTitleRef = useRef(onRequestUniqueTitle); + useEffect(() => { + if (!dataSet.name) { + // wait for all tiles to have registered their callbacks + setTimeout(() => { + const _title = onRequestUniqueTitleRef.current?.(); + if (_title) { + dataSet.setName(_title); + } + }, 100); + } + // don't request a title after we've been unmounted + return () => onRequestUniqueTitleRef.current = undefined; + }, []); // eslint-disable-line react-hooks/exhaustive-deps + + return { getTitle, onBeginTitleEdit, onEndTitleEdit }; +}; diff --git a/src/components/tools/table-tool/use-tool-api.ts b/src/components/tools/table-tool/use-tool-api.ts new file mode 100644 index 0000000000..8a98c37b51 --- /dev/null +++ b/src/components/tools/table-tool/use-tool-api.ts @@ -0,0 +1,35 @@ +import { useEffect, useMemo } from "react"; +import { useCurrent } from "../../../hooks/use-current"; +import { getLinkedTableIndex } from "../../../models/tools/table-links"; +import { TableMetadataModelType } from "../../../models/tools/table/table-content"; +import { IToolApi } from "../tool-api"; + +interface IProps { + metadata: TableMetadataModelType; + getTitle: () => string | undefined; + getContentHeight: () => number | undefined; + onRegisterToolApi: (toolApi: IToolApi, facet?: string | undefined) => void; + onUnregisterToolApi: (facet?: string | undefined) => void; +} +export const useToolApi = ({ + metadata, getTitle, getContentHeight, onRegisterToolApi, onUnregisterToolApi +}: IProps) => { + const metadataRef = useCurrent(metadata); + const toolApi: IToolApi = useMemo(() => ({ + getTitle, + getContentHeight, + isLinked: () => { + return metadataRef.current.isLinked; + }, + getLinkIndex: (index?: number) => { + return metadataRef.current.isLinked + ? getLinkedTableIndex(metadataRef.current.id) + : -1; + } + }), [getContentHeight, getTitle, metadataRef]); + + useEffect(() => { + onRegisterToolApi(toolApi); + return () => onUnregisterToolApi(); + }, [onRegisterToolApi, onUnregisterToolApi, toolApi]); +}; diff --git a/src/components/tools/text-tool.tsx b/src/components/tools/text-tool.tsx index 46c3a984b9..38cb101a2b 100644 --- a/src/components/tools/text-tool.tsx +++ b/src/components/tools/text-tool.tsx @@ -11,7 +11,8 @@ import { debouncedSelectTile } from "../../models/stores/ui"; import { TextContentModelType } from "../../models/tools/text/text-content"; import { hasSelectionModifier } from "../../utilities/event-utils"; import { TextToolbarComponent } from "./text-toolbar"; -import { IToolApi, IToolTileProps } from "./tool-tile"; +import { IToolApi } from "./tool-api"; +import { IToolTileProps } from "./tool-tile"; import { renderSlateMark, renderSlateBlock } from "./slate-renderers"; import "./text-tool.sass"; @@ -232,9 +233,8 @@ export default class TextToolComponent extends BaseComponent @@ -310,6 +311,11 @@ export default class TextToolComponent extends BaseComponent { + // text toolbar is based on editor focus rather than tile selection + return !!this.state.value?.selection.isFocused; + } + private handleChange = (change: SlateChange) => { const { value } = change; const { readOnly, model } = this.props; diff --git a/src/components/tools/text-toolbar.tsx b/src/components/tools/text-toolbar.tsx index 85b57bf5a8..894d2fa4ad 100644 --- a/src/components/tools/text-toolbar.tsx +++ b/src/components/tools/text-toolbar.tsx @@ -1,6 +1,6 @@ import React from "react"; import ReactDOM from "react-dom"; -import { useFloatingToolbarLocation } from "./hooks/use-floating-toolbar-location"; +import { IFloatingToolbarProps, useFloatingToolbarLocation } from "./hooks/use-floating-toolbar-location"; import { TextToolbarButton } from "./text-toolbar-button"; import { IRegisterToolApiProps } from "./tool-tile"; import { isMac } from "../../utilities/browser"; @@ -12,13 +12,10 @@ interface IButtonDef { toolTip: string; // Text for the button's tool-tip. } -interface IProps extends IRegisterToolApiProps { - documentContent?: HTMLElement | null; - toolTile?: HTMLElement | null; +interface IProps extends IFloatingToolbarProps, IRegisterToolApiProps { selectedButtons: string[]; onButtonClick: (buttonName: string, editor: any, event: React.MouseEvent) => void; editor: any; - enabled: boolean; } const kShortcutPrefix = isMac() ? "Cmd-" : "Ctrl-"; @@ -38,7 +35,8 @@ const handleMouseDown = (event: React.MouseEvent) => { }; export const TextToolbarComponent: React.FC = (props: IProps) => { - const { documentContent, enabled, editor, selectedButtons, onButtonClick, ...others } = props; + const { documentContent, editor, selectedButtons, onIsEnabled, onButtonClick, ...others } = props; + const enabled = onIsEnabled(); const toolbarLocation = useFloatingToolbarLocation({ documentContent, toolbarHeight: 29, diff --git a/src/components/tools/tile-comments.tsx b/src/components/tools/tile-comments.tsx index 9557c8e84d..7500819bc3 100644 --- a/src/components/tools/tile-comments.tsx +++ b/src/components/tools/tile-comments.tsx @@ -1,21 +1,23 @@ import React from "react"; import { observer, inject } from "mobx-react"; +import { ToolApiInterfaceContext } from "./tool-api"; import { BaseComponent } from "../base"; import { TileCommentsModelType, TileCommentModelType } from "../../models/tools/tile-comments"; -import { IToolApiInterface } from "./tool-tile"; import "./tile-comments.sass"; interface IProps { docKey: string; model: TileCommentsModelType; - toolApiInterface?: IToolApiInterface; } @inject("stores") @observer export class TileCommentsComponent extends BaseComponent { + static contextType = ToolApiInterfaceContext; + declare context: React.ContextType; + public render() { const { user } = this.stores; const { model } = this.props; @@ -63,13 +65,15 @@ export class TileCommentsComponent extends BaseComponent { } private handleHover = (selectionInfo?: string) => () => { - const { toolApiInterface, model } = this.props; + const { model } = this.props; + const toolApiInterface = this.context; const toolApi = toolApiInterface?.getToolApi(model.tileId); selectionInfo && toolApi?.setSelectionHighlight?.(selectionInfo, true); } private handleLeave = (selectionInfo?: string) => () => { - const { toolApiInterface, model } = this.props; + const { model } = this.props; + const toolApiInterface = this.context; const toolApi = toolApiInterface?.getToolApi(model.tileId); selectionInfo && toolApi?.setSelectionHighlight?.(selectionInfo, false); } diff --git a/src/components/tools/tool-api.tsx b/src/components/tools/tool-api.tsx new file mode 100644 index 0000000000..c34b29f673 --- /dev/null +++ b/src/components/tools/tool-api.tsx @@ -0,0 +1,26 @@ +import { createContext } from "react"; + +export interface IToolApi { + getTitle?: () => string | undefined; + hasSelection?: () => boolean; + deleteSelection?: () => void; + getSelectionInfo?: () => string; + setSelectionHighlight?: (selectionInfo: string, isHighlighted: boolean) => void; + isLinked?: () => boolean; + getLinkIndex?: (index?: number) => number; + getLinkedTables?: () => string[] | undefined; + getContentHeight?: () => number | undefined; + handleDocumentScroll?: (x: number, y: number) => void; + handleTileResize?: (entry: ResizeObserverEntry) => void; +} + +export interface IToolApiInterface { + register: (id: string, toolApi: IToolApi) => void; + unregister: (id: string) => void; + getToolApi: (id: string) => IToolApi; + forEach: (callback: (api: IToolApi) => void) => void; +} + +export type IToolApiMap = Record; + +export const ToolApiInterfaceContext = createContext(null); diff --git a/src/components/tools/tool-tile.sass b/src/components/tools/tool-tile.sass index 35f0dd0877..0a46d3819b 100644 --- a/src/components/tools/tool-tile.sass +++ b/src/components/tools/tool-tile.sass @@ -9,6 +9,15 @@ flex: 1 1 auto border: $half-border-width solid white + &.teacher + background-color: $learninglog-green-light-8 + margin: 5px 0 10px 20px + padding-right: 10px + border-left: $half-border-width solid $learninglog-green + + &:not(.text-tool-tile) + padding: 10px + .tool-tile-drag-handle position: absolute right: -2px diff --git a/src/components/tools/tool-tile.tsx b/src/components/tools/tool-tile.tsx index 28398c1866..80524e6601 100644 --- a/src/components/tools/tool-tile.tsx +++ b/src/components/tools/tool-tile.tsx @@ -17,6 +17,7 @@ import TextToolComponent from "./text-tool"; import ImageToolComponent from "./image-tool"; import DrawingToolComponent from "./drawing-tool/drawing-tool"; import PlaceholderToolComponent from "./placeholder-tool/placeholder-tool"; +import { IToolApi, ToolApiInterfaceContext } from "./tool-api"; import { HotKeys } from "../../utilities/hot-keys"; import { TileCommentsComponent } from "./tile-comments"; import { LinkIndicatorComponent } from "./link-indicator"; @@ -27,27 +28,6 @@ import "../../utilities/dom-utils"; import "./tool-tile.sass"; -export interface IToolApi { - hasSelection?: () => boolean; - deleteSelection?: () => void; - getSelectionInfo?: () => string; - setSelectionHighlight?: (selectionInfo: string, isHighlighted: boolean) => void; - isLinked?: () => boolean; - getLinkIndex?: (index?: number) => number; - getLinkedTables?: () => string[] | undefined; - handleDocumentScroll?: (x: number, y: number) => void; - handleTileResize?: (entry: ResizeObserverEntry) => void; -} - -export interface IToolApiInterface { - register: (id: string, toolApi: IToolApi) => void; - unregister: (id: string) => void; - getToolApi: (id: string) => IToolApi; - forEach: (callback: (api: IToolApi) => void) => void; -} - -export type IToolApiMap = Record; - export const kDragTiles = "org.concord.clue.drag-tiles"; export const kDragRowHeight = "org.concord.clue.row.height"; @@ -56,7 +36,7 @@ export const kDragTileId = "org.concord.clue.tile.id"; export const kDragTileContent = "org.concord.clue.tile.content"; export const kDragTileCreate = "org.concord.clue.tile.create"; // allows source compatibility to be checked in dragOver -export const dragTileSrcDocId = (id: string) => `org.concord.clue.src.${id}`; +export const dragTileSrcDocId = (id: string) => `org.concord.clue.src.${id.toLowerCase()}`; export const dragTileType = (type: string) => `org.concord.clue.tile.type.${type}`; export function extractDragTileSrcDocId(dataTransfer: DataTransfer) { @@ -77,7 +57,8 @@ export function extractDragTileType(dataTransfer: DataTransfer) { interface IToolTileBaseProps { context: string; - docId: string; + documentId?: string; // permanent id (key) of the containing document + docId: string; // ephemeral contentId for the DocumentContent documentContent: HTMLElement | null; scale?: number; widthPct?: number; @@ -85,6 +66,8 @@ interface IToolTileBaseProps { model: ToolTileModelType; readOnly?: boolean; onSetCanAcceptDrop: (tileId?: string) => void; + onRequestTilesOfType: (tileType: string) => Array<{ id: string, title?: string }>; + onRequestUniqueTitle: (tileId: string) => string | undefined; onRequestRowHeight: (tileId: string, height?: number, deltaHeight?: number) => void; } @@ -98,16 +81,19 @@ export interface IToolTileProps extends IToolTileBaseProps, IRegisterToolApiProp } interface IProps extends IToolTileBaseProps { - toolApiInterface?: IToolApiInterface; } -const kToolComponentMap: any = { - [kPlaceholderToolID]: PlaceholderToolComponent, - [kDrawingToolID]: DrawingToolComponent, - [kGeometryToolID]: GeometryToolComponent, - [kImageToolID]: ImageToolComponent, - [kTableToolID]: TableToolComponent, - [kTextToolID]: TextToolComponent +interface ToolComponentInfo { + ToolComponent: any; + toolTileClass: string; +} +const kToolComponentMap: Record = { + [kPlaceholderToolID]: { ToolComponent: PlaceholderToolComponent, toolTileClass: "placeholder-tile" }, + [kDrawingToolID]: { ToolComponent: DrawingToolComponent, toolTileClass: "drawing-tool-tile" }, + [kGeometryToolID]: { ToolComponent: GeometryToolComponent, toolTileClass: "geometry-tool-tile" }, + [kImageToolID]: { ToolComponent: ImageToolComponent, toolTileClass: "image-tool-tile" }, + [kTableToolID]: { ToolComponent: TableToolComponent, toolTileClass: "table-tool-tile" }, + [kTextToolID]: { ToolComponent: TextToolComponent, toolTileClass: "text-tool-tile" } }; interface IDragTileButtonProps { @@ -133,6 +119,9 @@ interface IState { @observer export class ToolTileComponent extends BaseComponent { + static contextType = ToolApiInterfaceContext; + declare context: React.ContextType; + private modelId: string; private domElement: HTMLDivElement | null; private resizeObserver: ResizeObserver; @@ -191,10 +180,10 @@ export class ToolTileComponent extends BaseComponent { const { model, readOnly, widthPct } = this.props; const { hoverTile } = this.state; const { appConfig, ui } = this.stores; - const ToolComponent = kToolComponentMap[model.content.type]; + const { ToolComponent, toolTileClass } = kToolComponentMap[model.content.type]; const isPlaceholderTile = ToolComponent === PlaceholderToolComponent; const isTileSelected = ui.isSelectedTile(model); - const classes = classNames("tool-tile", { + const classes = classNames("tool-tile", model.display, toolTileClass, { placeholder: isPlaceholderTile, readonly: readOnly, hovered: this.state.hoverTile, @@ -231,62 +220,57 @@ export class ToolTileComponent extends BaseComponent { private renderTile(ToolComponent: any) { const tileId = this.props.model.id; - const { toolApiInterface, ...otherProps } = this.props; return ToolComponent != null ? : null; } private renderLinkIndicators() { - const { model, toolApiInterface } = this.props; + const { model } = this.props; + const toolApiInterface = this.context; const toolApi = toolApiInterface?.getToolApi(model.id); const clientTableLinks = toolApi?.getLinkedTables?.(); - const tableLinkIndex = toolApi?.getLinkIndex?.(); return clientTableLinks ? clientTableLinks.map((id, index) => { return ; }) - : (tableLinkIndex != null) && (tableLinkIndex >= 0) - ? - : null; + : null; // tables don't use the original link indicator any more } private renderTileComments() { const tileId = this.props.model.id; - const { toolApiInterface } = this.props; const { documents } = this.stores; const documentContent = documents.findDocumentOfTile(tileId); if (documentContent) { const commentsModel = documentContent.comments.get(tileId); if (commentsModel) { - return ; + return ; } } } private getToolResizeHandler = () => { - const { model, toolApiInterface } = this.props; + const { model } = this.props; + const toolApiInterface = this.context; return toolApiInterface?.getToolApi(`${model.id}[layout]`)?.handleTileResize || toolApiInterface?.getToolApi(model.id)?.handleTileResize; } private handleRegisterToolApi = (toolApi: IToolApi, facet?: string) => { const id = facet ? `${this.modelId}[${facet}]` : this.modelId; - this.props.toolApiInterface?.register(id, toolApi); + const toolApiInterface = this.context; + toolApiInterface?.register(id, toolApi); // trigger initial render this.forceUpdate(); } private handleUnregisterToolApi = (facet?: string) => { const id = facet ? `${this.modelId}[${facet}]` : this.modelId; - this.props.toolApiInterface?.unregister(id); + const toolApiInterface = this.context; + toolApiInterface?.unregister(id); } private handleKeyDown = (e: React.KeyboardEvent) => { @@ -306,7 +290,7 @@ export class ToolTileComponent extends BaseComponent { return; } - const ToolComponent = kToolComponentMap[model.content.type]; + const ToolComponent = kToolComponentMap[model.content.type].ToolComponent; if (ToolComponent?.tileHandlesSelection) { ui.setSelectedTile(model, {append: hasSelectionModifier(e)}); } @@ -344,7 +328,7 @@ export class ToolTileComponent extends BaseComponent { } // set the drag data const { model, docId, height, scale } = this.props; - const ToolComponent = kToolComponentMap[model.content.type]; + const ToolComponent = kToolComponentMap[model.content.type].ToolComponent; // can't drag placeholder tiles if (ToolComponent === PlaceholderToolComponent) { e.preventDefault(); diff --git a/src/components/utilities/error-alert.scss b/src/components/utilities/error-alert.scss new file mode 100644 index 0000000000..9ff577f1a6 --- /dev/null +++ b/src/components/utilities/error-alert.scss @@ -0,0 +1,12 @@ +@import "../../components/vars.sass"; + +.custom-modal.error-alert { + width: 400px; + height: 160px; + outline: none; + + .modal-icon svg { + width: 36px * 0.7; + height: 34px * 0.7; + } +} diff --git a/src/components/utilities/error-alert.tsx b/src/components/utilities/error-alert.tsx new file mode 100644 index 0000000000..c764e74d50 --- /dev/null +++ b/src/components/utilities/error-alert.tsx @@ -0,0 +1,16 @@ +import React, { useEffect } from "react"; +import { IErrorAlertProps, useErrorAlert } from "./use-error-alert"; + +// Component wrapper for useErrorAlert() for use by class components. +const ErrorAlert: React.FC = (props) => { + + const [showAlert, hideAlert] = useErrorAlert(props); + + useEffect(() => { + showAlert(); + return () => hideAlert(); + }, [hideAlert, showAlert]); + + return null; +}; +export default ErrorAlert; diff --git a/src/components/utilities/single-string-dialog.scss b/src/components/utilities/single-string-dialog.scss new file mode 100644 index 0000000000..3017a9b73c --- /dev/null +++ b/src/components/utilities/single-string-dialog.scss @@ -0,0 +1,27 @@ +@import "../../components/vars.sass"; + +.custom-modal.single-string { + width: 400px; + height: 183px; + + .modal-icon svg { + width: 36px * 0.65; + height: 34px * 0.65; + fill: $charcoal; + } + + .input-row { + height: 30px; + display: flex; + align-items: center; + + label { + display: inline-block; + flex: 0 0 auto; + } + input { + height: 100%; + flex: 1 1 auto; + } + } +} diff --git a/src/components/utilities/single-string-dialog.tsx b/src/components/utilities/single-string-dialog.tsx index 9fa1d0e93d..49b12b0647 100644 --- a/src/components/utilities/single-string-dialog.tsx +++ b/src/components/utilities/single-string-dialog.tsx @@ -1,5 +1,5 @@ -import React from "react"; -import { Button, Dialog } from "@blueprintjs/core"; +import React, { useEffect } from "react"; +import { useSingleStringDialog } from "./use-single-string-dialog"; interface IProps { parentId?: string; @@ -12,73 +12,27 @@ interface IProps { maxLength?: number; } -interface IState { - content: string; -} - -export default -class SingleStringDialog extends React.Component { - - public state = { - content: this.props.content || "" - }; - - public render() { - const { title, prompt, placeholder, maxLength } = this.props; - return ( - -
{prompt}:
- input && input.focus()} - /> -
-
-
- ); - } - - private handleChange = (evt: React.FormEvent) => { - this.setState({ content: (evt.target as HTMLInputElement).value }); - } - - private handleAccept = () => { - const { onAccept, parentId } = this.props; - const { content } = this.state; - onAccept && onAccept(content, parentId); - } - - private handleCancel = () => { - const { onClose } = this.props; - onClose && onClose(); - } - - private handleKeyDown = (evt: React.KeyboardEvent) => { - evt.stopPropagation(); - if (evt.keyCode === 13) { - this.handleAccept(); - } else if (evt.keyCode === 27) { - this.handleCancel(); - } - } - -} +// Component wrapper for useSingleStringDialog() for use by class components. +const SingleStringDialog: React.FC = ({ + parentId, title, prompt, placeholder, content, maxLength, onAccept, onClose +}) => { + + const [showDialog, hideDialog] = useSingleStringDialog({ + title: title || "", + prompt, + placeholder, + value: content, + maxLength, + context: parentId, + onAccept, + onClose + }); + + useEffect(() => { + showDialog(); + return () => hideDialog(); + }, [hideDialog, showDialog]); + + return null; +}; +export default SingleStringDialog; diff --git a/src/components/utilities/tile-utils.ts b/src/components/utilities/tile-utils.ts index 815e6cc26a..137c2cadca 100644 --- a/src/components/utilities/tile-utils.ts +++ b/src/components/utilities/tile-utils.ts @@ -1,6 +1,7 @@ export interface IGetToolbarLocationBaseArgs { documentContent?: HTMLElement | null; toolTile?: HTMLElement | null; + scale?: number; toolbarHeight: number; minToolContent?: number; toolbarLeftOffset?: number; @@ -13,8 +14,9 @@ interface IGetToolbarLocationArgs extends IGetToolbarLocationBaseArgs { } export function getToolbarLocation({ - documentContent, toolTile, toolbarHeight, minToolContent, toolLeft, toolBottom, toolbarLeftOffset, toolbarTopOffset - }: IGetToolbarLocationArgs) { + documentContent, toolTile, scale, + toolbarHeight, minToolContent, toolLeft, toolBottom, toolbarLeftOffset, toolbarTopOffset +}: IGetToolbarLocationArgs) { const viewportHeight = window.innerHeight || document.documentElement.clientHeight; let minToolbarTop = minToolContent || 30; let maxToolbarTop = viewportHeight - toolbarHeight; @@ -22,13 +24,14 @@ export function getToolbarLocation({ let tileTopOffset = 0; if (documentContent && toolTile) { + const _scale = scale || 1; const docBounds = documentContent.getBoundingClientRect(); const tileBounds = toolTile.getBoundingClientRect(); const topOffset = tileBounds.top - docBounds.top; const leftOffset = tileBounds.left - docBounds.left; if ((topOffset != null) && (leftOffset != null)) { - tileTopOffset = topOffset; - tileLeftOffset = leftOffset; + tileTopOffset = topOffset / _scale; + tileLeftOffset = leftOffset / _scale; } minToolbarTop += topOffset; maxToolbarTop -= docBounds.top; diff --git a/src/components/utilities/use-caution-alert.tsx b/src/components/utilities/use-caution-alert.tsx new file mode 100644 index 0000000000..fbcf6864f1 --- /dev/null +++ b/src/components/utilities/use-caution-alert.tsx @@ -0,0 +1,51 @@ +import React from "react"; +import CautionSvg from "../../assets/icons/caution.svg"; +import { useCustomModal } from "../../hooks/use-custom-modal"; + +import "./error-alert.scss"; + +interface IProps { + className?: string; + title?: string; + content: string | React.FC; + confirmLabel?: string; + cancelLabel?: string; + onConfirm: () => void; + onClose?: () => void; +} + +interface ITextProps { + content: string; +} +const TextContent: React.FC = ({ content }) => { + return

{content}

; +}; + +export const useCautionAlert = ({ + className, title, content, confirmLabel, cancelLabel, onConfirm, onClose +}: IProps) => { + + const Content = typeof content === "string" + ? TextContent + : content; + const contentProps = typeof content === "string" ? { content } : {}; + + const handleConfirm = () => { + onConfirm(); + }; + + const [showAlert, hideAlert] = useCustomModal({ + className: `error-alert ${className || ""}`, + title: title || "", + Icon: CautionSvg, + Content, + contentProps, + buttons: [ + { label: cancelLabel || "Cancel" }, + { label: confirmLabel || "OK", isDefault: true, onClick: handleConfirm } + ], + onClose + }); + + return [showAlert, hideAlert]; +}; diff --git a/src/components/utilities/use-error-alert.tsx b/src/components/utilities/use-error-alert.tsx new file mode 100644 index 0000000000..2eb907a0ab --- /dev/null +++ b/src/components/utilities/use-error-alert.tsx @@ -0,0 +1,42 @@ +import React, { useCallback } from "react"; +import ErrorSvg from "../../assets/icons/error.svg"; +import { useCustomModal } from "../../hooks/use-custom-modal"; + +import "./error-alert.scss"; + +export interface IErrorAlertProps { + className?: string; + title?: string; + content: string | React.FC; + canCancel?: boolean; + buttonLabel?: string; + onClick?: () => void; + onClose?: () => void; +} + +export const useErrorAlert = ({ + className, title, content, canCancel, buttonLabel, onClick, onClose +}: IErrorAlertProps) => { + + const TextContent: React.FC = useCallback(() => { + return

{content}

; + }, [content]); + const Content = typeof content === "string" + ? TextContent + : content; + + const [showAlert, hideAlert] = useCustomModal({ + className: `error-alert ${className || ""}`, + title: title || "", + Icon: ErrorSvg, + Content, + contentProps: {}, + canCancel, + buttons: [ + { label: buttonLabel || "OK", isDefault: true, onClick } + ], + onClose + }); + + return [showAlert, hideAlert]; +}; diff --git a/src/components/utilities/use-single-string-dialog.tsx b/src/components/utilities/use-single-string-dialog.tsx new file mode 100644 index 0000000000..4f7fab86d6 --- /dev/null +++ b/src/components/utilities/use-single-string-dialog.tsx @@ -0,0 +1,53 @@ +import React, { useRef } from "react"; +import TextInputSvg from "../../assets/icons/text-input.svg"; +import { useCustomModal } from "../../hooks/use-custom-modal"; + +import "./single-string-dialog.scss"; + +interface IProps { + className?: string; + title: string; + prompt?: string; + label?: string; + placeholder?: string; + value?: string; + maxLength?: number; + context?: any; + onAccept: (value: string, context?: any) => void; + onClose?: () => void; +} +export const useSingleStringDialog = ({ + className, title, prompt, label, placeholder, value, maxLength, context, onAccept, onClose +}: IProps) => { + + const inputRef = useRef(null); + const valueRef = useRef(value); + + const Content: React.FC = () => { + return ( + <> + {prompt &&
{prompt}
} +
+ {label && } + valueRef.current = inputRef.current?.value}/> +
+ + ); + }; + + return useCustomModal({ + className: `single-string ${className || ""}`, + title, + Icon: TextInputSvg, + Content, + contentProps: {}, + focusElement: "#string-input", + buttons: [ + { label: "Cancel" }, + { label: "OK", isDefault: true, + onClick: () => onAccept(inputRef.current?.value || valueRef.current || "", context)} + ], + onClose + }); +}; diff --git a/src/components/vars.sass b/src/components/vars.sass index 57b7a00d47..45057dc72b 100644 --- a/src/components/vars.sass +++ b/src/components/vars.sass @@ -312,6 +312,11 @@ $id-orange: #ffc89c $id-purple: #ffc1eb $id-green: #91e7a2 +$highlight-blue: #0081ff +$highlight-blue-50: #80c0ff // $highlight-blue @ 50% opacity +$highlight-blue-25: #c0e0ff // $highlight-blue @ 25% opacity +$highlight-blue-50-35: #c3efff // $highlight-blue-50 @ 35% opacity + // // shared component dimensions // diff --git a/src/hooks/custom-modal.scss b/src/hooks/custom-modal.scss new file mode 100644 index 0000000000..e76ff320d3 --- /dev/null +++ b/src/hooks/custom-modal.scss @@ -0,0 +1,123 @@ +@import "../components/vars.sass"; + +$modal-header-height: 34px; +$modal-header-icon-width: 36px; +$modal-header-border-radius: 6px; +$modal-padding: 0 20px; +$modal-control-height: 30px; +$modal-control-border: solid 1.5px $charcoal-light-1; +$modal-control-border-radius: 5px; +$modal-button-min-width: 62px; +$modal-button-spacing: 10px; +$modal-footer-height: 45px; + +.custom-modal { + position: absolute; + color: $charcoal-dark-2; + background-color: white; + border: solid 2px $workspace-teal; + border-radius: 8px; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + display: flex; + flex-direction: column; + outline: none; + + .modal-header { + width: 100%; + height: $modal-header-height; + flex: 0 0 auto; + background-color: $charcoal-light-6; + border-top-left-radius: $modal-header-border-radius; + border-top-right-radius: $modal-header-border-radius; + font-weight: bold; + display: flex; + justify-content: center; + align-items: center; + + .modal-icon { + position: absolute; + left: 0; + width: $modal-header-icon-width; + height: $modal-header-height; + border-top-left-radius: $modal-header-border-radius; + display: flex; + justify-content: center; + align-items: center; + } + + .modal-close { + position: absolute; + right: 0; + width: $modal-header-icon-width; + height: $modal-header-height; + border: none; + border-top-right-radius: $modal-header-border-radius; + outline: none; + display: flex; + justify-content: center; + align-items: center; + + &:hover, &:focus { + background-color: $charcoal-light-4; + } + + &:active { + background-color: $charcoal-light-2; + } + } + } + + .modal-content { + width: 100%; + flex: 1 1 auto; + display: flex; + flex-direction: column; + justify-content: space-evenly; + padding: $modal-padding; + + input { + height: $modal-control-height; + border: $modal-control-border; + border-radius: $modal-control-border-radius; + } + } + + .modal-footer { + width: 100%; + height: $modal-footer-height; + flex: 0 0 auto; + display: flex; + justify-content: flex-end; + align-items: flex-start; + padding: $modal-padding; + + .modal-button { + height: $modal-control-height; + min-width: $modal-button-min-width; + margin-left: $modal-button-spacing; + color: $charcoal-dark-2; + background-color: white; + border: $modal-control-border; + border-radius: $modal-control-border-radius; + outline: none; + + &.disabled { + opacity: 35%; + } + + &.default:not(.disabled) { + background-color: $charcoal-light-6; + } + + &:hover:not(.disabled), &:focus:not(.disabled) { + background-color: $workspace-teal-light-4; + } + + &:active:not(.disabled) { + background-color: $workspace-teal-light-3; + } + } + } +} diff --git a/src/hooks/use-custom-modal.tsx b/src/hooks/use-custom-modal.tsx new file mode 100644 index 0000000000..cb0ccf7948 --- /dev/null +++ b/src/hooks/use-custom-modal.tsx @@ -0,0 +1,119 @@ +import classNames from "classnames"; +import React, { useCallback, useRef } from "react"; +import Modal from "react-modal"; +import { useModal } from "react-modal-hook"; +import CloseIconSvg from "../assets/icons/close/close.svg"; + +import "./custom-modal.scss"; + +// constant for use as return value from client onClick handlers +export const kLeaveModalOpen = true; + +interface IModalButton { + className?: string; + label: string | React.FC; + isDefault?: boolean; + isDisabled?: boolean; + onClick?: (() => void) | (() => boolean); // close dialog on falsy return value +} + +const invokeButton = (button: IModalButton, onClose: () => void) => { + // close dialog on falsy return value from onClick + !button.isDisabled && !button.onClick?.() && onClose(); +}; + +interface IProps { + className?: string; + title: string | React.FC; + Icon?: React.FC; + Content: React.FC; + contentProps: IContentProps; + focusElement?: string; + canCancel?: boolean; + // defined left-to-right, e.g. Extra Button, Cancel, OK + buttons: IModalButton[]; + onClose?: () => void; +} +export const useCustomModal = ({ + className, Icon, title, Content, contentProps, focusElement, canCancel, buttons, onClose +}: IProps, dependencies?: any[]) => { + + const contentElt = useRef(); + const hideModalRef = useRef<() => void>(); + const handleCloseRef = useRef<() => void>(() => hideModalRef.current?.()); + + const blurModal = useCallback(() => { + // focusing the content element blurs any input control + contentElt.current?.focus(); + }, []); + + const handleKeyDown = useCallback((e: KeyboardEvent) => { + if (e.key === "Enter") { + const defaultButton = buttons.find(b => b.isDefault); + if (defaultButton && !defaultButton.isDisabled) { + blurModal(); + // useRef to avoid circular dependencies + invokeButton(defaultButton, handleCloseRef.current); + e.stopPropagation(); + e.preventDefault(); + } + } + }, [blurModal, buttons, handleCloseRef]); + + const handleAfterOpen = ({overlayEl, contentEl}: { overlayEl: Element, contentEl: HTMLDivElement }) => { + contentElt.current = contentEl; + + contentEl.addEventListener("keydown", handleKeyDown, true); + + const element = focusElement && contentEl.querySelector(focusElement) as HTMLElement || contentEl; + element && setTimeout(() => { + element.focus?.(); + (element as HTMLInputElement).select?.(); + }); + }; + + const handleClose = useCallback(() => { + contentElt.current?.removeEventListener("keydown", handleKeyDown, true); + hideModalRef.current?.(); + }, [handleKeyDown]); + handleCloseRef.current = handleClose; + + const [showModal, hideModal] = useModal(() => { + return ( + +
+
+ {Icon && } +
+
{title}
+ {canCancel !== false && + } +
+
+ +
+
+ {buttons.map((b, i) => { + const classes = classNames("modal-button", b.className, { default: b.isDefault, disabled: b.isDisabled }); + const key = `${i}-${b.className}`; + const handleClick = () => invokeButton(b, handleClose); + return ( + + ); + })} +
+
+ ); + }, dependencies); + hideModalRef.current = hideModal; + + return [showModal, handleClose, blurModal]; +}; diff --git a/src/hooks/use-stores.ts b/src/hooks/use-stores.ts index 396ed0016a..b1ca6729c0 100644 --- a/src/hooks/use-stores.ts +++ b/src/hooks/use-stores.ts @@ -3,7 +3,8 @@ import { useContext } from "react"; import { ProblemModelType } from "../models/curriculum/problem"; import { AppConfigModelType } from "../models/stores/app-config-model"; import { GroupsModelType } from "../models/stores/groups"; -import { IStores } from "../models/stores/stores"; +import { SelectionStoreModelType } from "../models/stores/selection"; +import { getSettingFromStores, isFeatureSupported, IStores } from "../models/stores/stores"; import { UserModelType } from "../models/stores/user"; import { UIModelType } from "../models/stores/ui"; @@ -28,6 +29,18 @@ export function useProblemStore(): ProblemModelType { return useStores().problem; } +export function useSettingFromStores(key: string, group?: string) { + return getSettingFromStores(useStores(), key, group); +} + +export function useSharedSelectionStore(): SelectionStoreModelType { + return useStores().selection; +} + export function useUIStore(): UIModelType { return useStores().ui; } + +export function useFeatureFlag(feature: string) { + return isFeatureSupported(useStores(), feature); +} diff --git a/src/hooks/use-tool-api-interface.ts b/src/hooks/use-tool-api-interface.ts deleted file mode 100644 index 8381621df0..0000000000 --- a/src/hooks/use-tool-api-interface.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { each } from "lodash"; -import { useRef } from "react"; -import { IToolApi, IToolApiInterface, IToolApiMap } from "../components/tools/tool-tile"; - -export function useToolApiInterface(): [IToolApiMap, IToolApiInterface] { - const toolApiMap = useRef({}); - const toolApiInterface = useRef({ - register: (id: string, toolApi: IToolApi) => { - toolApiMap.current[id] = toolApi; - }, - unregister: (id: string) => { - delete toolApiMap.current[id]; - }, - getToolApi: (id: string) => { - return toolApiMap.current[id]; - }, - forEach: (callback: (api: IToolApi) => void) => { - each(toolApiMap.current, api => callback(api)); - } - }); - return [toolApiMap.current, toolApiInterface.current]; -} diff --git a/src/hooks/use-tooltip-options.ts b/src/hooks/use-tooltip-options.ts index 3e623261f9..197287984f 100644 --- a/src/hooks/use-tooltip-options.ts +++ b/src/hooks/use-tooltip-options.ts @@ -1,5 +1,8 @@ +import { useMemo } from "react"; import { TooltipProps } from "react-tippy"; +import "react-tippy/dist/tippy.css"; + const kDefaultTooltipOptions: TooltipProps = { position: "bottom", distance: 0, @@ -11,5 +14,5 @@ const kDefaultTooltipOptions: TooltipProps = { }; export const useTooltipOptions = (options?: TooltipProps) => { - return { ...kDefaultTooltipOptions, ...options }; + return useMemo(() => ({ ...kDefaultTooltipOptions, ...options }), [options]); }; diff --git a/src/index.html b/src/index.html index 17328547e7..31fc0d32f0 100644 --- a/src/index.html +++ b/src/index.html @@ -61,13 +61,6 @@ - - right-arrow - - - - down-arrow - Star diff --git a/src/lib/auth.ts b/src/lib/auth.ts index f089357f4b..42d77dad50 100644 --- a/src/lib/auth.ts +++ b/src/lib/auth.ts @@ -1,15 +1,16 @@ +import initials from "initials"; import jwt from "jsonwebtoken"; import superagent from "superagent"; import { AppMode } from "../models/stores/stores"; import { QueryParams, DefaultUrlParams } from "../utilities/url-params"; import { NUM_FAKE_STUDENTS, NUM_FAKE_TEACHERS } from "../components/demo/demo-creator"; import { AppConfigModelType } from "../models/stores/app-config-model"; -import { IPortalClassOffering, UserType } from "../models/stores/user"; +import { IPortalClassOffering } from "../models/stores/user"; +import { UserType } from "../models/stores/user-types"; import { getErrorMessage } from "../utilities/super-agent-helpers"; import { getPortalOfferings, getPortalClassOfferings, getProblemIdForAuthenticatedUser } from "./portal-api"; import { PortalJWT, PortalFirebaseJWT } from "./portal-types"; import { Logger, LogEventName } from "../lib/logger"; -import initials from "initials"; export const PORTAL_JWT_URL_SUFFIX = "api/v1/jwt/portal"; export const FIREBASE_JWT_URL_SUFFIX = "api/v1/jwt/firebase"; diff --git a/src/lib/logger.test.ts b/src/lib/logger.test.ts index ea5a4f6870..121ba9b589 100644 --- a/src/lib/logger.test.ts +++ b/src/lib/logger.test.ts @@ -8,7 +8,7 @@ import { InvestigationModel } from "../models/curriculum/investigation"; import { IStores, createStores } from "../models/stores/stores"; import { WorkspaceModel, ProblemWorkspace, WorkspaceModelType } from "../models/stores/workspace"; import { defaultTextContent } from "../models/tools/text/text-content"; -import { createToolTileModelFromContent, IDragTileItem } from "../models/tools/tool-tile"; +import { IDragTileItem, ToolTileModel } from "../models/tools/tool-tile"; import { createSingleTileContent } from "../utilities/test-utils"; import { UserModel } from "../models/stores/user"; @@ -63,7 +63,7 @@ describe("logger", () => { }); it("can log tile creation", async (done) => { - const tile = createToolTileModelFromContent(defaultTextContent()); + const tile = ToolTileModel.create({ content: defaultTextContent() }); mock.post(/.*/, (req, res) => { const request = JSON.parse(req.body()); diff --git a/src/lib/logger.ts b/src/lib/logger.ts index fbeff3d926..a96f7b0a7e 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -68,6 +68,8 @@ export enum LogEventName { SHOW_WORK, SHOW_TAB, SHOW_TAB_SECTION, + HIDE_SOLUTIONS, + SHOW_SOLUTIONS, GRAPH_TOOL_CHANGE, DRAWING_TOOL_CHANGE, diff --git a/src/models/curriculum/section.ts b/src/models/curriculum/section.ts index a2d95648e2..7e4fad8691 100644 --- a/src/models/curriculum/section.ts +++ b/src/models/curriculum/section.ts @@ -1,7 +1,7 @@ import { types } from "mobx-state-tree"; import { DocumentContentModel } from "../document/document-content"; import { SupportModel } from "./support"; -import { cloneDeep } from "lodash"; +import { each } from "lodash"; export type SectionType = string; @@ -21,11 +21,20 @@ export const kUnknownSectionType = "unknown"; export const kDefaultPlaceholder = "Create or drag tiles here"; const kUnknownSectionInfo = { initials: "?", title: "Unknown", placeholder: kDefaultPlaceholder }; -let gSectionInfoMap: ISectionInfoMap = { [kAllSectionType]: kAllSectionInfo }; +const gSectionInfoMap: ISectionInfoMap = { [kAllSectionType]: kAllSectionInfo }; export function setSectionInfoMap(sectionInfoMap?: ISectionInfoMap) { - gSectionInfoMap = cloneDeep(sectionInfoMap) || {}; - gSectionInfoMap[kAllSectionType] = kAllSectionInfo; + // regular content and teacher guide are two separate units, so we merge them into a single map + // teacher guide section types should be unique from regular content; we don't replace existing entries + each(sectionInfoMap, (sectionInfo, sectionType) => { + if (!gSectionInfoMap[sectionType]) { + gSectionInfoMap[sectionType] = sectionInfo; + } + else { + console.warn("setSectionInfoMap skipping redundant assignment of section type:", + `${sectionType} "${sectionInfo.title}"`); + } + }); } function getSectionInfo(type: SectionType) { diff --git a/src/models/curriculum/unit.ts b/src/models/curriculum/unit.ts index 440fd48627..646cfd3f05 100644 --- a/src/models/curriculum/unit.ts +++ b/src/models/curriculum/unit.ts @@ -1,4 +1,4 @@ -import { types } from "mobx-state-tree"; +import { Instance, types } from "mobx-state-tree"; import { DocumentContentModel } from "../document/document-content"; import { InvestigationModel } from "./investigation"; import { ISectionInfoMap, setSectionInfoMap } from "./section"; @@ -48,20 +48,42 @@ export const UnitModel = types const investigation = self.getInvestigation(investigationOrdinal); return { investigation, - problem: investigation && investigation.getProblem(problemOrdinal) + problem: investigation?.getProblem(problemOrdinal) }; } })); +export type UnitModelType = Instance; -export type UnitModelType = typeof UnitModel.Type; - -export function getUnitJson(unitId: string | undefined, appConfig: AppConfigModelType ) { - const unitUrlParam = unitId && appConfig.units.get(unitId); - if (!unitUrlParam){ +function getUnitSpec(unitId: string | undefined, appConfig: AppConfigModelType) { + const requestedUnit = unitId ? appConfig.getUnit(unitId) : undefined; + if (unitId && !requestedUnit) { console.warn(`unitId "${unitId}" not found in appConfig.units`); } - const urlParam = unitUrlParam || appConfig.defaultUnit && appConfig.units.get(appConfig.defaultUnit); - return fetch(urlParam!) + return requestedUnit || (appConfig.defaultUnit ? appConfig.getUnit(appConfig.defaultUnit) : undefined); +} + +export function getUnitJson(unitId: string | undefined, appConfig: AppConfigModelType) { + const unitSpec = getUnitSpec(unitId, appConfig); + const unitUrl = unitSpec?.content; + return fetch(unitUrl!) + .then(response => { + if (response.ok) { + return response.json(); + } + else { + throw Error(`Request rejected with status ${response.status}`); + } + }) + .catch(error => { + throw Error(`Request rejected with exception`); + }); +} + +export function getGuideJson(unitId: string | undefined, appConfig: AppConfigModelType) { + const unitSpec = getUnitSpec(unitId, appConfig); + const guideUrl = unitSpec?.guide; + if (!guideUrl) return; + return fetch(guideUrl) .then(response => { if (response.ok) { return response.json(); diff --git a/src/models/document/document-content.test.ts b/src/models/document/document-content.test.ts index aa80d06e62..2a269a101f 100644 --- a/src/models/document/document-content.test.ts +++ b/src/models/document/document-content.test.ts @@ -1,9 +1,17 @@ -import { DocumentContentModel, DocumentContentModelType, cloneContentWithUniqueIds, DocumentContentSnapshotType - } from "./document-content"; +import { + DocumentContentModel, DocumentContentModelType, cloneContentWithUniqueIds, DocumentContentSnapshotType +} from "./document-content"; import { IDropRowInfo } from "../../models/document/document-content"; import { cloneTileSnapshotWithoutId, IDragTileItem } from "../../models/tools/tool-tile"; import { defaultTextContent } from "../tools/text/text-content"; +// mock uniqueId so we can recognize auto-generated IDs +const { uniqueId, safeJsonParse } = jest.requireActual("../../utilities/js-utils"); +jest.mock("../../utilities/js-utils", () => ({ + uniqueId: () => `testid-${uniqueId()}`, + safeJsonParse: (json: string) => safeJsonParse(json) +})); + describe("DocumentContentModel", () => { let documentContent: DocumentContentModelType; @@ -244,7 +252,7 @@ describe("DocumentContentModel -- sectioned documents --", () => { it("will remove placeholder tiles when adding a new tile in an interior section", () => { // [Header:A, Placeholder, Header:B, Text] - content.addTileInNewRow(defaultTextContent("foo"), { rowIndex: 1 }); + content.addTileContentInNewRow(defaultTextContent("foo"), { rowIndex: 1 }); // [Header:A, Text, Header:B, Text] expect(content.rowCount).toBe(4); expect(isContentSection("A")).toBe(true); @@ -695,7 +703,7 @@ describe("DocumentContentModel -- move/copy tiles --", () => { const rowLayout: any = {}; documentContent.rowOrder.forEach(rowId => { const row = documentContent.getRow(rowId); - const key = rowId.indexOf("-") !== -1 ? "NEW_ROW" : rowId; + const key = rowId.indexOf("testid-") !== -1 ? "NEW_ROW" : rowId; rowLayout[key] = []; row?.tiles.forEach((rowTile, index) => { const tileType = documentContent.getTile(rowTile.tileId)!.content.type.toUpperCase(); diff --git a/src/models/document/document-content.ts b/src/models/document/document-content.ts index 9509261058..5f6eb66c1f 100644 --- a/src/models/document/document-content.ts +++ b/src/models/document/document-content.ts @@ -1,3 +1,4 @@ +import { cloneDeep, each } from "lodash"; import { types, getSnapshot, Instance, SnapshotIn } from "mobx-state-tree"; import { kDrawingToolID, StampModelType } from "../tools/drawing/drawing-content"; import { kGeometryToolID } from "../tools/geometry/geometry-content"; @@ -7,24 +8,28 @@ import { kTableToolID } from "../tools/table/table-content"; import { kTextToolID } from "../tools/text/text-content"; import { getToolContentInfoById } from "../tools/tool-content-info"; import { ToolContentUnionType } from "../tools/tool-types"; -import { createToolTileModelFromContent, ToolTileModel, ToolTileModelType, ToolTileSnapshotOutType - } from "../tools/tool-tile"; +import { + ToolTileModel, ToolTileModelType, ToolTileSnapshotInType, ToolTileSnapshotOutType +} from "../tools/tool-tile"; import { TileRowModel, TileRowModelType, TileRowSnapshotType, TileRowSnapshotOutType } from "../document/tile-row"; -import { cloneDeep, each } from "lodash"; -import { v4 as uuid } from "uuid"; import { Logger, LogEventName } from "../../lib/logger"; import { IDragTileItem } from "../../models/tools/tool-tile"; import { DocumentsModelType } from "../stores/documents"; +import { DisplayUserType } from "../stores/user-types"; +import { safeJsonParse, uniqueId } from "../../utilities/js-utils"; import { getParentWithTypeName } from "../../utilities/mst-utils"; import { DocumentTool, IDocumentAddTileOptions } from "./document"; -import { safeJsonParse } from "../../utilities/js-utils"; export interface INewTileOptions { rowHeight?: number; rowIndex?: number; } -export interface INewGeometryTileOptions extends INewTileOptions { +export interface INewTitledTileOptions extends INewTileOptions { + title?: string; +} + +export interface INewGeometryTileOptions extends INewTitledTileOptions { addSidecarNotes?: boolean; } @@ -54,6 +59,11 @@ export interface IDocumentContentAddTileOptions extends IDocumentAddTileOptions insertRowInfo?: IDropRowInfo; } +export interface IDragToolCreateInfo { + tool: DocumentTool; + title?: string; +} + export interface ITileCountsPerSection { [key: string]: number; } @@ -75,7 +85,7 @@ export const DocumentContentModel = types })) .views(self => { // used for drag/drop self-drop detection, for instance - const contentId = uuid(); + const contentId = uniqueId(); function rowContainsTile(rowId: string, tileId: string) { const row = self.rowMap.get(rowId); @@ -104,7 +114,7 @@ export const DocumentContentModel = types }, getTileContent(tileId: string): ToolContentUnionType | undefined { const tile = self.tileMap.get(tileId); - return tile && tile.content; + return tile?.content; }, get rowCount() { return self.rowOrder.length; @@ -168,7 +178,7 @@ export const DocumentContentModel = types snapshot.tileMap = (tileMap => { const _tileMap: { [id: string]: ToolTileSnapshotOutType } = {}; each(tileMap, (tile, id) => { - idMap[id] = tile.id = uuid(); + idMap[id] = tile.id = uniqueId(); _tileMap[tile.id] = tile; }); return _tileMap; @@ -182,7 +192,7 @@ export const DocumentContentModel = types snapshot.rowMap = (rowMap => { const _rowMap: { [id: string]: TileRowSnapshotOutType } = {}; each(rowMap, (row, id) => { - idMap[id] = row.id = uuid(); + idMap[id] = row.id = uniqueId(); row.tiles = row.tiles.map(tileLayout => { tileLayout.tileId = idMap[tileLayout.tileId]; return tileLayout; @@ -232,11 +242,35 @@ export const DocumentContentModel = types }); return tiles; }, + getTilesOfType(type: string) { + const tiles: string[] = []; + self.rowOrder.forEach(rowId => { + const row = self.getRow(rowId); + each(row?.tiles, tileEntry => { + const tile = self.getTile(tileEntry.tileId); + if (tile?.content.type === type) { + tiles.push(tileEntry.tileId); + } + }); + }); + return tiles; + }, publish() { return JSON.stringify(self.snapshotWithUniqueIds()); } })) .views(self => ({ + getUniqueTitle(tileType: string, titleBase: string, getTileTitle: (tileId: string) => string | undefined) { + const tiles = self.getTilesOfType(tileType); + const maxDefaultTitleIndex = tiles.reduce((maxIndex: number, tileId: string) => { + const title = getTileTitle(tileId); + const match = title?.match(new RegExp(`${titleBase} (\\d+)`)); + return match?.[1] + ? Math.max(maxIndex, +match[1]) + : maxIndex; + }, 0); + return `${titleBase} ${maxDefaultTitleIndex + 1}`; + }, getTileCountsPerSection(sectionIds: string[]): ITileCountsPerSection { const counts: ITileCountsPerSection = {}; sectionIds.forEach(sectionId => { @@ -326,8 +360,7 @@ export const DocumentContentModel = types self.addPlaceholderRowIfAppropriate(i); } }, - addTileInNewRow(content: ToolContentUnionType, options?: INewTileOptions): INewRowTile { - const tile = createToolTileModelFromContent(content); + addTileInNewRow(tile: ToolTileModelType, options?: INewTileOptions): INewRowTile { const o = options || {}; if (o.rowIndex === undefined) { // by default, insert new tiles after last visible on screen @@ -339,9 +372,17 @@ export const DocumentContentModel = types row.setRowHeight(o.rowHeight); } return { rowId: row.id, tileId: tile.id }; + } + })) + .actions(self => ({ + addTileContentInNewRow(content: ToolContentUnionType, options?: INewTileOptions): INewRowTile { + return self.addTileInNewRow(ToolTileModel.create({ content }), options); }, - addTileInExistingRow(content: ToolContentUnionType, options: INewTileOptions): INewRowTile | undefined { - const tile = createToolTileModelFromContent(content); + addTileSnapshotInNewRow(snapshot: ToolTileSnapshotInType, options?: INewTileOptions): INewRowTile { + return self.addTileInNewRow(ToolTileModel.create(snapshot), options); + }, + addTileSnapshotInExistingRow(snapshot: ToolTileSnapshotInType, options: INewTileOptions): INewRowTile | undefined { + const tile = ToolTileModel.create(snapshot); const o = options || {}; if (o.rowIndex === undefined) { // by default, insert new tiles after last visible on screen @@ -371,38 +412,38 @@ export const DocumentContentModel = types addPlaceholderTile(sectionId?: string) { const placeholderContentInfo = getToolContentInfoById(kPlaceholderToolID); const content = placeholderContentInfo?.defaultContent(sectionId); - return self.addTileInNewRow(content, { rowIndex: self.rowCount }); + return self.addTileContentInNewRow(content, { rowIndex: self.rowCount }); }, addGeometryTile(options?: INewGeometryTileOptions) { const geometryContentInfo = getToolContentInfoById(kGeometryToolID); - const result = self.addTileInNewRow( - geometryContentInfo?.defaultContent(), + const result = self.addTileContentInNewRow( + geometryContentInfo?.defaultContent({ title: options?.title }), { rowHeight: geometryContentInfo?.defaultHeight, ...options }); if (options?.addSidecarNotes) { const { rowId } = result; const row = self.rowMap.get(rowId); const textContentInfo = getToolContentInfoById(kTextToolID); if (row && textContentInfo) { - const tile = createToolTileModelFromContent(textContentInfo.defaultContent()); + const tile = ToolTileModel.create({ content: textContentInfo.defaultContent() }); self.insertNewTileInRow(tile, row, 1); result.additionalTileIds = [ tile.id ]; } } return result; }, - addTableTile(options?: INewTileOptions) { + addTableTile(options?: INewTitledTileOptions) { const tableContentInfo = getToolContentInfoById(kTableToolID); - return self.addTileInNewRow( - tableContentInfo?.defaultContent(), + return self.addTileContentInNewRow( + tableContentInfo?.defaultContent({ title: options?.title }), { rowHeight: tableContentInfo?.defaultHeight, ...options }); }, addTextTile(options?: INewTextTileOptions) { const textContentInfo = getToolContentInfoById(kTextToolID); - return self.addTileInNewRow(textContentInfo?.defaultContent(options?.text), options); + return self.addTileContentInNewRow(textContentInfo?.defaultContent(options?.text), options); }, addImageTile(options?: INewImageTileOptions) { const imageContentInfo = getToolContentInfoById(kImageToolID); - return self.addTileInNewRow(imageContentInfo?.defaultContent(options?.url), options); + return self.addTileContentInNewRow(imageContentInfo?.defaultContent(options?.url), options); }, addDrawingTile(options?: INewTileOptions) { let defaultStamps: StampModelType[]; @@ -413,7 +454,7 @@ export const DocumentContentModel = types defaultStamps = []; } const drawingContentInfo = getToolContentInfoById(kDrawingToolID); - return self.addTileInNewRow( + return self.addTileContentInNewRow( drawingContentInfo?.defaultContent({stamps: defaultStamps}), { rowHeight: drawingContentInfo.defaultHeight, ...options }); }, @@ -430,7 +471,7 @@ export const DocumentContentModel = types if (tile.rowHeight) { rowOptions.rowHeight = tile.rowHeight; } - result = self.addTileInExistingRow(content, rowOptions); + result = self.addTileSnapshotInExistingRow({ content }, rowOptions); } results.push(result); }); @@ -453,14 +494,14 @@ export const DocumentContentModel = types rowOptions.rowHeight = tile.rowHeight; } if (tile.rowIndex !== lastRowIndex) { - result = self.addTileInNewRow(content, rowOptions); + result = self.addTileContentInNewRow(content, rowOptions); if (lastRowIndex !== -1) { rowDelta++; } lastRowIndex = tile.rowIndex; } else { - result = self.addTileInExistingRow(content, rowOptions); + result = self.addTileSnapshotInExistingRow({ content }, rowOptions); } } results.push(result); @@ -589,7 +630,7 @@ export const DocumentContentModel = types } }, addTile(tool: DocumentTool, options?: IDocumentContentAddTileOptions) { - const {addSidecarNotes, url, insertRowInfo} = options || {}; + const { title, addSidecarNotes, url, insertRowInfo } = options || {}; // for historical reasons, this function initially places new rows at // the end of the content and then moves them to the desired location. const addTileOptions = { rowIndex: self.rowCount }; @@ -599,10 +640,10 @@ export const DocumentContentModel = types tileInfo = self.addTextTile(addTileOptions); break; case "table": - tileInfo = self.addTableTile(addTileOptions); + tileInfo = self.addTableTile({ title, ...addTileOptions }); break; case "geometry": - tileInfo = self.addGeometryTile({ addSidecarNotes, ...addTileOptions }); + tileInfo = self.addGeometryTile({ title, addSidecarNotes, ...addTileOptions }); break; case "image": tileInfo = self.addImageTile({ url, ...addTileOptions }); @@ -776,31 +817,59 @@ export interface IAuthoredTile { } export interface IAuthoredDocumentContent { - tiles: IAuthoredTile[]; + tiles: Array; } -function migrateSnapshot(snapshot: any): any { - interface OriginalTileLayoutModel { - height?: number; - } +interface OriginalTileLayoutModel { + height?: number; +} - interface OriginalToolTileModel { - layout?: OriginalTileLayoutModel; - content: any; +interface OriginalToolTileModel { + display?: DisplayUserType; + layout?: OriginalTileLayoutModel; + content: any; +} +type OriginalTilesSnapshot = Array; + +function migrateTile(content: DocumentContentModelType, tile: OriginalToolTileModel) { + const { layout, ...newTile } = cloneDeep(tile); + const tileHeight = layout?.height; + const { isSectionHeader, sectionId } = newTile.content; + if (isSectionHeader && sectionId) { + content.addSectionHeaderRow(sectionId); + } + else { + const options = { rowIndex: content.rowCount, rowHeight: tileHeight }; + content.addTileSnapshotInNewRow(newTile, options); } +} +function migrateRow(content: DocumentContentModelType, tiles: OriginalToolTileModel[]) { + let insertRowIndex = content.rowCount; + tiles.forEach((tile, tileIndex) => { + const { layout, ...newTile } = cloneDeep(tile); + const tileHeight = layout?.height; + const options = { rowIndex: insertRowIndex, rowHeight: tileHeight }; + if (tileIndex === 0) { + const newRowInfo = content.addTileSnapshotInNewRow(newTile, options); + const newRowIndex = content.getRowIndex(newRowInfo.rowId); + (newRowIndex >= 0) && (insertRowIndex = newRowIndex); + } + else { + content.addTileSnapshotInExistingRow(newTile, options); + } + }); +} + +function migrateSnapshot(snapshot: any): any { const docContent = DocumentContentModel.create(); - const tiles: OriginalToolTileModel[] = snapshot.tiles; - tiles.forEach(tile => { - const newTile = cloneDeep(tile); - const tileHeight = newTile.layout && newTile.layout.height; - const { isSectionHeader, sectionId } = newTile.content; - if (isSectionHeader && sectionId) { - docContent.addSectionHeaderRow(sectionId); + const tilesOrRows: OriginalTilesSnapshot = snapshot.tiles; + tilesOrRows.forEach(tileOrRow => { + if (Array.isArray(tileOrRow)) { + migrateRow(docContent, tileOrRow); } else { - const options = { rowIndex: docContent.rowCount, rowHeight: tileHeight }; - docContent.addTileInNewRow(newTile.content, options); + migrateTile(docContent, tileOrRow); } }); return getSnapshot(docContent); diff --git a/src/models/document/document.ts b/src/models/document/document.ts index e872eeb5bc..3e93c09857 100644 --- a/src/models/document/document.ts +++ b/src/models/document/document.ts @@ -12,6 +12,7 @@ import { IDocumentProperties } from "../../lib/db-types"; import { getLocalTimeStamp } from "../../utilities/time"; export interface IDocumentAddTileOptions { + title?: string; addSidecarNotes?: boolean; url?: string; } @@ -113,8 +114,10 @@ export const DocumentModel = types if (!docDisplayIdPropertyName) return undefined; if (docDisplayIdPropertyName === "key") return self.key; return self.getProperty(docDisplayIdPropertyName); + }, + getUniqueTitle(tileType: string, titleBase: string, getTileTitle: (tileId: string) => string | undefined) { + return self.content.getUniqueTitle(tileType, titleBase, getTileTitle); } - })) .views(self => ({ isMatchingSpec(type: DocumentType, properties: string[]) { diff --git a/src/models/document/tile-row.ts b/src/models/document/tile-row.ts index 4f55fec678..bd7a6c5d2d 100644 --- a/src/models/document/tile-row.ts +++ b/src/models/document/tile-row.ts @@ -1,6 +1,6 @@ import { types, Instance, SnapshotIn, SnapshotOut } from "mobx-state-tree"; -import { v4 as uuid } from "uuid"; import { ToolTileModelType } from "../tools/tool-tile"; +import { uniqueId } from "../../utilities/js-utils"; export const TileLayoutModel = types .model("TileLayout", { @@ -22,7 +22,7 @@ export type TileLayoutModelType = Instance; export const TileRowModel = types .model("TileRow", { - id: types.optional(types.identifier, () => uuid()), + id: types.optional(types.identifier, () => uniqueId()), height: types.maybe(types.number), isSectionHeader: false, sectionId: types.maybe(types.string), @@ -53,10 +53,6 @@ export const TileRowModel = types }, indexOfTile(tileId: string) { return self.tiles.findIndex(tileRef => tileRef.tileId === tileId); - }, - renderWidth(tileId: string) { - // for now, tiles divide row evenly - return 100 / (self.tiles.length || 1); } })) .actions(self => ({ diff --git a/src/models/image-map.ts b/src/models/image-map.ts index 34a231ea9b..4ff8a1ae9c 100644 --- a/src/models/image-map.ts +++ b/src/models/image-map.ts @@ -112,11 +112,11 @@ export const ImageMapModel = types getImageDimensions(entry && entry.displayUrl || url) .then(dimensions => { - const _entry = self.images.get(url); - if (_entry) { + const imageEntry = self.images.get(url); + if (imageEntry) { self.setDimensions(url, dimensions.width, dimensions.height); - self.syncContentUrl(url, _entry); - resolve(self.images.get(url)); + self.syncContentUrl(url, imageEntry); + resolve(imageEntry); } }); }); @@ -171,8 +171,9 @@ export const ImageMapModel = types resolve(clone(self.images.get(placeholderImage)!)); } - if (self.images.has(url)) { - return resolve(self.images.get(url)); + const imageEntry = self.images.get(url); + if (imageEntry) { + return resolve(imageEntry); } const handler = self.getHandler(url); diff --git a/src/models/stores/app-config-model.ts b/src/models/stores/app-config-model.ts index 9cacdb9974..67d5057abd 100644 --- a/src/models/stores/app-config-model.ts +++ b/src/models/stores/app-config-model.ts @@ -5,6 +5,12 @@ import { ToolButtonModel } from "../tools/tool-types"; import { ENavTab, NavTabModel, NavTabSpec } from "../view/nav-tabs"; import { SettingsMstType } from "./settings"; +const UnitSpecModel = types + .model("UnitSpec", { + content: types.string, + guide: "" + }); + const DocumentSpecModel = types .model("DocumentSpec", { documentType: types.string, @@ -46,7 +52,7 @@ export const AppConfigModel = types appName: "", pageTitle: "", demoProblemTitle: "", - units: types.map(types.string), + units: types.map(UnitSpecModel), unitCodeMap: types.map(types.string), defaultProblemOrdinal: "", defaultUnit: "", @@ -75,6 +81,10 @@ export const AppConfigModel = types settings: types.maybe(SettingsMstType) }) .views(self => ({ + getUnit(unitId: string) { + const unitCode = self.unitCodeMap.get(unitId) || unitId; + return self.units.get(unitCode); + }, get defaultDocumentContent(): DocumentContentModelType | undefined { return cloneContentWithUniqueIds(self.defaultDocumentTemplate); }, diff --git a/src/models/stores/stores.ts b/src/models/stores/stores.ts index aaefaf66f5..def14b7a9a 100644 --- a/src/models/stores/stores.ts +++ b/src/models/stores/stores.ts @@ -1,5 +1,5 @@ import { AppConfigModelType, AppConfigModel } from "./app-config-model"; -import { getUnitJson, UnitModel, UnitModelType } from "../curriculum/unit"; +import { getGuideJson, getUnitJson, UnitModel, UnitModelType } from "../curriculum/unit"; import { InvestigationModelType, InvestigationModel } from "../curriculum/investigation"; import { ProblemModel, ProblemModelType } from "../curriculum/problem"; import { UIModel, UIModelType } from "./ui"; @@ -24,6 +24,7 @@ export interface IBaseStores { unit: UnitModelType; investigation: InvestigationModelType; problem: ProblemModelType; + teacherGuide?: ProblemModelType; user: UserModelType; ui: UIModelType; groups: GroupsModelType; @@ -102,17 +103,27 @@ export const setUnitAndProblem = async (stores: IStores, unitId: string | undefi const unit = UnitModel.create(unitJson); const {investigation, problem} = unit.getProblem(problemOrdinal || stores.appConfig.defaultProblemOrdinal); - if (unit) { - stores.unit = unit; - stores.documents.setUnit(stores.unit); - if (investigation && problem) { - stores.investigation = investigation; - stores.problem = problem; - } - stores.problemPath = getProblemPath(stores); + stores.unit = unit; + stores.documents.setUnit(stores.unit); + if (investigation && problem) { + stores.investigation = investigation; + stores.problem = problem; + } + stores.problemPath = getProblemPath(stores); + + const guideJson = await getGuideJson(unitId, stores.appConfig); + const unitGuide = guideJson && UnitModel.create(guideJson); + const teacherGuide = unitGuide?.getProblem(problemOrdinal || stores.appConfig.defaultProblemOrdinal)?.problem; + if (teacherGuide) { + stores.teacherGuide = teacherGuide; } }; +export function isShowingTeacherContent(stores: IStores) { + const { ui: { showTeacherContent }, user: { isTeacher } } = stores; + return isTeacher && showTeacherContent; +} + export function isFeatureSupported(stores: IStores, feature: string, sectionId?: string) { const { unit, investigation, problem } = stores; const section = sectionId && problem.getSectionById(sectionId); diff --git a/src/models/stores/ui.ts b/src/models/stores/ui.ts index fcb0d04737..ea04c9f9e1 100644 --- a/src/models/stores/ui.ts +++ b/src/models/stores/ui.ts @@ -11,8 +11,8 @@ export type ToggleElement = "leftNavExpanded"; export const UIDialogTypeEnum = types.enumeration("dialogType", ["alert", "confirm", "prompt"]); export type UIDialogType = typeof UIDialogTypeEnum.Type; -type BooleanDialogResolver = (value?: boolean | PromiseLike | undefined) => void; -type StringDialogResolver = (value?: string | PromiseLike | undefined) => void; +type BooleanDialogResolver = (value: boolean | PromiseLike) => void; +type StringDialogResolver = (value: string | PromiseLike) => void; let dialogResolver: BooleanDialogResolver | StringDialogResolver | undefined; export const UIDialogModel = types @@ -36,6 +36,7 @@ export const UIModel = types selectedTileIds: types.array(types.string), showDemo: false, showDemoCreator: false, + showTeacherContent: true, dialog: types.maybe(UIDialogModel), problemWorkspace: WorkspaceModel, learningLogWorkspace: WorkspaceModel, @@ -119,6 +120,9 @@ export const UIModel = types toggleNavTabContent(show: boolean) { self.navTabContentShown = show; }, + toggleShowTeacherContent(show: boolean) { + self.showTeacherContent = show; + }, setError(error: string|null) { self.error = error ? error.toString() : error; }, diff --git a/src/models/stores/user-types.ts b/src/models/stores/user-types.ts new file mode 100644 index 0000000000..fd3a43fd8b --- /dev/null +++ b/src/models/stores/user-types.ts @@ -0,0 +1,7 @@ +import { Instance, types } from "mobx-state-tree"; + +export const UserTypeEnum = types.enumeration("type", ["student", "teacher"]); +export type UserType = Instance; + +export const DisplayUserTypeEnum = types.maybe(UserTypeEnum); +export type DisplayUserType = Instance; diff --git a/src/models/stores/user.ts b/src/models/stores/user.ts index 192c8257e3..f3d3093522 100644 --- a/src/models/stores/user.ts +++ b/src/models/stores/user.ts @@ -1,10 +1,8 @@ +import initials from "initials"; import { types } from "mobx-state-tree"; import { AuthenticatedUser } from "../../lib/auth"; import { PortalFirebaseStudentJWT } from "../../lib/portal-types"; -import initials from "initials"; - -export const UserTypeEnum = types.enumeration("type", ["student", "teacher"]); -export type UserType = typeof UserTypeEnum.Type; +import { UserTypeEnum } from "./user-types"; export const PortalClassOffering = types .model("PortalClassOffering", { diff --git a/src/models/tools/geometry/geometry-content.test.ts b/src/models/tools/geometry/geometry-content.test.ts index a198208b12..b4f408bd10 100644 --- a/src/models/tools/geometry/geometry-content.test.ts +++ b/src/models/tools/geometry/geometry-content.test.ts @@ -1,16 +1,22 @@ import { GeometryContentModel, GeometryContentModelType, kGeometryToolID, defaultGeometryContent, GeometryMetadataModel } from "./geometry-content"; import { JXGChange } from "./jxg-changes"; -import { isBoard } from "./jxg-board"; -import { isPoint, isFreePoint } from "./jxg-point"; -import { isPointInPolygon, isPolygon, getPointsForVertexAngle } from "./jxg-polygon"; +import { isPointInPolygon, getPointsForVertexAngle } from "./jxg-polygon"; import { canSupportVertexAngle, getVertexAngle, updateVertexAnglesFromObjects } from "./jxg-vertex-angle"; -import { isUuid } from "../../../utilities/test-utils"; +import { isBoard, isFreePoint, isPoint, isPolygon } from "./jxg-types"; import { clone } from "lodash"; import { destroy } from "mobx-state-tree"; import placeholderImage from "../../../assets/image_placeholder.png"; +// mock uniqueId so we can recognize auto-generated IDs +const { uniqueId, castArrayCopy, safeJsonParse } = jest.requireActual("../../../utilities/js-utils"); +jest.mock("../../../utilities/js-utils", () => ({ + uniqueId: () => `testid-${uniqueId()}`, + castArrayCopy: (itemOrArray: any) => castArrayCopy(itemOrArray), + safeJsonParse: (json: string) => safeJsonParse(json) +})); + describe("GeometryContent", () => { const divId = "1234"; @@ -142,7 +148,7 @@ describe("GeometryContent", () => { content.removeObjects(board, p1Id); expect(board.objects[p1Id]).toBeUndefined(); const p3: JXG.Point = content.addPoint(board, [2, 2]) as JXG.Point; - expect(isUuid(p3.id)).toBe(true); + expect(p3.id.startsWith("testid-")).toBe(true); // requests to remove points with invalid IDs are ignored content.removeObjects(board, ["foo"]); content.applyChange(board, { operation: "delete", target: "point" }); @@ -159,7 +165,7 @@ describe("GeometryContent", () => { let polygon: JXG.Polygon | undefined = content.createPolygonFromFreePoints(board) as JXG.Polygon; expect(isPolygon(polygon)).toBe(true); const polygonId = polygon.id; - expect(isUuid(polygonId)).toBe(true); + expect(polygonId.startsWith("testid-")).toBe(true); const ptInPolyCoords = new JXG.Coords(JXG.COORDS_BY_USER, [3, 2], board); const [, ptInScrX, ptInScrY] = ptInPolyCoords.scrCoords; diff --git a/src/models/tools/geometry/geometry-content.ts b/src/models/tools/geometry/geometry-content.ts index 4104ed0b08..38c51aa951 100644 --- a/src/models/tools/geometry/geometry-content.ts +++ b/src/models/tools/geometry/geometry-content.ts @@ -4,22 +4,26 @@ import { Optional } from "utility-types"; import { SelectionStoreModelType } from "../../stores/selection"; import { addLinkedTable } from "../table-links"; import { registerToolContentInfo } from "../tool-content-info"; -import { getTableContent, ITableChange, ITableLinkProperties, kLabelAttrName } from "../table/table-content"; -import { getAxisAnnotations, getBaseAxisLabels, guessUserDesiredBoundingBox, isBoard, +import { + getAxisLabelsFromDataSet, getRowLabelFromLinkProps, getTableContent, IColumnProperties, + ICreateRowsProperties, IRowProperties, ITableChange, ITableLinkProperties, kLabelAttrName +} from "../table/table-content"; +import { canonicalizeValue, linkedPointId } from "../table/table-model-types"; +import { getAxisAnnotations, getBaseAxisLabels, getObjectById, guessUserDesiredBoundingBox, kAxisBuffer, kGeometryDefaultAxisMin, kGeometryDefaultHeight, kGeometryDefaultWidth, kGeometryDefaultPixelsPerUnit, syncAxisLabels, toObj } from "./jxg-board"; import { ESegmentLabelOption, forEachNormalizedChange, ILinkProperties, JXGChange, JXGCoordPair, JXGProperties, JXGParentType, JXGUnsafeCoordPair, JXGStringPair } from "./jxg-changes"; import { applyChange, applyChanges, IDispatcherChangeContext } from "./jxg-dispatcher"; import { isMovableLine } from "./jxg-movable-line"; -import { isFreePoint, isPoint, kPointDefaults, kSnapUnit } from "./jxg-point"; -import { isPolygon, isVisibleEdge, prepareToDeleteObjects } from "./jxg-polygon"; -import { isLinkedPoint } from "./jxg-table-link"; -import { isComment } from "./jxg-types"; -import { isVertexAngle } from "./jxg-vertex-angle"; +import { kPointDefaults, kSnapUnit } from "./jxg-point"; +import { prepareToDeleteObjects } from "./jxg-polygon"; +import { getTableIdFromLinkChange } from "./jxg-table-link"; +import { + isBoard, isComment, isFreePoint, isLinkedPoint, isPoint, isPolygon, isVertexAngle, isVisibleEdge +} from "./jxg-types"; import { IDataSet } from "../../data/data-set"; import { assign, castArray, each, keys, omit, size as _size } from "lodash"; -import { v4 as uuid } from "uuid"; import { safeJsonParse, uniqueId } from "../../../utilities/js-utils"; import { getTileContentById } from "../../../utilities/mst-utils"; import { Logger, LogEventName } from "../../../lib/logger"; @@ -87,9 +91,15 @@ function defaultGeometryBoardChange(overrides?: JXGProperties) { } export function defaultGeometryContent(overrides?: JXGProperties): GeometryContentModelType { - const change = defaultGeometryBoardChange(overrides); - const changeJson = JSON.stringify(change); - return GeometryContentModel.create({ changes: [changeJson] }); + const { title, ...boardProps } = overrides || {}; + const changes: string[] = []; + if (title) { + const titleChange: JXGChange = { operation: "update", target: "metadata", properties: { title } }; + changes.push(JSON.stringify(titleChange)); + } + const boardChange = defaultGeometryBoardChange(boardProps); + changes.push(JSON.stringify(boardChange)); + return GeometryContentModel.create({ changes }); } export function getGeometryContent(target: IAnyStateTreeNode, tileId: string): GeometryContentModelType | undefined { @@ -114,6 +124,7 @@ const LinkedTableEntryModel = types export const GeometryMetadataModel = types .model("GeometryMetadata", { id: types.string, + title: types.maybe(types.string), disabled: types.array(types.string), selection: types.map(types.boolean), linkedTables: types.array(LinkedTableEntryModel) @@ -122,12 +133,23 @@ export const GeometryMetadataModel = types sharedSelection: undefined as any as SelectionStoreModelType, tableLinkDisposers: {} as { [id: string]: Lambda } })) + .views(self => ({ + isSharedSelected(id: string) { + const _id = id?.includes(":") ? id.split(":")[0] : id; + let isSelected = false; + self.sharedSelection?.sets.forEach(set => { + // ignore labels with auto-assigned IDs associated with selected points + if (set.isSelected(_id) && !id.endsWith("Label")) isSelected = true; + }); + return isSelected; + }, + })) .views(self => ({ isDisabled(feature: string) { return self.disabled.indexOf(feature) >= 0; }, isSelected(id: string) { - return !!self.selection.get(id); + return !!self.selection.get(id) || self.isSharedSelected(id); }, hasSelection() { return Array.from(self.selection.values()).some(isSelected => isSelected); @@ -157,6 +179,9 @@ export const GeometryMetadataModel = types } })) .actions(self => ({ + setTitle(title: string) { + self.title = title; + }, setSharedSelection(sharedSelection: SelectionStoreModelType) { self.sharedSelection = sharedSelection; }, @@ -208,7 +233,7 @@ export const GeometryMetadataModel = types export type GeometryMetadataModelType = Instance; export function setElementColor(board: JXG.Board, id: string, selected: boolean) { - const element = board.objects[id]; + const element = getObjectById(board, id); if (element) { const fillColor = element.getAttribute("clientFillColor") || kPointDefaults.fillColor; const strokeColor = element.getAttribute("clientStrokeColor") || kPointDefaults.strokeColor; @@ -241,19 +266,15 @@ export const GeometryContentModel = types })) .preProcessSnapshot(snapshot => preprocessImportFormat(snapshot)) .views(self => ({ + get title() { + return self.metadata.title; + }, isSelected(id: string) { return self.metadata.isSelected(id); }, hasSelection() { return self.metadata.hasSelection(); }, - get selectedIds() { - const selected: string[] = []; - self.metadata.selection.forEach((isSelected, id) => { - isSelected && selected.push(id); - }); - return selected; - }, get isLinked() { return self.metadata.linkedTables.length > 0; }, @@ -262,6 +283,12 @@ export const GeometryContentModel = types } })) .views(self => ({ + getSelectedIds(board: JXG.Board) { + // returns the ids in creation order + return board.objectsList + .filter(obj => self.isSelected(obj.id)) + .map(obj => obj.id); + }, getDeletableSelectedIds(board: JXG.Board) { // returns the ids in creation order return board.objectsList @@ -299,7 +326,7 @@ export const GeometryContentModel = types return self.getDeletableSelectedIds(board).length > 0; }, selectedObjects(board: JXG.Board) { - return self.selectedIds.map(id => board.objects[id]); + return board.objectsList.filter(obj => self.isSelected(obj.id)); } })) .actions(self => ({ @@ -364,33 +391,45 @@ export const GeometryContentModel = types function handleWillApplyChange(board: JXG.Board | string, change: JXGChange) { const op = change.operation.toLowerCase(); const target = change.target.toLowerCase(); - if (target === "tablelink") { - const tableId = (change.targetID as string) || - (change.parents && change.parents[0] as string); - if (tableId) { - const links = change.links as ITableLinkProperties; - const labels = links && links.labels; - const xEntry = labels && labels.find(entry => entry.id === "xAxis"); - const yEntry = labels && labels.find(entry => entry.id === "yAxis"); - if (op === "create") { - const tableContent = getTableContent(self, tableId); - if (tableContent) { - const axes: IAxisLabels = { x: xEntry && xEntry.label, y: yEntry && yEntry.label }; - self.metadata.addTableLink(tableId, axes); - } - } - else if (op === "delete") { - self.metadata.removeTableLink(tableId); + + if ((op === "update") && (target === "metadata")) { + const props = change?.properties as JXGProperties | undefined; + if (props?.title) { + self.metadata.setTitle(props.title); + } + } + + const tableId = getTableIdFromLinkChange(change); + if (tableId) { + const links = change.links as ITableLinkProperties; + const xLabel = links?.labels?.find(entry => entry.id === "xAxis")?.label; + const yLabel = links?.labels?.find(entry => entry.id === "yAxis")?.label; + if (op === "create") { + const tableContent = getTableContent(self, tableId); + if (tableContent) { + const axes: IAxisLabels = { x: xLabel, y: yLabel }; + self.metadata.addTableLink(tableId, axes); } - else if (op === "update") { - if (xEntry || yEntry) { - self.metadata.setTableLinkNames(tableId, xEntry && xEntry.label, yEntry && yEntry.label); - } + } + else if (op === "delete") { + self.metadata.removeTableLink(tableId); + } + else if (op === "update") { + if (xLabel || yLabel) { + self.metadata.setTableLinkNames(tableId, xLabel, yLabel); } } } } + function getLinkedTableChange(change: JXGChange) { + const links = change.links as ITableLinkProperties | undefined; + const linkId = links?.id; + const tableId = links?.tileIds[0]; + const tableContent = tableId ? getTableContent(self, tableId) : undefined; + return linkId ? tableContent?.getLinkedChange(linkId) : undefined; + } + function handleDidApplyChange(board: JXG.Board | undefined, change: JXGChange) { const { operation } = change; const target = change.target.toLowerCase(); @@ -548,7 +587,7 @@ export const GeometryContentModel = types operation: "create", target: "image", parents: [url, coords, size], - properties: assign({ id: uuid() }, properties) + properties: assign({ id: uniqueId() }, properties) }; const image = _applyChange(board, change); return image ? image as JXG.Image : undefined; @@ -561,7 +600,7 @@ export const GeometryContentModel = types operation: "create", target: "point", parents, - properties: assign({ id: uuid() }, properties) + properties: assign({ id: uniqueId() }, properties) }; const point = _applyChange(board, change); return point ? point as JXG.Point : undefined; @@ -576,7 +615,7 @@ export const GeometryContentModel = types operation: "create", target: links ? "linkedPoint" : "point", parents, - properties: parents.map((p, i) => ({ id: uuid(), ...(props && props[i] || props[0]) })), + properties: parents.map((p, i) => ({ id: uniqueId(), ...(props && props[i] || props[0]) })), links }; const points = _applyChange(board, change); @@ -588,7 +627,7 @@ export const GeometryContentModel = types operation: "create", target: "movableLine", parents, - properties: {id: uuid(), ...properties} + properties: {id: uniqueId(), ...properties} }; const elems = _applyChange(board, change); return elems ? elems as JXG.GeometryElement[] : undefined; @@ -598,7 +637,7 @@ export const GeometryContentModel = types const change: JXGChange = { operation: "create", target: "comment", - properties: {id: uuid(), anchor: anchorId } + properties: {id: uniqueId(), anchor: anchorId } }; const elems = _applyChange(board, change); return elems ? elems as JXG.GeometryElement[] : undefined; @@ -614,6 +653,15 @@ export const GeometryContentModel = types return _applyChange(board, change); } + function updateTitle(board: JXG.Board | undefined, title: string) { + const change: JXGChange = { + operation: "update", + target: "metadata", + properties: { title } + }; + return _applyChange(board, change); + } + function updateObjects(board: JXG.Board | undefined, ids: string | string[], properties: JXGProperties | JXGProperties[], @@ -629,17 +677,19 @@ export const GeometryContentModel = types } function createPolygonFromFreePoints( - board: JXG.Board, linkedTableId?: string, properties?: JXGProperties): JXG.Polygon | undefined { + board: JXG.Board, linkedTableId?: string, linkedColumnId?: string, properties?: JXGProperties + ): JXG.Polygon | undefined { const freePtIds = board.objectsList .filter(elt => isFreePoint(elt) && - (linkedTableId === elt?.getAttribute("linkedTableId"))) + (linkedTableId === elt?.getAttribute("linkedTableId")) && + (linkedColumnId === elt?.getAttribute("linkedColId"))) .map(pt => pt.id); if (freePtIds && freePtIds.length > 1) { const change: JXGChange = { operation: "create", target: "polygon", parents: freePtIds, - properties: assign({ id: uuid() }, properties) + properties: assign({ id: uniqueId() }, properties) }; const polygon = _applyChange(board, change); return polygon ? polygon as any as JXG.Polygon : undefined; @@ -653,31 +703,43 @@ export const GeometryContentModel = types operation: "create", target: "vertexAngle", parents, - properties: assign({ id: uuid(), radius: 1 }, properties) + properties: assign({ id: uniqueId(), radius: 1 }, properties) }; const angle = _applyChange(board, change); return angle ? angle as any as JXG.Angle : undefined; } - function addTableLink(board: JXG.Board, tableId: string, dataSet: IDataSet, links: ILinkProperties) { - const xAttr = dataSet.attributes.length >= 1 ? dataSet.attributes[0] : undefined; - const yAttr = dataSet.attributes.length >= 2 ? dataSet.attributes[1] : undefined; + function addTableLink( + board: JXG.Board | undefined, tableId: string, dataSet: IDataSet, links: ITableLinkProperties) { const axes = { - x: xAttr ? xAttr.name : undefined, - y: yAttr ? yAttr.name : undefined + x: links.labels?.find(entry => entry.id === "xAxis")?.label, + y: links.labels?.find(entry => entry.id === "yAxis")?.label }; + if (!axes.x || !axes.y) { + const [xAxisLabel, yAxisLabel] = getAxisLabelsFromDataSet(dataSet); + !axes.x && xAxisLabel && (axes.x = xAxisLabel); + !axes.y && yAxisLabel && (axes.y = yAxisLabel); + } + + // takes labels from dataSet (added by TableContent.getSharedData) if not in links.labels + const xAttr = dataSet.attributes.length >= 1 ? dataSet.attributes[0] : undefined; const labelAttr = dataSet.attrFromName(kLabelAttrName); const caseCount = dataSet.cases.length; const ids: string[] = []; const points: Array<{ label?: string, coords: JXGUnsafeCoordPair }> = []; for (let i = 0; i < caseCount; ++i) { - const id = dataSet.cases[i].__id__; - const label = labelAttr ? String(dataSet.getValue(id, labelAttr.id)) : undefined; - const x = xAttr ? Number(dataSet.getValue(id, xAttr.id)) : undefined; - const y = yAttr ? Number(dataSet.getValue(id, yAttr.id)) : undefined; - if (id) { - ids.push(id); - points.push({ label, coords: [x, y] }); + const caseId = dataSet.cases[i].__id__; + const labelFromLinks = getRowLabelFromLinkProps(links, caseId); + const label = labelFromLinks || + (labelAttr ? String(dataSet.getValue(caseId, labelAttr.id)) : undefined); + const x = xAttr ? Number(dataSet.getValue(caseId, xAttr.id)) : undefined; + for (let attrIndex = 1; attrIndex < dataSet.attributes.length; ++attrIndex) { + const yAttr = dataSet.attributes[attrIndex]; + if (caseId && yAttr) { + const y = yAttr ? Number(dataSet.getValue(caseId, yAttr.id)) : undefined; + ids.push(`${caseId}:${yAttr.id}`); + points.push({ label, coords: [x, y] }); + } } } self.metadata.addTableLink(tableId, axes); @@ -889,7 +951,7 @@ export const GeometryContentModel = types // map old ids to new ones const newIds: { [oldId: string]: string } = {}; selectedIds.forEach(id => { - newIds[id] = uuid(); + newIds[id] = uniqueId(); }); // create change objects for each object to be copied @@ -1015,6 +1077,7 @@ export const GeometryContentModel = types get batchChangeCount() { return batchChanges.length; }, + getLinkedTableChange, copySelection, findObjects, getOneSelectedPoint, @@ -1047,6 +1110,7 @@ export const GeometryContentModel = types addPoints, addMovableLine, removeObjects, + updateTitle, updateObjects, createPolygonFromFreePoints, addVertexAngle, @@ -1103,7 +1167,177 @@ export const GeometryContentModel = types } } }; - }); + }) + .views(self => ({ + getPositionOfPoint(dataSet: IDataSet, caseId: string, attrId: string): JXGUnsafeCoordPair { + const attrCount = dataSet.attributes.length; + const xAttr = attrCount > 0 ? dataSet.attributes[0] : undefined; + const yAttr = dataSet.attrFromID(attrId); + const xValue = xAttr ? dataSet.getValue(caseId, xAttr.id) : undefined; + const yValue = yAttr ? dataSet.getValue(caseId, yAttr.id) : undefined; + return [canonicalizeValue(xValue), canonicalizeValue(yValue)]; + } + })) + .views(self => ({ + getPointPositionsForColumns(dataSet: IDataSet, attrIds: string[]): [string[], JXGUnsafeCoordPair[]] { + const pointIds: string[] = []; + const positions: JXGUnsafeCoordPair[] = []; + dataSet.cases.forEach(aCase => { + const caseId = aCase.__id__; + attrIds.forEach(attrId => { + pointIds.push(linkedPointId(caseId, attrId)); + positions.push(self.getPositionOfPoint(dataSet, caseId, attrId)); + }); + }); + return [pointIds, positions]; + }, + getPointPositionsForRowsChange(dataSet: IDataSet, change: ITableChange): [string[], JXGUnsafeCoordPair[]] { + const pointIds: string[] = []; + const positions: JXGUnsafeCoordPair[] = []; + const caseIds = castArray(change.ids); + const propsArray: IRowProperties[] = change.action === "create" + ? (change.props as ICreateRowsProperties)?.rows + : castArray(change.props as any); + const xAttrId = dataSet.attributes.length > 0 ? dataSet.attributes[0].id : undefined; + caseIds.forEach((caseId, caseIndex) => { + const tableProps = (propsArray[caseIndex] || propsArray[0]) as IRowProperties; + // if x value changes, all points in row are affected + if (xAttrId && tableProps[xAttrId] != null) { + for (let attrIndex = 1; attrIndex < dataSet.attributes.length; ++attrIndex) { + const attrId = dataSet.attributes[attrIndex].id; + const pointId = linkedPointId(caseId, attrId); + const position = self.getPositionOfPoint(dataSet, caseId, attrId); + if (pointId && position) { + pointIds.push(pointId); + positions.push(position); + } + } + } + // otherwise, only points with y-value changes are affected + else { + each(tableProps, (value, attrId) => { + const pointId = linkedPointId(caseId, attrId); + const position = self.getPositionOfPoint(dataSet, caseId, attrId); + if (pointId && position) { + pointIds.push(pointId); + positions.push(position); + } + }); + } + }); + return [pointIds, positions]; + } + })) + .actions(self => ({ + syncColumnsChange(dataSet: IDataSet, change: ITableChange, links: ITableLinkProperties) { + const tableId = links.tileIds[0]; + let shouldUpdateAxisLabels = false; + switch (change.action) { + case "create": { + // new column => new point for each case + const attrIds = castArray(change.ids); + const [pointIds, positions] = self.getPointPositionsForColumns(dataSet, attrIds); + const props = pointIds.map(id => ({ id })); + pointIds && pointIds.length && self.addPoints(undefined, positions, props, links); + shouldUpdateAxisLabels = true; + break; + } + case "update": { + const ids = castArray(change.ids); + const attrIdsWithExpr: string[] = []; + const changeProps: IColumnProperties[] = castArray(change.props as any); + ids.forEach((attrId, index) => { + const props = changeProps[index] || changeProps[0]; + // update column name => update axis labels + if (props.name != null) { + shouldUpdateAxisLabels = true; + } + // update column expression => update points associated with column + if (props.expression != null) { + attrIdsWithExpr.push(attrId); + } + }); + if (attrIdsWithExpr.length) { + const [pointIds, positions] = self.getPointPositionsForColumns(dataSet, attrIdsWithExpr); + const props = positions.map(position => ({ position })); + pointIds && pointIds.length && self.updateObjects(undefined, pointIds, props, links); + } + break; + } + case "delete": { + // delete column => remove points associated with column + const pointIds: string[] = []; + const ids = castArray(change.ids); + ids.forEach(attrId => { + dataSet.cases.forEach(aCase => { + const caseId = aCase.__id__; + pointIds.push(linkedPointId(caseId, attrId)); + }); + shouldUpdateAxisLabels = true; + }); + pointIds && pointIds.length && self.removeObjects(undefined, pointIds, links); + break; + } + } + shouldUpdateAxisLabels && self.updateAxisLabels(undefined, tableId, links); + }, + syncRowsChange(dataSet: IDataSet, change: ITableChange, links: ITableLinkProperties) { + switch (change.action) { + case "create": { + // new table row => new points for each attribute in row + const [pointIds, positions] = self.getPointPositionsForRowsChange(dataSet, change); + const props = pointIds.map(id => ({ id })); + pointIds && pointIds.length && self.addPoints(undefined, positions, props, links); + break; + } + case "update": { + // update table row => update points associated with row + const [pointIds, positions] = self.getPointPositionsForRowsChange(dataSet, change); + const props = positions.map(position => ({ position })); + pointIds && pointIds.length && self.updateObjects(undefined, pointIds, props, links); + break; + } + case "delete": { + // delete table row => remove points associated with row + const pointIds: string[] = []; + const caseIds = castArray(change.ids); + caseIds.forEach(caseId => { + for (let attrIndex = 1; attrIndex < dataSet.attributes.length; ++attrIndex) { + pointIds.push(linkedPointId(caseId, dataSet.attributes[attrIndex].id)); + } + }); + change.ids && self.removeObjects(undefined, pointIds, links); + break; + } + } + }, + syncTableLinkChange(dataSet: IDataSet, change: ITableChange, links: ITableLinkProperties) { + const tableId = links.tileIds[0]; + switch (change.action) { + case "create": + self.addTableLink(undefined, tableId, dataSet, links); + break; + case "delete": + self.removeTableLink(undefined, tableId, links); + break; + } + } + })) + .actions(self => ({ + syncLinkedChange(dataSet: IDataSet, change: ITableChange, links: ITableLinkProperties) { + switch (change.target) { + case "columns": + self.syncColumnsChange(dataSet, change, links); + break; + case "rows": + self.syncRowsChange(dataSet, change, links); + break; + case "geometryLink": + self.syncTableLinkChange(dataSet, change, links); + break; + } + } + })); export type GeometryContentModelType = Instance; @@ -1153,10 +1387,21 @@ interface IMovableLineImportSpec { type IObjectImportSpec = IPointImportSpec | IPolygonImportSpec | IImageImportSpec | IMovableLineImportSpec; +interface IImportSpec { + title?: string; + board: IBoardImportSpec; + objects: IObjectImportSpec[]; +} + function preprocessImportFormat(snapshot: any) { - const boardSpecs = snapshot.board as IBoardImportSpec; - const objectSpecs = snapshot.objects as IObjectImportSpec[]; - if (!objectSpecs) return snapshot; + if (!snapshot.objects) return snapshot; + + const { title, board: boardSpecs, objects: objectSpecs } = snapshot as IImportSpec; + const changes: JXGChange[] = []; + + if (title) { + changes.push({ operation: "update", target: "metadata", properties: { title } }); + } function addBoard(boardSpec: IBoardImportSpec) { const { properties } = boardSpec || {} as IBoardImportSpec; @@ -1170,11 +1415,10 @@ function preprocessImportFormat(snapshot: any) { boundingBox, ...others })); } - const changes: JXGChange[] = []; addBoard(boardSpecs); function addComment(props: Record) { - const id = uuid(); + const id = uniqueId(); changes.push({ operation: "create", target: "comment", properties: {id, ...props }}); return id; } @@ -1263,8 +1507,10 @@ export function mapTileIdsInGeometrySnapshot(snapshot: SnapshotOut { const change: JXGChange = safeJsonParse(changeJson); - if ((change.operation === "create") && (change.target === "tableLink")) { - change.targetID = idMap[change.targetID as string]; + if ((change.target === "tableLink") && change.targetID) { + change.targetID = Array.isArray(change.targetID) + ? change.targetID.map(id => idMap[id]) + : idMap[change.targetID]; } if (change.links) { change.links.tileIds = change.links.tileIds.map(id => idMap[id]); @@ -1287,6 +1533,7 @@ export function getImageUrl(change?: JXGChange) { registerToolContentInfo({ id: kGeometryToolID, tool: "geometry", + titleBase: "Graph", modelClass: GeometryContentModel, metadataClass: GeometryMetadataModel, addSidecarNotes: true, diff --git a/src/models/tools/geometry/jxg-board.ts b/src/models/tools/geometry/jxg-board.ts index 4215c64883..b3963be28d 100644 --- a/src/models/tools/geometry/jxg-board.ts +++ b/src/models/tools/geometry/jxg-board.ts @@ -1,7 +1,9 @@ -import { JXGChange, JXGChangeAgent, JXGProperties } from "./jxg-changes"; import "./jxg"; +import { JXGChange, JXGChangeAgent, JXGProperties } from "./jxg-changes"; +import { isAxis, isBoard, isLinkedPoint, isPoint } from "./jxg-types"; import { goodTickValue } from "../../../utilities/graph-utils"; -import { assign, find, values } from "lodash"; +import { assign, each, find } from "lodash"; +import { ITableLinkProperties } from "../table/table-content"; const kScalerClasses = ["canvas-scaler", "scaled-list-item"]; @@ -11,10 +13,52 @@ export const kGeometryDefaultWidth = 480; export const kGeometryDefaultHeight = 320; export const kGeometryDefaultPixelsPerUnit = 18.3; // matches S&S curriculum images export const kGeometryDefaultAxisMin = 0; + +export function getObjectById(board: JXG.Board, id: string): JXG.GeometryElement | undefined { + let obj: JXG.GeometryElement | undefined = board.objects[id]; + if (!obj && id?.includes(":")) { + // legacy support for early tiles in which points were identified by caseId, + // before we added support for multiple columns, i.e. multiple points per row/case + // newer code uses `${caseId}:${attrId}` for the id of points + const caseId = id.split(":")[0]; + obj = board.objects[caseId]; + } + return obj; +} + +export function getPointsByCaseId(board: JXG.Board, caseId: string) { + if (!caseId || caseId.includes(":")) { + const obj = getObjectById(board, caseId); + return obj ? [obj] : []; + } + return board.objectsList.filter(obj => isPoint(obj) && (obj.id.split(":")[0] === caseId)); +} + +export function syncLinkedPoints(board: JXG.Board, links: ITableLinkProperties) { + if (board && links?.labels) { + // build map of points associated with each case + const ptsForCaseMap: Record = {}; + each(board.objects, (obj, id) => { + if (isLinkedPoint(obj)) { + const caseId = obj.getAttribute("linkedRowId"); + if (caseId) { + if (!ptsForCaseMap[caseId]) ptsForCaseMap[caseId] = [obj]; + else ptsForCaseMap[caseId].push(obj); + } + } + }); + // assign case label to each point associated with a given case + links.labels.forEach(item => { + const { id, label } = item; + const ptsForCase = ptsForCaseMap[id]; + if (ptsForCase) { + ptsForCase.forEach(pt => pt?.setAttribute({ name: label })); + } + }); + } +} + export const kAxisBuffer = 20; -export const isBoard = (v: any) => v instanceof JXG.Board; -export const isAxis = (v: any) => (v instanceof JXG.Line) && (v.elType === "axis"); -export const isAxisLabel = (v: any) => v instanceof JXG.Text && !!values(v.ancestors).find(el => isAxis(el)); export const getAxisType = (v: any) => { // stdform encodes orientation of axes const [ , stdFormY, stdFormX] = v.stdform; diff --git a/src/models/tools/geometry/jxg-changes.ts b/src/models/tools/geometry/jxg-changes.ts index f9e338eeb2..b139bedfd1 100644 --- a/src/models/tools/geometry/jxg-changes.ts +++ b/src/models/tools/geometry/jxg-changes.ts @@ -1,8 +1,8 @@ import { castArray } from "lodash"; export type JXGOperation = "create" | "update" | "delete"; -export type JXGObjectType = "board" |"comment" | "image" | "linkedPoint" | "movableLine" | "object" | - "point" | "polygon" | "tableLink" | "vertexAngle"; +export type JXGObjectType = "board" | "comment" | "image" | "linkedPoint" | "metadata" | "movableLine" | + "object" | "point" | "polygon" | "tableLink" | "vertexAngle"; export type JXGCoordPair = [number, number]; export type JXGUnsafeCoordPair = [number?, number?]; @@ -20,6 +20,7 @@ export interface JXGProperties { id?: string; labelOption?: ESegmentLabelOption; position?: JXGUnsafeCoordPair; + title?: string; // metadata property url?: string; xMin?: number; yMin?: number; diff --git a/src/models/tools/geometry/jxg-comment.ts b/src/models/tools/geometry/jxg-comment.ts index c5def77eeb..3fc3541810 100644 --- a/src/models/tools/geometry/jxg-comment.ts +++ b/src/models/tools/geometry/jxg-comment.ts @@ -1,9 +1,8 @@ +import { getObjectById } from "./jxg-board"; import { JXGChangeAgent } from "./jxg-changes"; -import { isBoard } from "./jxg-board"; import { isMovableLine } from "./jxg-movable-line"; import { objectChangeAgent } from "./jxg-object"; -import { isPoint } from "./jxg-point"; -import { isPolygon, isVisibleEdge } from "./jxg-polygon"; +import { isBoard, isPoint, isPolygon, isVisibleEdge } from "./jxg-types"; import { values } from "lodash"; import { uniqueId } from "../../../utilities/js-utils"; @@ -70,14 +69,14 @@ export const commentChangeAgent: JXGChangeAgent = { if (isBoard(board)) { const _board = board as JXG.Board; const centroidCoordinateGetter = (index: number) => () => { - const anchor = _board.objects[commentProps.anchor]; - const centroid = getCentroid(anchor); + const anchor = getObjectById(_board, commentProps.anchor); + const centroid = anchor && getCentroid(anchor); if (centroid) { return centroid[index]; } }; // Comments on table-linked points will not copy to new documents because the anchor isn't copied - if (!_board.objects[commentProps.anchor]) return; + if (!getObjectById(_board, commentProps.anchor)) return; const id = commentProps.id; const comment = _board.create("text", [0, -1, commentText], commentProps); diff --git a/src/models/tools/geometry/jxg-dispatcher.ts b/src/models/tools/geometry/jxg-dispatcher.ts index 0b03b08429..92898f2734 100644 --- a/src/models/tools/geometry/jxg-dispatcher.ts +++ b/src/models/tools/geometry/jxg-dispatcher.ts @@ -1,6 +1,6 @@ import { JXGChange, JXGChangeAgent, JXGChangeResult, JXGCreateHandler, JXGObjectType, IChangeContext } from "./jxg-changes"; -import { boardChangeAgent, isBoard, kReverse, sortByCreation } from "./jxg-board"; +import { boardChangeAgent, getObjectById, kReverse, sortByCreation } from "./jxg-board"; import { commentChangeAgent } from "./jxg-comment"; import { imageChangeAgent } from "./jxg-image"; import { movableLineChangeAgent } from "./jxg-movable-line"; @@ -8,6 +8,7 @@ import { objectChangeAgent } from "./jxg-object"; import { pointChangeAgent } from "./jxg-point"; import { polygonChangeAgent } from "./jxg-polygon"; import { linkedPointChangeAgent, tableLinkChangeAgent } from "./jxg-table-link"; +import { isBoard } from "./jxg-types"; import { vertexAngleChangeAgent } from "./jxg-vertex-angle"; import { castArrayCopy } from "../../../utilities/js-utils"; import { castArray } from "lodash"; @@ -61,9 +62,7 @@ export function applyChange(board: JXG.Board|string, change: JXGChange, const target = change.target.toLowerCase(); // give clients a chance to intercede before the change is applied - if (context && context.onWillApplyChange) { - context.onWillApplyChange(board, change); - } + context?.onWillApplyChange?.(board, change); // special case for update/object, where we dispatch by object type if ((change.operation === "update") && (target === "object")) { @@ -78,7 +77,7 @@ export function applyChange(board: JXG.Board|string, change: JXGChange, const result = dispatchChange(board, change, context); // give clients a chance to intercede after the change has been applied - if (context && context.onDidApplyChange) { + if (context?.onDidApplyChange) { if (isBoard(result)) _board = result as JXG.Board; else if (Array.isArray(result) && isBoard(result?.[0])) _board = result[0] as JXG.Board; context.onDidApplyChange(_board, change); @@ -90,7 +89,7 @@ export function applyChange(board: JXG.Board|string, change: JXGChange, function applyUpdateObjects(board: JXG.Board, change: JXGChange, context?: IChangeContext) { const ids = castArray(change.targetID); ids.forEach((id, index) => { - const obj = id && board.objects[id]; + const obj = id && getObjectById(board, id); const target = obj ? obj.getAttribute("clientType") || obj.elType as JXGObjectType : "object"; @@ -112,7 +111,7 @@ function applyDeleteObjects(board: JXG.Board, change: JXGChange, context?: IChan const ids = castArrayCopy(change.targetID); sortByCreation(board, ids, kReverse); ids.forEach(id => { - const obj = id && board.objects[id]; + const obj = id && getObjectById(board, id); const target = obj ? obj.getAttribute("clientType") || obj.elType as JXGObjectType : "object"; diff --git a/src/models/tools/geometry/jxg-image.ts b/src/models/tools/geometry/jxg-image.ts index b7feefe7ec..e208f7568f 100644 --- a/src/models/tools/geometry/jxg-image.ts +++ b/src/models/tools/geometry/jxg-image.ts @@ -1,8 +1,8 @@ +import { getObjectById } from "./jxg-board"; import { JXGChangeAgent } from "./jxg-changes"; import { objectChangeAgent } from "./jxg-object"; import { gImageMap } from "../../image-map"; -import { assign } from "lodash"; -import { v4 as uuid } from "uuid"; +import { uniqueId } from "../../../utilities/js-utils"; export const isImage = (v: any) => v instanceof JXG.Image; @@ -14,7 +14,7 @@ export const imageChangeAgent: JXGChangeAgent = { const imageEntry = url && gImageMap.getCachedImage(url); const displayUrl = imageEntry && imageEntry.displayUrl || ""; parents[0] = displayUrl; - const props = assign({ id: uuid(), fixed: true }, change.properties); + const props = { id: uniqueId(), fixed: true, ...change.properties }; return parents && parents.length >= 3 ? _board.create("image", parents, props) : undefined; @@ -25,7 +25,7 @@ export const imageChangeAgent: JXGChangeAgent = { const ids = Array.isArray(change.targetID) ? change.targetID : [change.targetID]; const props = Array.isArray(change.properties) ? change.properties : [change.properties]; ids.forEach((id, index) => { - const obj = board.objects[id] as JXG.GeometryElement; + const obj = getObjectById(board, id); const image = isImage(obj) ? obj as JXG.Image : undefined; const objProps = index < props.length ? props[index] : props[0]; if (image && objProps) { diff --git a/src/models/tools/geometry/jxg-movable-line.ts b/src/models/tools/geometry/jxg-movable-line.ts index d487bb5eca..a7588366f7 100644 --- a/src/models/tools/geometry/jxg-movable-line.ts +++ b/src/models/tools/geometry/jxg-movable-line.ts @@ -1,10 +1,10 @@ -import { getBaseAxisLabels, isBoard } from "./jxg-board"; +import { castArray, find, uniqWith } from "lodash"; +import { getBaseAxisLabels, getObjectById } from "./jxg-board"; import { JXGChangeAgent } from "./jxg-changes"; import { objectChangeAgent } from "./jxg-object"; import { syncClientColors } from "./jxg-point"; -import { castArray, each, find, uniqWith } from "lodash"; +import { isBoard } from "./jxg-types"; import { uniqueId } from "../../../utilities/js-utils"; -import { GeometryContentModelType } from "./geometry-content"; export const isMovableLine = (v: any) => { return v && (v.elType === "line") && (v.getAttribute("clientType") === kMovableLineType); @@ -16,19 +16,6 @@ export const isMovableLineControlPoint = (v: any) => { return v instanceof JXG.Point && v.getAttribute("clientType") === kMovableLineType; }; -// When a control point is clicked, deselect the rest of the line so the line slope can be changed -export const handleControlPointClick = (point: JXG.Point, content: GeometryContentModelType) => { - const line = find(point.descendants, el => isMovableLine(el)); - if (line) { - content.deselectElement(undefined, line.id); - each(line.ancestors, (parentPoint, parentId) => { - if (parentId !== point.id) { - content.deselectElement(undefined, parentId); - } - }); - } -}; - export const isMovableLineLabel = (v: any) => { return v instanceof JXG.Text && v.getAttribute("clientType") === kMovableLineType; }; @@ -188,7 +175,7 @@ export const movableLineChangeAgent: JXGChangeAgent = { if (!change.targetID) return; const ids = castArray(change.targetID); ids.forEach((id) => { - const obj = board.objects[id] as JXG.GeometryElement; + const obj = getObjectById(board, id); if (isMovableLine(obj)) { const line = obj as JXG.Line; board.removeObject(line); diff --git a/src/models/tools/geometry/jxg-object.ts b/src/models/tools/geometry/jxg-object.ts index bf93cfc469..9d7d03147f 100644 --- a/src/models/tools/geometry/jxg-object.ts +++ b/src/models/tools/geometry/jxg-object.ts @@ -1,5 +1,7 @@ -import { sortByCreation, kReverse } from "./jxg-board"; +import { sortByCreation, kReverse, getObjectById, syncLinkedPoints } from "./jxg-board"; import { JXGChangeAgent, JXGProperties, JXGCoordPair, JXGUnsafeCoordPair } from "./jxg-changes"; +import { isLinkedPoint } from "./jxg-types"; +import { ITableLinkProperties } from "../table/table-content"; import { castArrayCopy } from "../../../utilities/js-utils"; import { castArray, size } from "lodash"; @@ -39,8 +41,10 @@ export const objectChangeAgent: JXGChangeAgent = { const ids = castArray(change.targetID); const props: JXGProperties[] = castArray(change.properties); let hasSuspendedTextUpdates = false; + let hasLinkedPoints = false; ids.forEach((id, index) => { - const obj = board.objects[id] as JXG.GeometryElement; + const obj = getObjectById(board, id); + if (isLinkedPoint(obj)) hasLinkedPoints = true; const textObj = isText(obj) ? obj as JXG.Text : undefined; const objProps = index < props.length ? props[index] : props[0]; if (obj && objProps) { @@ -73,6 +77,7 @@ export const objectChangeAgent: JXGChangeAgent = { } } }); + if (hasLinkedPoints) syncLinkedPoints(board, change.links as ITableLinkProperties); if (hasSuspendedTextUpdates) board.suspendUpdate(); board.update(); return undefined; @@ -84,10 +89,8 @@ export const objectChangeAgent: JXGChangeAgent = { sortByCreation(board, ids, kReverse); // remove objects in reverse order of creation ids.forEach((id) => { - const obj = board.objects[id] as JXG.GeometryElement; - if (obj) { - board.removeObject(obj); - } + const obj = getObjectById(board, id); + obj && board.removeObject(obj); }); board.update(); } diff --git a/src/models/tools/geometry/jxg-point.ts b/src/models/tools/geometry/jxg-point.ts index 273b6778d5..48e5267e92 100644 --- a/src/models/tools/geometry/jxg-point.ts +++ b/src/models/tools/geometry/jxg-point.ts @@ -1,22 +1,9 @@ import { JXGChangeAgent, JXGCoordPair, JXGUnsafeCoordPair } from "./jxg-changes"; import { objectChangeAgent, isPositionGraphable, getGraphablePosition } from "./jxg-object"; import { prepareToDeleteObjects } from "./jxg-polygon"; -import { isCommentType } from "./jxg-types"; -import { castArray, values } from "lodash"; +import { castArray } from "lodash"; import { v4 as uuid } from "uuid"; -export const isPoint = (v: any) => v instanceof JXG.Point; - -export const isVisiblePoint = (v: any) => isPoint(v) && v.visProp.visible; - -export const isFreePoint = (v: any) => { - if (isVisiblePoint(v)) { - const point = v as JXG.Point; - return values(point.childElements).filter(el => !isCommentType(el)).length <= 1 && - values(point.descendants).filter(el => !isCommentType(el)).length <= 1; - } -}; - // For snap to grid const kPrevSnapUnit = 0.2; export const kSnapUnit = 0.1; diff --git a/src/models/tools/geometry/jxg-polygon.ts b/src/models/tools/geometry/jxg-polygon.ts index 0c547f2b34..cbd8d78c4e 100644 --- a/src/models/tools/geometry/jxg-polygon.ts +++ b/src/models/tools/geometry/jxg-polygon.ts @@ -1,14 +1,9 @@ +import { each, filter, find, uniqueId, values } from "lodash"; +import { getObjectById } from "./jxg-board"; import { ESegmentLabelOption, JXGChange, JXGChangeAgent } from "./jxg-changes"; import { getElementName, objectChangeAgent } from "./jxg-object"; -import { isPoint } from "./jxg-point"; -import { isVertexAngle } from "./jxg-vertex-angle"; +import { isPoint, isPolygon, isVertexAngle, isVisibleEdge } from "./jxg-types"; import { wn_PnPoly } from "./soft-surfer-sunday"; -import { assign, each, filter, find, values } from "lodash"; -import { v4 as uuid } from "uuid"; - -export const isPolygon = (v: any) => v instanceof JXG.Polygon; - -export const isVisibleEdge = (v: any) => v instanceof JXG.Line && (v.elType === "segment") && v.visProp.visible; export function isPointInPolygon(x: number, y: number, polygon: JXG.Polygon) { const v = polygon.vertices.map(vertex => { @@ -31,8 +26,8 @@ export function getPolygonEdges(polygon: JXG.Polygon) { } export function getPolygonEdge(board: JXG.Board, polygonId: string, pointIds: string[]) { - const point1 = board.objects[pointIds[0]]; - const segment = find(point1.childElements, child => { + const point1 = getObjectById(board, pointIds[0]); + const segment = find(point1?.childElements, child => { const seg = isVisibleEdge(child) ? child as JXG.Line : undefined; if (!seg) return false; const isEdgeOfPolygon = seg.parentPolygon?.id === polygonId; @@ -96,8 +91,8 @@ export function prepareToDeleteObjects(board: JXG.Board, ids: string[]) { // Identify polygons and angles scheduled for deletion and points that are vertices of polygons const polygonVertexMap: { [id: string]: string[] } = {}; ids.forEach(id => { - const elt = board.objects[id]; - if (isPoint(elt)) { + const elt = getObjectById(board, id); + if (elt && isPoint(elt)) { each(elt.childElements, child => { if (isPolygon(child)) { if (!polygonVertexMap[child.id]) { @@ -110,20 +105,20 @@ export function prepareToDeleteObjects(board: JXG.Board, ids: string[]) { else if (isPolygon(elt)) { polygonsToDelete[id] = elt as JXG.Polygon; } - else if (isVertexAngle(elt)) { + else if (elt && isVertexAngle(elt)) { anglesToDelete[id] = elt; } }); // Consider each polygon with vertices to be deleted each(polygonVertexMap, (vertexIds, polygonId) => { - const polygon = board.objects[polygonId] as JXG.Polygon; + const polygon = getObjectById(board, polygonId) as JXG.Polygon; const vertexCount = polygon.vertices.length - 1; const deleteCount = vertexIds.length; // remove points from polygons if possible if (vertexCount - deleteCount >= 2) { vertexIds.forEach(id => { - const pt = board.objects[id] as JXG.Point; + const pt = getObjectById(board, id) as JXG.Point; // removing multiple points at one time sometimes gives unexpected results polygon.removePoints(pt); }); @@ -194,14 +189,15 @@ export const polygonChangeAgent: JXGChangeAgent = { create: (board, change) => { const _board = board as JXG.Board; const parents = (change.parents || []) - .map(id => _board.objects[id as string]) + .map(id => getObjectById(_board, id as string)) .filter(pt => pt != null); - const props = assign({ - id: uuid(), + const props = { + id: uniqueId(), hasInnerPoints: true, clientFillColor: "#00FF00", - clientSelectedFillColor: "#00FF00" - }, change.properties); + clientSelectedFillColor: "#00FF00", + ...change.properties + }; const poly = parents.length ? _board.create("polygon", parents, props) : undefined; if (poly) { const segments = getPolygonEdges(poly); diff --git a/src/models/tools/geometry/jxg-table-link.ts b/src/models/tools/geometry/jxg-table-link.ts index d8a888acfc..532d40ab3f 100644 --- a/src/models/tools/geometry/jxg-table-link.ts +++ b/src/models/tools/geometry/jxg-table-link.ts @@ -1,8 +1,16 @@ -import { JXGChangeAgent, JXGCoordPair, ILinkProperties } from "./jxg-changes"; -import { createPoint, isPoint, pointChangeAgent } from "./jxg-point"; +import { syncLinkedPoints } from "./jxg-board"; +import { ILinkProperties, JXGChange, JXGChangeAgent, JXGCoordPair } from "./jxg-changes"; +import { createPoint, pointChangeAgent } from "./jxg-point"; +import { isPoint } from "./jxg-types"; import { ITableLinkProperties } from "../table/table-content"; +import { splitLinkedPointId } from "../table/table-model-types"; -export const isLinkedPoint = (v: any) => isPoint(v) && (v.getAttribute("clientType") === "linkedPoint"); +export function getTableIdFromLinkChange(change: JXGChange) { + return change.target.toLowerCase() === "tablelink" + // during development id was initially stored in parents + ? (change.targetID || change.parents?.[0]) as string + : undefined; +} export interface ITableLinkColors { fill: string; @@ -18,6 +26,7 @@ export function injectGetTableLinkColorsFunction(getTableLinkColors: GetTableLin function createLinkedPoint(board: JXG.Board, parents: JXGCoordPair, props: any, links?: ILinkProperties) { const tableId = links?.tileIds?.[0]; + const [linkedRowId, linkedColId] = splitLinkedPointId(props?.id); const linkColors = sGetTableLinkColors(tableId); if (!linkColors) return; const linkedProps = { @@ -30,22 +39,13 @@ function createLinkedPoint(board: JXG.Board, parents: JXGCoordPair, props: any, clientSelectedFillColor: linkColors.stroke, clientSelectedStrokeColor: linkColors.stroke, linkedTableId: tableId, - linkedRowId: props && props.id + linkedRowId, + linkedColId }; const _props = { ...props, ...linkedProps }; return createPoint(board as JXG.Board, parents, _props); } -function syncLinkedPoints(board: JXG.Board, links: ITableLinkProperties) { - if (board && links && links.labels) { - links.labels.forEach(item => { - const { id, label } = item; - const elt = board.objects[id]; - elt && elt.setAttribute({ name: label }); - }); - } -} - export const linkedPointChangeAgent: JXGChangeAgent = { create: (board, change) => { let result: JXG.Point | JXG.Point[] = []; @@ -96,8 +96,7 @@ export const tableLinkChangeAgent: JXGChangeAgent = { delete: (board, change) => { if (board) { - // during development id was initially stored in parents - const tableId = change.targetID || (change.parents && change.parents[0]); + const tableId = getTableIdFromLinkChange(change); const pts = board.objectsList.filter(elt => { return isPoint(elt) && tableId && (elt.getAttribute("linkedTableId") === tableId); }); diff --git a/src/models/tools/geometry/jxg-types.ts b/src/models/tools/geometry/jxg-types.ts index 6b9dc2b282..ca64e948d7 100644 --- a/src/models/tools/geometry/jxg-types.ts +++ b/src/models/tools/geometry/jxg-types.ts @@ -1,2 +1,28 @@ +import { values } from "lodash"; + +export const isBoard = (v: any) => v instanceof JXG.Board; +export const isAxis = (v: any) => (v instanceof JXG.Line) && (v.elType === "axis"); +export const isAxisLabel = (v: any) => v instanceof JXG.Text && !!values(v.ancestors).find(el => isAxis(el)); + +export const isPoint = (v: any) => v instanceof JXG.Point; +export const isVisiblePoint = (v: any) => isPoint(v) && v.visProp.visible; + +export const isLinkedPoint = (v: any) => isPoint(v) && (v.getAttribute("clientType") === "linkedPoint"); + export const isCommentType = (v: any) => v && v.getAttribute("clientType") === "comment"; export const isComment = (v: any) => isCommentType(v) && (v instanceof JXG.Text) && (v.elType === "text"); + +export const isFreePoint = (v: any) => { + if (isVisiblePoint(v)) { + const point = v as JXG.Point; + return values(point.childElements).filter(el => !isCommentType(el)).length <= 1 && + values(point.descendants).filter(el => !isCommentType(el)).length <= 1; + } +}; + +export const isPolygon = (v: any) => v instanceof JXG.Polygon; +export const isVisibleEdge = (v: any) => v instanceof JXG.Line && (v.elType === "segment") && v.visProp.visible; + +export const isVertexAngle = (v: any) => + (v instanceof JXG.Curve) && (v.elType === "angle") && + (v.getAttribute("clientType") === "vertexAngle"); diff --git a/src/models/tools/geometry/jxg-vertex-angle.ts b/src/models/tools/geometry/jxg-vertex-angle.ts index 94f1ab7394..4ddb3ef0c9 100644 --- a/src/models/tools/geometry/jxg-vertex-angle.ts +++ b/src/models/tools/geometry/jxg-vertex-angle.ts @@ -1,13 +1,10 @@ +import { castArray, each, values } from "lodash"; +import { getObjectById } from "./jxg-board"; import { JXGChangeAgent } from "./jxg-changes"; import { objectChangeAgent } from "./jxg-object"; -import { isPoint } from "./jxg-point"; import { getPointsForVertexAngle } from "./jxg-polygon"; -import { assign, castArray, each, values } from "lodash"; -import { v4 as uuid } from "uuid"; - -export const isVertexAngle = (v: any) => - (v instanceof JXG.Curve) && (v.elType === "angle") && - (v.getAttribute("clientType") === "vertexAngle"); +import { isPoint, isVertexAngle } from "./jxg-types"; +import { uniqueId } from "../../../utilities/js-utils"; export const canSupportVertexAngle = (vertex: JXG.Point): boolean => { const children = values(vertex.childElements); @@ -72,12 +69,12 @@ export const vertexAngleChangeAgent: JXGChangeAgent = { create: (board, change) => { const _board = board as JXG.Board; const parents = (change.parents || []) - .map(id => _board.objects[id as string]) + .map(id => getObjectById(_board, id as string)) .filter(pt => pt != null); // cf. http://jsxgraph.uni-bayreuth.de/wiki/index.php/Positioning_of_labels const overrides: any = { name() { return `${this.Value ? JXG.toFixed(this.Value() * 180 / Math.PI, 0) : ""}°`; }, clientType: "vertexAngle" }; - const props = assign({ id: uuid(), radius: 1 }, change.properties, overrides); + const props = { id: uniqueId(), radius: 1, ...change.properties, ...overrides }; return parents.length === 3 ? _board.create("angle", parents, props) : undefined; }, @@ -91,7 +88,7 @@ export const vertexAngleChangeAgent: JXGChangeAgent = { // get orphaned when deleting the angle. const dotIds: string[] = []; ids.forEach(id => { - const obj = board.objects[id]; + const obj = getObjectById(board, id); if (isVertexAngle(obj)) { const angle = obj as JXG.Angle; if (angle.dot && isPoint(angle.dot)) { diff --git a/src/models/tools/table-links.scss b/src/models/tools/table-links.scss index fc091bc8ce..084a667f27 100644 --- a/src/models/tools/table-links.scss +++ b/src/models/tools/table-links.scss @@ -13,6 +13,48 @@ $link-color-4-dark: $terra-dark-5; $link-color-5-light: $rust-light-1; $link-color-5-dark: $rust-dark-5; +.link-color-0 { + background-color: $link-color-0-light !important; + &:active:not(.disabled) { + background-color: $link-color-0-dark !important; + } +} + +.link-color-1 { + background-color: $link-color-1-light !important; + &:active:not(.disabled) { + background-color: $link-color-1-dark !important; + } +} + +.link-color-2 { + background-color: $link-color-2-light !important; + &:active:not(.disabled) { + background-color: $link-color-2-dark !important; + } +} + +.link-color-3 { + background-color: $link-color-3-light !important; + &:active:not(.disabled) { + background-color: $link-color-3-dark !important; + } +} + +.link-color-4 { + background-color: $link-color-4-light !important; + &:active:not(.disabled) { + background-color: $link-color-4-dark !important; + } +} + +.link-color-5 { + background-color: $link-color-5-light !important; + &:active:not(.disabled) { + background-color: $link-color-5-dark !important; + } +} + :export { linkColor0Light: $link-color-0-light; linkColor0Dark: $link-color-0-dark; diff --git a/src/models/tools/table-links.ts b/src/models/tools/table-links.ts index 276b0ae149..98b10a7466 100644 --- a/src/models/tools/table-links.ts +++ b/src/models/tools/table-links.ts @@ -11,10 +11,14 @@ export function getTableDocument(tableId: string) { return sTableDocumentMap.get(tableId); } -export function addTable(documentId: string, tableId: string) { +export function addTableToDocumentMap(documentId: string, tableId: string) { sTableDocumentMap.set(tableId, documentId); } +export function removeTableFromDocumentMap(tableId: string) { + sTableDocumentMap.delete(tableId); +} + export function getLinkedTables(documentId: string) { return sDocumentLinkedTables.get(documentId); } diff --git a/src/models/tools/table/table-content.md b/src/models/tools/table/table-content.md new file mode 100644 index 0000000000..c34d2b2626 --- /dev/null +++ b/src/models/tools/table/table-content.md @@ -0,0 +1,160 @@ +## Table Changes + +### createTable +```typescript +interface ICreateTable { + action: "create"; + target: "table"; + ids: string[]; // ids of columns to create; ids will be auto-generated if not provided + props: { + name?: string; // name of table + columns?: Array<{ + name?: string; // name of column + }> + } +} +``` + +### createColumns +```typescript +interface ICreateColumns { + action: "create"; + target: "columns"; + ids: string[]; // ids of columns to create; ids will be auto-generated if not provided + props: { + columns?: Array<{ name?: string; }> // name of each column + } +} +``` + +### createColumnsDeprecated +```typescript +// converted to canonical form automatically +interface ICreateColumnsDeprecated { + action: "create"; + target: "columns"; + ids: string[]; // ids of columns to create; ids will be auto-generated if not provided + props: Array<{ name?: string; }> // name of each column +} +``` + +### createRowsDeprecated +```typescript +// converted to canonical form automatically +interface ICreateRowsDeprecated { + action: "create"; + target: "rows"; + ids: string[]; // ids of rows to create; ids will be auto-generated if not provided + props: Array>; // each property is { [attributeID]: attributeValue } +} +``` + +### setTableName(name: string) +```typescript +interface ISetTableName { + action: "update"; + target: "table"; + props: { name: string }; +} +``` + +### setAttributeName(id: string, name: string) +```typescript +interface ISetAttributeName { + action: "update"; + target: "columns"; + ids: string; // expects single attribute ID despite name + props: { name: string }; +} +``` + +### removeAttributes(ids: string[]) +```typescript +interface IRemoveAttributes { + action: "delete"; + target: "columns"; + ids: string[]; // array of column/attribute IDs +} +``` + +### setExpression(id: string, expression: string, rawExpression: string) +```typescript +interface ISetExpression { + action: "update"; + target: "columns"; + ids: string; // expects single attribute ID despite name + props: { + expression: string, // canonicalized in terms of __x__ + rawExpression: string // what the user actually typed + } +} +``` + +### addCanonicalCases(cases: ICaseCreation[], beforeID?: string | string[], links?: ILinkProperties) +```typescript +interface IAddCanonicalCases { + action: "create"; + target: "rows"; + ids: string[]; // array of row/case IDs + props: { + rows: Array>; // each property is { [attributeID]: attributeValue } + beforeId?: string | string[]; // either the id of row to place all new rows before + // or an array of row IDs to place each new row before + }, + links?: { // ILinkProperties + id: string; + tileIds: string[]; // ids of geometry tiles to which these cases are connected + } +} +``` + +### setCanonicalCaseValues(caseValues: ICase[], links?: ILinkProperties) +```typescript +interface ISetCanonicalCaseValues { + action: "update"; + target: "rows"; + ids: string[]; // array of row/case IDs + props: Array>; // each property is { [attributeID]: attributeValue } + links?: { // ILinkProperties + id: string; + tileIds: string[]; // ids of geometry tiles to which these cases are connected + } +} +``` + +### removeCases(ids: string[], links?: ILinkProperties) +```typescript +interface IRemoveCases { + action: "delete"; + target: "rows"; + ids: string[]; // ids of rows/cases to remove + links?: { // ILinkProperties + id: string; + tileIds: string[]; // ids of geometry tiles to which these cases are connected + } +} +``` + +### addGeometryLink(geometryId: string, links: ILinkProperties) +```typescript +interface IAddGeometryLink { + action: "create"; + target: "geometryLink"; + ids: string; // id of geometry tile to link + links: { // ILinkProperties + id: string; + tileIds: string[]; // ids of connected geometry tiles + } +} +``` + +### removeGeometryLinks(geometryIds: string | string[], links?: ILinkProperties) +```typescript + action: "delete"; + target: "geometryLink"; + ids: string | string[]; // id or array of ids of affected geometry tiles + links?: { // ILinkProperties + id: string; + tileIds: string[]; // ids of connected geometry tiles + } +``` diff --git a/src/models/tools/table/table-content.ts b/src/models/tools/table/table-content.ts index 219e3f385c..4947d0d163 100644 --- a/src/models/tools/table/table-content.ts +++ b/src/models/tools/table/table-content.ts @@ -1,15 +1,16 @@ -import { types, Instance, SnapshotOut, IAnyStateTreeNode } from "mobx-state-tree"; +import { Parser } from "expr-eval"; +import { castArray, each } from "lodash"; +import { types, IAnyStateTreeNode, Instance, SnapshotIn, SnapshotOut } from "mobx-state-tree"; +import { getRowLabel, kSerializedXKey, canonicalizeValue, isLinkableValue } from "./table-model-types"; import { registerToolContentInfo } from "../tool-content-info"; import { addLinkedTable } from "../table-links"; import { IDataSet, ICaseCreation, ICase, DataSet } from "../../data/data-set"; +import { canonicalizeExpression } from "../../../components/tools/table-tool/expression-utils"; import { safeJsonParse, uniqueId } from "../../../utilities/js-utils"; -import { castArray, each } from "lodash"; import { getGeometryContent } from "../geometry/geometry-content"; import { JXGChange } from "../geometry/jxg-changes"; import { getTileContentById } from "../../../utilities/mst-utils"; import { Logger, LogEventName } from "../../../lib/logger"; -import { Parser } from "expr-eval"; -import { kSerializedXKey } from "../../../components/tools/table-tool/update-expression-dialog"; export const kTableToolID = "Table"; export const kCaseIdName = "__id__"; @@ -17,33 +18,57 @@ export const kLabelAttrName = "__label__"; export const kTableDefaultHeight = 160; -export function defaultTableContent() { +export function defaultTableContent(props?: { title?: string }) { return TableContentModel.create({ type: "Table", + name: props?.title, columns: [ { name: "x" }, { name: "y" } ] - } as any); + } as SnapshotIn); } -export function isLinkableValue(value: number | string | null | undefined) { - return value == null || Number.isNaN(value as any) || isFinite(Number(value)); +export function getTableContent(target: IAnyStateTreeNode, tileId: string): TableContentModelType | undefined { + const content = getTileContentById(target, tileId); + return content && content as TableContentModelType; } -export function canonicalizeValue(value: number | string | undefined) { - if (value == null || value === "") return undefined; - const num = Number(value); - return isFinite(num) ? num : undefined; +interface IGetTableContentHeight { + dataRows: number; + rowHeight?: number; + readOnly?: boolean; + hasExpressions?: boolean; + padding?: number; } +export const getTableContentHeight = ({ + dataRows, rowHeight, readOnly, hasExpressions, padding +}: IGetTableContentHeight) => { + const kDefaultRowHeight = 34; + const kDefaultPadding = 10; + const headerRows = 2 + (hasExpressions ? 1 : 0); + const inputRows = readOnly ? 0 : 1; + const kBorders = 2 * 2; + const _padding = 2 * (padding || kDefaultPadding); + return (headerRows + dataRows + inputRows) * (rowHeight || kDefaultRowHeight) + kBorders + _padding; +}; -export function getRowLabel(index: number, prefix = "p") { - return `${prefix}${index + 1}`; -} +export function getAxisLabelsFromDataSet(dataSet: IDataSet): [string | undefined, string | undefined] { + // label for x axis + const xAttr = dataSet.attributes.length > 0 ? dataSet.attributes[0] : undefined; + const xLabel = xAttr?.name; -export function getTableContent(target: IAnyStateTreeNode, tileId: string): TableContentModelType | undefined { - const content = getTileContentById(target, tileId); - return content && content as TableContentModelType; + // label for y axis + let yLabel = undefined; + for (let yIndex = 1; yIndex < dataSet.attributes.length; ++yIndex) { + // concatenate column names for y axis label + const yAttr = dataSet.attributes[yIndex]; + if (yAttr.name && (yAttr.name !== kLabelAttrName)) { + if (!yLabel) yLabel = yAttr.name; + else yLabel += `, ${yAttr.name}`; + } + } + return [xLabel, yLabel]; } export interface ITransferCase { @@ -59,11 +84,13 @@ export interface IRowLabel { } export interface IColumnProperties { - name: string; + name?: string; + expression?: string; + rawExpression?: string; } -export interface IRowProperties { - [key: string]: any; +export interface IColumnCreationProperties extends IColumnProperties{ + name: string; } export interface ILinkProperties { @@ -72,23 +99,46 @@ export interface ILinkProperties { } export interface ITableLinkProperties extends ILinkProperties { + // labels should be included when adding/removing rows, + // so that clients can synchronize any label changes labels?: IRowLabel[]; } -export interface ITableProperties { - columns?: IColumnProperties[]; - rows?: IRowProperties[]; - beforeId?: string | string[]; +export function getRowLabelFromLinkProps(links: ITableLinkProperties, rowId: string) { + const found = links.labels?.find(entry => entry.id === rowId); + return found?.label; +} + +export interface ICreateColumnsProperties { + columns?: IColumnCreationProperties[]; +} + +export type IUpdateColumnsProperties = IColumnProperties | IColumnProperties[]; + +export interface IUpdateTableProperties { name?: string; - expression?: string; - rawExpression?: string; } +export interface ICreateTableProperties extends IUpdateTableProperties, ICreateColumnsProperties { +} + +export type IRowProperties = Record; + +export interface ICreateRowsProperties { + rows: IRowProperties[]; + beforeId?: string | string[]; +} + +export type IUpdateRowsProperties = IRowProperties | IRowProperties[]; + +export type ITableChangeProperties = ICreateTableProperties | IUpdateTableProperties | + ICreateColumnsProperties | IUpdateColumnsProperties | + ICreateRowsProperties | IUpdateRowsProperties; export interface ITableChange { action: "create" | "update" | "delete"; target: "table" | "rows" | "columns" | "geometryLink"; ids?: string | string[]; - props?: ITableProperties; + props?: ITableChangeProperties; links?: ILinkProperties; } @@ -105,6 +155,12 @@ export const TableMetadataModel = types }, get linkCount() { return self.linkedGeometries.length; + }, + get hasExpressions() { + return Array.from(self.expressions.values()).some(expr => !!expr); + }, + hasExpression(attrId: string) { + return !!self.expressions.get(attrId); } })) .actions(self => ({ @@ -123,11 +179,25 @@ export const TableMetadataModel = types clearLinkedGeometries() { self.linkedGeometries.clear(); }, - setExpression(colId: string, expression: string) { - self.expressions.set(colId, expression); + setExpression(colId: string, expression?: string) { + if (expression) { + self.expressions.set(colId, expression); + } + else { + self.expressions.delete(colId); + } + }, + setRawExpression(colId: string, rawExpression?: string) { + if (rawExpression) { + self.rawExpressions.set(colId, rawExpression); + } + else { + self.rawExpressions.delete(colId); + } }, - setRawExpression(colId: string, rawExpression: string) { - self.rawExpressions.set(colId, rawExpression); + clearExpression(colId: string) { + self.rawExpressions.delete(colId); + self.expressions.delete(colId); }, clearRawExpressions(varName: string) { const parser = new Parser(); @@ -155,11 +225,11 @@ export const TableContentModel = types .preProcessSnapshot(snapshot => { const s = snapshot as any; // handle import format - if (s && s.columns) { + if (s?.columns) { return { isImported: true, changes: convertImportToChanges(s) }; } // handle early change formats - if (s && s.changes && s.changes.length) { + if (s?.changes?.length) { const { changes, ...snapOthers } = s; const parsedChanges = changes.map((change: string) => safeJsonParse(change)); const isConversionRequired = parsedChanges.some((c: any) => { @@ -192,24 +262,38 @@ export const TableContentModel = types get isLinked() { return self.metadata.linkedGeometries.length > 0; }, - getRowLabel(index: number) { - return getRowLabel(index); + get hasExpressions() { + return self.metadata.hasExpressions; } })) .views(self => ({ - getClientLinks(linkId: string, dataSet: IDataSet, addLabelMap: boolean): ITableLinkProperties { - let labels: IRowLabel[] = []; - if (addLabelMap && dataSet) { - labels = dataSet.cases.map((aCase, i) => ({ id: aCase.__id__, label: self.getRowLabel(i) })); - } - ["xAxis", "yAxis"].forEach((axis, index) => { - const attr = dataSet.attributes.length > index ? dataSet.attributes[index] : undefined; - if (attr) { - labels.unshift({ id: axis, label: attr.name }); - } - }); + /* + * Returns link metadata for attaching to client (e.g. geometry) tool actions + * that includes label information. + */ + getClientLinks(linkId: string, dataSet: IDataSet): ITableLinkProperties { + const labels: IRowLabel[] = []; + + // add axis labels + const [xAxisLabel, yAxisLabel] = getAxisLabelsFromDataSet(dataSet); + xAxisLabel && labels.push({ id: "xAxis", label: xAxisLabel }); + yAxisLabel && labels.push({ id: "yAxis", label: yAxisLabel }); + + // add label for each case, indexed by case ID + labels.push(...dataSet.cases.map((aCase, i) => ({ id: aCase.__id__, label: getRowLabel(i) }))); + return { id: linkId, tileIds: [self.metadata.id], labels }; }, + getLinkedChange(linkId: string) { + let parsedChange: ITableChange | undefined; + const foundIndex = self.changes.findIndex(changeJson => { + const change = safeJsonParse(changeJson) as ITableChange | undefined; + const isFound = change?.links?.id === linkId; + isFound && (parsedChange = change); + return isFound; + }); + return foundIndex >= 0 ? parsedChange : undefined; + }, canUndo() { return false; // const hasUndoableChanges = self.changes.length > 1; @@ -243,14 +327,14 @@ export const TableContentModel = types willRemoveFromDocument() { self.metadata.linkedGeometries.forEach(geometryId => { const geometryContent = getGeometryContent(self, geometryId); - geometryContent && geometryContent.removeTableLink(undefined, self.metadata.id); + geometryContent?.removeTableLink(undefined, self.metadata.id); }); self.metadata.clearLinkedGeometries(); }, appendChange(change: ITableChange) { self.changes.push(JSON.stringify(change)); - const toolId = self.metadata && self.metadata.id || ""; + const toolId = self.metadata?.id || ""; Logger.logToolChange(LogEventName.TABLE_TOOL_CHANGE, change.action, change, toolId); } })) @@ -262,27 +346,52 @@ export const TableContentModel = types props: { name } }); }, - setAttributeName(id: string, name: string) { + addAttribute(id: string, name: string, links?: ILinkProperties) { + self.appendChange({ + action: "create", + target: "columns", + ids: [id], + props: { columns: [{ name }] }, + links + }); + }, + setAttributeName(id: string, name: string, links?: ILinkProperties) { self.appendChange({ action: "update", target: "columns", ids: id, - props: { name } + props: { name }, + links }); }, - removeAttributes(ids: string[]) { + removeAttributes(ids: string[], links?: ILinkProperties) { self.appendChange({ action: "delete", target: "columns", - ids + ids, + links }); }, - setExpression(id: string, expression: string, rawExpression: string) { + setExpression(id: string, expression: string, rawExpression: string, links?: ILinkProperties) { self.appendChange({ action: "update", target: "columns", ids: id, - props: { expression, rawExpression } + props: { expression, rawExpression }, + links + }); + }, + setExpressions(rawExpressions: Map, xName: string, links?: ILinkProperties) { + self.appendChange({ + action: "update", + target: "columns", + ids: Array.from(rawExpressions.keys()), + props: Array.from(rawExpressions.values()) + .map(rawExpr => ({ + expression: canonicalizeExpression(rawExpr, xName), + rawExpression: rawExpr + })), + links }); }, addCanonicalCases(cases: ICaseCreation[], beforeID?: string | string[], links?: ILinkProperties) { @@ -311,7 +420,7 @@ export const TableContentModel = types action: "update", target: "rows", ids, - props: values as ITableProperties, + props: values, links }); }, @@ -373,26 +482,28 @@ export const TableContentModel = types })) .views(self => ({ applyCreate(dataSet: IDataSet, change: ITableChange, dataSetOnly = false) { - const tableProps = change && change.props as ITableProperties; switch (change.target) { - case "table": + case "table": { + const props = change?.props as ICreateTableProperties; + (props?.name != null) && dataSet.setName(props.name); + } + // fallthrough case "columns": { - (tableProps?.name != null) && dataSet.setName(tableProps.name); - const columns = tableProps && tableProps.columns; - columns && columns.forEach((col: any, index: number) => { - const id = change.ids && change.ids[index] || uniqueId(); + const props = change?.props as ICreateColumnsProperties; + props?.columns?.forEach((col, index) => { + const id = change.ids?.[index] || uniqueId(); dataSet.addAttributeWithID({ id, ...col }); }); break; } case "rows": { - const rows = tableProps && tableProps.rows && - tableProps.rows.map((row: any, index: number) => { - const id = change.ids && change.ids[index] || uniqueId(); - return { __id__: id, ...row }; - }); - const beforeId = tableProps && tableProps.beforeId; - if (rows && rows.length) { + const props = change?.props as ICreateRowsProperties; + const rows = props?.rows?.map((row: any, index: number) => { + const id = change.ids?.[index] || uniqueId(); + return { __id__: id, ...row }; + }); + const beforeId = props?.beforeId; + if (rows?.length) { dataSet.addCanonicalCasesWithIDs(rows, beforeId); self.updateDatasetByExpressions(dataSet); } @@ -410,38 +521,49 @@ export const TableContentModel = types applyUpdate(dataSet: IDataSet, change: ITableChange, dataSetOnly = false) { const ids = castArray(change.ids); switch (change.target) { - case "table": - (change.props?.name != null) && dataSet.setName(change.props.name); + case "table": { + const props = change.props as IUpdateTableProperties; + (props?.name != null) && dataSet.setName(props.name); break; + } case "columns": { - const colProps = change && change.props && castArray(change.props); - colProps && colProps.forEach((col: any, colIndex) => { - each(col, (value, prop) => { - switch (prop) { - case "name": { - const colId = ids[colIndex]; - dataSet.setAttributeName(colId, value); - if (colIndex === 0) { - self.metadata.clearRawExpressions(kSerializedXKey); + const props = change.props as IUpdateColumnsProperties; + const colProps = castArray(props); + colProps?.forEach((col, colIndex) => { + const colId = ids[colIndex]; + if (dataSet.attrFromID(colId)) { + each(col, (value, prop) => { + const _value = value as string; + switch (prop) { + case "name": { + dataSet.setAttributeName(colId, _value); + if (colIndex === 0) { + self.metadata.clearRawExpressions(kSerializedXKey); + } + break; } - break; + case "expression": + self.metadata.setExpression(colId, _value); + self.updateDatasetByExpressions(dataSet); + break; + case "rawExpression": + self.metadata.setRawExpression(colId, _value); + break; } - case "expression": - self.metadata.setExpression(ids[colIndex], value); - self.updateDatasetByExpressions(dataSet); - break; - case "rawExpression": - self.metadata.setRawExpression(ids[colIndex], value); - break; - } - }); + }); + } + else { + // encountered this situation during development, perhaps due to a prior bug + console.warn(`TableContent.applyUpdate: skipping attempt to update non-existent column ${colId}:`, + JSON.stringify(col)); + } }); break; } case "rows": { - const rowProps = change && change.props && castArray(change.props); + const rowProps: IRowProperties[] | undefined = change?.props && castArray(change.props as any); if (rowProps) { - rowProps.forEach((row: any, rowIndex) => { + rowProps.forEach((row, rowIndex) => { dataSet.setCanonicalCaseValues([{ __id__: ids[rowIndex], ...row }]); }); self.updateDatasetByExpressions(dataSet); @@ -454,12 +576,16 @@ export const TableContentModel = types const ids = change && castArray(change.ids); switch (change.target) { case "columns": - if (ids && ids.length) { - ids.forEach(id => dataSet.removeAttribute(id)); + if (ids?.length) { + ids.forEach(id => { + dataSet.removeAttribute(id); + // remove expressions from maps + self.metadata.clearExpression(id); + }); } break; case "rows": - if (ids && ids.length) { + if (ids?.length) { dataSet.removeCases(ids); } break; @@ -486,12 +612,23 @@ export const TableContentModel = types })) .views(self => ({ applyChanges(dataSet: IDataSet, start = 0) { + let hasColumnChanges = false; + let hasRowChanges = false; for (let i = start; i < self.changes.length; ++i) { const change = safeJsonParse(self.changes[i]); if (change) { + if ((change.target === "columns") || change.props?.columns) { + hasColumnChanges = true; + // most column changes (creation, deletion, expression changes) require re-rendering rows as well + hasRowChanges = true; + } + if ((change.target === "rows") || change.props?.rows) { + hasRowChanges = true; + } self.applyChange(dataSet, change); } } + return [hasColumnChanges, hasRowChanges]; }, applyChangesToDataSet(dataSet: IDataSet) { self.changes.forEach(jsonChange => { @@ -507,12 +644,13 @@ export const TableContentModel = types const dataSet = DataSet.create(); self.applyChangesToDataSet(dataSet); + // add a __label__ attribute to returned dataSet (used by GeometryContent.addTableLink) const attrIds = dataSet.attributes.map(attr => attr.id); const kLabelId = uniqueId(); dataSet.addAttributeWithID({ id: kLabelId, name: kLabelAttrName }); for (let i = 0; i < dataSet.cases.length; ++i) { const caseId = dataSet.cases[i].__id__; - const label = self.getRowLabel(i); + const label = getRowLabel(i); const caseValues: ICase = { __id__: caseId, [kLabelId]: label }; if (canonicalize) { attrIds.forEach(attrId => { @@ -524,9 +662,8 @@ export const TableContentModel = types } return dataSet; }, - isValidForGeometryLink() { - const dataSet = DataSet.create(); - self.applyChangesToDataSet(dataSet); + isValidDataSetForGeometryLink(dataSet: IDataSet) { + if ((dataSet.attributes.length < 2) || (dataSet.cases.length < 1)) return false; const attrIds = dataSet.attributes.map(attr => attr.id); for (const aCase of dataSet.cases) { @@ -535,6 +672,27 @@ export const TableContentModel = types } } return true; + }, + hasLinkableCases(dataSet: IDataSet) { + if ((dataSet.attributes.length < 2) || (dataSet.cases.length < 1)) return false; + + const attrIds = dataSet.attributes.map(attr => attr.id); + const isLinkableCaseValue = (value: number | string | null | undefined) => + (value != null) && (value !== "") && isFinite(Number(value)); + for (const aCase of dataSet.cases) { + if (attrIds.every(attrId => isLinkableCaseValue(dataSet.getValue(aCase.__id__, attrId)))) { + // we have at least one valid linkable case + return true; + } + } + return false; + } + })) + .views(self => ({ + isValidForGeometryLink() { + const dataSet = DataSet.create(); + self.applyChangesToDataSet(dataSet); + return self.isValidDataSetForGeometryLink(dataSet); } })); @@ -554,7 +712,7 @@ export function convertImportToChanges(snapshot: any) { // create rows const rowCount = columns.reduce((max, col) => { - const len = col.values && col.values.length || 0; + const len = col.values?.length || 0; return Math.max(max, len); }, 0); const rows: any[] = []; @@ -562,7 +720,7 @@ export function convertImportToChanges(snapshot: any) { const row: any = { __id__: uniqueId() }; columnProps.forEach((col: any, colIndex) => { const values = columns[colIndex].values; - if (col && col.id && i < values.length) { + if (col?.id && i < values.length) { row[col.id] = values[i]; } }); @@ -578,8 +736,10 @@ export function mapTileIdsInTableSnapshot(snapshot: SnapshotOut { const change: ITableChange = safeJsonParse(changeJson); - if ((change.action === "create") && (change.target === "geometryLink")) { - change.ids = idMap[change.ids as string]; + if ((change.target === "geometryLink") && change.ids) { + change.ids = Array.isArray(change.ids) + ? change.ids.map(id => idMap[id]) + : idMap[change.ids]; } if (change.links) { change.links.tileIds = change.links.tileIds.map(id => idMap[id]); @@ -592,6 +752,7 @@ export function mapTileIdsInTableSnapshot(snapshot: SnapshotOut `${caseId}:${attrId}`; +export const legacyLinkedPointId = (caseId: string) => caseId; +export const splitLinkedPointId = (id: string) => id.split(":"); diff --git a/src/models/tools/tool-content-info.ts b/src/models/tools/tool-content-info.ts index a4c9798c3e..addeabc5b6 100644 --- a/src/models/tools/tool-content-info.ts +++ b/src/models/tools/tool-content-info.ts @@ -7,6 +7,7 @@ export type ToolTileModelContentSnapshotPostProcessor = export interface IToolContentInfo { id: string; tool: string; + titleBase?: string; modelClass: any; metadataClass?: any; addSidecarNotes?: boolean; diff --git a/src/models/tools/tool-tile.ts b/src/models/tools/tool-tile.ts index 2fdb01cf22..66862bc9a4 100644 --- a/src/models/tools/tool-tile.ts +++ b/src/models/tools/tool-tile.ts @@ -1,9 +1,9 @@ -import { types, getSnapshot, Instance, SnapshotOut } from "mobx-state-tree"; -import { kPlaceholderToolID } from "./placeholder/placeholder-content"; -import { findMetadata, ToolContentUnion, ToolContentUnionType } from "./tool-types"; -import { v4 as uuid } from "uuid"; import { cloneDeep } from "lodash"; -import { Optional } from "utility-types"; +import { getSnapshot, Instance, SnapshotIn, SnapshotOut, types } from "mobx-state-tree"; +import { kPlaceholderToolID } from "./placeholder/placeholder-content"; +import { findMetadata, ToolContentUnion } from "./tool-types"; +import { DisplayUserTypeEnum } from "../stores/user-types"; +import { uniqueId } from "../../utilities/js-utils"; // generally negotiated with app, e.g. single column width for table export const kDefaultMinWidth = 60; @@ -22,20 +22,17 @@ export interface IDragTiles { items: IDragTileItem[]; } -export function createToolTileModelFromContent(content: ToolContentUnionType) { - return ToolTileModel.create({ content }); -} - export function cloneTileSnapshotWithoutId(tile: ToolTileModelType) { - const copy: Optional = cloneDeep(getSnapshot(tile)); - delete copy.id; + const { id, display, ...copy } = cloneDeep(getSnapshot(tile)); return copy; } export const ToolTileModel = types .model("ToolTile", { // if not provided, will be generated - id: types.optional(types.identifier, () => uuid()), + id: types.optional(types.identifier, () => uniqueId()), + // whether to restrict display to certain users + display: DisplayUserTypeEnum, // e.g. "GeometryContentModel", "ImageContentModel", "TableContentModel", "TextContentModel" content: ToolContentUnion }) @@ -79,4 +76,5 @@ export const ToolTileModel = types })); export type ToolTileModelType = Instance; +export type ToolTileSnapshotInType = SnapshotIn; export type ToolTileSnapshotOutType = SnapshotOut; diff --git a/src/models/view/nav-tabs.ts b/src/models/view/nav-tabs.ts index 826d372265..4b5eadd3dc 100644 --- a/src/models/view/nav-tabs.ts +++ b/src/models/view/nav-tabs.ts @@ -1,8 +1,10 @@ import { types, SnapshotIn, Instance } from "mobx-state-tree"; -import { UserModelType, UserTypeEnum } from "../stores/user"; +import { UserModelType } from "../stores/user"; +import { UserTypeEnum } from "../stores/user-types"; export enum ENavTab { kProblems = "problems", + kTeacherGuide = "teacher-guide", kStudentWork = "student-work", kMyWork = "my-work", kClassWork = "class-work", diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor.png new file mode 100644 index 0000000000..2e12d49560 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor2.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor2.png new file mode 100644 index 0000000000..08e5933150 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor2.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_CountingSquares.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_CountingSquares.png new file mode 100644 index 0000000000..7b07a25a08 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_2_CountingSquares.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Anchor.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Anchor.png new file mode 100644 index 0000000000..a5bf8c09e9 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Anchor.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_EqnCompare.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_EqnCompare.png new file mode 100644 index 0000000000..39ade7b3a0 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_EqnCompare.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_GraphConstant.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_GraphConstant.png new file mode 100644 index 0000000000..746acd9203 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_GraphConstant.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Height.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Height.png new file mode 100644 index 0000000000..321601e81d Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Height.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Intersection.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Intersection.png new file mode 100644 index 0000000000..bce667bd2d Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Intersection.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Table.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Table.png new file mode 100644 index 0000000000..24023eeddc Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_Table.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare1.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare1.png new file mode 100644 index 0000000000..c91f7233a7 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare1.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare2.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare2.png new file mode 100644 index 0000000000..249c7647b6 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare2.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare3.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare3.png new file mode 100644 index 0000000000..2dbda80167 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare3.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare4.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare4.png new file mode 100644 index 0000000000..aa6fe3ae92 Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare4.png differ diff --git a/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare5.png b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare5.png new file mode 100644 index 0000000000..caf64185af Binary files /dev/null and b/src/public/curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare5.png differ diff --git a/src/public/curriculum/moving-straight-ahead/moving-straight-ahead.json b/src/public/curriculum/moving-straight-ahead/moving-straight-ahead.json index ac563fd73d..edce4b35f5 100644 --- a/src/public/curriculum/moving-straight-ahead/moving-straight-ahead.json +++ b/src/public/curriculum/moving-straight-ahead/moving-straight-ahead.json @@ -163,6 +163,16 @@ "What do you think your walking rate is?
  • Make a prediction about your walking rate.
  • Use a meter stick and timer to help answer the following following questions about your walking rate. What is your walking rate in meters per second?
  • <
" ] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "Student answers will vary. It will be easier for students to find their walking rates by seeing how far they walk in, for example, 5 or 10 seconds and then divide the number of meters they walked by the number of seconds for which they walked." + ] + } } ] }, @@ -188,7 +198,136 @@ "format": "html", "text": [ "Situation A. Walking at a Consistent Rate", - "Assume you continue to walk at the consistent rate determined in the Initial Challenge.
  1. How long would it take you to walk 500 meters?
  2. How far could you walk in 5 seconds, 10 seconds, 30 seconds? In 60 seconds? In 1 hour?
  3. Write an equation that represents the distance d in meters that you could walk in t seconds. Compare your equation to your classmates’ equations.
  4. Describe what a graph of your equation would look like. Check your answer by making a graph of your data.
" + "Assume you continue to walk at the consistent rate determined in the Initial Challenge." + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "Answers will vary depending on the student’s walking rate. Sample answers are provided for a walking rate of 2 meters per second, and for a student who walks r meters per second." + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "1. How long would it take you to walk 500 meters?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "A student who walks 2 meters per second will walk 500 meters in 250 seconds, or 4 minutes and 10 seconds.", + "A student who walks r meters per second will walk 500 meters in 500/r seconds." + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "2. How far could you walk in 5 seconds, 10 seconds, 30 seconds? In 60 seconds? In 1 hour?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "A student who walks 2 meters per second will walk 10 meters in 5 seconds, 20 meters in 10 seconds, 60 meters in 30 seconds, 120 meters in 60 seconds, and 7200 meters in 1 hour.", + "A student who walks r meters per second will walk 5r meters in 5 seconds, 10r meters in 10 seconds, 30r meters in 30 seconds, 60r meters in 60 seconds, and 3600r meters in 1 hour." + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "3. Write an equation that represents the distance d in meters that you could walk in t seconds. Compare your equation to your classmates’ equations. Describe what a graph of your equation would look like. Check your answer by making a graph of your data. " + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "For a walking rate of 2 meters per second, an equation is d = 2t, where d is the distance in meters and t is the time in seconds.", + "For a walking rate of r meters per second, an equation is d = rt, where d is the distance in meters and t is the time in seconds." + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "4. Describe what a graph of your equation would look like. Check your answer by making a graph of your data. " + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "Possible answers.\nFor a walking rate of 2 meters per second: The graph would be a line starting at (0,0). For every one second walked, the distance increases by 2.", + "For a walking rate of r meters per second: The graph would be a line starting at (0,0). For every one second walked, the distance increases by r." + ] + } + }, + { + "layout": { + "height": 340 + }, + "display": "teacher", + "content": { + "type":"Geometry", + "board": { + "properties": { + "axisNames": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-1, -1], + "axisRange": [8, 10] + } + }, + "objects": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [1, 2], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [4, 8], + "properties": { + "name": "" + } + } ] } }, @@ -198,7 +337,17 @@ "format": "html", "text": [ "Situation B. Liz’s Claim", - "Liz claimed that walking rates are like ratios and she used proportional reasoning to answer the questions in Situation A. She wrote:\n
The walking rate is a multiplicative comparison statement. If I walk 1.5 m per sec, then I walk 7.5 m in 5 seconds, 15 m in 10 sec, … or 500 m in about 333 sec, etc.
\n\nIs she correct? Explain. " + "Liz claimed that walking rates are like ratios and she used proportional reasoning to answer the questions in Situation A. She wrote:\n The walking rate is a multiplicative comparison statement. If I walk 1.5 m per sec, then I walk 7.5 m in 5 seconds, 15 m in 10 sec, … or 500 m in about 333 sec, etc.\n\nIs she correct? Explain. " + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "Sample answer: She is correct. The ratio of meters walked to seconds always stays the same, so, for example, 1.5 meters/1 second = 7.5 meters/5 seconds = 15 meters/10 seconds. So you can always predict how long it will take to walk a specific distance based on this constant ratio." ] } } @@ -219,7 +368,18 @@ "format": "html", "text": ["Assume you continue to walk at the rate determined in the Initial Challenge. Describe in words the distance you could walk in a given number of seconds. Then write an equation to represent this information."] } - }] + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "For a walking rate of r meters per second, you can walk a distance in meters that is r times the number of seconds. That is, you can scale the ratio, meters per second, up or down by multiplying both meters and seconds by the same number. d = rt." + ] + } + } + ] }, "supports": [ ] @@ -280,29 +440,187 @@ "text": "Alana, Gilberto, and Leanne were students in Ms. Chang’s class. They each did the walking experiment to find their walking rates." } }, + [ + { + "content": { + "type": "Table", + "name": "Walking Rates", + "columns": [ + { "name": "Name", + "type": "string", + "values": ["Alana", "Gilberto", "Leanne"] + }, + { "name": "Walking Rate", + "type": "string", + "values": ["1 meter per second", "2 meters per second", "2.5 meters per second"] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "They had some questions concerning the different representations (tables, graphs and equations) of their walking data. To help them answer the questions:" + } + } + ], + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089\u2022\u0009Make a table showing the distance walked by each student for the first ten seconds." + } + }, { + "display": "teacher", "content": { "type": "Table", + "name": "Walking Rates (Distance / Time)", "columns": [ - { "name": "Name", - "type": "string", - "values": ["Alana", "Gilberto", "Leanne"] + { + "name": "Time (sec)", + "type": "number", + "values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] }, - { "name": "Walking Rate", - "type": "string", - "values": ["1 meter per second", "2 meters per second", "2.5 meters per second"] + { + "name": "Alana's D (m)", + "type": "number", + "values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + }, + { + "name": "Gilberto's D(m)", + "type": "number", + "values": [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + }, + { + "name": "Leanne's D(m)", + "type": "number", + "values": [0, 2.5, 5.0, 7.5, 10, 12.5, 15, 17.5, 20, 22.5, 25] } ] - }, + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089\u2022\u0009Graph the times and distances on the same coordinate axes. Label each line with the name of the person. Use a different color for each student." + } + }, + { "layout": { - "height": 110 + "height": 300 + }, + "display": "teacher", + "content": { + "title": "Walking Rates", + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t, D"], + "axisLabels": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-1, -2], + "axisRange": [10, 25] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0] + }, + { + "type": "point", + "parents": [10, 10], + "properties": { + "name": "Alana" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0] + }, + { + "type": "point", + "parents": [9, 18], + "properties": { + "name": "Gilberto" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0] + }, + { + "type": "point", + "parents": [6, 15], + "properties": { + "name": "Leanne" + } + } + ] + } + ] + } + }, + [ + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089\u2022\u0009Write an equation that represents the relationship between the time t and distance d walked by each student." + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Alana: d = t or d = 1t; Gilberto: d = 2t; Leanne: d = 2.5t." + } + } + ], + { + "content": { + "type": "Text", + "format": "html", + "text": "How are the different walking rates represented in the different equations, tables, and graphs?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "In the equation the walking rate is represented as the number that you multiply by the time to get distance. (Note that students will learn later that the multiplier is called the coefficient.) \nIn the table, the walking rate is represented as the difference between values for distance in consecutive rows (1 second apart). So, as the x-values increase by 1, the y values will increase by the walking rate. (Note that students will learn later that this is called the rate of change.)\nIn the graph, the walking rate is represented as the steepness of the graph – the greater the walking rate, the steeper the line on the graph. (Note that students will learn later that this is called the slope.)" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Which representation is more useful than another to solve a problem about walking? Explain." } }, { + "display": "teacher", "content": { "type": "Text", "format": "html", - "text": "They had some questions concerning the different representations (tables, graphs and equations) of their walking data. To help them answer the questions
  1. Make a table showing the distance walked by each student for the first ten seconds.
  2. Graph the times and distances on the same coordinate axes. Label each line with the name of the person. Use a different color for each student.
  3. Write an equation that represents the relationship between the time t and distance d walked by each student.
  • How are the different walking rates represented in the different equations, tables, and graphs?
  • Which representation is more useful than another to solve a problem about walking? Explain.
" + "text": "Answers will vary. Sample answers: The table is the most helpful because I can figure out the pattern, but I can also see many values that would answer questions.\nThe graph is the most important because I can see the pattern for the walking rates. I can also see how the pattern of change for one line is related to the pattern of change for another. I can also find or approximate answers to questions.\nThe equation is the most useful because I can use any amount of time to find the distance, not just small values for time like on a graph or table." } } ] @@ -321,34 +639,73 @@ "content": { "type": "Text", "format": "html", - "text": ["Situation A. Yvonne’s Claims
  1. Yvonne claims she can tell from the table that the relationships between time and distance are proportional. What evidence in the table shows they are proportional? Is this the same thing as saying the relationships are linear?
  2. Yvonne claims that she can use a table or a graph to answer the question:\n\u00a0\u00a0\u00a0For each student, if time t increases by 1 second, by how much \n\u00a0\u00a0\u00a0does the distance d change? \nIs she correct? Explain.
  3. Yvonne also claimed that the time and distance data represented in part 1 is the Constant of Proportionality. What do you think?
"] + "text": ["Situation A. Yvonne’s Claims \n\n1. Yvonne claims she can tell from the table that the relationships between time and distance are proportional. What evidence in the table shows they are proportional? Is this the same thing as saying the relationships are linear? "] } }, - { + { + "display": "teacher", "content": { "type": "Text", "format": "html", - "text": ["Situation B. Valentina and Omar have the Same Walking Rate\nValentina and Omar have the same walking rate. Each made a graph to represent their data. "] + "text": "The relationships are proportional. On the table, you can take any two coordinate pairs and write a proportion. Also, you can see this because any distance divided by time gives a constant ratio. Since the relationship is proportional, it is also linear because distance divided by time gives a constant rate of change. (Note: Not all linear relationships are proportional.)" } }, - { + { "content": { "type": "Text", "format": "html", - "text": ["Omar's Walking Rate: Distance d\u00a0 in meters vs. time t\u00a0 in seconds"] + "text": ["2. Yvonne claims that she can use a table or a graph to answer the question:\n\u00a0\u00a0\u00a0For each student, if time t increases by 1 second, by how much \n\u00a0\u00a0\u00a0does the distance d change? \nIs she correct? Explain."] } }, { - "layout": { - "height": 320 - }, + "display": "teacher", "content": { - "type":"Geometry", - "board": { - "properties": { - "axisNames": ["t", "d"], - "axisMin": [-5, -10], - "axisRange": [60, 100] + "type": "Text", + "format": "html", + "text": "She is correct. If time increases by 1 second, she can find the change in distance on a graph by looking at the steepness of the line. If time increases by 1 second, she can find the change in distance on a table by looking at the distance in two consecutive rows (one second apart) and calculating the difference." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Yvonne also claimed that the time and distance data represented in part 1 is the Constant of Proportionality. What do you think?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Yvonne is correct. All of the relationships are of the form d = rt. The value of r is the constant of proportionality for each relationship." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Valentina and Omar have the Same Walking Rate\nValentina and Omar have the same walking rate. Each made a graph to represent their data. "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Omar's Walking Rate: Distance d\u00a0 in meters vs. time t\u00a0 in seconds"] + } + }, + { + "layout": { + "height": 320 + }, + "content": { + "title": "Omar's Walking Rate", + "type":"Geometry", + "board": { + "properties": { + "axisNames": ["t", "d"], + "axisMin": [-5, -10], + "axisRange": [60, 100] } }, "objects": [ @@ -430,6 +787,7 @@ "height": 300 }, "content": { + "title": "Valentina’s Walking Rate", "type":"Geometry", "board": { "properties": { @@ -474,7 +832,30 @@ "content": { "type": "Text", "format": "html", - "text": ["
  1. How are their graphs similar? How are they different?
  2. Which expression could represent their distance?\n\n 5t \u00a0\u00a0\u00a0\u00a0 2t \u00a0\u00a0\u00a0\u00a0 0.5t
"] + "text": ["1. How are their graphs similar? How are they different?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Valentina and Omar’s graphs are similar in that, when the points are connected, the graphs have the same rate of change and y-intercept. Omar graphed his walking rate for 40 seconds, whereas Valentina graphed his walking rate for 4 seconds. Their scales are different as well. Omar uses intervals of 5 seconds and 10 meters, whereas Valentina uses intervals of 1 second and 1 meter. The different scales makes it appear that Valentina has a faster walking rate. However, their walking rates are the same. Because Omar’s vertical scale has twice the value as the horizontal scale, it appears to “pull down” the points as you have less vertical “movement” for every point. Valentina’s scales both have a value of one for every grid line. So, you will have the “same” movement on the horizontal and vertical axes for each coordinate pair." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Which expression could represent their distance?\n\n 5t \u00a0\u00a0\u00a0\u00a0 2t \u00a0\u00a0\u00a0\u00a0 0.5t"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The expression 2t could represent their distance. On both graphs, the distance traveled is always twice the time in seconds, so they are traveling 2 meters every second." } }, { @@ -500,9 +881,6 @@ "values": [0, 2, 9, 11, 20, 25] } ] - }, - "layout": { - "height": 210 } }, { @@ -521,9 +899,6 @@ "values": [0, 3, 6, 9, 12, 15] } ] - }, - "layout": { - "height": 210 } }, { @@ -540,6 +915,14 @@ "type": "Image", "url": "curriculum/moving-straight-ahead/images/MSA_1_2_evos_walkathon_graph.png" } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Elizabeth and Billie’s relationships are linear. Elizabeth walks at a constant rate of 3 meters every 2 seconds, which you can see in the table. Billie walks at a constant rate of 2.25 m/s, since the equation is in the form of d = rt, similar to the equations for Alana, Gilberto, and Leanne. Both of these relationships are also proportional, since at 0 seconds they have walked 0 meters.\n\n George’s, Evo’s, and Bob’s relationships are not linear. The table for George does not show a constant rate of change. Evo’s graph does not make a straight line, so it does not show a constant rate of change. In the equation for Bob, the rate is a variable, so the walking rate is not constant. (Some students may make graphs and claim the relationships are either linear or not based on whether the data lie on a straight line.)" + } } ] }, @@ -551,12 +934,22 @@ { "type": "nowWhatDoYouKnow", "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "How do you recognize a linear pattern of change in a verbal context, a table, a graph, an expression, or an equation?" + "tiles": [ + { + "content": { + "type": "Text", + "text": "How do you recognize a linear pattern of change in a verbal context, a table, a graph, an expression, or an equation?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "
  • Main idea: Relationships are linear when there is a constant rate of change.
  • Verbal context: key words include constant, [increase/decrease] by the same amount every [year/second/month]
  • Table: The values of one variable change at a constant rate when the other variable changes at a constant rate.
  • Graph: The graph is a straight line.
  • Expression: The independent variable is multiplied by a constant.
  • Equation: The independent variable is multiplied by a constant, so the dependent variable will change at a constant rate.
" + } } - }] + ] }, "supports": [ ] @@ -582,7 +975,7 @@ ] } }, - { + { "content": { "type": "Text", "format": "html", @@ -620,65 +1013,551 @@ "values": ["$10 regardless of how far she walks", "$2 per kilometer (km)", "$5 donation plus 50¢ per kilometer"] } ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["
  • Who will raise the most money? Explain.
    • "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The answer depends on how long the walkathon is. \nLeanne will raise the most money if the walkathon is shorter than 5 kilometers; Gilberto will “catch up” to Leanne when he walks 5 kilometers because he raises $2 per kilometer.\nGilberto will raise the most money if the walkathon is longer than 5 kilometers.\nAlana will never raise the most money because she has a smaller starting donation than Leanne and a smaller per-kilometer-walked donation than Gilberto." + } + }, + { + "layout": { + "height": 330 }, + "display": "teacher", + "content": { + "title": "Comparing Walking Rates", + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t, D"], + "axisLabels": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-1, -2], + "axisRange": [12, 15] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 10], + "properties": { + "name": "Leanne" + } + }, + { + "type": "point", + "parents": [10, 10], + "properties": { + "name": "" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0] + }, + { + "type": "point", + "parents": [6, 12], + "properties": { + "name": "Gilberto" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 5] + }, + { + "type": "point", + "parents": [16, 10], + "properties": { + "name": "Alana" + } + } + ] + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Table", + "name": "Donations", + "columns": [ + { + "name": "Distance (km)", + "type": "number", + "values": [0, 1, 2, 3, 4, 5, 6] + }, + { + "name": "Leanne's ($)", + "type": "number", + "values": [10, 10, 10, 10, 10, 10] + }, + { + "name": "Gilbero's ($)", + "type": "number", + "values": [0, 2, 4, 6, 8, 10] + }, + { + "name": "Alana's ($)", + "type": "number", + "values": [0, 2, 4, 6, 8, 10] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["
      • How does the relationship between dollars and kilometers represent a linear relationship?
        • "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "They are linear relationships because the students all raise a constant rate of money for each kilometer walked. Leanne raises $0 per kilometer, Gilberto raises $2 per kilometer, and Alana raises $0.50 per kilometer. This will form a straight line as each increase in 1 km leads to a constant increase in the donation monies." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["
          • How do these relationships compare to those in Problem 1.2? Explain.
            • "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Gilberto’s relationship is exactly like those in Problem 1.2 because when he has walked 0 km, he will earn $0. But Leanne’s and Alana’s relationships are different from those in Problem 1.2 because they have an extra amount of money added at the start of the walkathon. So, when they have walked 0 km, they will have raised $10 and $5, respectively. After that their plans have a constant rate of change." + } + } + ] + }, + "supports": [ + { + "text": "What are the variables for each plan?" + }, + { + "text": "How might a table, graph, or equation help?" + } + ] + }, + { + "type": "whatIf", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "Situation A. Using the Data\n1. In Alana’s plan, how is the fixed $5 donation represented in a table? A graph? An equation? How is the rate of change shown in the table, graph, and equation?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The fixed $5 donation represents the amount of money she raises by walking 0 kilometers. In the table, it is the amount of the donation when the distance is 0. (0,5) is the point where Alana’s graph intersects the y-axis; it is the point on the line for her plan with an x-coordinate of 0. In the equation, 5 is the term that is added to 0.50d where d represents the distance walked." + } + }, + { "layout": { - "height": 160 + "height": 330 + }, + "display": "teacher", + "content": { + "title": "Comparing Walking Rates", + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t, D"], + "axisLabels": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-1, -2], + "axisRange": [12, 15] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 10], + "properties": { + "name": "Leanne's fixed donation = y-intercept" + } + }, + { + "type": "point", + "parents": [10, 10], + "properties": { + "name": "" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0] + }, + { + "type": "point", + "parents": [6, 12], + "properties": { + "name": "Gilberto" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 5] + }, + { + "type": "point", + "parents": [16, 10], + "properties": { + "name": "Alana" + } + } + ] + } + ] } }, - { + { + "display": "teacher", + "content": { + "type": "Table", + "name": "Donation Table", + "columns": [ + { + "name": "Distance (km)", + "type": "string", + "values": ["0*", 1, 2, 3, 4, 5, 6] + }, + { + "name": "Alana's Donation ($)", + "type": "number", + "values": ["5*", 5.50, 6, 6.50, 7, 7.50, 8] + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "\u00a0\u00a0\u00a0 m = 5 + 0.50 d, where 5 is the fixed donation that is the 'amount added into' the equation. \n\nThe rate of change for Alana is $0.50 per kilometer. In the table, this is shown by the amount that the donation increases for every 1 kilometer or the amount each row of the y-variable increases for every increase of 1 km. The graph shows the rate of change as how much the line rises for every kilometer. In the equation, we see the rate of change in the coefficient, or the amount that is multiplied by the x-variable." + } + }, + { + "display": "teacher", + "content": { + "type": "Table", + "name": "Donation Table", + "columns": [ + { + "name": "Distance (km)", + "type": "string", + "values": ["0*", 1, 2, 3, 4, 5, 6] + }, + { + "name": "Alana's Donation ($)", + "type": "number", + "values": [5, 5.50, 6, 6.50, 7, 7.50, 8] + } + ] + } + }, + { + "display": "teacher", "content": { "type": "Text", "format": "html", - "text": ["
              • Who will raise the most money? Explain.
              • How does the relationship between dollars and kilometers represent a linear relationship?
              • How do these relationships compare to those in Problem 1.2? Explain.
                • "] + "text": "\u00a0\u00a0\u00a0 m = 5 + 0.50 d, where 0.50 is the rate of change which is the multiplier or coefficient of the variable d. \n\nThe rate of change for Alana is $0.50 per kilometer. In the table, this is shown by the amount that the donation increases for every 1 kilometer or the amount each row of the y-variable increases for every increase of 1 km. The graph shows the rate of change as how much the line rises for every kilometer. In the equation, we see the rate of change in the coefficient, or the amount that is multiplied by the x-variable." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "2. Suppose each student walks 8 kilometers in the walkathon. How much money does each sponsor donate? Explain how you found your answer." + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Leanne: Each sponsor donates $10 because they donate $10 regardless of how far she walks.\nGilberto: Each sponsor donates $2 • 8 = $16 because they donate $2 per kilometer he walks.\nAlana: Each sponsor donates $5 + $0.50 • 8 = $5 + $4 = $9 because they donate $5 plus $0.50 per kilometer she walks. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "3. Suppose each student raises $10 from a sponsor. How many kilometers does each student walk? Explain." + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Leanne: We cannot determine how far she walks since the amount of money she raises does not depend on how many kilometers she walks.\nGilberto: 5 kilometers because $2 x 5 = 10 or 10 ÷ 2 = 5.\nAlana: 10 kilometers because $10 - $5 = $5 so she has to raise $5 by walking; since she raises $0.50 per kilometer walked, she must walk $5 / $0.50 = 10 kilometers." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "4. On which graph does the point (12, 11) lie? What information does this point represent?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The point (12,11) lies on Alana’s graph since $5 + $0.50 x 12 = $5 + $6 = $11. This point means that if Alana walks 12 kilometers, each sponsor will donate $11." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "5. Yvonne claims that the relationships for Alana, Gilberto, and Leanne pledge plans are linear and proportional. Is she correct?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Leanne’s, Gilberto’s, and Alana’s plans are linear because they all show a constant rate of money raised per kilometer walked. Only Gilberto’s pledge plan is proportional because his plan doesn’t involve raising any money without walking any kilometers." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + " Situation B. Gilberto Gives T-shirts\n\nGilberto decides to give a T-shirt to each of his sponsors. Each shirt costs him $4.75. He plans to pay for each shirt with some of the money he raises from each sponsor.\n\n1. Write an expression that represents the amount of money Gilberto raises after paying for the T-shirts." + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "For each sponsor, Gilberto will earn $2 per kilometer walked and pay $4.75 regardless of how far he walks. The expression that represents the amount of money Gilberto will raise with this plan is 2*d – 4.75, where d represents the distance walked." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":[ + "2. How does this additional cost affect the amount of money he has raised reflected in a table, graph, and equation?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "When he has walked 0 km, he will have earned -$4.75, so (0,-4.75) will be a value on the table and will be the spot where Gilberto’s graph intersects the y-axis. After that, for each kilometer he walks, the money he raises will increase by $2. So (1,-2.75) will be a value on the table and the graph. In the equation, we subtract -$4.75 to represent this extra cost, so his profits are always decreased by $4.75, no matter how many kilometers he walks." + } + } + ] + }, + "supports": [{"text": "Which variable is the independent variable? Which is the dependent variable? "}] + }, + { + "type": "nowWhatDoYouKnow", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "How can you determine if a relationship is linear from a verbal context, table, graph, or equation?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "You can determine if a relationship is linear if there is a constant rate of change. That is, for every unit change in the independent variable there is a consistent change in the dependent variable. Another way to say this is “as the independent variable changes in equal increments, the dependent variable will change by a consistent amount.\n\nIn a table, as the independent variable increases by one unit the dependent variable will change by a consistent amount. The graph is a straight line. The equation is of the form y = ax + b. If b is 0 then the equation, y = ax is also proportional." + } + }, + { + "content": { + "type": "Text", + "text": "If a relationship is linear, explain how you can tell if it is proportional." + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Table: Values from the table are proportional. You can use the values to write proportions or “for every” ratio statements. For example, in the table for Gilberto:" + } + }, + { + "display": "teacher", + "content": { + "type": "Table", + "name": "Donation Table", + "columns": [ + { + "name": "Distance (km)", + "type": "number", + "values": [0, 1, 2, 3, 4, 5, 6] + }, + { + "name": "Gilberto's Donation ($)", + "type": "number", + "values": [0, 2, 4, 6, 8, 10, 12] + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Equation: The amount added into the equation is zero. Or the y-intercept is zero. For example, in the equation for Gilberto:\n\n \u00a0\u00a0\u00a0m = 2d or m = 2d + 0\n\nGraph: The graph of a proportional relationship is passes through the point (0,0). For example, in the graph for Gilberto:" + } + }, + { + "layout": { + "height": 330 + }, + "display": "teacher", + "content": { + "type": "Geometry", + "title": "Comparing Walking Rates", + "board": { + "properties": { + "axisNames": ["t, D"], + "axisLabels": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-1, -2], + "axisRange": [12, 15] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 10], + "properties": { + "name": "Leanne" + } + }, + { + "type": "point", + "parents": [10, 10], + "properties": { + "name": "" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "proportional line passes through (0, 0)" + } + }, + { + "type": "point", + "parents": [6, 12], + "properties": { + "name": "Gilberto" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 5] + }, + { + "type": "point", + "parents": [16, 10], + "properties": { + "name": "Alana" + } + } + ] + } + ] } } ] }, - "supports": [ - { - "text": "What are the variables for each plan?" - }, - { - "text": "How might a table, graph, or equation help?" - } - ] - }, - { - "type": "whatIf", - "content": { - "tiles": [ - { - "content": { - "type": "Text", - "format": "html", - "text":[ - "Situation A. Using the Data
                  1. In Alana’s plan, how is the fixed $5 donation represented in a table? A graph? An equation? How is the rate of change shown in the table, graph, and equation?
                  2. Suppose each student walks 8 kilometers in the walkathon. How much money does each sponsor donate? Explain how you found your answer.
                  3. Suppose each student raises $10 from a sponsor. How many kilometers does each student walk? Explain.
                  4. On which graph does the point (12, 11) lie? What information does this point represent?
                  5. Yvonne claims that the relationships for Alana, Gilberto, and Leanne pledge plans are linear and proportional. Is she correct?
                  " - ] - } - }, - { - "content": { - "type": "Text", - "format": "html", - "text":[ - " Situation B. Gilberto Gives T-shirts\n\nGilberto decides to give a T-shirt to each of his sponsors. Each shirt costs him $4.75. He plans to pay for each shirt with some of the money he raises from each sponsor.
                  1. Write an expression that represents the amount of money Gilberto raises after paying for the T-shirts.
                  2. How does this additional cost affect the amount of money he has raised reflected in a table, graph, and equation?
                  " - ] - } - } - ] - }, - "supports": [{"text": "Which variable is the independent variable? Which is the dependent variable? "}] - }, - { - "type": "nowWhatDoYouKnow", - "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "How can you determine if a relationship is linear from a verbal context, table, graph, or equation?\n\nIf a relationship is linear, explain how you can tell if it is proportional." - } - }] - }, "supports": [ ] } @@ -713,9 +1592,10 @@ } }, { - "content": { - "type": "Table", - "columns": [ + "content": { + "type": "Table", + "name": "Donations", + "columns": [ { "name": "week", "type": "number", @@ -727,11 +1607,8 @@ "values": [144, 132, 120, 108, 96, 84] } ] + } }, - "layout": { - "height": 190 - } - }, { "content": { "type": "Text", @@ -752,6 +1629,7 @@ }, "content": { "type": "Geometry", + "title": "Money in Account", "board": { "properties": { "axisNames": ["week", "$"], @@ -867,6 +1745,14 @@ "type": "Text", "text": "For each class, what is the pattern of change for the relationship between the variables? Explain how you know. " } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The pattern of change for Ms. Chang’s class is linear because the amount of money in the account decreases by a consistent amount of $12 each week. The pattern of change for Mr. Mamer’s class is linear because the data points on the graph form a straight line." + } } ] }, @@ -882,16 +1768,107 @@ "content": { "type": "Text", "format": "html", - "text": ["Situation A. Using the Data to Answer Questions\nFor each class:
                  1. How much money is in the account at the start? Explain.
                  2. How much money is withdrawn each week?
                  3. Write an equation that represents the relationship. Explain what information each number and variable represent.
                  4. After 10 weeks, how much money was used to buy items for the children’s ward at the hospital? How much money was left? Explain how you found the answer.
                  5. When is all the money spent? Where is this point on the graph?
                  6. How do the graphs of the data compare?
                  "] + "text": ["Situation A. Using the Data to Answer Questions\nFor each class: \n1. How much money is in the account at the start? Explain."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The pattern of change for Ms. Chang’s class is linear because the amount of money in the account decreases by a consistent amount of $12 each week. The pattern of change for Mr. Mamer’s class is linear because the data points on the graph form a straight line." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. How much money is withdrawn each week?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Ms. Chang: $144 because this is the amount of money in the account for week 0, or the start of keeping track of the money.\nMr. Mamer: $500 because this is the amount of money in the account for week 0, or the start of keeping track of the money." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Write an equation that represents the relationship. Explain what information each number and variable represent."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Ms. Chang: A = 144 + –12n or 144 – 12n, where n represents the number of weeks and A represents the amount of money in the account after n weeks. The rate at which the amount of money in the account is changing is –$12 per week, and the starting amount of money in the club’s account is $144.\nMr. Mamer: A = 500 + –10n or 500 – 10n, where n represents the number of weeks and A represents the amount of money in the account after n weeks. The rate at which the amount of money in the account is changing is –$10 per week, and the starting amount of money in the club’s account is $500. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["4. After 10 weeks, how much money was used to buy items for the children’s ward at the hospital? How much money was left? Explain how you found the answer."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Ms. Chang: The rate at which the amount of money in the account is changing is -$12 per week, so after 10 weeks the club has donated $12(10) = $120. Since they started with $144, they now have $144-$120=$24 left in the account.\nMr. Mamer: The rate at which the amount of money in the account is changing is -$10 per week, so after 10 weeks the club has donated $10(10) = $100. Since they started with $500, they now have $500-$100=$400 left in the account." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["5. When is all the money spent? Where is this point on the graph?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Ms. Chang: If they spent $12 per week and they had $144 at the beginning, then all the money would be spent after 144/12 = 12 weeks.\nMr. Mamer: If they spent $10 per week and they had $500 at the beginning, then all the money would be spent after 500/10 = 50 weeks. This is the point where the graph crosses the horizontal axis, since that represents A=0." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["6. How do the graphs of the data compare?"] } }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Both of the relationships in this Problem have decreasing rates of change, though the graph of Ms. Chang’s club’s account has a larger decreasing rate of change. Mr. Mamer’s club started with a larger amount of money in their account, so the y-intercept is larger." + } + }, { "content": { "type": "Text", "format": "html", - "text": ["Situation B. What’s the Question?\nOne of Mr. Mamer’s students wrote the following two statements to help her answer questions about their account\n\u00a0\u00a0\u00a0 500 - 10t = 100 \n\u00a0\u00a0\u00a0 500 - 10t < 100 \n\nWhat questions was she trying to answer?"] + "text": ["Situation B. What’s the Question?\nOne of Mr. Mamer’s students wrote the following two statements to help her answer questions about their account\n\u00a0\u00a0\u00a0 500 - 10t = 100 \n\u00a0\u00a0\u00a0 500 - 10t < 100 \n\nWhat questions was she trying to answer?"] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The first equation is setting the expression for how much money is left in the account after t weeks equal to 100, so she is trying to find how many weeks it will take for there to be $100 left in the account. The second equation is trying to find how many weeks it will take for there to be less than $100 left in the account." + } } ] }, @@ -903,12 +1880,22 @@ { "type": "nowWhatDoYouKnow", "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "Compare the patterns of change for the linear relationships in this Problem to those in previous Problems in this Investigation. Do any of these represent proportional situations? Explain." - } - }] + "tiles": [ + { + "content": { + "type": "Text", + "text": "Compare the patterns of change for the linear relationships in this Problem to those in previous Problems in this Investigation. Do any of these represent proportional situations? Explain." + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": " Both of the relationships in this Problem have decreasing rates of changes. As the independent variable increases, the dependent variable decreases. This results in the graph of a line that decreases from left to right and an equation for which the independent variable has a negative coefficient. Neither situation is proportional since their graphs do not go through the origin nor can the equation that represents them be written in the form y = ax. And the values from the relationship cannot be written as a “for every” statement or to form proportions." + } + } + ] }, "supports": [] } @@ -1219,9 +2206,6 @@ "values": [34, 41.5, 46.5, 54, 59] } ] - }, - "layout": { - "height": 160 } } ] @@ -1432,9 +2416,6 @@ "values": [5, 5.5, 6, 6.5, 7, 15, 17.5, 20] } ] - }, - "layout": { - "height": 240 } }, { @@ -2115,6 +3096,15 @@ "type": "Text", "text": "Determine the steepness of a set of stairs in your school or home. \n\n • \u00a0 How can you describe the steepness of the stairs?\n • \u00a0 Is the steepness the same between any two consecutive steps? \n • \u00a0 How do the stairs you measured compare to the carpenters’ guidelines? " } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Interesting situations to think about include: spiral staircases, school stairs, large steps (like at a museum), etc.\nExample: 7.25 in. to 11.25 inches for the rise to the run, or approximately 0.70 for the ratio of rise to run. This is the same for every step in the staircase. The ratio of rise to run is not within the carpenter’s guidelines." + } } ] }, @@ -2130,13 +3120,136 @@ "content": { "type": "Text", "format": "html", - "text": ["Situation A. Arch Middle School Stairs\nA set of stairs is being built for the front of the new Arch Middle School. The ratio of rise to run is 7 to 11.
                  1. Is this ratio within the carpenters’ guidelines?
                  2. Make a sketch of a set of stairs that meet this ratio. Label the lengths of the rise and run of a step.
                  3. Does everyone in your class have the same sketch? Explain why.
                  4. Write an equation that represents the relationship between rise and run.
                  5. How is the ratio of rise to run represented in the graph? Equation?
                  6. Does your graph represent a proportional relationship? Explain why.
                  "]} + "text": ["Situation A. Arch Middle School Stairs\nA set of stairs is being built for the front of the new Arch Middle School. The ratio of rise to run is 7 to 11. \n1. Is this ratio within the carpenters’ guidelines?Situation B. Anna’s Claim\n1.Anna claims that the ratio of rise to run is another way to express the pattern of change between the two variables in a linear situation. Is she correct? Explain why."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Yes, she is correct. The ratio of rise to run describes how much one variable changes if you change the other variable by a specific amount. If the variables are always related in this way, then they have a constant rate of change, which gives a linear relationship." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Is the ratio the same between any two steps? Explain."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Yes, because each step on the staircase will have the same height (or rise) and depth (or run)." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Does the ratio change if we take two steps at a time? Explain why."]} }, { + "display": "teacher", "content": { "type": "Text", "format": "html", - "text": ["Situation B. Anna’s Claim
                  1. Anna claims that the ratio of rise to run is another way to express the pattern of change between the two variables in a linear situation. Is she correct? Explain why.
                  2. Is the ratio the same between any two steps? Explain.
                  3. Does the ratio change if we take two steps at a time? Explain why.
                  "]} + "text": + "No, because we’re rising twice as high and running twice as far. So, the ratio will stay the same." + } } ] }, @@ -2148,12 +3261,23 @@ { "type": "nowWhatDoYouKnow", "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "How does the steepness of stairs expressed as a ratio related to a straight-line graph? To a linear equation that represents the graph?" + "tiles": [ + { + "content": { + "type": "Text", + "text": "How does the steepness of stairs expressed as a ratio related to a straight-line graph? To a linear equation that represents the graph?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The steepness of stairs is represented by the slope of a straight-line graph. In a linear equation that represents the graph, the steepness of the stairs is represented by the coefficient of x." + } } - }] + ] }, "supports": [] } @@ -2226,9 +3350,6 @@ "values": [6, 3, 0, -3, -6] } ] - }, - "layout": { - "height": 160 } }, { @@ -2275,9 +3396,6 @@ "values": [-1, -0.5, 0, 0.5, 1] } ] - }, - "layout": { - "height": 160 } }, { @@ -2334,73 +3452,71 @@ { "content": { "type": "Text", - "text": "Representation 1" + "text": "\u0089Representation 1\u0089\u0089\u0089Representation 2" } }, - { - "layout": { - "height": 200 - }, - "content": { - "type":"Geometry", - "board": { - "properties": { - "axisMin": [-5, -10], - "axisRange": [10, 32] - } + [ + { + "layout": { + "height": 200 }, - "objects": [ - { - "type": "movableLine", - "parents": [ - { - "type": "point", - "parents": [-2, 6] - }, - { - "type": "point", - "parents": [2, -6] - } - ] - } - ] - } - }, - { - "content": { - "type": "Text", - "text": "Representation 2" - } - }, - { - "layout": { - "height": 200 + "content": { + "type":"Geometry", + "title": "Representation 1", + "board": { + "properties": { + "axisMin": [-5, -10], + "axisRange": [10, 32] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [-2, 6] + }, + { + "type": "point", + "parents": [2, -6] + } + ] + } + ] + } }, - "content": { - "type":"Geometry", - "board": { - "properties": { - "axisMin": [-5, -3], - "axisRange": [10, 10] - } + { + "layout": { + "height": 200 }, - "objects": [ - { - "type": "movableLine", - "parents": [ - { - "type": "point", - "parents": [-4, -2] - }, - { - "type": "point", - "parents": [4, 2] - } - ] - } - ] + "content": { + "type":"Geometry", + "title": "Representation 2", + "board": { + "properties": { + "axisMin": [-5, -3], + "axisRange": [10, 10] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [-4, -2] + }, + { + "type": "point", + "parents": [4, 2] + } + ] + } + ] + } } - }, + ], { "content": { "type": "Table", @@ -2417,9 +3533,15 @@ "values": [-1, -0.5, 0, 0.5, 1] } ] - }, - "layout": { - "height": 160 + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Representation 1: The constant of proportionality is -3, which is the same as the rate of change (-3/1).\nRepresentation 2: The constant of proportionality is 1/2, which is the same as the rate of change (1/2).\nRepresentation 3: The constant of proportionality is 0.5, which is the same as the rate of change (0.5/1).\nStudent answers will vary. Possible situation for representation 2: You place a bucket under a leaking faucet, which collects 1 cup of water every 2 hours." } } ] @@ -2450,24 +3572,131 @@ "content": { "type": "Text", "format": "html", - "text": ["1. What is the rate of change and y-intercept associated with each representation?\n2. Do any of the relationships represent a proportional relationship? If so, what is the constant of proportionality? "] + "text": ["1. What is the rate of change and y-intercept associated with each representation?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Graph 1: slope: -3, y-intercept: 6\nGraph 2: slope: 3, y-intercept: 6\nTable 1 : slope :1.5, y-intercept : -1\nTable 2 : slope : -0.5, y-intercept : 5\nquation 1 : slope : 2.5, y-intercept : 5\nEquation 2 : slope : -3, y-intercept : 0" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Do any of the relationships represent a proportional relationship? If so, what is the constant of proportionality? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The relationship shown by Equation 2 is proportional with a constant of proportionality of -3." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. John’s Claims\n1. John noticed that if the points (0,0) and (1, a) are on a line, then the line represents a proportional relationship, and a is the constant of proportionality. Is he correct? Explain."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "He is correct because the line runs through the origin and, for every point on the line, the ratio of the x- and y-coordinates is always a." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. John also claims that the constant of proportionality is the unit rate. Is he correct? Explain why. "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "He is correct. The constant of proportionality a for this line means that each time the x-variable increases by 1, the y-variable increases by a. So, the ratio is a to 1, which is also a unit rate." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. More Lines\nThe points (3, 5) and (-2, 10) lie on a line.\n1. What is the rate of change or slope of the line?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The rate of change of the line is (10 – 5)/(-2 - 3) = 5/-5 = -1" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Find two more points that lie on this line. Explain your method."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. \nFor example, (-1,9) is on the line because you can increase the x-coordinate of (-2,10) by 1 and decrease the y-coordinate of (-2,10) by 1." } }, { "content": { "type": "Text", "format": "html", - "text": ["Situation B. John’s Claims\n1. John noticed that if the points (0,0) and (1, a) are on a line, then the line represents a proportional relationship, and a is the constant of proportionality. Is he correct? Explain.\n2. John also claims that the constant of proportionality is the unit rate. Is he correct? Explain why. "] + "text": ["3. Does this line represent a proportional relationship? Explain."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "This line does not represent a proportional situation because it does not pass through the origin." } }, { "content": { "type": "Text", "format": "html", - "text": ["Situation C. More Lines\nThe points (3, 5) and (-2, 10) lie on a line.
                  1. What is the rate of change or slope of the line?
                  2. Find two more points that lie on this line. Explain your method.
                  3. Does this line represent a proportional relationship? Explain.
                  4. What is the rate of change or slope of a horizontal line? A vertical line? Explain your reasoning.
                "] + "text": ["<4. What is the rate of change or slope of a horizontal line? A vertical line? Explain your reasoning."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The rate of change of a horizontal line is 0 because there is no “rise” no matter how far you “run.” The rate of change of a vertical line is undefined because there is no “run” no matter how far you “rise.”" + } } - } - ] + ] }, "supports": [ {"text": "Are the graphs steep? What will that mean about the rate of change?"}, @@ -2477,12 +3706,23 @@ { "type": "nowWhatDoYouKnow", "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "How is the rate of change of a linear relationship related to the constant of proportionality?" + "tiles": [ + { + "content": { + "type": "Text", + "text": "How is the rate of change of a linear relationship related to the constant of proportionality?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Some linear relationships are proportional and some are not. The rate of change represents how one variable changes compared to the other. For a given relationship, the rate of change is constant for any x- and y-values you choose.\nWhen a linear situation is also proportional, the unit rate, constant of proportionality, and the rate of change are all the same." + } } - }] + ] }, "supports": [] } @@ -2505,6 +3745,15 @@ "format": "html", "text": ["The students did so well in organizing the walkathon that Ms. Chang organized a special field trip to watch a movie. \n\nSuppose that a movie company charges the school $4.50 per student. But the movie company does not want to lose money. The company’s operating expenses include $130 for the staff and a film rental fee of $1.25 per student. \n\n• How many students need to attend the movie so that the theater’s income will equal its operating expenses? "] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The movie company will “break even” if there are 40 students in attendance.\nStudent answers will vary. \n\nSample response finding when Expenses equal Income:\nWe can find when the expenses and incomes are equal.\n\u00894.50n = 130 + 1.25n\n\u00893.25n = 130\n\u0089n = 40\n\nSample response using the Profit equation:\nWe can write equations for the movie company’s income I, expenses E, and model profit P as income – expenses. For some number of students n.\n\u0089P = I – E \n\u0089P = 4.50n – (130 + 1.25n)\n\u0089P = 3.25n – 130\nThe point at which the movie company will “break even” is the point at which their profit equals zero, so we can solve for which value of n makes P=0.\n\u00890 = 3.25n – 130\n\u0089130 = 3.25n\n\u008940 = n" + } } ] }, @@ -2528,7 +3777,7 @@ "content": { "type": "Text", "format": "html", - "text": ["Geraldo’s Strategy: I made the following tables:"] + "text": ["Geraldo’s Strategy: I made the following table:"] } }, { @@ -2545,22 +3794,6 @@ "name": "Income, I ($)", "type": "number", "values": [ ] - } - ] - }, - "layout": { - "height": 220 - } - }, - { - "content": { - "type": "Table", - "name": "Theater Expenses", - "columns": [ - { - "name": "Number of Students, x", - "type": "number", - "values": [0, 10, 20, 30, 40, 50, 60, 70] }, { "name": "Expenses, E ($)", @@ -2568,9 +3801,6 @@ "values": [ ] } ] - }, - "layout": { - "height": 180 } }, { @@ -2587,18 +3817,109 @@ "text": ["Sze’s Strategy: I wrote an expression that represents the theater’s profit. "] } }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Geraldo’s strategy could be used by filling out the table and looking for the number of students when the income is the same as the expenses. \n\nAnna’s strategy could be used by graphing the line for income and the line for operating expenses and looking for the intersection point. \n\nSze’s strategy could be used by making his expression into an equation equal to a profit of 0." + } + }, { "content": { "type": "Text", "format": "html", - "text": ["Situation B. Laneshia Uses Inequalities \nLaneshia wanted to find the number of students that make each of the following inequality statements true.
                • Expenses < 255 or $1.25n + $130 < $255
                • Income > 675 or $4.50n > $675
                1. Find the number of students that makes each inequality statement true.
                2. How might this information be helpful in making decisions about the showing of the film?
                "] + "text": ["Situation B. Laneshia Uses Inequalities \nLaneshia wanted to find the number of students that make each of the following inequality statements true.
                • Expenses < 255 or $1.25n + $130 < $255
                • Income > 675 or $4.50n > $675
                \n1. Find the number of students that makes each inequality statement true."] } }, - { + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "To find the number of students that will make expenses less than $255, we need to solve the associated equality. So 1.25n+130=255\n\u0089 1.25n = 125 \n\u0089 n = 100. So to make the inequality statement for expenses true, there need to be less than 100 students.\n\nTo find the number of students that will make the income greater than $675, we need to solve the associated equality. So 4.50n = 675 \n\u0089 n = 150. \nSo to make the inequality statement for income true, there need to be more than 150 students." + } + }, + { "content": { "type": "Text", "format": "html", - "text": ["Situation C. A Competing Company \nAt another theater, they used the equation, P\u00a0 = 3n\u00a0 – 115 to find the profit P for the number of students n that attend the theater. What do the numbers 3 and 115 tell you about
                1. the relationship between the number of students and the theater’s profit?
                2. the pattern of entries that would appear in a table of sample (students, profit) data?
                3. a graph of the relationship between the number of students and the profit?
                Write and solve an equation you can use to find the number of students for which the theaters in Exercise 1 and Exercise 2 make the same profit. Then find the amount of that profit."] + "text": ["2. How might this information be helpful in making decisions about the showing of the film?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Sample answer: If you only have a fixed amount of money to spend on showing the movie, then the expenses inequality can keep you from going into debt. If you need to raise a certain amount of money from showing the movie, then the income inequality can help you calculate how many tickets to sell." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. A Competing Company \nAt another theater, they used the equation, \n\u0089 P\u00a0 = 3n\u00a0 – 115 \nto find the profit P for the number of students n that attend the theater. What do the numbers 3 and 115 tell you about \n1. The relationship between the number of students and the theater’s profit? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you how much the theater’s profit will increase for each extra student who attends the theater. The number -115 tells you some expense or initial fee for using the theatre." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. the pattern of entries that would appear in a table of sample (students, profit) data? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you how much pattern of change. For every additional student, there is an increase of $3 between consecutive profit entries on the table. The number -115 tells you the profit entry that corresponds with zero students." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. a graph of the relationship between the number of students and the profit? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you the rate of change, or slope, of the line (because profit increases by 3 every time the number of students increases by 1). The number -115 tells you the y-intercept of the line." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Write and solve an equation you can use to find the number of students for which the theaters in Exercise 1 and Exercise 2 make the same profit. Then find the amount of that profit."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The equation for profit for the theater in the initial challenge was P1 = I – E = 4.50n – (130 + 1.25n) = 3.25n – 130. The equation for profit for the theater in this problem is P2 = 3n – 115. If they make the same profit, then we can set the expressions equal and solve for the number of students.\n\u00893.25n – 130 = 3n – 115\n\u0089 0.25n = 15\n\u0089 n = 60\nThis means that these two theaters will make the same profit for 60 students." } } ] @@ -2611,12 +3932,23 @@ { "type": "nowWhatDoYouKnow", "content": { - "tiles": [{ - "content": { - "type": "Text", - "text": "How do the situations in this problem compare to other problems in this unit? Do any of these represent proportional situations? Why? In what ways are tables, graphs, equations, and inequalities useful for solving problems?" + "tiles": [ + { + "content": { + "type": "Text", + "text": "How do the situations in this problem compare to other problems in this unit? Do any of these represent proportional situations? Why? In what ways are tables, graphs, equations, and inequalities useful for solving problems?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Sample answer: The movie theater situations in this Problem have positive rates of change (like the staircases). Some of the other problems showed decreasing/negative rates of changes. The movie theater problems don’t make sense for fractions of students, but the staircase problems make sense for fraction or decimal measurements. None of the movie theater problems are proportional situations, because none of them would pass through the origin if graphed.\nTables are useful for solving problems because they show several numerical values for a given pattern. Graphs are useful because they give you a sense of the pattern’s behavior over a wide range of values, which is helpful for estimating. Equations are useful because you can use them to calculate any specific value and the coefficients give you information about the problem situation. Inequalities are useful if you are looking for a range of possible answers." + } } - }] + ] }, "supports": [] } @@ -2664,6 +3996,14 @@ "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" ] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The coefficient a in the equation y = ax + b that represents a linear relationship is the rate of change between the independent variable and the dependent variable. It controls the slant of the line that represents the relationship. Greater absolute values of a mean there is a greater rate of change in the situation, so the lines are steeper. Positive values of a give lines that slant up. Negative values of a give lines that slant down. The value of b gives the y-intercept of the line. It is represented as the point (0, b) on the line or the pair of values in a table. In a table, the y-intercept is the value where the x-value is 0, and the rate of change is the difference in consecutive values of the dependent variable for constant increments in the independent variable.\nAny ordered pair (point) that lies on the graph of a linear relationship can be used to find the solution to a problem. The ordered pair (x, y) represents specific values of the variables. If the value of one of the variables is known, then the graph can be traced to find the corresponding value of the other variable. Similarly, any ordered pair in a table for a linear relationship can be used to find the solution to a problem.\nTo find solutions to inequalities, we can consider the solution to the corresponding equality. Then consider the values that would make sense. Often the situation indicates the values to solve an inequality. For example, we often look at “When is one company less expensive than another company?” or “How many items do we need to sell to make a profit?”" + } } ] }, @@ -2681,6 +4021,15 @@ "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" ] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "If you have an equation of the form y = ax + b and you know the value of x or y, you can substitute the value of the variable into the equation. Then, use the properties of equality to solve for the other variable. For example, if y = 3x + 4 and you want to find x when y = 10, then you substitute 10 in place of y: 10 = 3x + 4. Next, you can subtract 4 from both sides to get 6 = 3x. Now, divide both sides by 3 to get x = 2.\nFor the equation y = 3x + 4, to find the value of x when y = 10, you can graph the equation. Trace along the line to find the point whose y-coordinate is 10 and then read the corresponding x-value, which is 2. To use a table, construct a table of values for the equation either by hand or with graphing technology. Next, locate the pair of values in which y = 10 and find the corresponding x-value, which is 2.\nTo find the values that satisfy an inequality such as 3x + 4 < 10, you can solve the corresponding equation 3x + 4 = 10. The solution of this equation is x = 2. Then, test values less than and greater than 2 to determine the solution. In this case, x-values less than 2 make the inequality 3x + 4 < 10 true, so the solution is x < 2.\nTo find the values that satisfy an inequality such as 3x + 4 < 10, you can graph the corresponding linear relationship y = 3x + 4. Then, find the points on the line whose y-values are less than 10. You can also locate the x-values of these points on the x-axis or on a number line.\nIn Problem 3.2, Equation 1 two equivalent expressions for the number of pouches on the left side of the equation are 4x + 2 and 2(2x + 1). You can use the properties of operations to show that they are equivalent. Applying the Distributive Property to one of the expressions yields the other: 4x + 2 = 2(2x + 1). You can also argue that both of the expressions represent the number of pouches and coins in the picture.\nIn Problem 3.3, Set 3(a), two equivalent ways of writing the expression on the left side of the equation are 3(x + 1) and 3x + 3. You can tell they are equivalent because the equations 3(x + 1) = 21 and 3x + 3 = 21 have the same solution, even though you would take different steps when solving them. (To solve the first equation, you would divide each side by 3 and then subtract 1 from each side. To solve the second equation, you would subtract 3 from each side and then divide each side by 3. The solution for both equations is x = 6.)" + } } ] }, @@ -2698,6 +4047,15 @@ "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" ] } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Slope describes the steepness of a line. It is the ratio of vertical change to horizontal change. If it is positive, then the line is increasing from left to right. If it is negative, then it is decreasing from left to right. If the slope is zero, the line is horizontal. This is like walking on a flat surface as opposed to up or down a hill.\nFinding the slope is the same as finding the rate of change between two variables in a linear relationship. The horizontal distance change between two points is the same as the difference between two corresponding x-values of points in a table. The vertical change in distance is the same as the difference between two corresponding y-values of points in a table." + } } ] }, diff --git a/src/public/curriculum/moving-straight-ahead/msa-teacher-guide.json b/src/public/curriculum/moving-straight-ahead/msa-teacher-guide.json new file mode 100644 index 0000000000..f3692f2cd4 --- /dev/null +++ b/src/public/curriculum/moving-straight-ahead/msa-teacher-guide.json @@ -0,0 +1,3250 @@ +{ + "code": "msa", + "abbrevTitle": "MSA", + "title": "Moving Straight Ahead", + "subtitle": "Linear Expressions, Equations, and Relationships", + "placeholderText": "Enter notes here", + "settings": { + "table": { + "numFormat": ".2~f" + } + }, + "sections": { + "overview": { + "initials": "OV", + "title": "Overview", + "placeholder": "Work area for\noverview section" + }, + "launch": { + "initials": "LC", + "title": "Launch", + "placeholder": "Work area for\nInitial Challenge section" + }, + "explore": { + "initials": "EX", + "title": "Explore", + "placeholder": "Work area for\nExplore section" + }, + "summarize": { + "initials": "SM", + "title": "Summarize", + "placeholder": "Work area for\nSummarize section" + } + }, + "defaultStamps": [ + { + "url": "curriculum/moving-straight-ahead/stamps/coin.png", + "width": 25, + "height": 25 + }, + { + "url": "curriculum/moving-straight-ahead/stamps/pouch.png", + "width": 30, + "height": 37 + }, + { + "url": "curriculum/moving-straight-ahead/stamps/plus.png", + "width": 25, + "height": 25 + }, + { + "url": "curriculum/moving-straight-ahead/stamps/equals.png", + "width": 25, + "height": 25 + }, + { + "url": "curriculum/moving-straight-ahead/stamps/lparen.png", + "width": 25, + "height": 25 + }, + { + "url": "curriculum/moving-straight-ahead/stamps/rparen.png", + "width": 25, + "height": 25 + } + ], + "investigations": [ + { + "description": "Investigation 1", + "ordinal": 1, + "title": "MSA Investigation 1 Walking Rates", + "problems": [ + { + "description": "Problem 1.1", + "ordinal": 1, + "title": "MSA 1.1 Walking Marathons", + "subtitle": "Using Rates", + "disabled": ["GeometryMovableLineEquation"], + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "This Problem introduces patterns of change between two variables in the context of a walkathon. Students determine their walking rates in meters per second as a ratio of distance to time. This Problem connects back to the rate work done in Comparing and Scaling while laying the foundation for using rate to look at patterns of change. Students answer questions about time and distance using their constant walking rates and write an equation that models the distance walked over time at their constant walking rates." + ] + } + }, + { + "content": { + "type": "Text", + "text": "1.1 Walking Marathons: Using Rates\nAoL: Introduce & Introduce/Explore\nCCSSM: 7.RP.A.2, 7.RP.A.2a, 7.RP.A.2b, 7.RP.A.2c, 7.EE.B.4:" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": [ + "NWDYK\nAssume you continue to walk at the rate determined in the Initial Challenge. Describe in words the distance you could walk in a given number of seconds. Then write an equation to represent this information. " + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Emerging Mathematical Ideas\nBegin making sense of a problem context that involves a proportional relationship between two variables (time, distance) described initially in words and connecting it to an equation and a graph of the relationship. \nBegin to notice/recognize:
                • rate is a way to describe how far you can travel in a fixed interval of time – e.g., in two seconds I can move 20 feet, and use phrases like “consistent rate” and “constant rate” to describe relationships like this one,
                • proportional relationships,
                • an understanding of rates can be connected to prior experiences with ratios and proportional reasoning (multiplicative reasoning),
                • the relationship between the length of time traveled and the distance covered at a particular rate can be described in words, e.g., if I walk at a rate of 5 meters per second, then I can find the distance I travel by multiplying the number of seconds I travel by 5 m/sec. (the unit rate),
                • the distance traveled (d) at a constant rate (r) for a period of time (t) can be described by the equation d = r x t,
                • the equation needed to describe the distance traveled for two different people will be the same except that the value for the rate will vary, and
                • when points for several different values of time and distance traveled (at a given rate) are graphed, the points will form a straight line.
                " + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Launch (Getting Started) Connecting to Prior Knowledge\n\nThe introduction to the Investigation revisits Adrian’s Bike Rental from Grade 6 Variables and Patterns. In that Unit, students used contextual situations, tables, graphs, and equations to represent patterns relating variables such as cost, income, and profit. They looked at both consistent relationships (such as linear patterns) and non-consistent relationships to explain the pattern of change between two variables.\n\nThe four questions in the introduction to the Investigation offer overarching questions that the students should explore throughout the unit. You may want to display these questions in the classroom in some way to help keep students focused on the big ideas in the Unit.
                • How can you determine whether a relationship is linear by examining a table of data? A graph? An equation? A verbal context?
                • If the relationship is linear, how can you determine if it is a proportional relationship?
                • How do changes in one variable affect changes in a related variable? How are these changes represented in a table, graph, or equation?
                • If I know the value of one variable, how can I find the value of the other variable?
                After setting the scene for the Unit with the four questions, begin to introduce students to the context of the Problem." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "Ask students to describe if they are fast or slow walkers and to describe their evidence.", + "Suggested Questions", + "
                1. Who is the slowest walker you know? Who is the fastest walker you know? (Various answers.)
                2. Do you walk fast or slow? How do you know? (Various answers. Students should offer some reasoning for saying that they are fast or slow, such as, Teri always passes me in the hall because I walk slowly.)
                3. What do you think your walking rate is in miles per hour? In meters per second? (Various answers. Students’ conjectures will help set up the Problem.)
              ", + "Student predictions will likely be much higher than their actual walking rates. They may have some knowledge about walking rates if they have used a treadmill. On a treadmill, a person might set the walking speed at 4 miles per hour. One interesting thing about treadmills is that the rate of 4 miles per hour may also be reported as 15 minutes per mile. You might discuss why both these rates are reported or why treadmills do not report the rate in miles per minute or meters per hour." + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Presenting the Challenge\n\nTell a story about walkathons. Students may have some experience with other “–athons.” The Launch Video animation depicts two characters discussing an upcoming walkathon and helping each other figure out their walking rates. You can use this animation to help students understand the context of the walkathon. You can also use it as a demonstration of the steps needed for students to find their walking rates. \n\nNow tell students that they will have a chance to check their guesses about their walking rates. Describe the experiment. \n\nGive each group access to meter sticks (or a pre-set measurement of 10 meters) and a timer or a clock with seconds. Students should do the experiment twice to get a more accurate walking rate. They can choose either the rate they want or the average of the two. Make sure there is a person checking the time in each group. As the groups finish collecting their data, they can work on the questions in the What If…? questions. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "Ask students to describe if they are fast or slow walkers and to describe their evidence.", + "Suggested Questions", + "
              • What does meters per second mean? (A rate where we know how many meters in one second.)
              • How might meter sticks and a timer help? (Like the video explains, we can line-up 10 sticks and find how long it takes to walk 10 meters.)
              • What are the variables? (meters and seconds) What is the relationship between the variables? (The more distance I walk, the more time it will take.)
              " + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text":[ + "You could extend this Problem by asking some groups to record their data on a display such as a graph. Students may also record their graphs on transparent or electronic grids so that they can be used in the Summarize. \n\nThe following optional suggestions are designed to enrich the experiment:
              • Let the groups decide whether they want to calculate meters per second or seconds per meter.
              • Ask one group to change their walking rate—maybe walk, jog, sprint, and so on.
              • Ask some students to walk for 10 seconds rather than 10 meters. Be sure to discuss these suggestions in the Summarize if you assign them.
              " + ] + } + } + ] + }, + "supports": [ + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Explore (Digging In) Providing for Individual Needs\n\nAllow students to problem solve how to find their walking rates. For groups that do not know how to begin, you can ask them questions to help them decide how to conduct the experiment.\n\nSuggested Questions
              • What are the variables that we need to collect data on? (meters and seconds)
              • How can we measure those? (meters using a meter stick and seconds with a timer)
              • So, if someone is walking, what do we need to measure to find the walking rate? (the distance in meters and the time that it takes to walk that distance)
              • How long would you need to walk for someone to get an idea of how fast or slow you walk? (Answers will vary, but students might say a general distance such as walking down the hallway.)
              • What is a convenient distance to use? (Answers will vary. You may want to push for a distance like 10 meters.)
              " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "Look to see how students are recording their walking rates. Using the example from the Launch Video: 'Some may use unit rates, such as 2.5 meters per second, and some may use ratios, such as 2.5 m/1 sec. Some students will scale their results differently. There are two unit rates.'" + ] + } + }, + [ + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "\u0089 Unit Rate #1:\n 10 meters in 4 seconds [ \u2926 +10 ]\n 1 meter in 0.4 seconds." + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "\u0089 Unit Rate #2:\n 10 meters in 4 seconds [ \u2926 +4 ]\n 2.5 meters in 1 second." + } + } + ], + { + "content": { + "type": "Text", + "format": "html", + "text": "Students may not know which one to use. While both are accurate unit rates, a specific rate is asked for in the Initial Challenge. You can use the “for every” language from Grade 6 Comparing Quantities to help students analyze which rate to use for this problem.\n\nSuggested Questions
              • Your walking rate was 10 meters for every 4 seconds. (Using the values from the student’s walking.) There are two unit rates. Do we need to find how many seconds for every 1 meter? Or how many meters for every 1 second?
              • Have the student or group look back at the question in the Initial Challenge to see that it asks for meters per second. Does meters per second mean for every 1 meter or for every 1 second? (“per second” means for every 1 second)
              Discuss these ideas in the Summarize. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "While students are answering the questions in the What If...?, note their strategies for finding answers to the questions. Are students scaling the ratios? Are students using a table? Are students using a graph? These various strategies can be discussed in the Summarize.\n\nAs students complete the experiment and record their data, have them continue on to the What If…? questions.\n\nThe way that students answer the What If...? Situation questions can provide a formative assessment of the strategies that students have for answering the questions in the Unit. This will help you assess the types of questions that you will need to ask as you continue in the Unit. " + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Planning for the Summary\n\nWhat evidence will you use in the Summary to clarify and deepen understanding of the Now What Do You Know? What will you do if you do not have evidence?\n\n Now What Do You Know?\nAssume you continue to walk at the rate determined in the Initial Challenge. Describe in words the distance you could walk in a given number of seconds. Then write an equation to represent this information. " + } + } + ] + }, + "supports": [ + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Summarize (Orchestrating the Discussion) Solutions and Strategies \nAsk for some rates. You will find that they range from about 1 meter per second to 3 or 4 meters per second. But most students will cluster around 2 to 2.5 meters per second. Use one or two of the more typical walking rates to answer the questions in the Problem. \n\nIf students record their walking rates as both a rate and a ratio, ask how they are the same. You might ask students to write their walking rates in seconds per meter. If so, you can then ask questions to relate back to concepts in Comparing and Scaling." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions
              • What information does the rate tell you? (It tells you how long it takes a person to walk 1 meter.)
              • When might you use this rate rather than meters per second? (If time were an important factor, then this rate would be helpful. For example, if you were going to walk for 15 seconds, you could find the number of meters you would walk.)
              " + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Making the Mathematics Explicit \nThe What If...? Situations provide the opportunity to formatively assess how students can connect the ideas from Variables and Patterns, Comparing Quantities, and Comparing and Scaling to the mathematics that will be studied in more depth in this Unit." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": " Situation A Suggested Questions
              • How do you find how long it takes to walk a given distance, like #1 asking about 500 meters? (Note that this is informally solving for T when D is given. Students will have informal ways to find the value, using numerical reasoning or proportional reasoning. Later in the Unit, students will work more on solving the equations symbolically.)
              • How do you find how far you can walk in a given time, like #2 asking about various times? (Note that this is informally solving for D when T is given. Students will have informal ways to find the values, using numerical reasoning or proportional reasoning. Later in the Unit, students will work more on solving the equations symbolically.)
              • How does the equation show the relationship between the two variables? (The equation shows that the distance is the product of the walkingrate and the time, or d = rt. The walking rate is the coefficient of the independent variable.)
              • Explain what information the numbers and variables in your equation represent. (Take this opportunity to see how students interpret the expression 2t. They should say something like “If my walking rate is 2 meters per second, this is the distance that I walked after t seconds.” Emphasize that 2t means 2 times the value of t.)
              • Which variable in your equation is the independent variable, and which is the dependent variable? (Time is the independent variable, and distance is the dependent variable.)
              • [If some students made graphs during the Explore, display them for the class.] How is the walking rate represented in these graphs? (The walking rate affects the steepness of the line. The person who walks fastest has the greatest walking rate and, therefore, the steepest line.)
              • [Pick a typical equation from the class and ask students to use this equation to make a table.] How does the walking rate show up in the table? (In the table, as the time increases by 1 second, the distance increases by a constant amount equal to the walking rate.)
              " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Situation B Suggested Questions \nWe have found different ways that we can represent proportional relationships. We have used rate tables, comparison statements (like “for every” statements), and proportions.\n\n\u0089• Could we represent Liz’s claim with a rate table? (Yes.) What would it look like? \nPossible answer:" + } + }, + { + "content": { + "type": "Table", + "name": "Rate Table", + "columns": [ + { "name": "Distance (meters)", + "type": "number", + "values": [1.5, 7.5, 15, 500] + }, + { "name": "Time (seconds)", + "type": "string", + "values": ["1", "5", "10", "About 333"] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089• Could we represent Liz’s claim with a “for every” statement? (Yes. Possible answer: I travel 1 ½ meters for every second I walk.)" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089• Can we represent Liz’s claim with a proportion? Yes. Possible answers include:\n \u0089 1.5m /1 sec = 7.5 / 5 \u0089 1.5m / 1 sec = 15 / 10" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "\u0089• What would a sketch of Liz’s graph look like? (It would “start” at (0,0). As every second increase by 1, the distance would increase by 1.5.)" + } + }, + { + "layout": { + "height": 300 + }, + "content": { + "type":"Geometry", + "title": "Liz's Graph", + "board": { + "properties": { + "axisNames": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-0.5, -1], + "axisRange": [10, 20] + } + }, + "objects": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [1, 1.5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [2, 3], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [3, 4.5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [4, 6], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [5, 7.5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [10, 15], + "properties": { + "name": "" + } + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Now What Do Students Know\nAsk students to reflect on the discussion and answer the Now What Do You Know.\n\nssume you continue to walk at the rate determined in the Initial Challenge. Describe in words the distance you could walk in a given number of seconds. Then write an equation to represent this information. \n\nSee answers to the problem for more information about the strategies and embedded mathematics. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions
              • Have students compare their equations. How do the equations compare? (Students should see that the equations are the same except for the walking rates.)
              • What information does the walking rate provide? (It gives the unit rate, or how far you can walk for every 1 second.)
              • What does it mean to walk at a constant rate? (It means that you always walk the same distance for a set amount of time.)
              • Suppose you do not walk at a constant rate for the walkathon. Which of the questions in Problem 1.1 can you still answer? Why? (It would be difficult to answer any of the questions since they all assume a constant walking rate. For Question A, you can find the total time it took to walk 10 meters and then compute the average rate.) If some students made graphs during the Explore, display them for the class.
              • How is the walking rate represented in these graphs? (The walking rate affects the steepness of the line. The person who walks fastest has the greatest walking rate and, therefore, the steepest line.) Pick a typical equation from the class and ask students to use this equation to make a table.
              • The above questions on graphs and tables can be used to launch the next Problem. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Reflecting on Student Learning \nUse the following questions to assess student understanding at the end of the lesson.
                • What evidence do I have that students understand the Now What Do You Know question?
                • Where did my students get stuck?
                • What strategies did they use?
                • What breakthroughs did my students have today?
                • How will I use this to plan for tomorrow? For the next time I teach this lesson?
                • Where will I have the opportunity to reinforce these ideas as I continue through this Unit? The next Unit?" + } + } + ] + }, + "supports": [ + ] + } + ], + "supports": [] + }, + { + "description": "Problem 1.2", + "ordinal": 2, + "title": "MSA 1.2 Walking Rates and Linear Relationships", + "subtitle": "Tables, Graphs, and Equations", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Students explore the walking rates of three students. They look at the walking rate and its effect on various representations of the relationship between distance and time. This Problem introduces ways to represent proportional linear relationships between two variables using tables, graphs, and equations. It is also the first time that students are asked to explain why a relationship is linear or to recognize a linear relationship from a table or an equation." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "1.2 Walking Rates and Linear Relationships: Tables, Graphs and Equations\nAoL: Introduce & Explore\nCCSSM: 7.RP.A.2, 7.RP.A.2a, 7.RP.A.2b, 7.RP.A.2c, 7.RP.A.2d, 7.EE.B.4" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "NWDYK\nHow do you recognize a linear pattern of change in a verbal context, table, a graph, expression, or an equation? " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Emerging Mathematical Ideas\nBegin to make sense of linear patterns of change such as distance, and time (for given rates) including how to identify them and how to represent them in words, in a table, in a graph, as equivalent expressions, and as an equation connecting to prior experiences with proportional relationships.\n\nBegin to notice:
                  • the connection between equivalent expressions and an equation, that is, an equation equates two or more equivalent expressions,
                  • how a constant rate of change is represented in a verbal context, table, graph, and equation,
                  • the ways different representations of linear patterns (tables, graphs, or equations) are more or less useful in easily answering questions depending on the nature of the question (e.g., you can quickly see the rate of change from an equation, but the graph of a relationship is a quick way to see if the relationship is linear),
                  • the characteristics in a table, graph and equation that can be used to identify a proportional relationship and the constant of proportionality (unit rate), and
                  • how variations in the way axes of a coordinate graph are partitioned can make the graph of a relationship look very different e.g., steeper or flatter lines.
                  " + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Launch (Getting Started) Connecting to Prior Knowledge\n\nStudents first learned of expressions and equations in the Grade 6 Unit Variables and Patterns. The introduction to this Problem offers a chance to revisit the vocabulary while also introducing “equivalent expressions” and “rate of change.” Teaching Aid 1.2 can provide an example for the conversation. (PORTRAY)" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions
                  • What were the variables that we used in the last Problem? (distance in meters and time in seconds)
                  • Can you recall another time that you studied the relationship between distance and time? (We studied rates of cars in Variables and Patterns. We used 50 mph, 55 mph, and 60 mph rates to examine the patterns between distance and time in tables, graphs, and equations.)
                  • If we looked at your data on a graph, how could you describe the pattern of change for your walking rate? (Possible answer with a walking rate of 1.5: For every 1 second that I walked, I traveled 1.5 meters.)
                  • Here is an example [show Teaching Aid 1.2 or an example of a student’s data] of a table and graph for someone who walked 1.5 meters per second. What do you notice about the data on the graph? (The data lines up because the pattern is consistent.)
                  • How does this show up in the table? (Every increase of 1 second adds 1.5 meters to the distance.)
                  • Because this pattern of change describes how your data consistently increases over time, we call this the rate of change. What was your rate of change in your walking experiment? (Possible answer with a walking rate of 1.5 meters per second: 1.5.)
                  " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Note that the rate of change describes the change in a linear relationship. If the linear relationship is proportional, the rate of change is the same as the unit rate or constant of proportionality. This conversation started for students in Comparing and Scaling and will continue throughout this Unit.
                  • What equation can we use to represent the pattern in this data? (Distance is equal to 1.5 times the number of seconds walked, or d = 1.5t.)
                  • The equation is made up of two expressions. The equal sign shows that the expressions are equivalent. What are the two expressions? (d and 1.5t)
                  " + } + }, + { + "content": { + "display": "teacher", + "type": "Text", + "format": "html", + "text": "Presenting the Challenge\nIntroduce the three students and their walking rates. Let students know that they will be analyzing the progress of the three students. Encourage students to use different colors to represent each student. For example, put Alana’s data in red, Gilberto’s data in green, and Leanne’s data in blue." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions\n\nIf you have graphs and tables from Problem 1.1 display them, or use the Teaching Aid 1.1, and ask:
                  • Make a conjecture. If you increased your walking rate, how would it change your equation, graph, and table? (Students may not be able to answer at this time. Possible answer includes: If you increase the rate at which you walk, you can cover more distance in a given time. The distance in the table would increase for each second walked, and the graph would be steeper. Similarly, if you walk faster, it takes less time to cover a certain distance. The equation would have a larger number that multiplies by the variable.)\n\nNote that students are introduced to the word “coefficient” in the Grade 6 Unit Variables and Patterns. Since they may not have used the vocabulary term often in 6th grade, they are reintroduced to the term in Problem 2.2. While you may want to use that vocabulary earlier than Problem 2.2, the vocabulary term now might be too early for students. It helps students to have more experiences with the idea before the formal vocabulary is introduced.
                  Look for students to make conjectures at this time. Tell students that they will investigate the effect of the walking rate on the relationship between distance and time by looking at the walking rates of three students. They will be asked to make a table, graph, and write an equation for each of the walkers. Students will examine these representations to see how changing the walking rate affects each representation of the data. They will relate the walking rate to the rate of change, linearity, and proportionality.\nTo maximize class time, you may want to provide each student with Labsheet 1.2." + } + } + ] + }, + "supports": [ + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Explore (Digging In) Providing for Individual Needs\n\nStudents should each make their own tables and graphs, but they can discuss the questions in pairs. This will give you an opportunity to examine students’ abilities to make tables and graphs. If a student is having trouble getting started, you can pair the student temporarily with another student who seems to be on target to get started. Some students may need to see the tables separately rather than collapsed into one table. Seeing the table collapsed helps some students to see the variable time as independent. \n\nNote that students first learned the terms independent variable and dependent variable in Grade 6 Variables and Patterns. Students are given informal experiences identifying the variables in this unit. Students are reintroduced to the vocabulary of independent variable and dependent variable in the Introduction of Problem 1.3.\n\nSuggested Questions
                  • What are the two variables in the relationship? (time, distance)
                  • Why do you think that there are four columns in the table? (Because all of the information is on one table.)
                  • \nStudents may need to see the tables separately to understand that the time column is the same for all three students." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "
                    • Which axis should represent time? Which should represent distance? Explain. (The horizontal axis usually represents time [the independent variable], and the vertical axis represents distance.)
                    Students may not see how the walking rate is represented in the table or graph. This conversation may be something that you leave students thinking about until the Summary.\n\nCheck to see if students are able to determine if a relationship is proportional (Situation A). Students should use the ideas from Comparing and Scaling (unit rate/constant of proportionality, proportions, scaling on rate tables) to determine if the relationships are proportional.\n\nCheck to see if students are noticing when the x-variable (time) is not increasing by 1. This occurs in both Situation B (Omar’s graph) and Situation C (Elizabeth Walkathon). Both are linear and proportional, but the rate of change is not obvious because the time is not increasing by 1 second." + } + }, + { + "content": { + "display": "teacher", + "type": "Text", + "format": "html", + "text": "Planning for the Summary\nWhat evidence will you use in the Summary to clarify and deepen understanding of the Now What Do You Know question? What will you do if you do not have evidence? \n\nNow What Do You Know?\nHow do you recognize a linear pattern of change in a verbal context, table, graph, expression, or equation?" + } + } + ] + }, + "supports": [ + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Summarize (Orchestrating the Discussion) Solutions and Strategies \n\nSuggested Questions
                    • Who walks the fastest? (Leanne) Who walks the slowest? (Alana) How can you tell? (Graph: Leanne’s line is the highest or steepest or has the largest angle from the x-axis. Alana’s line is the lowest or least steep or has the smallest angle from the x-axis. Table: For any number of seconds, other than zero seconds, Leanne has traveled the greatest distance and Alana has traveled the least distance. For example, at 5 seconds Leanne has walked 12.5 meters when Alana has only walked 5 seconds. Equation: The number multiplied by the time is the larger for Leanne who is faster and smaller for Alana who walks slower.)
                    • If my walking rate was 2.3 meters per second, where would the line of my data be on the graph? (Between Leanne’s and Gilberto’s, because for every one second that you walk, you would travel 2.3 meters, 2 seconds would be 4.6 meters, etc.)
                    • What is the equation for Alana? (d = 1t) Gilberto? (d = 2t) Leanne? (d = 2.5t) How did you find it? (Various answers. For example, to find the distance we multiply by the walking rate.)
                    • If you increased your walking rate, what effect would that have on your table or graph? (If you increase the rate at which you walk, you can cover more distance in a given time. The distance in each row of the table would increase, and the graph would be steeper. Similarly, if you walk faster, it takes less time to cover a certain distance.)
                    • As you change your walking rate to a faster rate, what effect does this have on the original equation? (The number multiplying [the coefficient] by the time t will increase.)
                    " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Making the Mathematics Explicit \n\nDuring this portion of the Summary, you will want to focus on using the representations (verbal context, table, graph, expression, equation) to help students understand how to answer these questions:\n\u0089Is the relationship linear? \n\u0089If so, what is the rate of change? \n\u0089Is the relationship the proportional? \n\u0089If so, what is the constant of proportionality? \n\u0089Will the rate of change and the constant of proportionality always be the same?\nYou may want to make anchor charts that can be used to display the representations. These can be marked up to display the big ideas in the problem. (PORTRAYAL) The following are examples of anchor charts generated in a classroom during the Summary conversation. " + } + }, + [ + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor.png" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_2_Anchor2.png" + } + } + ], + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions
                    • Is the relationship between the variables (time walked and distance) linear? (Yes. They are walking at a consistent rate, so the points line up to make a straight line on the graph.)
                    • How does the walking rate/rate of change show up in the different representations? (In the word description, it is the walking rate. In the graph, it affects the steepness of the line. In the equation or expression, it is the number multiplied by t in the equation. In the table, it is the consistent change in distance as time changes by 1 second.)
                    Recognizing the rate of change in tables is a bit more complex. See the following discussion as a model of how to help students see the patterns in a table. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Using a Table to Find the Rate of ChangeFor each unit change in time, there is a constant change in distance for a linear relationship. This rate of change should be explored in the different representations. It may be difficult for students to recognize the effect of changing the rate of walking when they use a table. Students can draw on what they learned in the Unit Comparing and Scaling.
                    • Gilberto walks at a rate of 2 meters per second. As the number of seconds he walks increases from 1 second to 2 seconds then 2 seconds to 3 seconds, how does his distance change? (The distance increases by 2 meters from for every second that he walks.) \n\nShow students this thinking on a table.(LANGUAGE)
                    • " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "To find the rate of change, students may instead use proportional reasoning to determine that, if the time triples, then the distance should also triple.\n\n 1 sec / 2 m = x3 => 3 sec / 6 m\n\nSimilarly, if the distance value is twice the time value after 1 second, the distance should continue to be twice the time value. There is a multiplicative 2 to 1 relationship between distance and time. \n\n 2 m / 1 sec = 10 m / 5 sec\n\nIn this Problem, the relationship between the variables is both linear and proportional. So, the latter thinking using proportions works. However, students will be confronted with a non-proportional relationship in Problem 1.3. There, students will need to rely on finding the rate of change by looking at the change in the dependent variable as the independent variable increases by 1. \n\nNote: Students tend to set up their tables using an interval of 1 second because that is what makes most sense to them. This means that they need to produce many pairs of data to get a sense of what is happening over a reasonable span of time. You may want to discuss the advantages and disadvantages of using other intervals, such as 2 seconds or 5 seconds. Situation B with Omar’s Walking Rate Graph and Situation C with Elizabeth’s Walkathon Table provide this opportunity." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Using a Graph to Find the Rate of Change\nIt should be fairly easy for students to recognize the effect of changing the rate of walking when they use a graph—it changes the “steepness” of the line. Some students say that the line “goes up faster” or “has a larger angle from the x-axis.” These intuitive ideas are the goal at this time.
                      • What do you notice about the graphs when the walking rate increases? (“The graph gets steeper,” “it goes up faster”, or “it has a larger angle from the x-axis.”)
                      • If I choose two points on the graph, how can I find the walking rate? (Find the change for an increase of 1 on the x-axis.)\n\n(PORTRAYAL) Pick two points on one of the graphs and ask students how the time and the distance change from one point to the next. This is an opportunity to connect the Problem to the unit rates in Comparing and Scaling. For example, for Leanne, two points are (3, 7.5) and (6, 15). \n\n\u0089 (3, 7.5) At 3 seconds she travels 7.5 meters\n\u0089 (6, 15) At 6 seconds she travels 15 meters\n\u0089 So, as the time increases by 
3 seconds and distance increases by 7.5 meters\n\u0089             \u2925 \u00F7 3\n\u0089 This means that every 1 second she increases her distance by 2.5 meters. \nShow the vertical and horizontal changes on the graph by drawing in dotted lines. " + } + }, + { + "layout": { + "height": 320 + }, + "content": { + "type":"Geometry", + "title": "Demonstrating Rate of Change", + "board": { + "properties": { + "axisNames": ["Time (seconds)", "Distance (meters)"], + "axisMin": [-0.5, -1], + "axisRange": [10, 20] + } + }, + "objects": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [1, 2.5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [2, 5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [3, 7.5], + "properties": { + "name": "+ 3" + } + }, + { + "type": "point", + "parents": [4, 10], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [5, 12.5], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [6, 15], + "properties": { + "name": "+ 7.5" + } + }, + { + "type": "point", + "parents": [7, 17.5], + "properties": { + "name": "" + } + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Then look at what the dividing by 3 looks like on the graph. (Note that as teachers, we know the idea of slope and tend to display the move from one point to the next by going up then over. For students who are not yet introduced to slope, it is more intuitive to go over then up. This comes from thinking of the independent variable first, then the dependent. At this time, it is important to be flexible with the way students display the change from one point to the next.) " + } + }, + { + "layout": { + "height": 180 + }, + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_2_CountingSquares.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Students may want to see the graphs of these equations on a graphing calculator or some other graphing technology. If you do this, then ask students to use the technology to answer questions similar to those above.\n\nUsing an Equation or Expression to Find the Rate of Change\nStudents may be able to recognize the effect of changing the rate of walking when they use the equation d = rt, or distance = rate • time. The rate r is the coefficient of t, the number by which time is multiplied. The word coefficient
is defined in the next Investigation. At this point, students will say it is the rate at which people walk, which is “the number that time is multiplied by to get the distance.” This is a good opportunity to discuss Situation A, #3 Yvonne’s Claim about proportionality. In the equation d = rt, r is the rate of change and the unit rate/constant of proportionality. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Situation C\nPick one or two of the representations and ask:
                        • What are the variables? (The variables for George, Elizabeth, and Billie are time and distance. The variables for Evo are not labeled. The variables for Bob are time t in seconds and walking rate r in meters per second.) 

                        • Describe the patterns of change between the two variables. How did you find the pattern? (For Elizabeth, for every increase of 2 seconds, the distance increases by 3 meters. Each row of the table increases by the same number of seconds. For Billie, for every 1 second, the distance increases by 2.25 meters. The equation is in the form d = rt, so the walking rate is the same as the value of r. For George, distance increases with time, but there does not seem to be a pattern. For Bob, as rate increases, time decreases.) 

                        • Describe what is happening in each situation. (According to the table, George is not walking at a constant rate. Elizabeth is walking at a constant rate and is using an interval of 2 seconds. If Evo’s represents time and distance, she walked at a consistent rate, stopped for some time, then walked again at a consistent rate. Billie is also walking at a constant rate because the equation is similar to those for Alana, Gilberto, and Leanne. Bob is walking 100 meters, but the rate and time are not known. His walking rate may or may not be constant because the variables are time and rate, not time and distance.) 

                        • After 5 seconds, who is ahead? (According to the table, George walks 25 meters in 5 seconds. In that time, Elizabeth walks 7.5 meters, and Billie walks 11.25 meters. (Note: Using the equation for Bob, a time of
5 seconds results in a rate of 20 m/s, which is not a realistic walking rate.)
                        The table of Elizabeth’s time and distance represents a linear relationship, but students need to note that time is not increasing by an interval of 1 second. Go back to the idea of writing the rate as a unit rate, as discussed earlier in this section.
                        • For those that are linear, compare the walking rates to those of the original three students. Who is the fastest? Who is the slowest? (Elizabeth walks 3 meters for every 2 seconds, or 1.5 meters per second. This is faster than Alana but slower than Gilberto. Billie walks 2.25 meters per second, which is faster than Alana and Gilberto but slower than Leanne. Since Leanne is still the fastest, her graph is the steepest.)
                        Conclude by discussing the ideas of being linear and proportional.
                        • Was every relationship in this problem linear? Explain. (No. The data for George, Bob, and Evo were not linear.)
                        • Were the linear relationships in this problem proportional? (Yes. If we used values from the table or points from the graph, we could write proportions.)
                        • How can you tell if a graph does not represent a linear relationship?
(A graph represents a linear relationship if it is one straight line. Therefore, if the graph is not a straight line, the relationship it models is not linear.) 

                        • How can you tell if a table does not represent a linear relationship?
(A table does not represent a linear relationship if for each unit change in the independent variable, there is not a constant change in the dependent variable.) 

                        • How can you tell if an equation represents a linear relationship? (Various answers. At this time, students’ experiences are limited. Students may identify that there is a number multiplied by one variable to get values for the other variable.) 

                        " + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Now What Do Students Know\nAsk students to reflect on the discussion and answer the Now What Do You Know questions.\n\nHow do you recognize a linear pattern of change in a verbal context, table, graph, expression, or equation? \nSee answers to the problem for more information about the strategies and embedded mathematics. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Reflecting on Student Learning 
\nUse the following questions to assess student understanding at the end of the lesson. 

                        • What evidence do I have that students understand the Now What Do You Know question?
                        • Where did my students get stuck?
                        • What strategies did they use?
                        • What breakthroughs did my students have today?
                        • How will I use this to plan for tomorrow? For the next time I teach this lesson?
                        • Where will I have the opportunity to reinforce these ideas as I continue through this Unit? The next Unit? 

                        " + } + } + ] + }, + "supports": [ + ] + } + ], + "supports": [] + }, + { + "description": "Problem 1.3", + "ordinal": 3, + "title": "MSA 1.3 Raising Money", + "subtitle": "Using Linear Relationships to Solve Equations", + "sections": [{ + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "A new situation involving collecting money from sponsors for the walkathon helps student compare and contrast proportional to non-proportional relationships. The Problem furthers students’ understanding of rate of change between the two variables in a linear relationship. Students will compare the amount of money donated and the distance walked for a walkathon. Students see linear relationships in a new context and interpret information using verbal descriptions, tables, graphs, and equations. They also informally explore the y-intercept." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "1.3 Raising Money: Using Linear Relationships to Solve Equations\nAoL: Explore & Analysis\nCCSSM: 7.RP.A.2, 7.RP.A.2a, 7.RP.A.2b, 7.RP.A.2c, 7.RP.A.2d, 7.EE.B.4." + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "NWDYK\nHow can you determine if a relationship is linear from a context, table, graph, or equation?\nIf a relationship is linear, explain how you can tell if it is proportional?" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Emerging Mathematical Ideas\nExpand understanding of linear and proportional relationships exploring a new context (miles walked, dollars raised) while using multiple representations to answer a variety of relevant questions.\n\nExplore the Walkathon Fundraising context working to:
                        • identify independent and dependent variables in a real-world situation,
                        • represent linear relationships in tables, graphs, and equations give descriptions in words,
                        • make sense of an initial value in a linear relationship (a fixed donation) compared to a constant rate of change (dollars for each mile walked) and how each are represented in tables, graphs, equations and in the words describing the relationship,
                        • distinguish between linear and proportional relationships described in words, tables, graphs and equations (e.g., proportional relationships have a constant rate of change and must contain the point (0,0), where-as linear relationships have a constant rate of change, but may or may not contain the point (0,0)),
                        • interpret meaning of data points on graphs, in tables, and satisfying equations, and
                        • use and compare multiple linear relationships to answer relevant questions.
                        " + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Launch (Getting Started) Connecting to Prior Knowledge\n\nIn the last two Problems, students looked at proportional, linear relationships that involved time as the independent variable and distance as the dependent variable. In this Problem, students will look at a relationship in which distance is the independent variable.\n\nStudents first learned the terms independent variable and dependent variable in Grade 6 Variables and Patterns. If you have not used the terms in this unit, reintroduce students to the vocabulary of independent variable and dependent variable in the introduction of Problem 1.3.\n\nPick one of the previous examples to review dependent variables and independent variables.\n\nPresenting the Challenge\nMany schools have walkathons or something similar to raise funds for charity. Ask students how they determined what to charge their patrons." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions\n\n• What variables can affect the amount of money that a student raises? (The variables are the pledge amount for each sponsor, the distance a student walks, and the number of sponsors.) \n\n• How can you use these variables to estimate the amount of money each student will collect? (If you know how much a sponsor pledges to donate and how far the student plans to walk, you can figure out how much each student might collect from each sponsor. For example, if the sponsor pledges to donate $4 for each kilometer walked, and the student plans to walk 5 kilometers, then you can estimate that the student will collect 4 * 5 = $20 from each sponsor.)\n\n 
• Will the amount of money raised be the same for each walker? Explain. (No. The amount of money raised might depend on the distance that each student walks, as well as his or her pledge plan, so the amount of money raised may not be the same for each walker.) 
\n\n• Which variable is the independent variable? Which is the dependent variable? (Distance walked is the independent variable, and the amount of money raised from each sponsor is the dependent variable.) 
\n\nDisplay the three pledge plans of Leanne, Alana, and Gilberto.\n\n• How might you decide who is going to raise the most money? (Various answers. Do not have students go into detail. Asking the question is just to get a formative assessment of whether students may have solution strategies in mind.)\n\nIf students hesitate, offer a solution strategy by asking questions.\n\n• How might a table, graph, or equation help you decide who will raise the most money? (Various answers. No exact answer is needed at this time.)" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Labsheet 1.3 is available to maximize students’ time in making the representations. \n\nAn alternative approach to making the representations would be to provide students with Teaching Aid 1.3. The Teaching Aid has tables, graphs, and equations that can be sorted and matched to each of the Pledge Plans. Students can cut apart and sort the representations to match the pledge plans." + } + } + ] + }, + "supports": [ + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Explore (Digging In) Providing for Individual Needs\n\nAs you circulate, ask students for explanations. Look for students who have interesting ways to explain their thinking. Be sure to discuss these in the Summarize. 
\n\nStudents may or may not start by representing the pledge plans with tables and graphs. Without the representations, it may be difficult to answer the questions with specific values. Students may make broad statements, such as saying that Leanne starts out making the most. Push students to find a value for when others might make more.\n\nSuggested Questions\n• Who starts out making the most? (Leanne)\n• Will she always make the most? How much would each person raise if they walked 20 kilometers? (Leanne - $10, Gilberto - $20, Alana - $15)\n• When did it change? At what distance does Leanne raise less than Gilberto? Less than Alana? (Leave students to think about these detailed questions. Be sure to revisit them in the Summary.)\n\nBy this time in the unit, most students should have few problems making tables and graphs. Writing the equations may be difficult for some students. Encourage those students to write out the relationship in words. (LANGUAGE) Being able to write a verbal description of the relationship in each pledge plan is the first step to being able to write the same relationship algebraically. For example, use a plan to ask questions like the following. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Suggested Questions \n• How does Gilberto’s plan work? (A sponsor will donate $2 for each kilometer Gilberto walks.)\n• What are the variables and what letter name can we give them? (Amount of money, A, and number of kilometers he walks, d.)\n• Which is the independent variable? (Number of kilometers he walks.)\n• What happens with the independent variable in Gilberto’s plan? What happens for every kilometer that he walks? (He will make $2.)\n• How could we write that as an expression? ($2 times every kilometer walked or 2 * d.)\n• How can we write this an equation? (The amount a sponsor donates is found by finding $2 times every kilometer walked or A = 2 • d.)\n\nRemind students that 2 * d is often written 2d, so the equation becomes A = 2d, where A is the amount the sponsor donates and d is the number of kilometers walked. 
" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Planning for the Summary \nWhat evidence will you use in the Summary to clarify and deepen understanding of the Now What Do You Know question? What will you do if you do not have evidence? Now What Do You Know?\nHow can you determine if a relationship is linear from a context, table, graph, or equation? If a relationship is linear, explain how you can tell if it is proportional." + } + } + ] + }, + "supports": [] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": "Summarize (Orchestrating the Discussion) Solutions and Strategies \n\nBegin by asking students: What “What If...?” questions do you have? (Students may or may not have any What If’s at this time.)\n\nYou may want to make anchor charts that can be used to display the representations. You can work with students to make the charts. Then, these can be marked up to display the big ideas in the problem, such as showing the rate of change in the table, graph, and equation. (PROBLEM SOLVING) The following are examples of anchors charts generated in a classroom during the Summary conversation. " + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_Anchor.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Discuss Initial Challenge. If you did not ask students to identify the dependent and independent variables in the Launch, ask them now.\n\n Look at the points of intersection and raise questions about what those points tell us about who will raise the most money.\n\nSuggested Questions \n\n• Who makes the most money at the beginning of the walking? (Leanne. She is getting $10 for any distance. So, she makes $10 for 0, 1, 2, etc. kilometers. Gilberto and Alana get less than that for the first few kilometers.)\n\n• Point to the intersection of Leanne’s and Gilberto’s lines. What point is this? (5, 10) " + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_Intersection.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• What does that tell us about the pledges? (Both Leanne and Gilberto walk 5 kilometers and will get $10 in pledges.) \n\n• What information does each intersection point represent in the situation? (Each intersection point is where two of the plans raise an equal amount of money for the same distance. The coordinates represent equal distances and equal amounts donated.) \n\nDirect students to the intersection of Alana’s and Gilberto’s lines. Pick two points to the left of the point of intersection, one on each line, with the same x-value. \n\n• How are the two points similar? How are they different? How can you show the difference in money raised? (The two points represent the
same distance walked, but they represent different amounts of money raised. For distances to the left of the point of intersection, Alana’s graph is above Gilberto’s, so Alana raises more money than Gilberto. You can show the difference in money collected by drawing a vertical line between Alana’s and Gilberto’s lines and measuring the distance. You can also find the difference in the y-coordinates to find the difference in the amount of money raised for that distance.) \n\nThen, repeat the process for two points to the right of the point of intersection. (Now Gilberto’s graph is above Alana’s, so he raises more money for a given distance.) \n\n• In Situation A #2, you found the money raised for each pledge plan if the student walked 8 kilometers. How is this information represented on the graph? (The amount of money raised for each student is the vertical distance between the x-axis and the point on the student’s line with an x-coordinate of 8.) \n\n" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_Height.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "You may want to let students know that when you are given the value of one variable and have to find the value of the other variable, they are finding solutions. In Investigation 3, students will learn to find solutions using equations. In Investigations 1 and 2, students use primarily tables and graphs to find solutions.\n\n• In Situation A #4, you located the point (12, 11) on Alana’s graph. Write a question that could be answered by locating this point. (Sample answers: What is the amount of money Alana raises from each sponsor if she walks 12 kilometers? How many kilometers does Alana need to walk if she wants each sponsor to donate $11?) \n\nThe preceding questions are designed to prepare students to solve equations symbolically. Later in this Unit, they will continue to relate coordinates of an ordered pair to specific information about the values of variables. \n\nMaking the Mathematics Explicit In Comparing and Scaling, students observed that the rate tables relating cost of pizza to number of pizzas worked differently if a constant delivery charge was added. They noticed that there is a constant of proportionality (unit rate) when there is no delivery charge, but not a constant of proportionality (no unit rate) when there is a delivery charge. Here, students are learning about the specific details of linear relationships, in particular when are they proportional or not proportional and the role of the y-intercept. \n\nSuggested Questions \n• How are the tables, graphs, and equations for the pledge plans different from the walking rate representations? (Various answers. Students will probably mention the y-intercepts without knowing the term. They will discuss the “starting point” on the graph, the “beginning of the table or the (0,y)”, and the “amount added on in the equation.” It is typical for students to say that Leanne’s is a straight line and the others are not. Students need a way to express the horizontal line.)\n• Are the relationships between the distance walked and the money earned in pledges all linear? (Yes.) How do you know? (At this time, students are likely to say that the graphs are straight lines or that the data is consistent.)\n\nTo help students focus on determining the linearity and proportionality of the relationships, ask about the rate of change.\n\nSuggested Questions \n• How is the rate of change represented in a context? (At this time, students are likely to say it is the amount of money for every meter walked or the “per” or “per kilometer” amount.)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_Table.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How can we tell by looking at the context if the relationship is proportional? (At this time, students might not be able to tell from the context if the relationship is proportional. Some students might say that there is some other amount other than the “per kilometer” amount. The other amount is added in [additive] and the “per kilometer” amount is multiplied [multiplicative].)\n\nThe multiplicative and additive ideas and vocabulary were introduced in Grade 6.\n\n• How is the rate of change represented in a Table? (How much the dependent variable changes for every increase of 1 in the independent variable. For Leanne the rate of change is 0; for every increase of 1 kilometer she will collect no more dollars. For Gilberto the rate of changes is 2, and for Alana the rate of is 0.50.)\n\nThis is how it is shown in the tables. (LANGUAGE)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare1.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How can we tell by looking at the table if the relationship is proportional? (Check to see if values scale up or scale down to make proportions.)\n\nThis is how it is shown in the tables and with proportions made from table values. (LANGUAGE)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare2.png" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_EqnCompare.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How is the rate of change represented in a graph? (For every increase of 1 in the independent variable “going over 1 on the x-axis,” the dependent variable changes by the rate of change “goes up by the rate of change”.) \n\nThis is how it is shown on the graphs. (LANGUAGE)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare3.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How can we tell by looking at the graph if the relationship is proportional? (A graph of a proportional relationship passes through the origin (0,0) or the y-intercept is zero. This happens because a line going through the origin shows only a multiplicative relationship. When there is an additive part, it shifts the line off (0,0).)\n\nStudents may relate back to the Hats Off to the Wumps Problem in Stretching and Shrinking where addition in the rule shifted the hat rather than stretching or shrinking the hat, which happened through multiplication.\n\nThe term “y-intercept” is introduced in the introduction to Problem 1.4. This would be a good time to introduce the vocabulary to students.\n\nThis is how it is shown on the graphs. (LANGUAGE)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_GraphConstant.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How is the rate of change represented in an equation? (The rate of change is the coefficient of the variable or the number multiplied by the variable.)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare4.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• How can we tell by looking at the equation if the relationship is proportional? (The amount added to the equation is zero. The amount added is the y-intercept on the graph.)" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_TG_1_3_TableCompare5.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "• Why does “adding an amount” make the relationship non-proportional? (To be proportional, you have to have the two quantities change in a multiplicative way, keeping the factors and multiples of the quantities. When an amount is added, it gets spread over the dependent variable in a non-constant way. For example, with Leanne’s money amount, she will collect $10 for walking no kilometers, $10 for 1 kilometer, $5 for each of 2 kilometers, $3.33 for each of 3 kilometers, etc. The amount for every kilometer is not consistent.)\n\nDiscuss all of Situation B. The purpose of this question is to introduce students to a negative y-intercept. Make sure students discuss the variables and numbers in the equation and connect where the information shows up in the graph, table, and equation. \n\nAt the end of this Problem, students will have had experiences with y-intercepts that are positive, negative, or zero. The term y-intercept is introduced in the next Problem. It would be appropriate to name the y-intercepts while summarizing this Problem.\n\nCompare the representations in this Problem to the walkathon in Problem 1.2. All the relationships are linear, but the graphs in this Problem do not all pass through the origin, so they are not all proportional relationships. \n\n• In Problem 1.2, you noticed for Alana’s rate of 1 m/s that if she walked twice as long, her distance would also be twice as much. Would the amount of money she raises double if she walks twice as far? Explain. (No. The equation for Alana’s pledge plan is A = 5 + 0.5d, which is not a proportional relationship. The ratio between the money pledged and the distance walked is not constant even though the plan involves a constant rate of change.) \n\nThis idea will be revisited as students gain more experience with linear equations of the form y = ax + b. " + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Now What Do Students Know\nAsk students to reflect on the discussion and answer the Now What Do You Know questions.\n\nHow can you determine if a relationship is linear from a context, table, graph, or equation?\nIf a relationship is linear, explain how you can tell if it is proportional.\n\nSee answers to the Problem for more information about the strategies and embedded mathematics." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": "Reflecting on Student Learning 
\n\nUse the following questions to assess student understanding at the end of the lesson. 

                        • What evidence do I have that students understand the Now What Do You Know question?
                        • Where did my students get stuck?
                        • What strategies did they use?
                        • What breakthroughs did my students have today?
                        • How will I use this to plan for tomorrow? For the next time I teach this lesson?
                        • Where will I have the opportunity to reinforce these ideas as I continue through this Unit? The next Unit? 

                        " + } + } + ] + }, + "supports": [ + ] + } + ], + "supports": [] + }, + { + "description": "Problem 1.4", + "ordinal": 4, + "title": "MSA 1.4 Walkathon Money", + "subtitle": "Expressing Linear Relationships and Proportionality", + "sections": [{ + "type": "overview", + "content": { + "tiles": [ + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + ] + }, + "supports": [ + {"text": "What is the independent variable? What is the dependent variable?"} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + ] + }, + "supports": [ + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + ] + }, + "supports": [] + } + ], + "supports": [] + } + ] + }, + { + "description": "Investigation 2", + "ordinal": 2, + "title": "MSA Investigation 2 Using Tables, Graphs, and Equations to Explore Linear Relationships", + "problems": [ + { + "description": "Problem 2.1", + "ordinal": 1, + "title": "MSA 2.1 Henri and Emile’s Race", + "subtitle": "Developing Strategies to Find a Solution", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["In the last Investigation, you examined linear relationships. For example, the distance, d, a person walks at a rate depends on the amount of time, t, the person walks. Also, the amount of money, A, a person raises from each sponsor depends on the distance, d, walked in the walkathon. Both of these relationships are linear. You might have written the following equations to represent these two relationships for Alana. \n\u00a0\u00a0\u00a0 d = 1t \u00a0 or d = t\n \u00a0\u00a0\u00a0 and \n \u00a0\u00a0\u00a0 A = 5 + 0.5d"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["You looked at tables and graphs to represent these relationships. These representations are useful in answering questions about linear relationships. For example, A = 5 + 0.5d "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["If you know something about distance d, how can you find the corresponding value of A? \nIf you know something about A, how can you find the corresponding value of d?"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["In this Investigation, you will continue to solve problems involving walking rates and other linear relationships using tables, graphs, and equations. "] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["In Ms. Chang’s class, Emile found out that his walking rate is 2.5 meters per second. That is, Emile walks 2.5 meters every 1 second. When he gets home from school, he helps his little brother Henri determine his walking rate. They find that Henri’s walking rate is 1 meter per second. \n\nHenri challenges Emile to a walking race. Because Emile’s walking rate is faster, Emile gives Henri a 45-meter head start. Emile knows his brother would enjoy winning the race, but he does not want to make the race so short that it is obvious his brother will win. "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["• How long should the race be so that Henri will win in a close race? Give evidence to support your answer. "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "With a 45-meter head start, Emile will catch up to Henri after 30 seconds at the 75-meter mark. The race should be less than 30 seconds or 75 meters, depending on how they determine the length of the race.\nPossible student answers may include tables, graphs, words, and diagrams. Some examples include the following. " + } + }, + [ + { + "display": "teacher", + "content": { + "type": "Table", + "name": "Meters and Brother's Distances", + "columns": [ + { + "name": "Meters", + "type": "number", + "values": [0, 10, 20, 30, 40, 50] + }, + { + "name": "Henri", + "type": "number", + "values": [45, 55, 65, 75, 85] + }, + { + "name": "Emile", + "type": "number", + "values": [0, 25, 50, 75, 100] + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Guess and Check\n\n10 meters \u0089 Henri 10 + 45 = 55\n \u0089\u0089\u0089Emile 2.5*10 = 25" + } + } + ], + { + "layout": { + "height": 330 + }, + "display": "teacher", + "content": { + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t, D"], + "axisLabels": ["Meters", "Distance"], + "axisMin": [-10, -10], + "axisRange": [50, 100] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "" + } + }, + { + "type": "point", + "parents": [30, 80], + "properties": { + "name": "Emile" + } + } + ] + }, + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [10, 55], + "properties": { + "name": "Henri" + } + }, + { + "type": "point", + "parents": [40, 100], + "properties": { + "name": "" + } + } + ] + } + ] + } + } + ] + }, + "supports": [ + { + "text": "How might a table help? How might a graph help? Would an equation help?" + }, + { + "text": "Would a diagram or picture help?" + }, + { + "text": "What do we know about the race at the beginning?" + } + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text":["Situation A. Using Tables and Graphs\nIn Ms. Kreuger’s class some students used tables and graphs to find the length of the race and other information about the race.
                        1. How can a table or graph be used to find the length of the race?
                        2. How does the walking rate of each brother show up in the table and graph?
                        3. After 20 seconds, how far apart are the brothers? How is this distance represented in the table and on the graph?
                        4. What information does the y-intercept of each graph represent in terms of the race?
                        5. Is the point (26, 70) on the graph or table of one of the brothers? Explain.
                        6. Mary wrote the inequality: 45 + t\u00a0 < 2.5t. What information was she looking for?
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":["Situation B. Using Equations\nAmit wrote equations to represent the relationships between time and distance. He wrote: \n\ndEmile = 2.5t \u00a0 for Emile \ndHenri = 45 + 1t \u00a0for Henri \n\nHe makes five claims. Are they correct? Explain."] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":["Claim #1 You can tell the walking rate and y-intercept from the equation. \nClaim #2 You can determine which of the two lines will be steeper from the equation. \nClaim #3 Both equations represent linear relationships. But neither of them is proportional. \nClaim #4 You can find the time when Emile catches Henri by setting the expressions for distance equal.\n \u00a0\u00a0\u00a0 dEmile = dHenri \u00a0\u00a0 or \u00a0\u00a0 2.5t = 45 +1t. \nThen find the value for t that makes the equation true.\nClaim #5 You can use the expression (45 – 1.5t) – 2.5t\u00a0 to find the distance the brothers are apart for any given second t. "] + } + } + ] + }, + "supports": [ + {"text": "Can a table help? Can a graph help?"}, + {"text": "(2) What does it mean that one line is steeper than the other? How do you know it from a graph?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "text": "How can a table, graph, and an equation that represents a linear relationship be used to answer questions about the linear relationship? What other strategies could you use?" + } + }] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 2.2", + "ordinal": 2, + "title": "MSA 2.2 Comparing Cost Relationships", + "subtitle": "Using Tables and Graphs to Find Solutions to Equations", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["All of the linear relationships you have studied so far can be written in the form y = ax + b, or y = b + ax. In this equation, y depends on x."] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_2_2_In_y=ax+b_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["The point at which a graph crosses the y-axis is called the y-intercept. The coordinates of the y-intercept for the graph shown above are (0, b). To save time, we sometimes refer to the number b, rather than the coordinates of the point (0, b), as the y-intercept. \n\nA coefficient is the number that multiplies a variable in an equation. The a in y = ax + b is the coefficient of x, so ax means a times x.\n\nThe equation of distance dEmile that Emile walks after t seconds is dEmile = 2.5t.\n\nEmile"] + } + }, + { + "layout": { + "height": 300 + }, + "content": { + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t", "dEmile"], + "axisLabels": ["time", "distance"], + "axisMin": [-20, -40], + "axisRange": [56, 130] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 0], + "properties": { + "name": "y-intercept (0, 0)" + } + }, + { + "type": "point", + "parents": [5, 12.5] + } + ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["The equation of distance dHenri that Henri walks after t seconds is dHenri = 45 + t.\n\nHenri"] + } + }, + { + "layout": { + "height": 300 + }, + "content": { + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["t", "dHenri"], + "axisLabels": ["time", "distance"], + "axisMin": [-20, -40], + "axisRange": [56, 130] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 45], + "properties": { + "name": "y-intercept (0, 45)" + } + }, + { + "type": "point", + "parents": [5, 50] + } + ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text":["A solution of an equation is an ordered pair that makes the equation true and lies on the graph of the line. For example, in the equation that represents the distance Henri walks dHenri = 45 + t, (0,45) is a solution to the equation. When the coordinate values are substituted into the equation it is a true statement; 45 = 45 + 0.\n \u00a0What does the point (0,45) represent in the context of the race?.\n\nIn the graphs for Emile and Henri:\n \u00a0What would t be if (t, 48) are the coordinates of a point on the graph? Explain. \n \u00a0What would d be if (10, d) are the coordinates of a point on the graph? Explain. "] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Ms. Chang’s class decides to give T-shirts to each person who participates in the walkathon. They obtain the cost of the T-shirts from two different companies. Mighty Tee charges $49 plus $1 per T-shirt. No-Shrink Tee charges $4.50 per T-shirt. Ms. Chang writes the following equations to represent the relationships relating cost to the number of T-shirts:\n\n CMighty = 49 + n\n CNo-Shrink = 4.5n\n\nThe number of T-shirts is n. \nCMighty is the cost in dollars for Mighty Tee. \nCNo-Shrink is the cost in dollars for No-Shrink Tee. \n\n • Which company should they choose? Give evidence for your answer. "] + } + } + ] + }, + "supports": [ + {"text": "How might a table help? How might a graph help?"}, + {"text": "Can you use the equations to help answer the question?"}, + {"text": "What would be the cost of one shirt from each plan? 10 shirts? 20 shirts?"} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Using Tables and Graphs to Find a Solution\nSome students in Ms. Chang’s class used graphs to decide which company to use. Others used tables.
                        1. Explain how a graph or a table could be helpful.
                        2. What if the class only had $120 to spend, how would this affect your answer?
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Using Tables, Graphs, and Equations\nExplain how you could use a table, graph, or equation to answer each question:
                        1. For each company, find the costs of 20 T-shirts.
                        2. For each company find the number of T-shirts you can buy for $135. How many T-shirts can you buy for less than $135? Greater than $135?
                        3. Find the number of T-shirts where the cost of buying shirts from the two companies is equal. What is the cost?
                        4. Find the number of T-shirts when CMighty < CNo-Shrink.
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. More Competition\nThe following table represents the costs from another company, The Big Tee.
                        1. Compare the cost for this company to the costs for the other two companies.
                        2. Is this company a better deal? Explain why.
                        3. Are any of the relationships represented by the three companies linear? Proportional? Explain.
                        "] + } + }, + { + "content": { + "type": "Table", + "name": "T-Shirt Costs", + "columns": [ + { + "name": "n", + "type": "number", + "values": [0, 3, 5, 8, 10] + }, + { + "name": "C", + "type": "number", + "values": [34, 41.5, 46.5, 54, 59] + } + ] + } + } + ] + }, + "supports": [ + { "text": "What do the number 0 and 34 mean in the table of T-shirt costs for The Big Tee?" }, + { "text": "How can you compare which company is a better deal when they all have different ways of charging for the shirts?" }, + { "text": "What does it mean for relationships to be proportional?"}, + { "text": "How can you tell if relationships are linear?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "text": "How do you know if the ordered pair of numbers for a point on a graph is a solution to an equation? How can you use a table or graph to find a solution for an equation?" + } + }] + }, + "supports": [ + { "text": "Would it help to look at examples where you used a table, graph, or equation to answer a question?" } + ] + } + ], + "supports": [] + }, + { + "description": "Problem 2.3", + "ordinal": 3, + "title": "MSA 2.3 Connecting Tables, Graphs, and Equations to Solutions", + "subtitle":"", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "format": "html", + "text": ["Look again at Alana’s pledge plan from Problem 1.3. Suppose A represents the amount raised in dollars and d represents the distance walked in kilometers. You can express this plan with the equation A = 5 + 0.5d. "] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_2_4_In_alanas_plan_350w.png" + } + }, + { + "layout": { + "height": 300 + }, + "content": { + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["d", "A"], + "axisMin": [-1, -2], + "axisRange": [20, 22] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [0, 5] + }, + { + "type": "point", + "parents": [14, 12], + "properties": { + "name": "" + } + } + ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Kilometers Walked\n Explain why the point (14, 12) is on the graph of Alana’s pledge plan. \n Write a question you could answer by locating this point. \n How can you use the equation for Alana’s pledge plan to check the answer to the question you made up?\n How can you use a graph to find the number of kilometers that Alana walks if a sponsor donates $17? How could you use an equation to answer this question?\n\n In this Problem, you will investigate similar questions relating to pledge plans for a walkathon."] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Consider the following pledge plans. In each equation, y is the amount pledged in dollars by each sponsor and x is the distance walked in kilometers.\n\nPlan 1 y = 5x - 3\nPlan 2 y = - x + 6\nPlan 3 y = 2"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["
                        • What information does the equation give about the pledge plan? Does the plan make sense? Explain your reasoning.
                        • How might a table or graph of the equation help answer questions about the pledge plans?
                        "] + } + } + ] + }, + "supports": [ + { + "text": "How much would you raise if you walked one kilometer? Two kilometers? Three kilometers?" + } + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Connecting Equations and Graphs
                        1. Which plan has a graph that contains the point (2,4)? What question could you answer by locating this point?
                        2. Which plan has a graph that you can use to find the solution for 8 = 5x – 3? What would the coordinates of the point that represents the solution tell you about the situation?
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Connecting Equations and Tables\nAll of the following coordinates are in the table of one plan. Two of coordinates have a missing value: \n(4, 2) (1.2, ?) (?, -4)
                        1. Find the missing value. Explain how you found it.
                        2. Write a question you could answer by finding the missing value.
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. Finding Solutions\nFor Plan 1, y = 5x - 3
                        1. Find the value of y when x = 7
                        2. Find the value of x when y = 32.
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation D. Linear or Non Linear
                        1. Sally is trying to figure out if the relationships represented by the three plans are linear. How can you help her decide by looking at the equations?
                        2. Yvonne claims that only Plan 3 is proportional. Do you agree? Explain why.
                        "] + } + } + ] + }, + "supports": [{"text": "Can you explain the meaning of (2, 4) in terms of dollars and distance?"}] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "text": "Describe the advantages and disadvantages of using tables, graphs, aand symbolic methods to solve equations." + } + }] + }, + "supports": [] + } + ], + "supports": [] + } + ] + }, + { + "description": "Investigation 3", + "ordinal": 3, + "title": "MSA Investigation 3 Solving Linear Equations Symbolically", + "problems": [ + { + "description": "Problem 3.1", + "ordinal": 1, + "title": "MSA 3.1 Mystery Pouches", + "subtitle": "Exploring Equality", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Throughout this Unit, you have been solving equations with two variables. Sometimes the value of one variable is known, and you want to find the value of the other variable. In this Investigation, you will continue to find the value of a variable without using a table or a graph or numeric reasoning. You will also learn to use symbolic methods to solve a linear equation. In the last Investigation, you examined the patterns in the table, graph, and equation for the relationship relating Alana’s distance d and money earned A in the walkathon.\n\nAlana's Walkathon Table"] + } + }, + { + "content": { + "type": "Table", + "columns": [ + { + "name": "d", + "type": "number", + "values": [0, 1, 2, 3, 4, 20, 25, 30] + }, + { + "name": "A", + "type": "number", + "values": [5, 5.5, 6, 6.5, 7, 15, 17.5, 20] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Alana's Walkathon Earning Graphs"] + } + }, + { + "layout": { + "height": 320 + }, + "content": { + "type": "Geometry", + "board": { + "properties": { + "axisNames": ["d", "A"], + "axisMin": [-4, -4], + "axisRange": [55, 60] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [3, 6.5], + "properties": { + "name": "(3, 6.5)" + } + }, + { + "type": "point", + "parents": [30, 20], + "properties": { + "name": "(30, 20)" + } + } + ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["\nAlana's Walkathon Earning Equation: A \u00a0 = 5 + 0.5d \n\nThe graph of the relationship is a line that contains infinitely many points. The coordinates of each point can be substituted into the equation to make a true statement. The corresponding entries in the table are the coordinates of points on the line representing the equation, A = 5 + 0.5d. The coordinates of these points are solutions to the equation."] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "In a relationship between two variables, if you know the value of one variable, you can use a table or a graph to find the value of the other variable. For example, \n\nSuppose Alana raises $20 from a sponsor, how many kilometers did she walk?
                        • Using numeric reasoning: Subtract $5 from $20 to get $15. This is the amount earned for walking d kilometers. So 15 = 0.5d \u00a0 or 15/0.5 = 30 = d.
                        • Using the graph: Locate the point with the value $20, which is (30,20). So she walked 30 kilometers.
                        • Using the table: Find the coordinate that corresponds to $20 for the amount earned, which is 30 km. So she walked 30 kilometers.
                        • Using the equation: This question can also be represented by the equation as 20 = 5 + 0.5d and then the properties of equality can be used to solve the equation, which is similar to numeric reasoning.
                        How could you use an equation to find the distance that Alana walks if she earns $20?\n\nIn this Investigation you will develop strategies for solving equations of the form y = ax + b\u00a0 symbolically." + ] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["To raise more money, Ms. Chang’s class decides to hold a raffle. They put some gold coins into a pouch, and people will guess the amount of coins in the pouch. At the end of the walkathon the class will give the pouch to the person who guessed the exact number of gold coins. \n\nTo make the contest interesting, they decide to add a code for the amount of money in the pouch. The code consists of an equation using gold coins and pouches. Each pouch has the same number of gold coins. "] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_coin_and_pouch_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "The code below indicates that there are $11 in gold coins in the pouches and in loose coins as shown on the left side of the equation." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_eleven_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["How much money was in each pouch?\nHow much money did the winner receive?\nThe class made up several other codes. For each code the total number of coins on each side of the equation is the same and each pouch contains the same number of coins.
                        • What is the number of gold coins in each pouch?
                        • How can you check your answer?
                        Write down your steps so that someone else could follow your steps to find the number of coins in a pouch. "] + } + }, + { + "content": { + "type": "Text", + "text": "1." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_1_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "\n2." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_2_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "\n3." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_3_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "\n4." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_4_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "\n5." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_5_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "\n6." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_IC_coins_pouches_6_350w.png" + } + } + ] + }, + "supports": [ + {"text": "What does the sign “=” mean?"}, + {"text": "Can you represent each clue in a different way?"} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Nicole’s Strategy\nIn Code 2, Nicole thought of the left-hand side of the equation as having two groups. Each group contained one pouch and two coins. She visualized the following steps to help her find the number of coins in a pouch. \n1. What is Nicole’s strategy? Can her strategy be used for other coin and pouch situations?"] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_1_WI_coins_pouches_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "2. Noah looked at Nicole’s strategy and claimed that she was applying the Distributive Property. Is Noah’s claim correct? Explain.\n\n3. Yvonne thought that Nicole was just dividing both sides of the original equation by 2. Is she correct? Explain. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Aman’s Code \nAman made up another code, but then he forgot the number of coins he put in the pouches. But he did remember that there were 5 pouches and 10 coins with a total of 35 dollars.
                        1. What might the pouches and coin picture look like?
                        2. How many dollars are in a pouch?
                        "] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. Another Donor\nA local merchant donates $200 for the Walkathon.
                        1. They suggested the following code:\n6P + $20 = $200. P represents a pouch. How much money is in each pouch?
                        2. Mateo wrote two different expressions that could be codes to represent the $200. For each expression how much money is in each pouch?\n2P + $45 \u00a0\u00a0 4P + $20
                        3. Design another code that the merchant could use. Give it to a classmate to solve.
                        "] + } + } + ] + }, + "supports": [ + {"text": "What information do we have? "}, + {"text": "What are we trying to find? "} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "text": "Pouches with an unknown number of coins and coins are represented with an equation. What strategies can you use to find the number of coins in each pouch? How do you know if your answer is correct?" + } + }] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 3.2", + "ordinal": 2, + "title": "MSA 3.2 From Pouches to Variables", + "subtitle": "Writing and Solving Equations", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "In the last Problem, you used pictures of pouches and gold coins to solve equations. Your solutions maintained the equality of coins on both sides of the equal sign. For example, you might have removed (or subtracted) the same number of coins on both sides of the equation. To better understand how to maintain equality, let’s look first at numerical statements." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["The equation 85 = 70 + 15 states that the quantities 85 and 70 + 15 are equal. \nWhat do you have to do to maintain equality if you:\n • subtract 15 from the left-hand side of the original equation?\n • add 10 to the right-hand side of the original equation?\n • divide the left-hand side of the original equation by 5?\n • multiply the right-hand side of the original equation by 4?"] + } + }, + { + "content": { + "type": "Text", + "text": "The picture below shows a situation from Problem 3.1." + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_2_In_coins_pouches_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Because the number of gold coins in each pouch is unknown, you can let x represent the number of coins in one pouch. You can let 1 represent the value of one gold coin. Then this situation can be represented with one of the following equations:\n\n 2x + 4 = 12 or 2(x + 2) = 12 or x + 2 + x + 2 = 12\n\nThe expressions 2x + 4, 2(x + 2), and x + 2 + x + 2 are equivalent expressions. Note that you can apply the Distributive Property to the expression 2x + 4 to write 2(x + 2). So, \n\n \u00a0\u00a0\u00a0 2x + 4 = 2(x + 2)\n\nWhat properties of operations could you use to show that \n\n \u00a0\u00a0\u00a0 x + 2 + x + 2 = 2(x + 2)?"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Two or more expressions are equivalent if they have the same value, regardless of what number is substituted for the variable. Recall that you have been solving linear equations of the form y = ax\u00a0 and y = x + b\u00a0 using fact families and numeric reasoning. In this Problem, you will revisit problems that involve linear situations with pouches and coins, but you will use symbolic equations to represent your solution process to equations of the form y = ax + b where the value of y is given or ax + b = cx + d."] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Suppose x \u00a0 represents the number of coins in one pouch and 1 represents the value of one coin in the following situations.
                        • Write an equation to represent each situation.
                        • Are there other possibilities for the equations that you could write? Explain.
                        • Use your equation to find the number of gold coins in each pouch. Check your answers.
                        "] + } + }, + { + "content": { + "type": "Text", + "text": "\nEquation 1" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_2_IC_coins_pouches_1_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "Equation 2" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_2_IC_coins_pouches_2_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "Equation 3" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_2_IC_coins_pouches_3_350w.png" + } + } + ] + }, + "supports": [{"text": "How can you express the number of coins in one pouch? In two pouches? In three pouches?"}] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. More Pouches\nA messenger has 6 pouches and 27 coins. There is a total of $105.
                        1. Write an equation to represent the situation. Then solve the equation to find the number of dollars in each pouch.
                        2. AJ claims that there is more than one way to write the equation. Is he correct? Explain.
                        3. Will the solution for each equation be the same? Explain.
                        "]} + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Applying Your Strategies\nUse your strategies to solve each equation. Check your answer.
                        1. 30 = 6 + 4x
                        2. 7x = 6 + 5x
                        3. 7x + 2 = 12 + 5x
                        4. 2(x + 4) = 16
                        "]} + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. More or Less\nA messenger has 6 pouches and 30 coins. The total must be less than 102 coins. How would you write this inequality? What are some solutions?"]} + } + ] + }, + "supports": [ + {"text": "Would a diagram help?"}, + {"text": "What does 'x' mean in the equations?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "text": "Describe a strategy for solving equations using what you know about equality. How do you know if your answer is correct?" + } + }] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 3.3", + "ordinal": 3, + "title": "MSA 3.3 Solving Linear Equations", + "subtitle": "", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["So far in this Investigation, all of the situations have involved positive whole numbers. \n\nTo maintain the equality of two expressions, you can add, subtract, multiply, or divide each side of the equality by the same number. These are called the properties of equality. In the last Problem, you applied properties of equality and properties of numbers to find a solution to an equation. \n\nDoes it make sense to think about negative numbers in a coin situation?\nDoes it make sense to think about fractions in a coin situation?\nWhat are some situations where it makes sense to use fractions or negative numbers?"] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + ] + }, + "supports": [{"text": "Would drawing a diagram help?"}] + }, + { + "type": "explore", + "content": { + "tiles": [ + ] + }, + "supports": [ + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + ] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 3.4", + "ordinal": 4, + "title": "MSA 3.4 The Point of Intersection", + "subtitle": "Using Equations and Inequalities", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["In Problem 2.2, you used graphs and tables to find when the costs of two different plans for buying T-shirts were equal. The graphs of the two cost plans are shown below. Cn represents the costs of the No-Shrink Tee. Cm represents the costs of the Mighty Tee. The point of intersection of the two lines tells us when the costs for the two T-shirt plans are equal."] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_4_In_two_plans_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["What information do the coordinates of the point of intersection of the two lines give you about this situation? \n\nHow could you use the two equations to find the coordinates of the point of intersection of the two lines? That is, for what number of T-shirts n is Cm = Cn\u00a0 or 49+n\u00a0 = 4.5n\u00a0? How could you use the equation or its graph or table to find the number of T-shirts where the cost is less than $60? That is, for values of n, is \n \u00a0 \u00a0 Cmighty\u00a0 < 60? Or \u00a0 \u00a0 49 + n\u00a0 < $60"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["When either the value of x or y is known, what strategies do you have for solving \n • equations of the form y = ax+ b? \n • inequalities of the form ax +b < y or ax +b > y?"] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["A local bakery, Fabulous Fabian’s Bakery, wants to set up a snack booth at the Walkathon. They will donate their profits to the school. To make a profit the business has to consider the expenses that might occur. For a T-shirt company, the expenses may include the cost of buying the shirts, costs for printing, costs to advertise, and labor charges. For a bakery the cost might include cost of ingredients, labor charges, advertising, etc."] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["At Fabulous Fabian’s Bakery, the expenses E\u00a0 to make n cakes per month is given by the equation: \n\n \u00a0\u00a0\u00a0 E\u00a0 = 825 + 3.25n\n\nThe income Inc\u00a0 for selling n cakes is given by the equation: \n\n \u00a0\u00a0\u00a0 Inc\u00a0 = 8.20 n
                        • What information do the numbers in each equation represent?
                        • How many cakes does Fabian need to sell in order to start making a profit?
                        "] + } + } + ] + }, + "supports": [ + {"text": "Can you explain the meaning of the equation in your own words? "}, + {"text": "How much will it cost Fabian to make 1 cake? 2 cakes? "}, + {"text": "What does it mean by “making a profit”? "} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_3_4_WI_bakery_350w.png" + } + }, + { + "content": { + "type": "Text", + "format":"html", + "text": ["Situation A. Kevin’s Graph\nKevin drew the graph above to help him find the number of cakes sold to make a profit.
                        1. Explain how Kevin could use his graph to determine Fabian’s profit.
                        2. Kevin highlighted the vertical distance 330 between the two lines on the graphs. What does the 330 represent on the graph? What does it represent in the real world?
                        3. Adia claims she can find the coordinates of the point of intersection by solving the equation 8.20n = 825 + 3.25n. Is this possible? Explain. How does it help?
                        "] + } + }, + { + "content": { + "type": "Text", + "format":"html", + "text": ["Situation B. Fabian’s Profit Equation
                        1. Fabian uses the equation P = Income – Expenses to predict the profit. He wrote P = 8.20n – (825 + 3.25). Does this make sense? Explain.
                        2. Adia rewrites Fabian’s profit equation as P = 4.95n – 825. Is she correct? Explain.
                        "] + } + }, + { + "content": { + "type": "Text", + "format":"html", + "text": ["Situation C. Fabian’s Profit Inequality \nFabian and his sister are looking for other ways to express how to find the number of cakes needed to make a profit. Explain why each representation does or does not make sense.", + "\nFabian's representation: Inequality Statement P > 4.95n - 825", + "\nHis Sister's representation: Number Line"] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_Fabian_Numberline.png" + } + } + ] + }, + "supports": [ + {"text": "What are his expenses and his income for the month?"}, + {"text": "What do the coefficients of n represent?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [{ + "content": { + "type": "Text", + "format": "html", + "text": ["Describe how you can solve an equation of the form ax + b = y? \nDescribe how you can solve an inequality of the form ax + b < c or ax + b > c? "] + } + }] + }, + "supports": [] + } + ], + "supports": [] + } + ] + }, + { + "description": "Investigation 4", + "ordinal": 4, + "title": "MSA Investigation 4 Connecting Rates and Ratios", + "problems": [ + { + "description": "Problem 4.1", + "ordinal": 1, + "title": "MSA 4.1 Climbing Stairs", + "subtitle": "Using the Ratio of Rise and Run", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["All of the patterns of change you have explored in this Unit involved rates of change. For example, you worked with walking rates expressed in meters per second and pledge rates expressed in dollars per kilometer. In these situations, you found that the rate a affects the following things in a linear relationship represented by y = ax + b:
                        • the steepness of the graph
                        • if the linear situation is represented by the equation y = ax, then the situation is also proportional and a represents the constant of proportionality
                        • how the y-values in the table change for each unit change in the x-values
                        In this Investigation, you will explore another way to express the rates of change. "] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_In_skiing_350w.png" + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + + "type": "Text", + "text": "Climbing stairs is good exercise, so some athletes run up and down stairs as part of their training. The steepness of stairs determines how difficult they are to climb. By investigating the steepness of stairs, you can find another important way to describe the steepness of a line. \n\nCarpenters have developed the guidelines below to ensure that the stairs they build are relatively easy for a person to climb. Steps are measured in inches. \n\n • Twice the rise plus the run for each step should be between 24 and 26 inches.\n • The rise plus the run for each step should be between 17 and 19 inches. \n\nThe steepness of stairs is determined by the ratio of the rise to the run for each step. The rise and run are labeled in the diagram below. " + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_1_In_running_stairs_350w.png" + } + }, + { + "content": { + "type": "Text", + "text": "Determine the steepness of a set of stairs in your school or home. \n\n • \u00a0 How can you describe the steepness of the stairs?\n • \u00a0 Is the steepness the same between any two consecutive steps? \n • \u00a0 How do the stairs you measured compare to the carpenters’ guidelines? " + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Interesting situations to think about include: spiral staircases, school stairs, large steps (like at a museum), etc.\nExample: 7.25 in. to 11.25 inches for the rise to the run, or approximately 0.70 for the ratio of rise to run. This is the same for every step in the staircase. The ratio of rise to run is not within the carpenter’s guidelines." + } + } + ] + }, + "supports": [ + {"text": "How can you use rise and run to explain the steepness of stairs?"} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Arch Middle School Stairs\nA set of stairs is being built for the front of the new Arch Middle School. The ratio of rise to run is 7 to 11. \n1. Is this ratio within the carpenters’ guidelines?2(rise) + run = 2(7) + 11 = 14 + 11 = 25, which is between 24 and 26 inches. \nRise + run = 7 + 11 = 18, which is between 17 and 19 inches.\nYes, these stairs meet the carpenters’ guidelines. Note that a scaled-up equivalent ratio of 14 to 22 would not meet the guidelines. " + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Make a sketch of a set of stairs that meet this ratio. Label the lengths of the rise and run of a step."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary.\nExample: a set of stairs with a height of 3.5 inches and a depth of 5.5 inches." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Does everyone in your class have the same sketch? Explain why."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Not everyone in the class will have the same sketch because even the same ratio can be represented by different numbers." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["4. Write an equation that represents the relationship between rise and run."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary based on their stairs.\nExample answer using the stairs at Arch Middle School, rise = (7/11)run." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["5. How is the ratio of rise to run represented in the graph? Equation?"]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The ratio of rise to run is represented in the graph by the steepness of the line and in the equation by the coefficient of x." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["6. Does your graph represent a proportional relationship? Explain why. "]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The graph does represent a proportional relationship because it passes through the origin." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Anna’s Claim\n1.Anna claims that the ratio of rise to run is another way to express the pattern of change between the two variables in a linear situation. Is she correct? Explain why."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Yes, she is correct. The ratio of rise to run describes how much one variable changes if you change the other variable by a specific amount. If the variables are always related in this way, then they have a constant rate of change, which gives a linear relationship." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Is the ratio the same between any two steps? Explain."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Yes, because each step on the staircase will have the same height (or rise) and depth (or run)." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Does the ratio change if we take two steps at a time? Explain why."]} + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "No, because we’re rising twice as high and running twice as far. So, the ratio will stay the same." + } + } + ] + }, + "supports": [ + {"text": "How do you know if a relationship is linear? "}, + {"text": "How do you know if a relationship is proportional? "} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "How does the steepness of stairs expressed as a ratio related to a straight-line graph? To a linear equation that represents the graph?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The steepness of stairs is represented by the slope of a straight-line graph. In a linear equation that represents the graph, the steepness of the stairs is represented by the coefficient of x." + } + } + ] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 4.2", + "ordinal": 2, + "title": "MSA 4.2 The Constant of Proportionality", + "subtitle": "", + "sections": [ + { + "type": "overview", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "The method for finding the steepness of stairs suggests a way to find the steepness of a line. A line drawn from the bottom step of a set of stairs to the top step touches each step at one point. The rise and the run of a step are the vertical and the horizontal changes, respectively, between two points on the line. " + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_2_In_stairs_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["The steepness of the line is the ratio of rise to run, or vertical change to horizontal change, for this step. We call this ratio the rate of change or slope of the line. "] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_2_In_slope_350w.png" + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_2_stairgraph.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Slope = (24-12)/(12-6) = 6/12 = ½", + "\nUnlike the steepness of stairs, the rate of change of a line can be negative. To determine the rate of change of a line, you need to consider the direction, or sign, of the vertical and horizontal changes from one point to another. If vertical change is negative for positive horizontal change, the rate of change will be negative. Lines that slant upward from left to right have positive rate of change. Lines that slant downward from left to right have a negative rate of change. You will learn more about slopes of lines in the 8th grade Thinking with Mathematical Models.", + "\nRecall that proportional relationships can be represented by a multiplicative comparison statement between two quantities x and y. It can also be represented by the equation y = ax. The graph of this equation is a straight line through the origin. The coefficient a in the equation y = ax is the constant of proportionality." + ] + } + }, + { + "content": { + "type": "Table", + "columns": [ + { + "name": "x", + "type": "number", + "values": [-2, -1, 0, 1, 2] + }, + { + "name": "y", + "type": "number", + "values": [6, 3, 0, -3, -6] + } + ] + } + }, + { + "layout": { + "height": 200 + }, + "content": { + "type":"Geometry", + "board": { + "properties": { + "axisMin": [-0.2, -1], + "axisRange": [5, 11] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [1, 4] + }, + { + "type": "point", + "parents": [4,2] + } + ] + } + ] + } + }, + { + "content": { + "type": "Table", + "columns": [ + { + "name": "x", + "ordinal": 1, + "values": [-2, -1, 0, 1, 2] + }, + { + "name": "y", + "type": "number", + "values": [-1, -0.5, 0, 0.5, 1] + } + ] + } + }, + { + "layout": { + "height": 200 + }, + "content": { + "type":"Geometry", + "board": { + "properties": { + "axisMin": [-0.2, -1], + "axisRange": [5, 11] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [2, 2] + }, + { + "type": "point", + "parents": [5, 4] + } + ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["What is the constant of proportionality for the proportional relationship represented in the table?"] + } + } + ] + }, + "supports": [] + }, + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["The graphs and tables below represent proportional situations. For each Representation:
                        • What is the constant of proportionality?
                        • How is rate of change related to the constant of proportionality?
                        Pick one Situation and write an application or story that could be represented with this representation. "] + } + }, + { + "content": { + "type": "Text", + "text": "\u0089Representation 1\u0089\u0089\u0089Representation 2" + } + }, + [ + { + "layout": { + "height": 200 + }, + "content": { + "type":"Geometry", + "title": "Representation 1", + "board": { + "properties": { + "axisMin": [-5, -10], + "axisRange": [10, 32] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [-2, 6] + }, + { + "type": "point", + "parents": [2, -6] + } + ] + } + ] + } + }, + { + "layout": { + "height": 200 + }, + "content": { + "type":"Geometry", + "title": "Representation 2", + "board": { + "properties": { + "axisMin": [-5, -3], + "axisRange": [10, 10] + } + }, + "objects": [ + { + "type": "movableLine", + "parents": [ + { + "type": "point", + "parents": [-4, -2] + }, + { + "type": "point", + "parents": [4, 2] + } + ] + } + ] + } + } + ], + { + "content": { + "type": "Table", + "name": "Representation 3", + "columns": [ + { + "name": "x", + "type": "number", + "values": [-2, -1, 0, 1, 2] + }, + { + "name": "y", + "type": "number", + "values": [-1, -0.5, 0, 0.5, 1] + } + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Representation 1: The constant of proportionality is -3, which is the same as the rate of change (-3/1).\nRepresentation 2: The constant of proportionality is 1/2, which is the same as the rate of change (1/2).\nRepresentation 3: The constant of proportionality is 0.5, which is the same as the rate of change (0.5/1).\nStudent answers will vary. Possible situation for representation 2: You place a bucket under a leaking faucet, which collects 1 cup of water every 2 hours." + } + } + ] + }, + "supports": [ + {"text": "Would an equation help find the constant of proportionality?"}, + {"text": "What is the rate of change in the graphs and the table? "} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Representing Rates of Change\nThe graphs, tables, and equations represent linear relationships. "] + } + }, + { + "content": { + "type": "Image", + "url": "curriculum/moving-straight-ahead/images/MSA_4_2_WI_graphs_and_tables_350w.png" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["1. What is the rate of change and y-intercept associated with each representation?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Graph 1: slope: -3, y-intercept: 6\nGraph 2: slope: 3, y-intercept: 6\nTable 1 : slope :1.5, y-intercept : -1\nTable 2 : slope : -0.5, y-intercept : 5\nquation 1 : slope : 2.5, y-intercept : 5\nEquation 2 : slope : -3, y-intercept : 0" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Do any of the relationships represent a proportional relationship? If so, what is the constant of proportionality? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The relationship shown by Equation 2 is proportional with a constant of proportionality of -3." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. John’s Claims\n1. John noticed that if the points (0,0) and (1, a) are on a line, then the line represents a proportional relationship, and a is the constant of proportionality. Is he correct? Explain."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "He is correct because the line runs through the origin and, for every point on the line, the ratio of the x- and y-coordinates is always a." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. John also claims that the constant of proportionality is the unit rate. Is he correct? Explain why. "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "He is correct. The constant of proportionality a for this line means that each time the x-variable increases by 1, the y-variable increases by a. So, the ratio is a to 1, which is also a unit rate." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. More Lines\nThe points (3, 5) and (-2, 10) lie on a line.\n1. What is the rate of change or slope of the line?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The rate of change of the line is (10 – 5)/(-2 - 3) = 5/-5 = -1" + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. Find two more points that lie on this line. Explain your method."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. \nFor example, (-1,9) is on the line because you can increase the x-coordinate of (-2,10) by 1 and decrease the y-coordinate of (-2,10) by 1." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. Does this line represent a proportional relationship? Explain."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "This line does not represent a proportional situation because it does not pass through the origin." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["<4. What is the rate of change or slope of a horizontal line? A vertical line? Explain your reasoning."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The rate of change of a horizontal line is 0 because there is no “rise” no matter how far you “run.” The rate of change of a vertical line is undefined because there is no “run” no matter how far you “rise.”" + } + } + ] + }, + "supports": [ + {"text": "Are the graphs steep? What will that mean about the rate of change?"}, + {"text": "How do you find the rate of change in a graph, table, or equation?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "How is the rate of change of a linear relationship related to the constant of proportionality?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Some linear relationships are proportional and some are not. The rate of change represents how one variable changes compared to the other. For a given relationship, the rate of change is constant for any x- and y-values you choose.\nWhen a linear situation is also proportional, the unit rate, constant of proportionality, and the rate of change are all the same." + } + } + ] + }, + "supports": [] + } + ], + "supports": [] + }, + { + "description": "Problem 4.3", + "ordinal": 3, + "title": "MSA 4.3 Pulling it All Together", + "subtitle": "", + "sections": [ + { + "type": "launch", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["The students did so well in organizing the walkathon that Ms. Chang organized a special field trip to watch a movie. \n\nSuppose that a movie company charges the school $4.50 per student. But the movie company does not want to lose money. The company’s operating expenses include $130 for the staff and a film rental fee of $1.25 per student. \n\n• How many students need to attend the movie so that the theater’s income will equal its operating expenses? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The movie company will “break even” if there are 40 students in attendance.\nStudent answers will vary. \n\nSample response finding when Expenses equal Income:\nWe can find when the expenses and incomes are equal.\n\u00894.50n = 130 + 1.25n\n\u00893.25n = 130\n\u0089n = 40\n\nSample response using the Profit equation:\nWe can write equations for the movie company’s income I, expenses E, and model profit P as income – expenses. For some number of students n.\n\u0089P = I – E \n\u0089P = 4.50n – (130 + 1.25n)\n\u0089P = 3.25n – 130\nThe point at which the movie company will “break even” is the point at which their profit equals zero, so we can solve for which value of n makes P=0.\n\u00890 = 3.25n – 130\n\u0089130 = 3.25n\n\u008940 = n" + } + } + ] + }, + "supports": [ + {"text": "How much does the operating expense cost if 10 students watch the movie? "}, + {"text": "How much does the school pay for the movie if 10 students watch the movie?"} + ] + }, + { + "type": "explore", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation A. Student Strategies \nThe following students used different strategies to answer the question in the Initial Challenge. Examine each strategy and describe how each could or could not be used to answer the question."] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Geraldo’s Strategy: I made the following table:"] + } + }, + { + "content": { + "type": "Table", + "name": "Theater Income", + "columns": [ + { + "name": "Number of Students, x", + "type": "number", + "values": [0, 10, 20, 30, 40, 50, 60, 70] + }, + { + "name": "Income, I ($)", + "type": "number", + "values": [ ] + }, + { + "name": "Expenses, E ($)", + "type": "number", + "values": [ ] + } + ] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Anna’s Strategy: On the same set of axes, I graphed the theater’s income and operating expenses for any number of students from 0 to 100."] + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Sze’s Strategy: I wrote an expression that represents the theater’s profit. "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Geraldo’s strategy could be used by filling out the table and looking for the number of students when the income is the same as the expenses. \n\nAnna’s strategy could be used by graphing the line for income and the line for operating expenses and looking for the intersection point. \n\nSze’s strategy could be used by making his expression into an equation equal to a profit of 0." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation B. Laneshia Uses Inequalities \nLaneshia wanted to find the number of students that make each of the following inequality statements true.
                        • Expenses < 255 or $1.25n + $130 < $255
                        • Income > 675 or $4.50n > $675
                        \n1. Find the number of students that makes each inequality statement true."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "To find the number of students that will make expenses less than $255, we need to solve the associated equality. So 1.25n+130=255\n\u0089 1.25n = 125 \n\u0089 n = 100. So to make the inequality statement for expenses true, there need to be less than 100 students.\n\nTo find the number of students that will make the income greater than $675, we need to solve the associated equality. So 4.50n = 675 \n\u0089 n = 150. \nSo to make the inequality statement for income true, there need to be more than 150 students." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. How might this information be helpful in making decisions about the showing of the film?"] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Sample answer: If you only have a fixed amount of money to spend on showing the movie, then the expenses inequality can keep you from going into debt. If you need to raise a certain amount of money from showing the movie, then the income inequality can help you calculate how many tickets to sell." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Situation C. A Competing Company \nAt another theater, they used the equation, \n\u0089 P\u00a0 = 3n\u00a0 – 115 \nto find the profit P for the number of students n that attend the theater. What do the numbers 3 and 115 tell you about \n1. The relationship between the number of students and the theater’s profit? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you how much the theater’s profit will increase for each extra student who attends the theater. The number -115 tells you some expense or initial fee for using the theatre." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["2. the pattern of entries that would appear in a table of sample (students, profit) data? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you how much pattern of change. For every additional student, there is an increase of $3 between consecutive profit entries on the table. The number -115 tells you the profit entry that corresponds with zero students." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["3. a graph of the relationship between the number of students and the profit? "] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The number 3 tells you the rate of change, or slope, of the line (because profit increases by 3 every time the number of students increases by 1). The number -115 tells you the y-intercept of the line." + } + }, + { + "content": { + "type": "Text", + "format": "html", + "text": ["Write and solve an equation you can use to find the number of students for which the theaters in Exercise 1 and Exercise 2 make the same profit. Then find the amount of that profit."] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "The equation for profit for the theater in the initial challenge was P1 = I – E = 4.50n – (130 + 1.25n) = 3.25n – 130. The equation for profit for the theater in this problem is P2 = 3n – 115. If they make the same profit, then we can set the expressions equal and solve for the number of students.\n\u00893.25n – 130 = 3n – 115\n\u0089 0.25n = 15\n\u0089 n = 60\nThis means that these two theaters will make the same profit for 60 students." + } + } + ] + }, + "supports": [ + {"text": "What information do you need to know if a situation is linear?"}, + {"text": "How do you know your equation represents the linear situation?"} + ] + }, + { + "type": "summarize", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "text": "How do the situations in this problem compare to other problems in this unit? Do any of these represent proportional situations? Why? In what ways are tables, graphs, equations, and inequalities useful for solving problems?" + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Student answers will vary. Sample answer: The movie theater situations in this Problem have positive rates of change (like the staircases). Some of the other problems showed decreasing/negative rates of changes. The movie theater problems don’t make sense for fractions of students, but the staircase problems make sense for fraction or decimal measurements. None of the movie theater problems are proportional situations, because none of them would pass through the origin if graphed.\nTables are useful for solving problems because they show several numerical values for a given pattern. Graphs are useful because they give you a sense of the pattern’s behavior over a wide range of values, which is helpful for estimating. Equations are useful because you can use them to calculate any specific value and the coefficients give you information about the problem situation. Inequalities are useful if you are looking for a range of possible answers." + } + } + ] + }, + "supports": [] + } + ], + "supports": [] + } + ] + }, + { + "description": "Mathematical Reflections", + "ordinal": 5, + "title": "MSA MR1 - MR4", + "problems": [{ + "description": "Mathematical Reflections", + "ordinal": 1, + "title": "Moving Straight Ahead Mathematical Reflections", + "subtitle": "", + "sections": [ + { + "type": "MathReflection1", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "Main idea: In a linear relationship, as the independent variable increases in equal increments, the corresponding dependent variable increases (or decreases) by a consistent amount. Students might describe this as the rate of change. They should realize that this could be zero (as with Leanne) or negative (as with Ms. Chang and Mr. Mamer). They may realize that the rate of change can be measured anywhere on the graph or table. A linear relationship can be represented by the equation y = ax + b. The point where the line crosses the y-axis is b, the y-intercept. The rate of change is represented by a. If b is 0, then the relationship is also proportional. In a linear and proportional relationship, the rate of change is also a unit rate that is the constant of proportionality. Inequalities appeared briefly as a contrast to equality in Problem 1.4. " + } + } + ] + }, + "supports": [ ] + }, + { + "type": "MathReflection2", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": "The coefficient a in the equation y = ax + b that represents a linear relationship is the rate of change between the independent variable and the dependent variable. It controls the slant of the line that represents the relationship. Greater absolute values of a mean there is a greater rate of change in the situation, so the lines are steeper. Positive values of a give lines that slant up. Negative values of a give lines that slant down. The value of b gives the y-intercept of the line. It is represented as the point (0, b) on the line or the pair of values in a table. In a table, the y-intercept is the value where the x-value is 0, and the rate of change is the difference in consecutive values of the dependent variable for constant increments in the independent variable.\nAny ordered pair (point) that lies on the graph of a linear relationship can be used to find the solution to a problem. The ordered pair (x, y) represents specific values of the variables. If the value of one of the variables is known, then the graph can be traced to find the corresponding value of the other variable. Similarly, any ordered pair in a table for a linear relationship can be used to find the solution to a problem.\nTo find solutions to inequalities, we can consider the solution to the corresponding equality. Then consider the values that would make sense. Often the situation indicates the values to solve an inequality. For example, we often look at “When is one company less expensive than another company?” or “How many items do we need to sell to make a profit?”" + } + } + ] + }, + "supports": [ ] + }, + { + "type": "MathReflection3", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "If you have an equation of the form y = ax + b and you know the value of x or y, you can substitute the value of the variable into the equation. Then, use the properties of equality to solve for the other variable. For example, if y = 3x + 4 and you want to find x when y = 10, then you substitute 10 in place of y: 10 = 3x + 4. Next, you can subtract 4 from both sides to get 6 = 3x. Now, divide both sides by 3 to get x = 2.\nFor the equation y = 3x + 4, to find the value of x when y = 10, you can graph the equation. Trace along the line to find the point whose y-coordinate is 10 and then read the corresponding x-value, which is 2. To use a table, construct a table of values for the equation either by hand or with graphing technology. Next, locate the pair of values in which y = 10 and find the corresponding x-value, which is 2.\nTo find the values that satisfy an inequality such as 3x + 4 < 10, you can solve the corresponding equation 3x + 4 = 10. The solution of this equation is x = 2. Then, test values less than and greater than 2 to determine the solution. In this case, x-values less than 2 make the inequality 3x + 4 < 10 true, so the solution is x < 2.\nTo find the values that satisfy an inequality such as 3x + 4 < 10, you can graph the corresponding linear relationship y = 3x + 4. Then, find the points on the line whose y-values are less than 10. You can also locate the x-values of these points on the x-axis or on a number line.\nIn Problem 3.2, Equation 1 two equivalent expressions for the number of pouches on the left side of the equation are 4x + 2 and 2(2x + 1). You can use the properties of operations to show that they are equivalent. Applying the Distributive Property to one of the expressions yields the other: 4x + 2 = 2(2x + 1). You can also argue that both of the expressions represent the number of pouches and coins in the picture.\nIn Problem 3.3, Set 3(a), two equivalent ways of writing the expression on the left side of the equation are 3(x + 1) and 3x + 3. You can tell they are equivalent because the equations 3(x + 1) = 21 and 3x + 3 = 21 have the same solution, even though you would take different steps when solving them. (To solve the first equation, you would divide each side by 3 and then subtract 1 from each side. To solve the second equation, you would subtract 3 from each side and then divide each side by 3. The solution for both equations is x = 6.)" + } + } + ] + }, + "supports": [ ] + }, + { + "type": "MathReflection4", + "content": { + "tiles": [ + { + "content": { + "type": "Text", + "format": "html", + "text": [ + "In this Unit you are continuing to explore patterns of change between two variables using linear situations. You use tables, graphs, expressions, equations, and inequalities to represent these linear patterns and solve problems. At the end of this Investigation, what do you know about linear expressions, equations, inequalities, and relationships?" + ] + } + }, + { + "display": "teacher", + "content": { + "type": "Text", + "format": "html", + "text": + "Slope describes the steepness of a line. It is the ratio of vertical change to horizontal change. If it is positive, then the line is increasing from left to right. If it is negative, then it is decreasing from left to right. If the slope is zero, the line is horizontal. This is like walking on a flat surface as opposed to up or down a hill.\nFinding the slope is the same as finding the rate of change between two variables in a linear relationship. The horizontal distance change between two points is the same as the difference between two corresponding x-values of points in a table. The vertical change in distance is the same as the difference between two corresponding y-values of points in a table." + } + } + ] + }, + "supports": [ ] + } + ] + } + ], + "supports": [ + ] + } + ], + "supports": [] +} diff --git a/src/utilities/color-utils.ts b/src/utilities/color-utils.ts index 099d533bf1..b46fd846a7 100644 --- a/src/utilities/color-utils.ts +++ b/src/utilities/color-utils.ts @@ -1,5 +1,14 @@ import colorString from "color-string"; +export const lightenColor = (color: string, pct = 0.5) => { + const rgb = colorString.get.rgb(color); + if (!rgb || !isFinite(pct) || (pct < 0) || (pct > 1)) return color; + rgb[0] += Math.round(pct * (255 - rgb[0])); + rgb[1] += Math.round(pct * (255 - rgb[1])); + rgb[2] += Math.round(pct * (255 - rgb[2])); + return colorString.to.hex(rgb); +}; + export const luminanceRGB = (r: number, g: number, b: number, scale = 1) => { // https://en.wikipedia.org/wiki/Relative_luminance return (r * 0.2126 + g * 0.7152 + b * 0.0722) / scale; diff --git a/src/utilities/js-utils.ts b/src/utilities/js-utils.ts index 637d349765..d41625344a 100644 --- a/src/utilities/js-utils.ts +++ b/src/utilities/js-utils.ts @@ -52,3 +52,53 @@ export function uniqueId(idLength = 16): string { // cf. https://zelark.github.io/nano-id-cc/ return nanoid(idLength); } + +/* + * uniqueTitle() + * + * returns a unique title from a given base name, adding a unique numeric suffix + */ +export function uniqueTitle(base: string, isValid: (name: string) => boolean) { + let name: string; + for (let i = 1; !isValid(name = `${base} ${i}`); ++i) { + // nothing to do + } + return name; +} + +/* + * uniqueName() + * + * returns a unique name from a given base name, adding a numeric suffix if necessary + */ +export function uniqueName(base: string, isValid: (name: string) => boolean) { + if (isValid(base)) return base; + let name: string; + for (let i = 2; !isValid(name = `${base}${i}`); ++i) { + // nothing to do + } + return name; +} + +/* + * uniqueSubscriptedName() + * + * returns a unique name from a given base name, adding subscripts if necessary + */ +export function uniqueSubscriptedName(base: string, isValid: (name: string) => boolean) { + if (isValid(base)) return base; + const numToSubscripts = (num: number) => { + const subscripts = "\u2080\u2081\u2082\u2083\u2084\u2085\u2086\u2087\u2088\u2089"; + const str = `${Math.trunc(num)}`; + let result = ""; + for (let i = 0; i < str.length; ++i) { + result += subscripts[str.charCodeAt(i) - "0".charCodeAt(0)]; + } + return result; + }; + let name: string; + for (let i = 2; !isValid(name = `${base}${numToSubscripts(i)}`); ++i) { + // nothing to do + } + return name; +} diff --git a/webpack.config.js b/webpack.config.js index 72cd2efaf4..c5235992c1 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -29,6 +29,21 @@ module.exports = (env, argv) => { }, module: { rules: [ + { + test: /bundle\.js$/, + loader: require.resolve('string-replace-loader'), + options: { + multiple: [ + { // react-data-grid doesn't currently provide a means of clearing cell selection + search: /if \(!isCellWithinBounds\(position\)\) return;/g, + replace: + "// [CC] (string-replace-loader) allow clearing the selection\n" + + " if (!(position.idx === -1 && position.rowIdx === -1) && !isCellWithinBounds(position)) return;", + strict: true // fail build if replacement not performed + } + ] + } + }, { test: /popper\.js$/, loader: require.resolve('string-replace-loader'), @@ -54,8 +69,16 @@ module.exports = (env, argv) => { loader: 'ts-loader', exclude: /node_modules/ }, + { // disable svgo optimization for files ending in .nosvgo.svg + test: /\.nosvgo\.svg$/i, + loader: "@svgr/webpack", + options: { + svgo: false + } + }, { test: /\.svg$/i, + exclude: /\.nosvgo\.svg$/i, oneOf: [ { issuer: /\.[tj]sx?$/i,