diff --git a/docs/en_US/release_notes_4_30.rst b/docs/en_US/release_notes_4_30.rst index 0efad07f2..5bcc59da2 100644 --- a/docs/en_US/release_notes_4_30.rst +++ b/docs/en_US/release_notes_4_30.rst @@ -9,6 +9,7 @@ This release contains a number of bug fixes and new features since the release o New features ************ +| `Issue #1802 `_ - Added ERD Diagram support with basic table fields, primary key, foreign key, and DDL SQL generation. Housekeeping ************ diff --git a/web/.eslintrc.js b/web/.eslintrc.js index 1fdd07fbf..9b75cd809 100644 --- a/web/.eslintrc.js +++ b/web/.eslintrc.js @@ -18,6 +18,7 @@ module.exports = { 'eslint:recommended', 'plugin:react/recommended', ], + 'parser': 'babel-eslint', 'parserOptions': { 'ecmaVersion': 2018, 'ecmaFeatures': { diff --git a/web/package.json b/web/package.json index b77776569..c1cc5c492 100644 --- a/web/package.json +++ b/web/package.json @@ -7,12 +7,15 @@ ], "license": "PostgreSQL", "devDependencies": { - "@babel/core": "~7.6.0", - "@babel/preset-env": "~7.6.0", + "@babel/core": "^7.10.2", + "@babel/plugin-proposal-object-rest-spread": "^7.9.6", + "@babel/preset-env": "^7.10.2", + "@emotion/core": "^10.0.14", + "@emotion/styled": "^10.0.14", "autoprefixer": "^9.6.4", "axios-mock-adapter": "^1.17.0", - "babel-loader": "~8.0.5", - "babel-plugin-transform-object-rest-spread": "^7.0.0-beta.3", + "babel-eslint": "^10.1.0", + "babel-loader": "^8.1.0", "copy-webpack-plugin": "^5.1.0", "core-js": "^3.2.1", "cross-env": "^5.2.0", @@ -41,7 +44,8 @@ "popper.js": "^1.14.7", "postcss-loader": "^3.0.0", "prop-types": "^15.7.2", - "raw-loader": "^1.0.0", + "raw-loader": "^3.1.0", + "resize-observer-polyfill": "^1.5.1", "sass": "^1.24.4", "sass-loader": "^7.1.0", "sass-resources-loader": "^2.0.0", @@ -50,7 +54,7 @@ "url-loader": "^1.1.2", "webpack": "^4.41.2", "webpack-bundle-analyzer": "^3.5.1", - "webpack-cli": "^3.2.3", + "webpack-cli": "^3.3.11", "webpack-require-from": "^1.8.0", "yarn-audit-html": "^1.1.0" }, @@ -58,12 +62,12 @@ "@babel/plugin-proposal-class-properties": "^7.10.4", "@babel/preset-react": "^7.10.4", "@fortawesome/fontawesome-free": "^5.14.0", + "@projectstorm/react-diagrams": "^6.3.0", "@simonwep/pickr": "^1.5.1", + "@tippyjs/react": "^4.2.0", "acitree": "git+https://github.com/imsurinder90/jquery-aciTree.git#rc.7", "alertifyjs": "git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263", "axios": "^0.18.1", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-preset-es2015-without-strict": "~0.0.4", "babelify": "~10.0.0", "backbone": "1.4.0", "backform": "^0.2.0", @@ -75,12 +79,17 @@ "bootstrap4-toggle": "3.4.0", "bowser": "2.1.2", "browserify": "~16.2.3", + "canvg": "^3.0.7", "chart.js": "^2.9.3", + "closest": "^0.0.1", "codemirror": "^5.54.0", "css-loader": "2.1.0", "cssnano": "^4.1.10", + "dagre": "^0.8.4", "dropzone": "^5.5.1", "exports-loader": "~0.7.0", + "html-to-image": "^0.1.1", + "html2canvas": "^1.0.0-rc.7", "immutability-helper": "^3.0.0", "imports-loader": "^0.8.0", "ip-address": "^5.8.9", @@ -91,11 +100,17 @@ "json-bignumber": "^1.0.1", "karma-coverage": "^2.0.3", "leaflet": "^1.5.1", + "lodash": "4.*", + "ml-matrix": "^6.5.0", "moment": "^2.24.0", "moment-timezone": "^0.5.23", "mousetrap": "^1.6.3", + "pathfinding": "^0.4.18", + "paths-js": "^0.4.9", + "raf": "^3.4.1", "react": "^16.13.1", "react-dom": "^16.13.1", + "react-to-print": "^2.10.3", "requirejs": "~2.3.6", "select2": "^4.0.6-rc.1", "shim-loader": "^1.0.1", diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 1bae28f9c..0b9af2ca1 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -767,6 +767,7 @@ def utils(): editor_insert_pair_brackets=insert_pair_brackets, editor_indent_with_tabs=editor_indent_with_tabs, app_name=config.APP_NAME, + app_version_int=config.APP_VERSION_INT, pg_libpq_version=pg_libpq_version, support_ssh_tunnel=config.SUPPORT_SSH_TUNNEL, logout_url=_get_logout_url() diff --git a/web/pgadmin/browser/register_browser_preferences.py b/web/pgadmin/browser/register_browser_preferences.py index 640a05468..3b335be12 100644 --- a/web/pgadmin/browser/register_browser_preferences.py +++ b/web/pgadmin/browser/register_browser_preferences.py @@ -497,7 +497,8 @@ def register_browser_preferences(self): category_label=PREF_LABEL_OPTIONS, options=[{'label': gettext('Query Tool'), 'value': 'qt'}, {'label': gettext('Debugger'), 'value': 'debugger'}, - {'label': gettext('Schema Diff'), 'value': 'schema_diff'}], + {'label': gettext('Schema Diff'), 'value': 'schema_diff'}, + {'label': gettext('ERD Tool'), 'value': 'erd_tool'}], help_str=gettext('Select Query Tool, Debugger, or Schema Diff from ' 'the drop-down to set open in new browser tab for ' 'that particular module.'), diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py index 450d8c5ab..d6d4eae97 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/__init__.py @@ -21,7 +21,6 @@ from pgadmin.browser.server_groups.servers.utils import parse_priv_to_db from pgadmin.utils.ajax import make_json_response, internal_server_error, \ make_response as ajax_response, gone from .utils import BaseTableView -from pgadmin.utils.preferences import Preferences from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ constraints.foreign_key import utils as fkey_utils @@ -134,8 +133,7 @@ class TableModule(SchemaChildModule): blueprint = TableModule(__name__) -class TableView(BaseTableView, DataTypeReader, VacuumSettings, - SchemaDiffTableCompare): +class TableView(BaseTableView, DataTypeReader, SchemaDiffTableCompare): """ This class is responsible for generating routes for Table node @@ -589,7 +587,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, Returns: JSON of selected table node """ - status, res = self._fetch_properties(did, scid, tid) + status, res = self._fetch_table_properties(did, scid, tid) if not status: return res if not res['rows']: @@ -599,86 +597,6 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, gid, sid, did, scid, tid, res=res ) - @staticmethod - def _check_rlspolicy_support(res): - """ - This function is used to check whether 'rlspolicy' in response - as it supported for version 9.5 and above - :param res: - :return: - """ - if 'rlspolicy' in res['rows'][0]: - # Set the value of rls policy - if res['rows'][0]['rlspolicy'] == "true": - res['rows'][0]['rlspolicy'] = True - - # Set the value of force rls policy for table owner - if res['rows'][0]['forcerlspolicy'] == "true": - res['rows'][0]['forcerlspolicy'] = True - - def _fetch_properties(self, did, scid, tid): - """ - This function is used to fetch the properties of the specified object - :param did: - :param scid: - :param tid: - :return: - """ - sql = render_template( - "/".join([self.table_template_path, self._PROPERTIES_SQL]), - did=did, scid=scid, tid=tid, - datlastsysoid=self.datlastsysoid - ) - status, res = self.conn.execute_dict(sql) - if not status: - return False, internal_server_error(errormsg=res) - - elif len(res['rows']) == 0: - return False, gone( - gettext(self.not_found_error_msg())) - - # Update autovacuum properties - self.update_autovacuum_properties(res['rows'][0]) - - # We will check the threshold set by user before executing - # the query because that can cause performance issues - # with large result set - pref = Preferences.module('browser') - table_row_count_pref = pref.preference('table_row_count_threshold') - table_row_count_threshold = table_row_count_pref.get() - estimated_row_count = int(res['rows'][0].get('reltuples', 0)) - - # Check whether 'rlspolicy' in response as it supported for - # version 9.5 and above - TableView._check_rlspolicy_support(res) - - # If estimated rows are greater than threshold then - if estimated_row_count and \ - estimated_row_count > table_row_count_threshold: - res['rows'][0]['rows_cnt'] = str(table_row_count_threshold) + '+' - - # If estimated rows is lower than threshold then calculate the count - elif estimated_row_count and \ - table_row_count_threshold >= estimated_row_count: - sql = render_template( - "/".join( - [self.table_template_path, 'get_table_row_count.sql'] - ), data=res['rows'][0] - ) - - status, count = self.conn.execute_scalar(sql) - - if not status: - return False, internal_server_error(errormsg=count) - - res['rows'][0]['rows_cnt'] = count - - # If estimated_row_count is zero then set the row count with same - elif not estimated_row_count: - res['rows'][0]['rows_cnt'] = estimated_row_count - - return True, res - @BaseTableView.check_precondition def types(self, gid, sid, did, scid, tid=None, clid=None): """ @@ -686,12 +604,8 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, This function will return list of types available for column node for node-ajax-control """ - condition = render_template( - "/".join([ - self.table_template_path, 'get_types_where_condition.sql' - ]), - show_system_objects=self.blueprint.show_system_objects - ) + condition = self.get_types_condition_sql( + self.blueprint.show_system_objects) status, types = self.get_types(self.conn, condition, True, sid) @@ -1073,7 +987,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, data[k] = v try: - status, res = self._fetch_properties(did, scid, tid) + status, res = self._fetch_table_properties(did, scid, tid) if not status: return res @@ -1314,7 +1228,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, res = None if tid is not None: - status, res = self._fetch_properties(did, scid, tid) + status, res = self._fetch_table_properties(did, scid, tid) if not status: return res @@ -1378,7 +1292,7 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, """ main_sql = [] - status, res = self._fetch_properties(did, scid, tid) + status, res = self._fetch_table_properties(did, scid, tid) if not status: return res @@ -1665,57 +1579,12 @@ class TableView(BaseTableView, DataTypeReader, VacuumSettings, :return: Table dataset """ - if tid: - status, data = self._fetch_properties(did, scid, tid) + status, res = BaseTableView.fetch_tables(self, sid, did, scid, tid) + if not status: + current_app.logger.error(res) + return False - if not status: - current_app.logger.error(data) - return False - - data = super(TableView, self).properties( - 0, sid, did, scid, tid, res=data, return_ajax_response=False - ) - - return data - - else: - res = dict() - sql = render_template("/".join([self.table_template_path, - self._NODES_SQL]), scid=scid) - status, tables = self.conn.execute_2darray(sql) - if not status: - current_app.logger.error(tables) - return False - - for row in tables['rows']: - status, data = self._fetch_properties(did, scid, row['oid']) - - if status: - data = super(TableView, self).properties( - 0, sid, did, scid, row['oid'], res=data, - return_ajax_response=False - ) - - # Get sub module data of a specified table for object - # comparison - self._get_sub_module_data_for_compare(sid, did, scid, data, - row) - res[row['name']] = data - - return res - - def _get_sub_module_data_for_compare(self, sid, did, scid, data, row): - # Get sub module data of a specified table for object - # comparison - for module in self.tables_sub_modules: - module_view = SchemaDiffRegistry.get_node_view(module) - if module_view.blueprint.server_type is None or \ - self.manager.server_type in \ - module_view.blueprint.server_type: - sub_data = module_view.fetch_objects_to_compare( - sid=sid, did=did, scid=scid, tid=row['oid'], - oid=None) - data[module] = sub_data + return res def get_submodule_template_path(self, module_name): """ diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/utils.py index cae6c157c..3e99e5698 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/utils.py @@ -318,22 +318,23 @@ def _get_sql_for_create_fk_const(data, conn, template_path): len(data['columns']) < 1): return True, '-- definition incomplete', name, '' - if data['autoindex'] and \ + if data.get('autoindex', False) and \ ('coveringindex' not in data or data['coveringindex'] == ''): return True, '-- definition incomplete', name, '' - # Get the parent schema and table. - schema, table = get_parent(conn, - data['columns'][0]['references']) + if 'references' in data['columns'][0]: + # Get the parent schema and table. + schema, table = get_parent(conn, + data['columns'][0]['references']) - # Below handling will be used in Schema diff in case - # of different database comparison - _checks_for_schema_diff(table, schema, data) + # Below handling will be used in Schema diff in case + # of different database comparison + _checks_for_schema_diff(table, schema, data) sql = render_template("/".join([template_path, 'create.sql']), data=data, conn=conn) - if data['autoindex']: + if data.get('autoindex', False): sql += render_template( "/".join([template_path, 'create_index.sql']), data=data, conn=conn) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py index 1a72d8ab3..d700ccff2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/__init__.py @@ -175,8 +175,7 @@ class PartitionsModule(CollectionNodeModule): blueprint = PartitionsModule(__name__) -class PartitionsView(BaseTableView, DataTypeReader, VacuumSettings, - SchemaDiffObjectCompare): +class PartitionsView(BaseTableView, DataTypeReader, SchemaDiffObjectCompare): """ This class is responsible for generating routes for Partition node diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/foreign_key/sql/default/create.sql b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/foreign_key/sql/default/create.sql index 22fd79a9c..c8dd96f82 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/foreign_key/sql/default/create.sql +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/templates/foreign_key/sql/default/create.sql @@ -2,21 +2,21 @@ ALTER TABLE {{ conn|qtIdent(data.schema, data.table) }} ADD{% if data.name %} CONSTRAINT {{ conn|qtIdent(data.name) }}{% endif%} FOREIGN KEY ({% for columnobj in data.columns %}{% if loop.index != 1 %} , {% endif %}{{ conn|qtIdent(columnobj.local_column)}}{% endfor %}) REFERENCES {{ conn|qtIdent(data.remote_schema, data.remote_table) }} ({% for columnobj in data.columns %}{% if loop.index != 1 %} -, {% endif %}{{ conn|qtIdent(columnobj.referenced)}}{% endfor %}) {% if data.confmatchtype %}MATCH FULL{% else %}MATCH SIMPLE{% endif%} +, {% endif %}{{ conn|qtIdent(columnobj.referenced)}}{% endfor %}){% if data.confmatchtype is defined %} {% if data.confmatchtype %}MATCH FULL{% else %}MATCH SIMPLE{% endif%}{% endif%}{% if data.confupdtype is defined %} ON UPDATE{% if data.confupdtype == 'a' %} NO ACTION{% elif data.confupdtype == 'r' %} RESTRICT{% elif data.confupdtype == 'c' %} CASCADE{% elif data.confupdtype == 'n' %} SET NULL{% elif data.confupdtype == 'd' %} - SET DEFAULT{% endif %} + SET DEFAULT{% endif %}{% endif %}{% if data.confdeltype is defined %} ON DELETE{% if data.confdeltype == 'a' %} NO ACTION{% elif data.confdeltype == 'r' %} RESTRICT{% elif data.confdeltype == 'c' %} CASCADE{% elif data.confdeltype == 'n' %} SET NULL{% elif data.confdeltype == 'd' %} - SET DEFAULT{% endif %} + SET DEFAULT{% endif %}{% endif %} {% if data.condeferrable %} DEFERRABLE{% if data.condeferred %} diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py index 66bea8128..1e501b1cb 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/utils.py @@ -45,9 +45,13 @@ from pgadmin.browser.server_groups.servers.databases.schemas.tables.\ from pgadmin.browser.server_groups.servers.databases.schemas. \ tables.row_security_policies import \ utils as row_security_policies_utils +from pgadmin.utils.preferences import Preferences +from pgadmin.browser.server_groups.servers.databases.schemas.utils \ + import VacuumSettings +from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry -class BaseTableView(PGChildNodeView, BasePartitionTable): +class BaseTableView(PGChildNodeView, BasePartitionTable, VacuumSettings): """ This class is base class for tables and partitioned tables. @@ -101,7 +105,11 @@ class BaseTableView(PGChildNodeView, BasePartitionTable): driver = get_driver(PG_DEFAULT_DRIVER) did = kwargs['did'] self.manager = driver.connection_manager(kwargs['sid']) - self.conn = self.manager.connection(did=kwargs['did']) + if "conn_id" in kwargs: + self.conn = self.manager.connection( + did=kwargs['did'], conn_id=kwargs['conn_id']) + else: + self.conn = self.manager.connection(did=kwargs['did']) self.qtIdent = driver.qtIdent self.qtTypeIdent = driver.qtTypeIdent # We need datlastsysoid to check if current table is system table @@ -442,6 +450,161 @@ class BaseTableView(PGChildNodeView, BasePartitionTable): status=200 ) + def get_types_condition_sql(self, show_system_objects): + condition = render_template( + "/".join([ + self.table_template_path, 'get_types_where_condition.sql' + ]), + show_system_objects=show_system_objects + ) + + return condition + + def fetch_tables(self, sid, did, scid, tid=None): + """ + This function will fetch the list of all the tables + and will be used by schema diff. + + :param sid: Server Id + :param did: Database Id + :param scid: Schema Id + :param tid: Table Id + :return: Table dataset + """ + + if tid: + status, data = self._fetch_table_properties(did, scid, tid) + + if not status: + return False, data + + data = BaseTableView.properties( + self, 0, sid, did, scid, tid, res=data, + return_ajax_response=False + ) + + return True, data + + else: + res = dict() + sql = render_template("/".join([self.table_template_path, + self._NODES_SQL]), scid=scid) + status, tables = self.conn.execute_2darray(sql) + if not status: + return False, tables + + for row in tables['rows']: + status, data = \ + self._fetch_table_properties(did, scid, row['oid']) + + if status: + data = BaseTableView.properties( + self, 0, sid, did, scid, row['oid'], res=data, + return_ajax_response=False + ) + + # Get sub module data of a specified table for object + # comparison + BaseTableView._get_sub_module_data_for_compare( + self, sid, did, scid, data, row) + res[row['name']] = data + res[row['name']] = data + + return True, res + + def _get_sub_module_data_for_compare(self, sid, did, scid, data, row): + # Get sub module data of a specified table for object + # comparison + for module in self.tables_sub_modules: + module_view = SchemaDiffRegistry.get_node_view(module) + if module_view.blueprint.server_type is None or \ + self.manager.server_type in \ + module_view.blueprint.server_type: + sub_data = module_view.fetch_objects_to_compare( + sid=sid, did=did, scid=scid, tid=row['oid'], + oid=None) + data[module] = sub_data + + @staticmethod + def _check_rlspolicy_support(res): + """ + This function is used to check whether 'rlspolicy' in response + as it supported for version 9.5 and above + :param res: + :return: + """ + if 'rlspolicy' in res['rows'][0]: + # Set the value of rls policy + if res['rows'][0]['rlspolicy'] == "true": + res['rows'][0]['rlspolicy'] = True + + # Set the value of force rls policy for table owner + if res['rows'][0]['forcerlspolicy'] == "true": + res['rows'][0]['forcerlspolicy'] = True + + def _fetch_table_properties(self, did, scid, tid): + """ + This function is used to fetch the properties of the specified object + :param did: + :param scid: + :param tid: + :return: + """ + sql = render_template( + "/".join([self.table_template_path, self._PROPERTIES_SQL]), + did=did, scid=scid, tid=tid, + datlastsysoid=self.datlastsysoid + ) + status, res = self.conn.execute_dict(sql) + if not status: + return False, internal_server_error(errormsg=res) + + elif len(res['rows']) == 0: + return False, gone( + gettext(self.not_found_error_msg())) + + # Update autovacuum properties + self.update_autovacuum_properties(res['rows'][0]) + + # We will check the threshold set by user before executing + # the query because that can cause performance issues + # with large result set + pref = Preferences.module('browser') + table_row_count_pref = pref.preference('table_row_count_threshold') + table_row_count_threshold = table_row_count_pref.get() + estimated_row_count = int(res['rows'][0].get('reltuples', 0)) + + # Check whether 'rlspolicy' in response as it supported for + # version 9.5 and above + BaseTableView._check_rlspolicy_support(res) + + # If estimated rows are greater than threshold then + if estimated_row_count and \ + estimated_row_count > table_row_count_threshold: + res['rows'][0]['rows_cnt'] = str(table_row_count_threshold) + '+' + + # If estimated rows is lower than threshold then calculate the count + elif estimated_row_count and \ + table_row_count_threshold >= estimated_row_count: + sql = render_template( + "/".join( + [self.table_template_path, 'get_table_row_count.sql'] + ), data=res['rows'][0] + ) + + status, count = self.conn.execute_scalar(sql) + + if not status: + return False, internal_server_error(errormsg=count) + + res['rows'][0]['rows_cnt'] = count + + # If estimated_row_count is zero then set the row count with same + elif not estimated_row_count: + res['rows'][0]['rows_cnt'] = estimated_row_count + + return True, res + def _format_column_list(self, data): # Now we have all lis of columns which we need # to include in our create definition, Let's format them diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py index 297f05194..db455cd64 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/utils.py @@ -110,13 +110,15 @@ class DataTypeReader: """ # Check if template path is already set or not # if not then we will set the template path here + manager = conn.manager if not hasattr(self, 'manager') \ + else self.manager if not hasattr(self, 'data_type_template_path'): self.data_type_template_path = 'datatype/sql/' + ( '#{0}#{1}#'.format( - self.manager.server_type, - self.manager.version - ) if self.manager.server_type == 'gpdb' else - '#{0}#'.format(self.manager.version) + manager.server_type, + manager.version + ) if manager.server_type == 'gpdb' else + '#{0}#'.format(manager.version) ) sql = render_template( "/".join([self.data_type_template_path, 'get_types.sql']), @@ -701,3 +703,23 @@ def get_schema(sid, did, scid): ) return status, schema_name + + +def get_schemas(conn, show_system_objects=False): + """ + This function will return the schemas. + """ + + ver = conn.manager.version + server_type = conn.manager.server_type + + SQL = render_template( + "/".join(['schemas', + '{0}/#{1}#'.format(server_type, ver), + 'sql/nodes.sql']), + show_sysobj=show_system_objects, + schema_restrictions=None + ) + + status, rset = conn.execute_2darray(SQL) + return status, rset diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 6a97dd5ba..b937493f7 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -82,6 +82,10 @@ define('pgadmin.node.database', [ applies: ['object', 'context'], callback: 'disconnect_database', category: 'drop', priority: 5, label: gettext('Disconnect Database...'), icon: 'fa fa-unlink', enable : 'is_connected', + },{ + name: 'generate_erd', node: 'database', module: this, + applies: ['object', 'context'], callback: 'generate_erd', + category: 'erd', priority: 5, label: gettext('Generate ERD(Beta)...'), }]); _.bindAll(this, 'connection_lost'); @@ -236,6 +240,15 @@ define('pgadmin.node.database', [ return false; }, + /* Generate the ERD */ + generate_erd: function(args) { + var input = args || {}, + t = pgBrowser.tree, + i = input.item || t.selected(), + d = i && i.length == 1 ? t.itemData(i) : undefined; + pgBrowser.erd.showErdTool(d, i, true); + }, + /* Connect the database (if not connected), before opening this node */ beforeopen: function(item, data) { if(!data || data._type != 'database' || data.label == 'template0') { diff --git a/web/pgadmin/browser/templates/browser/js/utils.js b/web/pgadmin/browser/templates/browser/js/utils.js index 79fccaa03..8d35bfd25 100644 --- a/web/pgadmin/browser/templates/browser/js/utils.js +++ b/web/pgadmin/browser/templates/browser/js/utils.js @@ -68,6 +68,7 @@ define('pgadmin.browser.utils', braceMatching: '{{ editor_brace_matching }}' == 'True', is_indent_with_tabs: '{{ editor_indent_with_tabs }}' == 'True', app_name: '{{ app_name }}', + app_version_int: '{{ app_version_int}}', pg_libpq_version: {{pg_libpq_version|e}}, support_ssh_tunnel: '{{ support_ssh_tunnel }}' == 'True', logout_url: '{{logout_url}}', diff --git a/web/pgadmin/static/bundle/browser.js b/web/pgadmin/static/bundle/browser.js index 19549a137..14140a2fd 100644 --- a/web/pgadmin/static/bundle/browser.js +++ b/web/pgadmin/static/bundle/browser.js @@ -10,6 +10,7 @@ define('bundled_browser',[ 'pgadmin.browser', 'sources/browser/index', + 'top/tools/erd/static/js/index', ], function(pgBrowser) { pgBrowser.init(); }); diff --git a/web/pgadmin/static/js/backform.pgadmin.js b/web/pgadmin/static/js/backform.pgadmin.js index 3686ffe5b..59d24ac59 100644 --- a/web/pgadmin/static/js/backform.pgadmin.js +++ b/web/pgadmin/static/js/backform.pgadmin.js @@ -1465,6 +1465,10 @@ define([ collection: collection, node_info: self.model.node_info, }); + + if(data.beforeAdd) { + m = data.beforeAdd.apply(self, [m]); + } collection.add(m); var idx = collection.indexOf(m), diff --git a/web/pgadmin/static/js/backgrid.pgadmin.js b/web/pgadmin/static/js/backgrid.pgadmin.js index f94e7828c..675725e07 100644 --- a/web/pgadmin/static/js/backgrid.pgadmin.js +++ b/web/pgadmin/static/js/backgrid.pgadmin.js @@ -10,10 +10,10 @@ define([ 'sources/gettext', 'underscore', 'jquery', 'backbone', 'backform', 'backgrid', 'alertify', 'moment', 'bignumber', 'codemirror', 'sources/utils', 'sources/keyboard_shortcuts', 'sources/select2/configure_show_on_scroll', - 'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle', + 'sources/window', 'bootstrap.datetimepicker', 'backgrid.filter', 'bootstrap.toggle', ], function( gettext, _, $, Backbone, Backform, Backgrid, Alertify, moment, BigNumber, CodeMirror, - commonUtils, keyboardShortcuts, configure_show_on_scroll + commonUtils, keyboardShortcuts, configure_show_on_scroll, pgWindow ) { /* * Add mechanism in backgrid to render different types of cells in @@ -43,7 +43,7 @@ define([ // bind shortcut in cell edit mode _.extend(Backgrid.InputCellEditor.prototype.events, { 'keydown': function(e) { - let preferences = pgBrowser.get_preferences_for_module('browser'); + let preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('browser'); if(preferences && keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,e)) { pgBrowser.keyboardNavigation.bindAddGridRow(); } else { @@ -323,7 +323,7 @@ define([ }, events: { 'keydown': function (event) { - let preferences = pgBrowser.get_preferences_for_module('browser'); + let preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('browser'); if(preferences && keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,event)) { pgBrowser.keyboardNavigation.bindAddGridRow(); } @@ -764,7 +764,7 @@ define([ }, onKeyDown: function(e) { - let preferences = pgBrowser.get_preferences_for_module('browser'); + let preferences = pgWindow.default.pgAdmin.Browser.get_preferences_for_module('browser'); if(keyboardShortcuts.validateShortcutKeys(preferences.add_grid_row,e)) { pgBrowser.keyboardNavigation.bindAddGridRow(); } diff --git a/web/pgadmin/static/js/custom_prop_types.js b/web/pgadmin/static/js/custom_prop_types.js new file mode 100644 index 000000000..4e4f45b9b --- /dev/null +++ b/web/pgadmin/static/js/custom_prop_types.js @@ -0,0 +1,10 @@ +import PropTypes from 'prop-types'; + +const CustomPropTypes = { + ref: PropTypes.oneOfType([ + PropTypes.func, + PropTypes.shape({ current: PropTypes.instanceOf(Element) }), + ]), +}; + +export default CustomPropTypes; diff --git a/web/pgadmin/static/scss/_bootstrap.overrides.scss b/web/pgadmin/static/scss/_bootstrap.overrides.scss index 9b612757e..e6ffa247f 100644 --- a/web/pgadmin/static/scss/_bootstrap.overrides.scss +++ b/web/pgadmin/static/scss/_bootstrap.overrides.scss @@ -181,6 +181,15 @@ legend { } } +.btn-warning { + @include button-variant($color-warning, $color-warning-fg); + border-color: $color-warning; + @include hover() { + color: $color-warning-fg !important; + border-color: $color-warning !important; + } +} + .form-group fieldset { background-color: $color-gray-lighter; @@ -371,6 +380,11 @@ td.switch-cell > div.toggle { line-height: 0.7rem; } +.btn-xs { + @extend .btn-sm; + padding: 0.125rem 0.25rem !important; +} + .btn-toolbar { min-width: 100%; } diff --git a/web/pgadmin/static/scss/_pgadmin.style.scss b/web/pgadmin/static/scss/_pgadmin.style.scss index fadd71b7b..f8f2bcf99 100644 --- a/web/pgadmin/static/scss/_pgadmin.style.scss +++ b/web/pgadmin/static/scss/_pgadmin.style.scss @@ -886,6 +886,12 @@ table.table-noouter-border { border-bottom: $table-border-width solid transparent; } } + + &.table-noheader { + & > tbody tr:first-of-type td { + border-top: none !important; + } + } } table.table-bottom-border { diff --git a/web/pgadmin/static/scss/_tippy.overrides.scss b/web/pgadmin/static/scss/_tippy.overrides.scss new file mode 100644 index 000000000..9750434b7 --- /dev/null +++ b/web/pgadmin/static/scss/_tippy.overrides.scss @@ -0,0 +1,9 @@ +@import "~node_modules/tippy.js/dist/tippy.css"; + +.tippy-box { + background-color: $popover-bg; + color: $popover-body-color; + .tippy-arrow { + color: $popover-bg; + } +} diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss index 19e79adf2..cc751b77e 100644 --- a/web/pgadmin/static/scss/pgadmin.scss +++ b/web/pgadmin/static/scss/pgadmin.scss @@ -13,7 +13,6 @@ $theme-colors: ( } @import "node_modules/bootstrap/scss/bootstrap"; - @import 'webcabin.pgadmin'; @import 'bootstrap.overrides'; @import 'backgrid.overrides'; @@ -27,3 +26,4 @@ $theme-colors: ( @import 'pgadmin.style'; @import 'bootstrap4-toggle.overrides'; @import 'pickr.overrides'; +@import 'tippy.overrides'; diff --git a/web/pgadmin/static/scss/resources/_default.variables.scss b/web/pgadmin/static/scss/resources/_default.variables.scss index 9d913788d..b71c86a4c 100644 --- a/web/pgadmin/static/scss/resources/_default.variables.scss +++ b/web/pgadmin/static/scss/resources/_default.variables.scss @@ -111,8 +111,8 @@ $dropdown-spacer: .125rem; //no-change $dropdown-link-disabled-color: $text-muted; $nav-divider-margin-y: .25rem; -$popover-bg: $color-gray-dark !default; -$popover-body-color: $white !default; +$popover-bg: $color-fg !default; +$popover-body-color: $color-bg !default; $popover-border-color: $dropdown-border-color; $popover-box-shadow: $dropdown-box-shadow; @@ -349,3 +349,16 @@ $grid-hover-fg-color: $color-fg !default; $btn-copied-color-fg: $active-color !default; +/** ERD **/ +$erd-row-padding: 0.25rem; +$erd-node-border-color: $border-color !default; +$erd-canvas-bg: $color-bg !default; +$erd-canvas-grid: $color-gray !default; +$erd-link-color: $color-fg !default; +$erd-link-selected-color: $color-fg !default; + + +@function url-friendly-colour($colour) { + @return '%23' + str-slice('#{$colour}', 2, -1) +} +$erd-bg-grid: url("data:image/svg+xml, %3Csvg width='100%25' viewBox='0 0 45 45' style='background-color:#{url-friendly-colour($erd-canvas-bg)}' height='100%25' xmlns='http://www.w3.org/2000/svg'%3E%3Cdefs%3E%3Cpattern id='smallGrid' width='15' height='15' patternUnits='userSpaceOnUse'%3E%3Cpath d='M 15 0 L 0 0 0 15' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='0.5'/%3E%3C/pattern%3E%3Cpattern id='grid' width='45' height='45' patternUnits='userSpaceOnUse'%3E%3Crect width='100' height='100' fill='url(%23smallGrid)'/%3E%3Cpath d='M 100 0 L 0 0 0 100' fill='none' stroke='#{url-friendly-colour($erd-canvas-grid)}' stroke-width='1'/%3E%3C/pattern%3E%3C/defs%3E%3Crect width='100%25' height='100%25' fill='url(%23grid)' /%3E%3C/svg%3E%0A"); diff --git a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss index 129b9a214..d8ca65b50 100644 --- a/web/pgadmin/static/scss/resources/dark/_theme.variables.scss +++ b/web/pgadmin/static/scss/resources/dark/_theme.variables.scss @@ -121,3 +121,11 @@ $color-success-hover-fg: $color-fg; $datagrid-selected-color: $color-primary-fg; $select2-placeholder: #999; + +/* ERD */ +$erd-row-padding: 0.25rem; +$erd-node-border-color: $border-color; +$erd-canvas-bg: $color-gray-light; +$erd-canvas-grid: #444952; +$erd-link-color: $color-fg; +$erd-link-selected-color: $color-fg; diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 598ed52b4..46db6a70a 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -20,16 +20,17 @@ function isServerInformationAvailable(parentData) { return parentData.server === undefined; } -export function getPanelTitle(pgBrowser, selected_item=null, custom_title=null) { +export function getPanelTitle(pgBrowser, selected_item=null, custom_title=null, parentData=null) { var preferences = pgBrowser.get_preferences_for_module('browser'); - if(selected_item == null) { + if(selected_item == null && parentData == null) { selected_item = pgBrowser.treeMenu.selected(); } - const parentData = getTreeNodeHierarchyFromIdentifier - .call(pgBrowser, selected_item); - if (isServerInformationAvailable(parentData)) { - return; + if(parentData == null) { + parentData = getTreeNodeHierarchyFromIdentifier.call(pgBrowser, selected_item); + if (isServerInformationAvailable(parentData)) { + return; + } } const db_label = getDatabaseLabel(parentData); diff --git a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js b/web/pgadmin/tools/datagrid/static/js/show_query_tool.js index 90131dd40..867b739d8 100644 --- a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js +++ b/web/pgadmin/tools/datagrid/static/js/show_query_tool.js @@ -18,7 +18,7 @@ function hasDatabaseInformation(parentData) { return parentData.database; } -function generateUrl(trans_id, title, parentData) { +function generateUrl(trans_id, title, parentData, sqlId) { let url_endpoint = url_for('datagrid.panel', { 'trans_id': trans_id, }); @@ -32,6 +32,10 @@ function generateUrl(trans_id, title, parentData) { url_endpoint += `&did=${parentData.database._id}`; } + if(sqlId) { + url_endpoint += `&sql_id=${sqlId}`; + } + return url_endpoint; } @@ -85,6 +89,25 @@ export function generateScript(parentData, datagrid, alertify) { launchDataGrid(datagrid, transId, url_endpoint, queryToolTitle, '', alertify); } +export function showERDSqlTool(parentData, erdSqlId, queryToolTitle, datagrid, alertify) { + const transId = getRandomInt(1, 9999999); + parentData = { + server_group: { + _id: parentData.sgid, + }, + server: { + _id: parentData.sid, + server_type: parentData.stype, + }, + database: { + _id: parentData.did, + }, + }; + + const gridUrl = generateUrl(transId, queryToolTitle, parentData, erdSqlId); + launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, '', alertify); +} + export function launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, sURL, alertify) { let retVal = datagrid.launch_grid(transId, gridUrl, true, queryToolTitle, sURL); diff --git a/web/pgadmin/tools/erd/__init__.py b/web/pgadmin/tools/erd/__init__.py new file mode 100644 index 000000000..380dc12ec --- /dev/null +++ b/web/pgadmin/tools/erd/__init__.py @@ -0,0 +1,553 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +"""A blueprint module implementing the erd tool.""" +import simplejson as json + +from flask import url_for, request +from flask import render_template, current_app as app +from flask_security import login_required +from flask_babelex import gettext +from werkzeug.useragents import UserAgent +from pgadmin.utils import PgAdminModule, \ + SHORTCUT_FIELDS as shortcut_fields +from pgadmin.utils.ajax import make_json_response, bad_request, \ + internal_server_error +from pgadmin.model import Server +from config import PG_DEFAULT_DRIVER +from pgadmin.utils.driver import get_driver +from pgadmin.browser.utils import underscore_unescape +from pgadmin.browser.server_groups.servers.databases.schemas.utils \ + import get_schemas +from pgadmin.browser.server_groups.servers.databases.schemas.tables. \ + constraints.foreign_key import utils as fkey_utils +from pgadmin.utils.constants import PREF_LABEL_KEYBOARD_SHORTCUTS, \ + PREF_LABEL_DISPLAY +from .utils import ERDHelper +from pgadmin.utils.exception import ConnectionLost + +MODULE_NAME = 'erd' + + +class ERDModule(PgAdminModule): + """ + class ERDModule(PgAdminModule) + + A module class for ERD derived from PgAdminModule. + """ + + LABEL = gettext("ERD tool") + + def get_own_menuitems(self): + return {} + + def get_own_javascripts(self): + return [{ + 'name': 'pgadmin.erd', + 'path': url_for('erd.index') + "erd", + 'when': None + }] + + def get_panels(self): + return [] + + def get_exposed_url_endpoints(self): + """ + Returns: + list: URL endpoints + """ + return [ + 'erd.panel', + 'erd.initialize', + 'erd.prequisite', + 'erd.sql', + 'erd.tables', + 'erd.close' + ] + + def register_preferences(self): + self.preference.register( + 'keyboard_shortcuts', + 'open_project', + gettext('Open project'), + 'keyboardshortcut', + { + 'alt': False, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 79, + 'char': 'o' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'save_project', + gettext('Save project'), + 'keyboardshortcut', + { + 'alt': False, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 83, + 'char': 's' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'save_project_as', + gettext('Save project as'), + 'keyboardshortcut', + { + 'alt': False, + 'shift': True, + 'control': True, + 'key': { + 'key_code': 83, + 'char': 's' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'generate_sql', + gettext('Generate SQL'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 83, + 'char': 's' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'add_table', + gettext('Add table'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 65, + 'char': 'a' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'edit_table', + gettext('Edit table'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 69, + 'char': 'e' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'clone_table', + gettext('Clone table'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 67, + 'char': 'c' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'drop_table', + gettext('Drop table'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 68, + 'char': 'd' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'add_edit_note', + gettext('Add/Edit note'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 78, + 'char': 'n' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'one_to_many', + gettext('One to many link'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 79, + 'char': 'o' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'many_to_many', + gettext('Many to many link'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 77, + 'char': 'm' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'auto_align', + gettext('Auto align'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': False, + 'control': True, + 'key': { + 'key_code': 76, + 'char': 'l' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'zoom_to_fit', + gettext('Zoom to fit'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': True, + 'control': False, + 'key': { + 'key_code': 70, + 'char': 'f' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'zoom_in', + gettext('Zoom in'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': True, + 'control': False, + 'key': { + 'key_code': 187, + 'char': '+' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + self.preference.register( + 'keyboard_shortcuts', + 'zoom_out', + gettext('Zoom out'), + 'keyboardshortcut', + { + 'alt': True, + 'shift': True, + 'control': False, + 'key': { + 'key_code': 189, + 'char': '-' + } + }, + category_label=PREF_LABEL_KEYBOARD_SHORTCUTS, + fields=shortcut_fields + ) + + +blueprint = ERDModule(MODULE_NAME, __name__, static_url_path='/static') + + +@blueprint.route( + '/panel/', + methods=["POST"], + endpoint='panel' +) +@login_required +def panel(trans_id): + """ + This method calls index.html to render the erd tool. + + Args: + panel_title: Title of the panel + """ + + params = { + 'trans_id': trans_id, + 'title': request.form['title'] + } + if request.args: + params.update({k: v for k, v in request.args.items()}) + + if 'gen' in params: + params['gen'] = True if params['gen'] == 'true' else False + + close_url = request.form['close_url'] + + # We need client OS information to render correct Keyboard shortcuts + user_agent = UserAgent(request.headers.get('User-Agent')) + + """ + Animations and transitions are not automatically GPU accelerated and by + default use browser's slow rendering engine. We need to set 'translate3d' + value of '-webkit-transform' property in order to use GPU. After applying + this property under linux, Webkit calculates wrong position of the + elements so panel contents are not visible. To make it work, we need to + explicitly set '-webkit-transform' property to 'none' for .ajs-notifier, + .ajs-message, .ajs-modal classes. + + This issue is only with linux runtime application and observed in Query + tool and debugger. When we open 'Open File' dialog then whole Query tool + panel content is not visible though it contains HTML element in back end. + + The port number should have already been set by the runtime if we're + running in desktop mode. + """ + is_linux_platform = False + + from sys import platform as _platform + if "linux" in _platform: + is_linux_platform = True + + s = Server.query.filter_by(id=params['sid']).first() + + params.update({ + 'bgcolor': s.bgcolor, + 'fgcolor': s.fgcolor, + 'client_platform': user_agent.platform, + 'is_desktop_mode': app.PGADMIN_RUNTIME, + 'is_linux': is_linux_platform + }) + + return render_template( + "erd/index.html", + title=underscore_unescape(params['title']), + close_url=close_url, + params=json.dumps(params), + ) + + +@blueprint.route( + '/initialize////', + methods=["POST"], endpoint='initialize' +) +@login_required +def initialize_erd(trans_id, sgid, sid, did): + """ + This method is responsible for instantiating and initializing + the erd tool object. It will also create a unique + transaction id and store the information into session variable. + + Args: + sgid: Server group Id + sid: Server Id + did: Database Id + """ + # Read the data if present. Skipping read may cause connection + # reset error if data is sent from the client + if request.data: + _ = request.data + + conn = _get_connection(sid, did, trans_id) + + return make_json_response( + data={ + 'connId': str(trans_id), + 'serverVersion': conn.manager.version, + } + ) + + +def _get_connection(sid, did, trans_id): + """ + Get the connection object of ERD. + :param sid: + :param did: + :param trans_id: + :return: + """ + manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid) + try: + conn = manager.connection(did=did, conn_id=trans_id, + auto_reconnect=True, + use_binary_placeholder=True) + status, msg = conn.connect() + if not status: + app.logger.error(msg) + raise ConnectionLost(sid, conn.db, trans_id) + + return conn + except Exception as e: + app.logger.error(e) + raise + + +@blueprint.route('/prequisite////', + methods=["GET"], + endpoint='prequisite') +@login_required +def prequisite(trans_id, sgid, sid, did): + conn = _get_connection(sid, did, trans_id) + helper = ERDHelper(trans_id, sid, did) + status, col_types = helper.get_types() + + if not status: + return internal_server_error(errormsg=col_types) + + status, schemas = get_schemas(conn, show_system_objects=False) + + if not status: + return internal_server_error(errormsg=schemas) + + return make_json_response( + data={ + 'col_types': col_types, + 'schemas': schemas['rows'] + }, + status=200 + ) + + +@blueprint.route('/sql////', + methods=["POST"], + endpoint='sql') +@login_required +def sql(trans_id, sgid, sid, did): + data = json.loads(request.data, encoding='utf-8') + helper = ERDHelper(trans_id, sid, did) + conn = _get_connection(sid, did, trans_id) + + sql = '' + for tab_key, tab_data in data.get('nodes', {}).items(): + sql += '\n\n' + helper.get_table_sql(tab_data) + + for link_key, link_data in data.get('links', {}).items(): + link_sql, name = fkey_utils.get_sql(conn, link_data, None) + sql += '\n\n' + link_sql + + return make_json_response( + data=sql, + status=200 + ) + + +@blueprint.route('/tables////', + methods=["GET"], + endpoint='tables') +@login_required +def tables(trans_id, sgid, sid, did): + helper = ERDHelper(trans_id, sid, did) + status, tables = helper.get_all_tables() + + if not status: + return internal_server_error(errormsg=tables) + + return make_json_response( + data=tables, + status=200 + ) + + +@blueprint.route('/close////', + methods=["DELETE"], + endpoint='close') +@login_required +def close(trans_id, sgid, sid, did): + manager = get_driver( + PG_DEFAULT_DRIVER).connection_manager(sid) + if manager is not None: + conn = manager.connection(did=did, conn_id=trans_id) + + # Release the connection + if conn.connected(): + conn.cancel_transaction(trans_id, did=did) + manager.release(did=did, conn_id=trans_id) + return make_json_response(data={'status': True}) diff --git a/web/pgadmin/tools/erd/static/js/erd_module.js b/web/pgadmin/tools/erd/static/js/erd_module.js new file mode 100644 index 000000000..6aa22a869 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_module.js @@ -0,0 +1,215 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import Alertify from 'pgadmin.alertifyjs'; +import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; +import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; +import {getRandomInt} from 'sources/utils'; + + +export function setPanelTitle(erdToolPanel, panelTitle) { + erdToolPanel.title(''+panelTitle+''); +} + +export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser, wcDocker) { + /* Return back, this has been called more than once */ + if (pgBrowser.erd) + return pgBrowser.erd; + + pgBrowser.erd = { + init: function() { + if (this.initialized) + return; + + this.initialized = true; + csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + + + // Define the nodes on which the menus to be appear + var menus = [{ + name: 'erd', + module: this, + applies: ['tools'], + callback: 'showErdTool', + priority: 1, + label: gettext('New ERD project(Beta)'), + enable: this.erdToolEnabled, + }]; + + pgBrowser.add_menus(menus); + + // Creating a new pgBrowser frame to show the data. + var erdFrameType = new pgBrowser.Frame({ + name: 'frm_erdtool', + showTitle: true, + isCloseable: true, + isPrivate: true, + url: 'about:blank', + }); + + let self = this; + /* Cache may take time to load for the first time + * Keep trying till available + */ + let cacheIntervalId = setInterval(function() { + if(pgBrowser.preference_version() > 0) { + self.preferences = pgBrowser.get_preferences_for_module('erd'); + clearInterval(cacheIntervalId); + } + },0); + + pgBrowser.onPreferencesChange('erd', function() { + self.preferences = pgBrowser.get_preferences_for_module('erd'); + }); + + // Load the newly created frame + erdFrameType.load(pgBrowser.docker); + return this; + }, + + erdToolEnabled: function(obj) { + /* Same as query tool */ + var isEnabled = (() => { + if (!_.isUndefined(obj) && !_.isNull(obj)) { + if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) { + if (obj._type == 'database' && obj.allowConn) { + return true; + } else if (obj._type != 'database') { + return true; + } else { + return false; + } + } else { + return false; + } + } else { + return false; + } + })(); + return isEnabled; + }, + + // Callback to draw schema diff for objects + showErdTool: function(data, aciTreeIdentifier, gen=false) { + const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + if (node === undefined || !node.getData()) { + Alertify.alert( + gettext('ERD Error'), + gettext('No object selected.') + ); + return; + } + + const parentData = getTreeNodeHierarchyFromIdentifier.call( + pgBrowser, + aciTreeIdentifier + ); + + if(_.isUndefined(parentData.database)) { + Alertify.alert( + gettext('ERD Error'), + gettext('Please select a database/database object.') + ); + return; + } + + const transId = getRandomInt(1, 9999999); + const panelTitle = getPanelTitle(pgBrowser, aciTreeIdentifier); + const [panelUrl, panelCloseUrl] = this.getPanelUrls(transId, panelTitle, parentData, gen); + + let erdToolForm = ` +
+ + +
+ + `; + + var open_new_tab = pgBrowser.get_preferences_for_module('browser').new_browser_tab_open; + if (open_new_tab && open_new_tab.includes('erd_tool')) { + var newWin = window.open('', '_blank'); + newWin.document.write(erdToolForm); + newWin.document.title = panelTitle; + } else { + /* On successfully initialization find the dashboard panel, + * create new panel and add it to the dashboard panel. + */ + var propertiesPanel = pgBrowser.docker.findPanels('properties'); + var erdToolPanel = pgBrowser.docker.addPanel('frm_erdtool', wcDocker.DOCK.STACKED, propertiesPanel[0]); + + // Set panel title and icon + setPanelTitle(erdToolPanel, 'Untitled'); + erdToolPanel.icon('fa fa-sitemap'); + erdToolPanel.focus(); + + // Listen on the panel closed event. + erdToolPanel.on(wcDocker.EVENT.CLOSED, function() { + $.ajax({ + url: panelCloseUrl, + method: 'DELETE', + }); + }); + + var openErdToolURL = function(j) { + // add spinner element + let $spinner_el = + $(`
+
+
+
+
+
+
`).appendTo($(j).data('embeddedFrame').$container); + + let init_poller_id = setInterval(function() { + var frameInitialized = $(j).data('frameInitialized'); + if (frameInitialized) { + clearInterval(init_poller_id); + var frame = $(j).data('embeddedFrame'); + if (frame) { + frame.onLoaded(()=>{ + $spinner_el.remove(); + }); + frame.openHTML(erdToolForm); + } + } + }, 100); + }; + + openErdToolURL(erdToolPanel); + } + }, + + getPanelUrls: function(transId, panelTitle, parentData, gen) { + let openUrl = url_for('erd.panel', { + trans_id: transId, + }); + + openUrl += `?sgid=${parentData.server_group._id}` + +`&sid=${parentData.server._id}` + +`&server_type=${parentData.server.server_type}` + +`&did=${parentData.database._id}` + +`&gen=${gen}`; + + let closeUrl = url_for('erd.close', { + trans_id: transId, + sgid: parentData.server_group._id, + sid: parentData.server._id, + did: parentData.database._id, + }); + + return [openUrl, closeUrl]; + }, + }; + + return pgBrowser.erd; +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js new file mode 100644 index 000000000..5cbec4974 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ERDCore.js @@ -0,0 +1,395 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +/* + * The ERDCore is the middleware between the canvas engine and the UI DOM. + */ +import createEngine from '@projectstorm/react-diagrams'; +import {DagreEngine, PathFindingLinkFactory, PortModelAlignment} from '@projectstorm/react-diagrams'; +import { ZoomCanvasAction } from '@projectstorm/react-canvas-core'; + +import {TableNodeFactory, TableNodeModel } from './nodes/TableNode'; +import {OneToManyLinkFactory, OneToManyLinkModel } from './links/OneToManyLink'; +import { OneToManyPortFactory } from './ports/OneToManyPort'; +import ERDModel from './ERDModel'; + +export default class ERDCore { + constructor() { + this._cache = {}; + this.table_counter = 1; + this.node_position_updating = false; + this.link_position_updating = false; + this.initializeEngine(); + this.initializeModel(); + this.computeTableCounter(); + } + + initializeEngine() { + this.engine = createEngine({ + registerDefaultDeleteItemsAction: false, + registerDefaultZoomCanvasAction: false, + }); + this.dagre_engine = new DagreEngine({ + graph: { + marginx: 5, + marginy: 5, + }, + includeLinks: true, + }); + + this.engine.getNodeFactories().registerFactory(new TableNodeFactory()); + this.engine.getLinkFactories().registerFactory(new OneToManyLinkFactory()); + this.engine.getPortFactories().registerFactory(new OneToManyPortFactory()); + this.registerKeyAction(new ZoomCanvasAction({inverseZoom: true})); + } + + initializeModel(data, callback=()=>{}) { + let model = new ERDModel(); + if(data) { + model.deserializeModel(data, this.engine); + } + + const registerNodeEvents = (node) => { + node.registerListener({ + eventDidFire: (e) => { + if(e.function === 'selectionChanged') { + this.fireEvent({}, 'nodesSelectionChanged', true); + } + else if(e.function === 'showNote') { + this.fireEvent({node: e.entity}, 'showNote', true); + } + else if(e.function === 'editNode') { + this.fireEvent({node: e.entity}, 'editNode', true); + } + else if(e.function === 'nodeUpdated') { + this.fireEvent({}, 'nodesUpdated', true); + } + else if(e.function === 'positionChanged') { + /* Eat up the excessive positionChanged events if node is dragged continuosly */ + if(!this.node_position_updating) { + this.node_position_updating = true; + this.fireEvent({}, 'nodesUpdated', true); + setTimeout(()=>{ + this.node_position_updating = false; + }, 500); + } + } + }, + }); + }; + + const registerLinkEvents = (link) => { + link.registerListener({ + eventDidFire: (e) => { + if(e.function === 'selectionChanged') { + this.fireEvent({}, 'linksSelectionChanged', true); + } + else if(e.function === 'positionChanged') { + /* positionChanged is triggered manually in Link */ + /* Eat up the excessive positionChanged events if link is dragged continuosly */ + if(!this.link_position_updating) { + this.link_position_updating = true; + this.fireEvent({}, 'linksUpdated', true); + setTimeout(()=>{ + this.link_position_updating = false; + }, 500); + } + } + }, + }); + }; + + /* Register events for deserialized data */ + model.getNodes().forEach(node => { + registerNodeEvents(node); + }); + model.getLinks().forEach(link => { + registerLinkEvents(link); + }); + + /* Listen and register events for new data */ + model.registerListener({ + 'nodesUpdated': (e)=>{ + if(e.isCreated) { + registerNodeEvents(e.node); + } + }, + 'linksUpdated': (e)=>{ + if(e.isCreated) { + registerLinkEvents(e.link); + } + }, + }); + + model.setGridSize(15); + this.engine.setModel(model); + callback(); + } + + computeTableCounter() { + /* Some inteligence can be added to set the counter */ + this.table_counter = 1; + } + + setCache(data, value) { + if(typeof(data) == 'string') { + this._cache[data] = value; + } else { + this._cache = { + ...this._cache, + ...data, + }; + } + } + + getCache(key) { + return key ? this._cache[key]: this._cache; + } + + registerModelEvent(eventName, callback) { + this.getModel().registerListener({ + [eventName]: callback, + }); + } + + getNextTableName() { + let newTableName = `newtable${this.table_counter}`; + this.table_counter++; + return newTableName; + } + + getEngine() {return this.engine;} + + getModel() {return this.getEngine().getModel();} + + getNewNode(initData) { + return this.getEngine().getNodeFactories().getFactory('table').generateModel({ + initialConfig: { + otherInfo: { + data:initData, + }, + }, + }); + } + + getNewLink(type, initData) { + return this.getEngine().getLinkFactories().getFactory(type).generateModel({ + initialConfig: { + data:initData, + }, + }); + } + + getNewPort(type, initData, initOptions) { + return this.getEngine().getPortFactories().getFactory(type).generateModel({ + initialConfig: { + data:initData, + options:initOptions, + }, + }); + } + + addNode(data, position=[50, 50]) { + let newNode = this.getNewNode(data); + this.clearSelection(); + newNode.setPosition(position[0], position[1]); + this.getModel().addNode(newNode); + return newNode; + } + + addLink(data, type) { + let tableNodesDict = this.getModel().getNodesDict(); + let sourceNode = tableNodesDict[data.referenced_table_uid]; + let targetNode = tableNodesDict[data.local_table_uid]; + + let portName = sourceNode.getPortName(data.referenced_column_attnum); + let sourcePort = sourceNode.getPort(portName); + /* Create the port if not there */ + if(!sourcePort) { + sourcePort = sourceNode.addPort(this.getNewPort(type, null, {name:portName, alignment:PortModelAlignment.RIGHT})); + } + + portName = targetNode.getPortName(data.local_column_attnum); + let targetPort = targetNode.getPort(portName); + /* Create the port if not there */ + if(!targetPort) { + targetPort = targetNode.addPort(this.getNewPort(type, null, {name:portName, alignment:PortModelAlignment.RIGHT})); + } + + /* Link the ports */ + let newLink = this.getNewLink(type, data); + newLink.setSourcePort(sourcePort); + newLink.setTargetPort(targetPort); + this.getModel().addLink(newLink); + return newLink; + } + + serialize(version) { + return { + version: version||0, + data: this.getModel().serialize(), + }; + } + + deserialize(json_data) { + if(json_data.version) { + this.initializeModel(json_data.data); + } + } + + serializeData() { + let nodes = {}, links = {}; + let nodesDict = this.getModel().getNodesDict(); + + Object.keys(nodesDict).forEach((id)=>{ + nodes[id] = nodesDict[id].serializeData(); + }); + + this.getModel().getLinks().map((link)=>{ + links[link.getID()] = link.serializeData(nodesDict); + }); + + /* Separate the links from nodes so that we don't have any dependancy issues */ + return { + 'nodes': nodes, + 'links': links, + }; + } + + deserializeData(data){ + let oidUidMap = {}; + let uidFks = []; + data.forEach((node)=>{ + let newData = { + name: node.name, + schema: node.schema, + description: node.description, + columns: node.columns, + primary_key: node.primary_key, + }; + let newNode = this.addNode(newData); + oidUidMap[node.oid] = newNode.getID(); + if(node.foreign_key) { + node.foreign_key.forEach((a_fk)=>{ + uidFks.push({ + uid: newNode.getID(), + data: a_fk.columns[0], + }); + }); + } + }); + + /* Lets use the oidUidMap for creating the links */ + uidFks.forEach((fkData)=>{ + let tableNodesDict = this.getModel().getNodesDict(); + let newData = { + local_table_uid: fkData.uid, + local_column_attnum: undefined, + referenced_table_uid: oidUidMap[fkData.data.references], + referenced_column_attnum: undefined, + }; + + let sourceNode = tableNodesDict[newData.referenced_table_uid]; + let targetNode = tableNodesDict[newData.local_table_uid]; + + newData.local_column_attnum = _.find(targetNode.getColumns(), (col)=>col.name==fkData.data.local_column).attnum; + newData.referenced_column_attnum = _.find(sourceNode.getColumns(), (col)=>col.name==fkData.data.referenced).attnum; + + this.addLink(newData, 'onetomany'); + }); + setTimeout(this.dagreDistributeNodes.bind(this), 0); + } + + repaint() { + this.getEngine().repaintCanvas(); + } + + clearSelection() { + this.getEngine() + .getModel() + .clearSelection(); + } + + getNodesData() { + return this.getEngine().getModel().getNodes().map((node)=>{ + return node.getData(); + }); + } + + getSelectedNodes() { + return this.getEngine() + .getModel() + .getSelectedEntities() + .filter(entity => entity instanceof TableNodeModel); + } + + getSelectedLinks() { + return this.getEngine() + .getModel() + .getSelectedEntities() + .filter(entity => entity instanceof OneToManyLinkModel); + } + + dagreDistributeNodes() { + this.dagre_engine.redistribute(this.getModel()); + this.getEngine() + .getLinkFactories() + .getFactory(PathFindingLinkFactory.NAME) + .calculateRoutingMatrix(); + this.repaint(); + } + + zoomIn() { + let model = this.getEngine().getModel(); + if(model){ + model.setZoomLevel(model.getZoomLevel() + 25); + this.repaint(); + } + } + + zoomOut() { + let model = this.getEngine().getModel(); + if(model) { + model.setZoomLevel(model.getZoomLevel() - 25); + this.repaint(); + } + } + + zoomToFit() { + this.getEngine().zoomToFit(); + } + + // Sample call: this.fireAction({ type: 'keydown', ctrlKey: true, code: 'KeyN' }); + fireAction(event) { + this.getEngine().getActionEventBus().fireAction({ + event: { + ...event, + key: '', + preventDefault: () => {}, + stopPropagation: () => {}, + }, + }); + } + + fireEvent(data, eventName, model=false) { + if(model) { + this.getEngine().getModel().fireEvent(data, eventName); + } else { + this.getEngine().fireEvent(data, eventName); + } + } + + registerKeyAction(action) { + this.getEngine().getActionEventBus().registerAction(action); + } + + deregisterKeyAction(action) { + this.getEngine().getActionEventBus().deregisterAction(action); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ERDModel.js b/web/pgadmin/tools/erd/static/js/erd_tool/ERDModel.js new file mode 100644 index 000000000..ae73db8ac --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ERDModel.js @@ -0,0 +1,21 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import { DiagramModel } from '@projectstorm/react-diagrams'; +import _ from 'lodash'; + +export default class ERDModel extends DiagramModel { + constructor(options) { + super(options); + } + + getNodesDict() { + return _.fromPairs(this.getNodes().map(node => [node.getID(), node])); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js new file mode 100644 index 000000000..9b6e54fa9 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/DialogWrapper.js @@ -0,0 +1,158 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import * as commonUtils from 'sources/utils'; + +export default class DialogWrapper { + constructor(dialogContainerSelector, dialogTitle, typeOfDialog, + jquery, pgBrowser, alertify, backform, backgrid) { + + this.dialogContainerSelector = dialogContainerSelector; + this.dialogTitle = dialogTitle; + this.jquery = jquery; + this.pgBrowser = pgBrowser; + this.alertify = alertify; + this.backform = backform; + this.backgrid = backgrid; + this.typeOfDialog = typeOfDialog; + } + + main(title, dialogModel, okCallback) { + this.set('title', title); + this.dialogModel = dialogModel; + this.okCallback = okCallback; + } + + build() { + this.alertify.pgDialogBuild.apply(this); + } + + disableOKButton() { + this.__internal.buttons[1].element.disabled = true; + } + + enableOKButton() { + this.__internal.buttons[1].element.disabled = false; + } + + focusOnDialog(alertifyDialog) { + let backform_tab = this.jquery(alertifyDialog.elements.body).find('.backform-tab'); + backform_tab.attr('tabindex', -1); + this.pgBrowser.keyboardNavigation.getDialogTabNavigator(this.jquery(alertifyDialog.elements.dialog)); + let container = backform_tab.find('.tab-content:first > .tab-pane.active:first'); + + if(container.length === 0 && alertifyDialog.elements.content.innerHTML) { + container = this.jquery(alertifyDialog.elements.content); + } + commonUtils.findAndSetFocus(container); + } + + setup() { + return { + buttons: [{ + text: gettext('Cancel'), + key: 27, + className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button', + 'data-btn-name': 'cancel', + }, { + text: gettext('OK'), + key: 13, + className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button', + 'data-btn-name': 'ok', + }], + // Set options for dialog + options: { + title: this.dialogTitle, + //disable both padding and overflow control. + padding: !1, + overflow: !1, + model: 0, + resizable: true, + maximizable: true, + pinnable: false, + closableByDimmer: false, + modal: false, + }, + }; + } + + prepare() { + const $container = this.jquery(this.dialogContainerSelector); + const dialog = this.createDialog($container); + dialog.render(); + this.elements.content.innerHTML = ''; + this.elements.content.appendChild($container.get(0)); + this.jquery(this.elements.body.childNodes[0]).addClass( + 'alertify_tools_dialog_properties obj_properties' + ); + const statusBar = this.jquery( + '
' + + ' ' + + '
').appendTo($container); + + statusBar.find('.close-error').on('click', ()=>{ + statusBar.addClass('d-none'); + }); + + var onSessionInvalid = (msg) => { + statusBar.find('.alert-text').text(msg); + statusBar.removeClass('d-none'); + this.disableOKButton(); + return true; + }; + + var onSessionValidated = () => { + statusBar.find('.alert-text').text(''); + statusBar.addClass('d-none'); + this.enableOKButton(); + return true; + }; + + this.dialogModel.on('pgadmin-session:valid', onSessionValidated); + this.dialogModel.on('pgadmin-session:invalid', onSessionInvalid); + this.dialogModel.startNewSession(); + this.disableOKButton(); + this.focusOnDialog(this); + } + + callback(event) { + if (this.wasOkButtonPressed(event)) { + this.okCallback(this.view.model.toJSON(true)); + } + } + + createDialog($container) { + let fields = this.backform.generateViewSchema( + null, this.dialogModel, 'create', null, null, true, null + ); + + this.view = new this.backform.Dialog({ + el: $container, + model: this.dialogModel, + schema: fields, + }); + + return this.view; + } + + wasOkButtonPressed(event) { + return event.button['data-btn-name'] === 'ok'; + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/ManyToManyDialog.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/ManyToManyDialog.js new file mode 100644 index 000000000..abec79f5e --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/ManyToManyDialog.js @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import Backform from 'sources/backform.pgadmin'; +import Alertify from 'pgadmin.alertifyjs'; +import $ from 'jquery'; + +import DialogWrapper from './DialogWrapper'; +import _ from 'lodash'; + +export default class ManyToManyDialog { + constructor(pgBrowser) { + this.pgBrowser = pgBrowser; + } + + dialogName() { + return 'manytomany_dialog'; + } + + getDataModel(attributes, tableNodesDict) { + const parseColumns = (columns)=>{ + return columns.map((col)=>{ + return { + value: col.attnum, label: col.name, + }; + }); + }; + + let dialogModel = this.pgBrowser.DataModel.extend({ + defaults: { + left_table_uid: undefined, + left_table_column_attnum: undefined, + right_table_uid: undefined, + right_table_column_attnum: undefined, + }, + schema: [{ + id: 'left_table_uid', label: gettext('Left Table'), + type: 'select2', readonly: true, + options: ()=>{ + let retOpts = []; + _.forEach(tableNodesDict, (node, uid)=>{ + let [schema, name] = node.getSchemaTableName(); + retOpts.push({value: uid, label: `(${schema}) ${name}`}); + }); + return retOpts; + }, + }, { + id: 'left_table_column_attnum', label: gettext('Left table Column'), + type: 'select2', disabled: false, first_empty: false, + editable: true, options: (view)=>{ + return parseColumns(tableNodesDict[view.model.get('left_table_uid')].getColumns()); + }, + },{ + id: 'right_table_uid', label: gettext('Right Table'), + type: 'select2', disabled: false, + editable: true, options: (view)=>{ + let retOpts = []; + _.forEach(tableNodesDict, (node, uid)=>{ + if(uid === view.model.get('left_table_uid')) { + return; + } + let [schema, name] = node.getSchemaTableName(); + retOpts.push({value: uid, label: `(${schema}) ${name}`}); + }); + return retOpts; + }, + },{ + id: 'right_table_column_attnum', label: gettext('Right table Column'), + type: 'select2', disabled: false, deps: ['right_table_uid'], + editable: true, options: (view)=>{ + if(view.model.get('right_table_uid')) { + return parseColumns(tableNodesDict[view.model.get('right_table_uid')].getColumns()); + } + return []; + }, + }], + validate: function(keys) { + var msg = undefined; + + // Nothing to validate + if (keys && keys.length == 0) { + this.errorModel.clear(); + return null; + } else { + this.errorModel.clear(); + } + + if (_.isUndefined(this.get('left_table_column_attnum')) || this.get('left_table_column_attnum') == '') { + msg = gettext('Select the left table column.'); + this.errorModel.set('left_table_column_attnum', msg); + return msg; + } + if (_.isUndefined(this.get('right_table_uid')) || this.get('right_table_uid') == '') { + msg = gettext('Select the right table.'); + this.errorModel.set('right_table_uid', msg); + return msg; + } + if (_.isUndefined(this.get('right_table_column_attnum')) || this.get('right_table_column_attnum') == '') { + msg = gettext('Select the right table column.'); + this.errorModel.set('right_table_column_attnum', msg); + return msg; + } + }, + }); + + return new dialogModel(attributes); + } + + createOrGetDialog(title) { + const dialogName = this.dialogName(); + + if (!Alertify[dialogName]) { + Alertify.dialog(dialogName, () => { + return new DialogWrapper( + `
`, + title, + null, + $, + this.pgBrowser, + Alertify, + Backform + ); + }); + } + return Alertify[dialogName]; + } + + show(title, attributes, tablesData, sVersion, callback) { + let dialogTitle = title || gettext('Unknown'); + const dialog = this.createOrGetDialog('manytomany_dialog'); + dialog(dialogTitle, this.getDataModel(attributes, tablesData), callback).resizeTo(this.pgBrowser.stdW.sm, this.pgBrowser.stdH.md); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/OneToManyDialog.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/OneToManyDialog.js new file mode 100644 index 000000000..0f4a9ce3e --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/OneToManyDialog.js @@ -0,0 +1,140 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import Backform from 'sources/backform.pgadmin'; +import Alertify from 'pgadmin.alertifyjs'; +import $ from 'jquery'; + +import DialogWrapper from './DialogWrapper'; +import _ from 'lodash'; + +export default class OneToManyDialog { + constructor(pgBrowser) { + this.pgBrowser = pgBrowser; + } + + dialogName() { + return 'onetomany_dialog'; + } + + getDataModel(attributes, tableNodesDict) { + const parseColumns = (columns)=>{ + return columns.map((col)=>{ + return { + value: col.attnum, label: col.name, + }; + }); + }; + + let dialogModel = this.pgBrowser.DataModel.extend({ + defaults: { + local_table_uid: undefined, + local_column_attnum: undefined, + referenced_table_uid: undefined, + referenced_column_attnum: undefined, + }, + schema: [{ + id: 'local_table_uid', label: gettext('Local Table'), + type: 'select2', readonly: true, + options: ()=>{ + let retOpts = []; + _.forEach(tableNodesDict, (node, uid)=>{ + let [schema, name] = node.getSchemaTableName(); + retOpts.push({value: uid, label: `(${schema}) ${name}`}); + }); + return retOpts; + }, + }, { + id: 'local_column_attnum', label: gettext('Local Column'), + type: 'select2', disabled: false, first_empty: false, + editable: true, options: (view)=>{ + return parseColumns(tableNodesDict[view.model.get('local_table_uid')].getColumns()); + }, + },{ + id: 'referenced_table_uid', label: gettext('Referenced Table'), + type: 'select2', disabled: false, + editable: true, options: (view)=>{ + let retOpts = []; + _.forEach(tableNodesDict, (node, uid)=>{ + if(uid === view.model.get('local_table_uid')) { + return; + } + let [schema, name] = node.getSchemaTableName(); + retOpts.push({value: uid, label: `(${schema}) ${name}`}); + }); + return retOpts; + }, + },{ + id: 'referenced_column_attnum', label: gettext('Referenced Column'), + type: 'select2', disabled: false, deps: ['referenced_table_uid'], + editable: true, options: (view)=>{ + if(view.model.get('referenced_table_uid')) { + return parseColumns(tableNodesDict[view.model.get('referenced_table_uid')].getColumns()); + } + return []; + }, + }], + validate: function(keys) { + var msg = undefined; + + // Nothing to validate + if (keys && keys.length == 0) { + this.errorModel.clear(); + return null; + } else { + this.errorModel.clear(); + } + + if (_.isUndefined(this.get('local_column_attnum')) || this.get('local_column_attnum') == '') { + msg = gettext('Select the local column.'); + this.errorModel.set('local_column_attnum', msg); + return msg; + } + if (_.isUndefined(this.get('referenced_table_uid')) || this.get('referenced_table_uid') == '') { + msg = gettext('Select the referenced table.'); + this.errorModel.set('referenced_table_uid', msg); + return msg; + } + if (_.isUndefined(this.get('referenced_column_attnum')) || this.get('referenced_column_attnum') == '') { + msg = gettext('Select the referenced table column.'); + this.errorModel.set('referenced_column_attnum', msg); + return msg; + } + }, + }); + + return new dialogModel(attributes); + } + + createOrGetDialog(title) { + const dialogName = this.dialogName(); + + if (!Alertify[dialogName]) { + Alertify.dialog(dialogName, () => { + return new DialogWrapper( + `
`, + title, + null, + $, + this.pgBrowser, + Alertify, + Backform + ); + }); + } + return Alertify[dialogName]; + } + + show(title, attributes, tablesData, sVersion, callback) { + let dialogTitle = title || gettext('Unknown'); + const dialog = this.createOrGetDialog('onetomany_dialog'); + dialog(dialogTitle, this.getDataModel(attributes, tablesData), callback).resizeTo(this.pgBrowser.stdW.sm, this.pgBrowser.stdH.md); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/TableDialog.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/TableDialog.js new file mode 100644 index 000000000..1b6bb99b7 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/TableDialog.js @@ -0,0 +1,739 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import gettext from 'sources/gettext'; +import Backgrid from 'sources/backgrid.pgadmin'; +import Backform from 'sources/backform.pgadmin'; +import Alertify from 'pgadmin.alertifyjs'; +import $ from 'jquery'; +import _ from 'lodash'; + +import DialogWrapper from './DialogWrapper'; + +export function transformToSupported(data) { + /* Table fields */ + data = _.pick(data, ['oid', 'name', 'schema', 'description', 'columns', 'primary_key', 'foreign_key']); + + /* Columns */ + data['columns'] = data['columns'].map((column)=>{ + return _.pick(column,[ + 'name','description','attowner','attnum','cltype','min_val_attlen','min_val_attprecision','max_val_attlen', + 'max_val_attprecision', 'is_primary_key','attnotnull','attlen','attprecision','attidentity','colconstype', + 'seqincrement','seqstart','seqmin','seqmax','seqcache','seqcycle', + ]); + }); + + /* Primary key */ + data['primary_key'] = data['primary_key'].map((primary_key)=>{ + primary_key = _.pick(primary_key, ['columns']); + primary_key['columns'] = primary_key['columns'].map((column)=>{ + return _.pick(column, ['column']); + }); + return primary_key; + }); + + return data; +} + +export default class TableDialog { + constructor(pgBrowser) { + this.pgBrowser = pgBrowser; + } + + dialogName() { + return 'entity_dialog'; + } + + getDataModel(attributes, colTypes, schemas, sVersion) { + let dialogObj = this; + let columnsModel = this.pgBrowser.DataModel.extend({ + idAttribute: 'attnum', + defaults: { + name: undefined, + description: undefined, + attowner: undefined, + attnum: undefined, + cltype: undefined, + min_val_attlen: undefined, + min_val_attprecision: undefined, + max_val_attlen: undefined, + max_val_attprecision: undefined, + is_primary_key: false, + attnotnull: false, + attlen: null, + attprecision: null, + attidentity: 'a', + colconstype: 'n', + seqincrement: undefined, + seqstart: undefined, + seqmin: undefined, + seqmax: undefined, + seqcache: undefined, + seqcycle: undefined, + }, + initialize: function(attrs) { + if (_.size(attrs) !== 0) { + this.set({ + 'old_attidentity': this.get('attidentity'), + }, {silent: true}); + } + dialogObj.pgBrowser.DataModel.prototype.initialize.apply(this, arguments); + + if(!this.get('cltype') && colTypes.length > 0) { + this.set({ + 'cltype': colTypes[0]['value'], + }, {silent: true}); + } + }, + schema: [{ + id: 'name', label: gettext('Name'), cell: 'string', + type: 'text', disabled: false, + cellHeaderClasses: 'width_percent_30', + editable: true, + }, { + // Need to show this field only when creating new table + // [in SubNode control] + id: 'is_primary_key', label: gettext('Primary key?'), + cell: Backgrid.Extension.TableChildSwitchCell, type: 'switch', + deps: ['name'], cellHeaderClasses: 'width_percent_5', + options: { + onText: gettext('Yes'), offText: gettext('No'), + onColor: 'success', offColor: 'ternary', + }, + visible: function () { + return true; + }, + disabled: false, + editable: true, + }, { + id: 'description', label: gettext('Comment'), cell: 'string', type: 'multiline', + }, { + id: 'cltype', label: gettext('Data type'), + cell: 'select2', + type: 'select2', disabled: false, + control: 'select2', + cellHeaderClasses: 'width_percent_30', + select2: { allowClear: false, first_empty: false }, group: gettext('Definition'), + options: function () { + return colTypes; + }, + }, { + id: 'attlen', label: gettext('Length/Precision'), cell: Backgrid.Extension.IntegerDepCell, + deps: ['cltype'], type: 'int', group: gettext('Definition'), cellHeaderClasses: 'width_percent_20', + disabled: function (m) { + var of_type = m.get('cltype'), + flag = true; + _.each(colTypes, function (o) { + if (of_type == o.value) { + if (o.length) { + m.set('min_val_attlen', o.min_val, { silent: true }); + m.set('max_val_attlen', o.max_val, { silent: true }); + flag = false; + } + } + }); + + flag && setTimeout(function () { + if (m.get('attlen')) { + m.set('attlen', null); + } + }, 10); + + return flag; + }, + editable: function (m) { + var of_type = m.get('cltype'), + flag = false; + _.each(colTypes, function (o) { + if (of_type == o.value) { + if (o.length) { + m.set('min_val_attlen', o.min_val, { silent: true }); + m.set('max_val_attlen', o.max_val, { silent: true }); + flag = true; + } + } + }); + + !flag && setTimeout(function () { + if (m.get('attlen')) { + m.set('attlen', null); + } + }, 10); + + return flag; + }, + }, { + id: 'attprecision', label: gettext('Scale'), cell: Backgrid.Extension.IntegerDepCell, + deps: ['cltype'], type: 'int', group: gettext('Definition'), cellHeaderClasses: 'width_percent_20', + disabled: function (m) { + var of_type = m.get('cltype'), + flag = true; + _.each(colTypes, function (o) { + if (of_type == o.value) { + if (o.precision) { + m.set('min_val_attprecision', 0, { silent: true }); + m.set('max_val_attprecision', o.max_val, { silent: true }); + flag = false; + } + } + }); + + flag && setTimeout(function () { + if (m.get('attprecision')) { + m.set('attprecision', null); + } + }, 10); + return flag; + }, + editable: function (m) { + if (!colTypes) { + // datatypes not loaded yet, may be this call is from CallByNeed from backgrid cell initialize. + return true; + } + + var of_type = m.get('cltype'), + flag = false; + _.each(colTypes, function (o) { + if (of_type == o.value) { + if (o.precision) { + m.set('min_val_attprecision', 0, { silent: true }); + m.set('max_val_attprecision', o.max_val, { silent: true }); + flag = true; + } + } + }); + + !flag && setTimeout(function () { + if (m.get('attprecision')) { + m.set('attprecision', null); + } + }, 10); + + return flag; + }, + }, { + id: 'attnotnull', label: gettext('Not NULL?'), cell: 'switch', + type: 'switch', cellHeaderClasses: 'width_percent_20', + group: gettext('Constraints'), + options: { onText: gettext('Yes'), offText: gettext('No'), onColor: 'success', offColor: 'ternary' }, + disabled: function(m) { + if (m.get('colconstype') == 'i') { + setTimeout(function () { + m.set('attnotnull', true); + }, 10); + } + return false; + }, + }, { + id: 'colconstype', + label: gettext('Type'), + cell: 'string', + type: 'radioModern', + controlsClassName: 'pgadmin-controls col-12 col-sm-9', + controlLabelClassName: 'control-label col-sm-3 col-12', + group: gettext('Constraints'), + options: function() { + var opt_array = [ + {'label': gettext('NONE'), 'value': 'n'}, + {'label': gettext('IDENTITY'), 'value': 'i'}, + ]; + + if (sVersion >= 120000) { + opt_array.push({ + 'label': gettext('GENERATED'), + 'value': 'g', + }); + } + + return opt_array; + }, + disabled: false, + visible: function() { + if (sVersion >= 100000) { + return true; + } + return false; + }, + }, { + id: 'attidentity', label: gettext('Identity'), control: 'select2', + cell: 'select2', + select2: {placeholder: 'Select identity', allowClear: false, width: '100%'}, + group: gettext('Constraints'), + 'options': [ + {label: gettext('ALWAYS'), value: 'a'}, + {label: gettext('BY DEFAULT'), value: 'd'}, + ], + deps: ['colconstype'], + visible: function(m) { + if (sVersion >= 100000 && m.isTypeIdentity(m)) { + return true; + } + return false; + }, + disabled: function() { + return false; + }, + }, { + id: 'seqincrement', label: gettext('Increment'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + min: 1, deps: ['attidentity', 'colconstype'], disabled: 'isIdentityColumn', + visible: 'isTypeIdentity', + },{ + id: 'seqstart', label: gettext('Start'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + disabled: function(m) { + let isIdentity = m.get('attidentity'); + if(!_.isUndefined(isIdentity) && !_.isNull(isIdentity) && !_.isEmpty(isIdentity)) + return false; + return true; + }, deps: ['attidentity', 'colconstype'], + visible: 'isTypeIdentity', + },{ + id: 'seqmin', label: gettext('Minimum'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + deps: ['attidentity', 'colconstype'], disabled: 'isIdentityColumn', + visible: 'isTypeIdentity', + },{ + id: 'seqmax', label: gettext('Maximum'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + deps: ['attidentity', 'colconstype'], disabled: 'isIdentityColumn', + visible: 'isTypeIdentity', + },{ + id: 'seqcache', label: gettext('Cache'), type: 'int', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + min: 1, deps: ['attidentity', 'colconstype'], disabled: 'isIdentityColumn', + visible: 'isTypeIdentity', + },{ + id: 'seqcycle', label: gettext('Cycled'), type: 'switch', + mode: ['properties', 'create', 'edit'], group: gettext('Constraints'), + deps: ['attidentity', 'colconstype'], disabled: 'isIdentityColumn', + visible: 'isTypeIdentity', + }], + validate: function(keys) { + var msg = undefined; + + // Nothing to validate + if (keys && keys.length == 0) { + this.errorModel.clear(); + return null; + } else { + this.errorModel.clear(); + } + + if (_.isUndefined(this.get('name')) + || String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Column name cannot be empty.'); + this.errorModel.set('name', msg); + return msg; + } + + if (_.isUndefined(this.get('cltype')) + || String(this.get('cltype')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Column type cannot be empty.'); + this.errorModel.set('cltype', msg); + return msg; + } + + if (!_.isUndefined(this.get('cltype')) + && !_.isUndefined(this.get('attlen')) + && !_.isNull(this.get('attlen')) + && this.get('attlen') !== '') { + // Validation for Length field + if (this.get('attlen') < this.get('min_val_attlen')) + msg = gettext('Length/Precision should not be less than: ') + this.get('min_val_attlen'); + if (this.get('attlen') > this.get('max_val_attlen')) + msg = gettext('Length/Precision should not be greater than: ') + this.get('max_val_attlen'); + // If we have any error set then throw it to user + if(msg) { + this.errorModel.set('attlen', msg); + return msg; + } + } + + if (!_.isUndefined(this.get('cltype')) + && !_.isUndefined(this.get('attprecision')) + && !_.isNull(this.get('attprecision')) + && this.get('attprecision') !== '') { + // Validation for precision field + if (this.get('attprecision') < this.get('min_val_attprecision')) + msg = gettext('Scale should not be less than: ') + this.get('min_val_attprecision'); + if (this.get('attprecision') > this.get('max_val_attprecision')) + msg = gettext('Scale should not be greater than: ') + this.get('max_val_attprecision'); + // If we have any error set then throw it to user + if(msg) { + this.errorModel.set('attprecision', msg); + return msg; + } + } + + var minimum = this.get('seqmin'), + maximum = this.get('seqmax'), + start = this.get('seqstart'); + + if (!this.isNew() && this.get('colconstype') == 'i' && + (this.get('old_attidentity') == 'a' || this.get('old_attidentity') == 'd') && + (this.get('attidentity') == 'a' || this.get('attidentity') == 'd')) { + if (_.isUndefined(this.get('seqincrement')) + || String(this.get('seqincrement')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Increment value cannot be empty.'); + this.errorModel.set('seqincrement', msg); + return msg; + } else { + this.errorModel.unset('seqincrement'); + } + + if (_.isUndefined(this.get('seqmin')) + || String(this.get('seqmin')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Minimum value cannot be empty.'); + this.errorModel.set('seqmin', msg); + return msg; + } else { + this.errorModel.unset('seqmin'); + } + + if (_.isUndefined(this.get('seqmax')) + || String(this.get('seqmax')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Maximum value cannot be empty.'); + this.errorModel.set('seqmax', msg); + return msg; + } else { + this.errorModel.unset('seqmax'); + } + + if (_.isUndefined(this.get('seqcache')) + || String(this.get('seqcache')).replace(/^\s+|\s+$/g, '') == '') { + msg = gettext('Cache value cannot be empty.'); + this.errorModel.set('seqcache', msg); + return msg; + } else { + this.errorModel.unset('seqcache'); + } + } + var min_lt = gettext('Minimum value must be less than maximum value.'), + start_lt = gettext('Start value cannot be less than minimum value.'), + start_gt = gettext('Start value cannot be greater than maximum value.'); + + if (_.isEmpty(minimum) || _.isEmpty(maximum)) + return null; + + if ((minimum == 0 && maximum == 0) || + (parseInt(minimum, 10) >= parseInt(maximum, 10))) { + this.errorModel.set('seqmin', min_lt); + return min_lt; + } else { + this.errorModel.unset('seqmin'); + } + + if (start && minimum && parseInt(start) < parseInt(minimum)) { + this.errorModel.set('seqstart', start_lt); + return start_lt; + } else { + this.errorModel.unset('seqstart'); + } + + if (start && maximum && parseInt(start) > parseInt(maximum)) { + this.errorModel.set('seqstart', start_gt); + return start_gt; + } else { + this.errorModel.unset('seqstart'); + } + + return null; + }, + // Check whether the column is identity column or not + isIdentityColumn: function(m) { + let isIdentity = m.get('attidentity'); + if(!_.isUndefined(isIdentity) && !_.isNull(isIdentity) && !_.isEmpty(isIdentity)) + return false; + return true; + }, + // Check whether the column is a identity column + isTypeIdentity: function(m) { + let colconstype = m.get('colconstype'); + if (!_.isUndefined(colconstype) && !_.isNull(colconstype) && colconstype == 'i') { + return true; + } + return false; + }, + // Check whether the column is a generated column + isTypeGenerated: function(m) { + let colconstype = m.get('colconstype'); + if (!_.isUndefined(colconstype) && !_.isNull(colconstype) && colconstype == 'g') { + return true; + } + return false; + }, + }); + + const formatSchemaItem = function(opt) { + if (!opt.id) { + return opt.text; + } + + var optimage = $(opt.element).data('image'); + + if (!optimage) { + return opt.text; + } else { + return $('').append( + $('', { + class: 'wcTabIcon ' + optimage, + }) + ).append($('').text(opt.text)); + } + }; + + let dialogModel = this.pgBrowser.DataModel.extend({ + defaults: { + name: undefined, + schema: undefined, + description: undefined, + columns: [], + primary_key: [], + }, + initialize: function() { + dialogObj.pgBrowser.DataModel.prototype.initialize.apply(this, arguments); + + if(!this.get('schema') && schemas.length > 0) { + this.set({ + 'schema': schemas[0]['name'], + }, {silent: true}); + } + }, + schema: [{ + id: 'name', label: gettext('Name'), type: 'text', disabled: false, + },{ + id: 'schema', label: gettext('Schema'), type: 'text', + control: 'select2', select2: { + allowClear: false, first_empty: false, + templateResult: formatSchemaItem, + templateSelection: formatSchemaItem, + }, + options: function () { + return schemas.map((schema)=>{ + return { + 'value': schema['name'], + 'image': 'icon-schema', + 'label': schema['name'], + }; + }); + }, + filter: function(d) { + // If schema name start with pg_* then we need to exclude them + if(d && d.label.match(/^pg_/)) + { + return false; + } + return true; + }, + },{ + id: 'description', label: gettext('Comment'), type: 'multiline', + },{ + id: 'columns', label: gettext('Columns'), type: 'collection', mode: ['create'], + group: gettext('Columns'), + model: columnsModel, + subnode: columnsModel, + disabled: false, + uniqueCol : ['name'], + columns : ['name' , 'cltype', 'attlen', 'attprecision', 'attnotnull', 'is_primary_key'], + control: Backform.UniqueColCollectionControl.extend({ + initialize: function() { + + Backform.UniqueColCollectionControl.prototype.initialize.apply(this, arguments); + var self = this, + collection = self.model.get(self.field.get('name')); + + if(collection.isEmpty()) { + self.last_attnum = -1; + } else { + var lastCol = collection.max(function(col) { + return col.get('attnum'); + }); + self.last_attnum = lastCol.get('attnum'); + } + + collection.on('change:is_primary_key', function(m) { + var primary_key_coll = self.model.get('primary_key'), + column_name = m.get('name'), + primary_key, primary_key_column_coll; + + if(m.get('is_primary_key')) { + // Add column to primary key. + if (primary_key_coll.length < 1) { + primary_key = new (primary_key_coll.model)({}, { + top: self.model, + collection: primary_key_coll, + handler: primary_key_coll, + }); + primary_key_coll.add(primary_key); + } else { + primary_key = primary_key_coll.first(); + } + + primary_key_column_coll = primary_key.get('columns'); + var primary_key_column_exist = primary_key_column_coll.where({column:column_name}); + + if (primary_key_column_exist.length == 0) { + var primary_key_column = new ( + primary_key_column_coll.model + )({column: column_name}, { + silent: true, + top: self.model, + collection: primary_key_coll, + handler: primary_key_coll, + }); + + primary_key_column_coll.add(primary_key_column); + } + + primary_key_column_coll.trigger( + 'pgadmin:multicolumn:updated', primary_key_column_coll + ); + } else { + // remove column from primary key. + if (primary_key_coll.length > 0) { + primary_key = primary_key_coll.first(); + // Do not alter existing primary key columns. + if (!_.isUndefined(primary_key.get('oid'))) { + return; + } + + primary_key_column_coll = primary_key.get('columns'); + var removedCols = primary_key_column_coll.where({column:column_name}); + if (removedCols.length > 0) { + primary_key_column_coll.remove(removedCols); + _.each(removedCols, function(local_model) { + local_model.destroy(); + }); + if (primary_key_column_coll.length == 0) { + /* Ideally above line of code should be "primary_key_coll.reset()". + * But our custom DataCollection (extended from Backbone collection in datamodel.js) + * does not respond to reset event, it only supports add, remove, change events. + * And hence no custom event listeners/validators get called for reset event. + */ + primary_key_coll.remove(primary_key_coll.first()); + } + } + primary_key_column_coll.trigger('pgadmin:multicolumn:updated', primary_key_column_coll); + } + } + }); + + collection.on('change:name', function(m) { + let primary_key = self.model.get('primary_key').first(); + if(primary_key) { + let updatedCols = primary_key.get('columns').where( + {column: m.previous('name')} + ); + if (updatedCols.length > 0) { + /* + * Table column name has changed so update + * column name in primary key as well. + */ + updatedCols[0].set( + {'column': m.get('name')}, + {silent: true}); + } + } + }); + + collection.on('remove', function(m) { + let primary_key = self.model.get('primary_key').first(); + if(primary_key) { + let removedCols = primary_key.get('columns').where( + {column: m.get('name')} + ); + + primary_key.get('columns').remove(removedCols); + } + }); + }, + }), + canAdd: true, + canEdit: true, canDelete: true, + // For each row edit/delete button enable/disable + canEditRow: true, + canDeleteRow: true, + allowMultipleEmptyRow: false, + beforeAdd: function(newModel) { + this.last_attnum++; + newModel.set('attnum', this.last_attnum); + return newModel; + }, + },{ + // Here we will create tab control for constraints + // We will hide the tab for ERD + type: 'nested', control: 'tab', group: gettext('Constraints'), mode: ['properties'], + schema: [{ + id: 'primary_key', label: '', + model: this.pgBrowser.Nodes['primary_key'].model.extend({ + validate: ()=>{}, + }), + subnode: this.pgBrowser.Nodes['primary_key'].model.extend({ + validate: ()=>{}, + }), + editable: false, type: 'collection', + }, + ], + }], + validate: function() { + var msg, + name = this.get('name'), + schema = this.get('schema'); + + if ( + _.isUndefined(name) || _.isNull(name) || + String(name).replace(/^\s+|\s+$/g, '') == '' + ) { + msg = gettext('Table name cannot be empty.'); + this.errorModel.set('name', msg); + return msg; + } + this.errorModel.unset('name'); + if ( + _.isUndefined(schema) || _.isNull(schema) || + String(schema).replace(/^\s+|\s+$/g, '') == '' + ) { + msg = gettext('Table schema cannot be empty.'); + this.errorModel.set('schema', msg); + return msg; + } + this.errorModel.unset('schema'); + return null; + }, + }); + + return new dialogModel(attributes); + } + + createOrGetDialog(type) { + const dialogName = this.dialogName(); + + if (!Alertify[dialogName]) { + Alertify.dialog(dialogName, () => { + return new DialogWrapper( + `
`, + null, + type, + $, + this.pgBrowser, + Alertify, + Backform + ); + }); + } + return Alertify[dialogName]; + } + + show(title, attributes, colTypes, schemas, sVersion, callback) { + let dialogTitle = title || gettext('Unknown'); + const dialog = this.createOrGetDialog('table_dialog'); + dialog(dialogTitle, this.getDataModel(attributes, colTypes, schemas, sVersion), callback).resizeTo(this.pgBrowser.stdW.md, this.pgBrowser.stdH.md); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/index.js b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/index.js new file mode 100644 index 000000000..eb0ab1336 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/dialogs/index.js @@ -0,0 +1,32 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import TableDialog, {transformToSupported as transformToSupportedTable} from './TableDialog'; +import OneToManyDialog from './OneToManyDialog'; +import ManyToManyDialog from './ManyToManyDialog'; +import pgBrowser from 'top/browser/static/js/browser'; +import 'sources/backgrid.pgadmin'; +import 'sources/backform.pgadmin'; + +export default function getDialog(dialogName) { + if(dialogName === 'entity_dialog') { + return new TableDialog(pgBrowser); + } else if(dialogName === 'onetomany_dialog') { + return new OneToManyDialog(pgBrowser); + } else if(dialogName === 'manytomany_dialog') { + return new ManyToManyDialog(pgBrowser); + } +} + +export function transformToSupported(type, data) { + if(type == 'table') { + return transformToSupportedTable(data); + } + return data; +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/index.js b/web/pgadmin/tools/erd/static/js/erd_tool/index.js new file mode 100644 index 000000000..1bd4c3bc6 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/index.js @@ -0,0 +1,30 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import ReactDOM from 'react-dom'; +import BodyWidget from './ui_components/BodyWidget'; +import getDialog, {transformToSupported} from './dialogs'; +import Alertify from 'pgadmin.alertifyjs'; +import pgWindow from 'sources/window'; + +export default class ERDTool { + constructor(container, params) { + this.container = document.querySelector(container); + this.params = params; + } + + render() { + /* Mount the React ERD tool to the container */ + ReactDOM.render( + , + this.container + ); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/links/OneToManyLink.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/links/OneToManyLink.jsx new file mode 100644 index 000000000..f7bed2f63 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/links/OneToManyLink.jsx @@ -0,0 +1,288 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import { + RightAngleLinkModel, + RightAngleLinkWidget, + DefaultLinkFactory, + PortModelAlignment, + LinkWidget, + PointModel +} from '@projectstorm/react-diagrams'; +import {Point} from '@projectstorm/geometry'; +import _ from 'lodash'; + +export const OneToManyModel = { + local_table_uid: undefined, + local_column_attnum: undefined, + referenced_table_uid: undefined, + referenced_column_attnum: undefined, +} + +export class OneToManyLinkModel extends RightAngleLinkModel { + constructor({data, ...options}) { + super({ + type: 'onetomany', + width: 1, + class: 'link-onetomany', + locked: true, + ...options + }); + + this._data = { + ...data, + }; + } + + getData() { + return this._data; + } + + setData(data) { + this._data = data; + } + + serializeData(nodesDict) { + let data = this.getData(); + let target = nodesDict[data['local_table_uid']].getData(); + let source = nodesDict[data['referenced_table_uid']].getData(); + return { + 'schema': target.schema, + 'table': target.name, + 'remote_schema': source.schema, + 'remote_table': source.name, + 'columns': [{ + 'local_column': _.find(target.columns, (col)=>data.local_column_attnum == col.attnum).name, + 'referenced': _.find(source.columns, (col)=>data.referenced_column_attnum == col.attnum).name, + }], + } + } + + serialize() { + return { + ...super.serialize(), + data: this.getData() + }; + } +} + +const CustomLinkEndWidget = props => { + const { point, rotation, tx, ty, type } = props; + + const svgForType = (itype) => { + if(itype == 'many') { + return ( + <> + + + + ) + } else if (type == 'one') { + return ( + + ) + } + } + + return ( + + + + {svgForType(type)} + + + + ); +}; + +export class OneToManyLinkWidget extends RightAngleLinkWidget { + constructor(props) { + super(props); + } + + endPointTranslation(alignment, offset) { + let degree = 0; + let tx = 0, ty = 0; + switch(alignment) { + case PortModelAlignment.BOTTOM: + ty = -offset; + break; + case PortModelAlignment.LEFT: + degree = 90; + tx = offset + break; + case PortModelAlignment.TOP: + degree = 180; + ty = offset; + break; + case PortModelAlignment.RIGHT: + degree = -90; + tx = -offset; + break; + } + return [degree, tx, ty]; + } + + addCustomWidgetPoint(type, endpoint, point) { + let offset = 30; + const [rotation, tx, ty] = this.endPointTranslation(endpoint.options.alignment, offset); + if(!point) { + point = this.props.link.point( + endpoint.getX()-tx, endpoint.getY()-ty, {'one': 1, 'many': 2}[type] + ); + } else { + point.setPosition(endpoint.getX()-tx, endpoint.getY()-ty); + } + + return { + type: type, + point: point, + rotation: rotation, + tx: tx, + ty: ty + } + } + + generateCustomEndWidget({type, point, rotation, tx, ty}) { + return ( + + ); + } + + draggingEvent(event, index) { + let points = this.props.link.getPoints(); + // get moving difference. Index + 1 will work because links indexes has + // length = points.lenght - 1 + let dx = Math.abs(points[index].getX() - points[index + 1].getX()); + let dy = Math.abs(points[index].getY() - points[index + 1].getY()); + + // moving with y direction + if (dx === 0) { + this.calculatePositions(points, event, index, 'x'); + } else if (dy === 0) { + this.calculatePositions(points, event, index, 'y'); + } + this.props.link.setFirstAndLastPathsDirection(); + } + + handleMove = function(event) { + this.props.link.getTargetPort() + this.draggingEvent(event, this.dragging_index); + this.props.link.fireEvent({}, 'positionChanged'); + }.bind(this); + + render() { + //ensure id is present for all points on the path + let points = this.props.link.getPoints(); + let paths = []; + + let onePoint = this.addCustomWidgetPoint('one', this.props.link.getSourcePort(), points[0]); + let manyPoint = this.addCustomWidgetPoint('many', this.props.link.getTargetPort(), points[points.length-1]); + + if (!this.state.canDrag && points.length > 2) { + // Those points and its position only will be moved + for (let i = 1; i < points.length; i += points.length - 2) { + if (i - 1 === 0) { + if (this.props.link.getFirstPathXdirection()) { + points[i].setPosition(points[i].getX(), points[i - 1].getY()); + } else { + points[i].setPosition(points[i - 1].getX(), points[i].getY()); + } + } else { + if (this.props.link.getLastPathXdirection()) { + points[i - 1].setPosition(points[i - 1].getX(), points[i].getY()); + } else { + points[i - 1].setPosition(points[i].getX(), points[i - 1].getY()); + } + } + } + } + + // If there is existing link which has two points add one + if (points.length === 2 && !this.state.canDrag) { + this.props.link.addPoint( + new PointModel({ + link: this.props.link, + position: new Point(onePoint.point.getX(), manyPoint.point.getY()) + }) + ); + } + + paths.push(this.generateCustomEndWidget(onePoint)); + for (let j = 0; j < points.length - 1; j++) { + paths.push( + this.generateLink( + LinkWidget.generateLinePath(points[j], points[j + 1]), + { + 'data-linkid': this.props.link.getID(), + 'data-point': j, + onMouseDown: (event) => { + if (event.button === 0) { + this.setState({ canDrag: true }); + this.dragging_index = j; + // Register mouse move event to track mouse position + // On mouse up these events are unregistered check "this.handleUp" + window.addEventListener('mousemove', this.handleMove); + window.addEventListener('mouseup', this.handleUp); + } + }, + onMouseEnter: (event) => { + this.setState({ selected: true }); + this.props.link.lastHoverIndexOfPath = j; + } + }, + j + ) + ); + } + paths.push(this.generateCustomEndWidget(manyPoint)); + + + this.refPaths = []; + return {paths}; + } +} + +export class OneToManyLinkFactory extends DefaultLinkFactory { + constructor() { + super('onetomany'); + } + + generateModel(event) { + return new OneToManyLinkModel(event.initialConfig); + } + + generateReactWidget(event) { + return ; + } + + generateLinkSegment(model, selected, path) { + return ( + + + ); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx new file mode 100644 index 000000000..2016af598 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/nodes/TableNode.jsx @@ -0,0 +1,202 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import { DefaultNodeModel, PortWidget } from '@projectstorm/react-diagrams'; +import { AbstractReactFactory } from '@projectstorm/react-canvas-core'; +import _ from 'lodash'; +import { IconButton, DetailsToggleButton } from '../ui_components/ToolBar'; + +const TYPE = 'table'; + +export class TableNodeModel extends DefaultNodeModel { + constructor({otherInfo, ...options}) { + super({ + ...options, + type: TYPE + }); + + this._note = otherInfo.note || ''; + + this._data = { + columns: [], + ...otherInfo.data, + }; + } + + getPortName(attnum) { + return `coll-port-${attnum}`; + } + + setNote(note) { + this._note = note; + } + + getNote() { + return this._note; + } + + addColumn(col) { + this._data.columns.push(col); + } + + getColumnAt(attnum) { + return _.find(this.getColumns(), (col)=>col.attnum==attnum); + } + + getColumns() { + return this._data.columns; + } + + setName(name) { + this._data['name'] = name; + } + + cloneData(name) { + let newData = { + ...this.getData() + }; + if(name) { + newData['name'] = name + } + return newData; + } + + setData(data) { + let self = this; + /* Remove the links if column dropped */ + _.differenceWith(this._data.columns, data.columns, function(existing, incoming) { + return existing.attnum == incoming.attnum; + }).forEach((col)=>{ + let existPort = self.getPort(self.getPortName(col.attnum)); + if(existPort) { + existPort.removeAllLinks(); + self.removePort(existPort); + } + }); + this._data = data; + this.fireEvent({}, 'nodeUpdated'); + } + + getData() { + return this._data; + } + + getSchemaTableName() { + return [this._data.schema, this._data.name]; + } + + remove() { + Object.values(this.getPorts()).forEach((port)=>{ + port.removeAllLinks(); + }); + super.remove(); + } + + serializeData() { + return this.getData(); + } + + serialize() { + return { + ...super.serialize(), + otherInfo: { + data: this.getData(), + note: this.getNote(), + } + }; + } +} + +export class TableNodeWidget extends React.Component { + constructor(props) { + super(props); + + this.state = { + show_details: true + } + + this.props.node.registerListener({ + toggleDetails: (event) => { + this.setState({show_details: event.show_details}); + }, + }); + } + + generateColumn(col) { + let port = this.props.node.getPort(this.props.node.getPortName(col.attnum)); + return ( +
+
+
+
+ {col.name}  + {this.state.show_details && + {col.cltype}{col.attlen ? ('('+ col.attlen + (col.attprecision ? ','+col.attprecision : '') +')') : ''}} +
+
+
{this.generatePort(port)}
+
+ ) + } + + generatePort = port => { + if(port) { + return ( + + ); + } + return <>; + }; + + toggleShowDetails = (e) => { + e.preventDefault(); + this.setState((prevState)=>({show_details: !prevState.show_details})); + } + + render() { + let node_data = this.props.node.getData(); + return ( +
{this.props.node.fireEvent({}, 'editNode')}}> +
+ {e.stopPropagation();}} /> + {this.props.node.getNote() && + { + this.props.node.fireEvent({}, 'showNote') + }} title="Check note" />} +
+
+ + {node_data.schema} +
+
+ + {node_data.name} +
+
+ {_.map(node_data.columns, (col)=>this.generateColumn(col))} +
+
+ ); + } +} + +export class TableNodeFactory extends AbstractReactFactory { + constructor() { + super(TYPE); + } + + generateModel(event) { + return new TableNodeModel(event.initialConfig); + } + + generateReactWidget(event) { + return ; + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ports/OneToManyPort.js b/web/pgadmin/tools/erd/static/js/erd_tool/ports/OneToManyPort.js new file mode 100644 index 000000000..6f6e2c0f2 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ports/OneToManyPort.js @@ -0,0 +1,43 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import { PortModel } from '@projectstorm/react-diagrams-core'; +import {OneToManyLinkModel} from '../links/OneToManyLink'; +import { AbstractModelFactory } from '@projectstorm/react-canvas-core'; + +const TYPE = 'onetomany'; + +export default class OneToManyPortModel extends PortModel { + constructor({options}) { + super({ + ...options, + type: TYPE, + }); + } + + removeAllLinks() { + Object.values(this.getLinks()).forEach((link)=>{ + link.remove(); + }); + } + + createLinkModel() { + return new OneToManyLinkModel({}); + } +} + +export class OneToManyPortFactory extends AbstractModelFactory { + constructor() { + super(TYPE); + } + + generateModel(event) { + return new OneToManyPortModel(event.initialConfig||{}); + } +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx new file mode 100644 index 000000000..af9271d21 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx @@ -0,0 +1,681 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import * as React from 'react'; +import { CanvasWidget } from '@projectstorm/react-canvas-core'; +import axios from 'axios'; +import { Action, InputType } from '@projectstorm/react-canvas-core'; +import PropTypes from 'prop-types'; + +import ERDCore from '../ERDCore'; +import ToolBar, {IconButton, DetailsToggleButton, ButtonGroup} from './ToolBar'; +import ConnectionBar, { STATUS as CONNECT_STATUS } from './ConnectionBar'; +import Loader from './Loader'; +import FloatingNote from './FloatingNote'; +import {setPanelTitle} from '../../erd_module'; +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import {showERDSqlTool} from 'tools/datagrid/static/js/show_query_tool'; + +/* Custom react-diagram action for keyboard events */ +export class KeyboardShortcutAction extends Action { + constructor(shortcut_handlers=[]) { + super({ + type: InputType.KEY_DOWN, + fire: ({ event })=>{ + this.callHandler(event); + } + }); + this.shortcuts = {}; + + for(let i=0; i{ + this.realignGrid({backgroundPosition: `${event.offsetX}px ${event.offsetY}px`}); + event.stopPropagation(); + }, + 'zoomUpdated': (event)=>{ + let { gridSize } = this.diagram.getModel().getOptions(); + let bgSize = gridSize*event.zoom/100; + this.realignGrid({backgroundSize: `${bgSize*3}px ${bgSize*3}px`}); + }, + 'nodesSelectionChanged': ()=>{ + this.setState({ + single_node_selected: this.diagram.getSelectedNodes().length == 1, + any_item_selected: this.diagram.getSelectedNodes().length > 0 || this.diagram.getSelectedLinks().length > 0, + }); + }, + 'linksSelectionChanged': ()=>{ + this.setState({ + single_link_selected: this.diagram.getSelectedLinks().length == 1, + any_item_selected: this.diagram.getSelectedNodes().length > 0 || this.diagram.getSelectedLinks().length > 0, + }); + }, + 'linksUpdated': () => { + this.setState({dirty: true}); + }, + 'nodesUpdated': ()=>{ + this.setState({dirty: true}); + }, + 'showNote': (event)=>{ + this.showNote(event.node); + }, + 'editNode': (event) => { + this.addEditNode(event.node); + } + }; + Object.keys(diagramEvents).forEach(eventName => { + this.diagram.registerModelEvent(eventName, diagramEvents[eventName]); + }); + } + + registerKeyboardShortcuts() { + /* First deregister to avoid double events */ + this.keyboardActionObj && this.diagram.deregisterKeyAction(this.keyboardActionObj); + + this.keyboardActionObj = new KeyboardShortcutAction([ + [this.state.preferences.open_project, this.onLoadDiagram], + [this.state.preferences.save_project, this.onSaveDiagram], + [this.state.preferences.save_project_as, this.onSaveAsDiagram], + [this.state.preferences.generate_sql, this.onSQLClick], + [this.state.preferences.add_table, this.onAddNewNode], + [this.state.preferences.edit_table, this.onEditNode], + [this.state.preferences.clone_table, this.onCloneNode], + [this.state.preferences.drop_table, this.onDeleteNode], + [this.state.preferences.add_edit_note, this.onNoteClick], + [this.state.preferences.one_to_many, this.onOneToManyClick], + [this.state.preferences.many_to_many, this.onManyToManyClick], + [this.state.preferences.auto_align, this.onAutoDistribute], + [this.state.preferences.zoom_to_fit, this.diagram.zoomToFit], + [this.state.preferences.zoom_in, this.diagram.zoomIn], + [this.state.preferences.zoom_out, this.diagram.zoomOut] + ]); + + this.diagram.registerKeyAction(this.keyboardActionObj); + } + + handleAxiosCatch(err) { + let alert = this.props.alertify.alert().set('title', gettext('Error')); + if (err.response) { + // client received an error response (5xx, 4xx) + alert.set('message', `${err.response.statusText} - ${err.response.data.errormsg}`).show(); + console.error('response error', err.response); + } else if (err.request) { + // client never received a response, or request never left + alert.set('message', gettext('Client error') + ':' + err).show(); + console.error('client eror', err); + } else { + alert.set('message', err.message).show(); + console.error('other error', err); + } + } + + async componentDidMount() { + this.setLoading('Preparing'); + this.setTitle(this.state.current_file); + this.setState({ + preferences: this.props.pgAdmin.Browser.get_preferences_for_module('erd') + }, this.registerKeyboardShortcuts); + this.registerModelEvents(); + this.realignGrid({ + backgroundSize: '45px 45px', + backgroundPosition: '0px 0px', + }); + + this.props.pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:select_file', this.openFile, this); + this.props.pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:create_file', this.saveFile, this); + this.props.pgAdmin.Browser.onPreferencesChange('erd', () => { + this.setState({ + preferences: this.props.pgAdmin.Browser.get_preferences_for_module('erd') + }, ()=>this.registerKeyboardShortcuts()); + }); + + let done = await this.initConnection(); + if(!done) return; + + done = await this.loadPrequisiteData(); + if(!done) return; + + if(this.props.params.gen) { + await this.loadTablesData(); + } + } + + componentDidUpdate() { + if(this.state.dirty) { + this.setTitle(this.state.current_file, true); + } + } + + getDialog(dialogName) { + if(dialogName === 'entity_dialog') { + return (title, attributes, callback)=>{ + this.props.getDialog(dialogName).show( + title, attributes, this.diagram.getCache('colTypes'), this.diagram.getCache('schemas'), this.state.server_version, callback + ); + }; + } else if(dialogName === 'onetomany_dialog' || dialogName === 'manytomany_dialog') { + return (title, attributes, callback)=>{ + this.props.getDialog(dialogName).show( + title, attributes, this.diagram.getModel().getNodesDict(), this.state.server_version, callback + ); + }; + } + } + + setLoading(message) { + this.setState({loading_msg: message}); + } + + realignGrid({backgroundSize, backgroundPosition}) { + if(backgroundSize) { + this.canvasEle.style.backgroundSize = backgroundSize; + } + if(backgroundPosition) { + this.canvasEle.style.backgroundPosition = backgroundPosition; + } + } + + addEditNode(node) { + let dialog = this.getDialog('entity_dialog'); + if(node) { + let [schema, table] = node.getSchemaTableName(); + dialog(_.escape(`Table: ${table} (${schema})`), node.getData(), (newData)=>{ + node.setData(newData); + this.diagram.repaint(); + }); + } else { + dialog('New table', {name: this.diagram.getNextTableName()}, (newData)=>{ + let newNode = this.diagram.addNode(newData); + newNode.setSelected(true); + }); + } + } + + onEditNode() { + const selected = this.diagram.getSelectedNodes(); + if(selected.length == 1) { + this.addEditNode(selected[0]); + } + } + + onAddNewNode() { + this.addEditNode(); + } + + onCloneNode() { + const selected = this.diagram.getSelectedNodes(); + if(selected.length == 1) { + let newData = selected[0].cloneData(this.diagram.getNextTableName()); + let {x, y} = selected[0].getPosition(); + let newNode = this.diagram.addNode(newData, [x+20, y+20]); + newNode.setSelected(true); + } + } + + onDeleteNode() { + this.props.alertify.confirm( + gettext('Delete ?'), + gettext('You have selected %s tables and %s links.', this.diagram.getSelectedNodes().length, this.diagram.getSelectedLinks().length) + + '
' + gettext('Are you sure you want to delete ?'), + () => { + this.diagram.getSelectedNodes().forEach((node)=>{ + node.setSelected(false); + node.remove(); + }); + this.diagram.getSelectedLinks().forEach((link)=>{ + link.getTargetPort().remove(); + link.getSourcePort().remove(); + link.setSelected(false); + link.remove(); + }); + this.diagram.repaint(); + }, + () => {} + ); + } + + onAutoDistribute() { + this.diagram.dagreDistributeNodes(); + } + + onDetailsToggle() { + this.setState((prevState)=>({ + show_details: !prevState.show_details + }), ()=>{ + this.diagram.getModel().getNodes().forEach((node)=>{ + node.fireEvent({show_details: this.state.show_details}, 'toggleDetails'); + }) + }); + } + + onHelpClick() { + let url = url_for('help.static', {'filename': 'erd.html'}); + window.open(url, 'pgadmin_help'); + } + + onLoadDiagram() { + var params = { + 'supported_types': ['pgerd'], // file types allowed + 'dialog_type': 'select_file', // open select file dialog + }; + this.props.pgAdmin.FileManager.init(); + this.props.pgAdmin.FileManager.show_dialog(params); + } + + openFile(fileName) { + axios.post(url_for('sqleditor.load_file'), { + 'file_name': decodeURI(fileName) + }).then((res)=>{ + this.setState({ + current_file: fileName, + dirty: false, + }); + this.setTitle(fileName); + this.diagram.deserialize(res.data); + this.registerModelEvents(); + }).catch((err)=>{ + this.handleAxiosCatch(err); + }); + } + + onSaveDiagram(isSaveAs=false) { + if(this.state.current_file && !isSaveAs) { + this.saveFile(this.state.current_file); + } else { + var params = { + 'supported_types': ['pgerd'], + 'dialog_type': 'create_file', + 'dialog_title': 'Save File', + 'btn_primary': 'Save', + }; + this.props.pgAdmin.FileManager.init(); + this.props.pgAdmin.FileManager.show_dialog(params); + } + } + + onSaveAsDiagram() { + this.onSaveDiagram(true); + } + + saveFile(fileName) { + axios.post(url_for('sqleditor.save_file'), { + 'file_name': decodeURI(fileName), + 'file_content': JSON.stringify(this.diagram.serialize(this.props.pgAdmin.Browser.utils.app_version_int)) + }).then(()=>{ + this.props.alertify.success(gettext('Project saved successfully.')); + this.setState({ + current_file: fileName, + dirty: false, + }); + this.setTitle(fileName); + }).catch((err)=>{ + this.handleAxiosCatch(err); + }); + } + + getCurrentProjectName(path) { + let currPath = path || this.state.current_file || 'Untitled'; + return currPath.split('\\').pop().split('/').pop(); + } + + setTitle(title, dirty=false) { + if(title === null || title === '') { + title = 'Untitled'; + } + title = this.getCurrentProjectName(title) + (dirty ? '*': ''); + if (this.new_browser_tab) { + window.document.title = title; + } else { + _.each(this.props.pgAdmin.Browser.docker.findPanels('frm_erdtool'), function(p) { + if (p.isVisible()) { + setPanelTitle(p, title); + } + }); + } + } + + onSQLClick() { + let scriptHeader = gettext('-- This script was generated by a beta version of the ERD tool in pgAdmin 4.\n'); + scriptHeader += gettext('-- Please log an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new if you find any bugs, including reproduction steps.\n'); + + let url = url_for('erd.sql', { + trans_id: this.props.params.trans_id, + sgid: this.props.params.sgid, + sid: this.props.params.sid, + did: this.props.params.did + }); + + this.setLoading(gettext('Preparing the SQL...')); + axios.post(url, this.diagram.serializeData()) + .then((resp)=>{ + let sqlScript = resp.data.data; + sqlScript = scriptHeader + 'BEGIN;\n' + sqlScript + '\nEND;'; + + let parentData = { + sgid: this.props.params.sgid, + sid: this.props.params.sid, + did: this.props.params.did, + stype: this.props.params.server_type, + } + + let sqlId = `erd${this.props.params.trans_id}`; + localStorage.setItem(sqlId, sqlScript); + showERDSqlTool(parentData, sqlId, this.props.params.title, this.props.pgAdmin.DataGrid, this.props.alertify); + }) + .catch((error)=>{ + this.handleAxiosCatch(error); + }) + .then(()=>{ + this.setLoading(null); + }) + } + + onOneToManyClick() { + let dialog = this.getDialog('onetomany_dialog'); + let initData = {local_table_uid: this.diagram.getSelectedNodes()[0].getID()}; + dialog('One to many relation', initData, (newData)=>{ + let newLink = this.diagram.addLink(newData, 'onetomany'); + this.diagram.clearSelection(); + newLink.setSelected(true); + this.diagram.repaint(); + }); + } + + onManyToManyClick() { + let dialog = this.getDialog('manytomany_dialog'); + let initData = {left_table_uid: this.diagram.getSelectedNodes()[0].getID()}; + dialog('Many to many relation', initData, (newData)=>{ + let nodes = this.diagram.getModel().getNodesDict(); + let left_table = nodes[newData.left_table_uid]; + let right_table = nodes[newData.right_table_uid]; + let tableData = { + name: `${left_table.getData().name}_${right_table.getData().name}`, + schema: left_table.getData().schema, + columns: [{ + ...left_table.getColumnAt(newData.left_table_column_attnum), + 'name': `${left_table.getData().name}_${left_table.getColumnAt(newData.left_table_column_attnum).name}`, + 'is_primary_key': false, + 'attnum': 0, + },{ + ...right_table.getColumnAt(newData.right_table_column_attnum), + 'name': `${right_table.getData().name}_${right_table.getColumnAt(newData.right_table_column_attnum).name}`, + 'is_primary_key': false, + 'attnum': 1, + }] + } + let newNode = this.diagram.addNode(tableData); + this.diagram.clearSelection(); + newNode.setSelected(true); + + let linkData = { + local_table_uid: newNode.getID(), + local_column_attnum: newNode.getColumns()[0].attnum, + referenced_table_uid: newData.left_table_uid, + referenced_column_attnum : newData.left_table_column_attnum, + } + this.diagram.addLink(linkData, 'onetomany'); + + linkData = { + local_table_uid: newNode.getID(), + local_column_attnum: newNode.getColumns()[1].attnum, + referenced_table_uid: newData.right_table_uid, + referenced_column_attnum : newData.right_table_column_attnum, + } + + this.diagram.addLink(linkData, 'onetomany'); + + this.diagram.repaint(); + }); + } + + showNote(noteNode) { + if(noteNode) { + this.noteRefEle = this.diagram.getEngine().getNodeElement(noteNode); + this.setState({ + note_node: noteNode, + note_open: true + }); + } + } + + onNoteClick(e) { + let noteNode = this.diagram.getSelectedNodes()[0]; + this.showNote(noteNode); + } + + onNoteClose(updated) { + this.setState({note_open: false}); + updated && this.diagram.fireEvent({}, 'nodesUpdated', true); + } + + async initConnection() { + this.setLoading(gettext('Initializing connection...')); + this.setState({conn_status: CONNECT_STATUS.CONNECTING}); + + let initUrl = url_for('erd.initialize', { + trans_id: this.props.params.trans_id, + sgid: this.props.params.sgid, + sid: this.props.params.sid, + did: this.props.params.did + }); + + try { + let response = await axios.post(initUrl); + this.setState({ + conn_status: CONNECT_STATUS.CONNECTED, + server_version: response.data.data.serverVersion + }); + return true; + } catch (error) { + this.setState({conn_status: CONNECT_STATUS.FAILED}); + this.handleAxiosCatch(error); + return false; + } finally { + this.setLoading(null); + } + } + + /* Get all prequisite in one conn since + * we have only one connection + */ + async loadPrequisiteData() { + this.setLoading(gettext('Fetching required data...')); + let url = url_for('erd.prequisite', { + trans_id: this.props.params.trans_id, + sgid: this.props.params.sgid, + sid: this.props.params.sid, + did: this.props.params.did + }); + + try { + let response = await axios.get(url); + let data = response.data.data; + this.diagram.setCache('colTypes', data['col_types']); + this.diagram.setCache('schemas', data['schemas']); + return true; + } catch (error) { + this.handleAxiosCatch(error); + return false; + } finally { + this.setLoading(null); + } + } + + async loadTablesData() { + this.setLoading(gettext('Fetching schema data...')); + let url = url_for('erd.tables', { + trans_id: this.props.params.trans_id, + sgid: this.props.params.sgid, + sid: this.props.params.sid, + did: this.props.params.did + }); + + try { + let response = await axios.get(url); + let tables = response.data.data.map((table)=>{ + return this.props.transformToSupported('table', table); + }); + this.diagram.deserializeData(tables); + return true; + } catch (error) { + this.handleAxiosCatch(error); + return false; + } finally { + this.setLoading(null); + } + } + + render() { + return ( + <> + + + + {this.onSaveDiagram()}} title={gettext('Save project')} + shortcut={this.state.preferences.save_project} disabled={!this.state.dirty}/> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + {this.canvasEle = ele?.ref?.current}} engine={this.diagram.getEngine()} /> +
+ + ); + } +} + + +BodyWidget.propTypes = { + params:PropTypes.shape({ + trans_id: PropTypes.number.isRequired, + sgid: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, + sid: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, + did: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, + server_type: PropTypes.string.isRequired, + title: PropTypes.string.isRequired, + bgcolor: PropTypes.string, + fgcolor: PropTypes.string, + gen: PropTypes.bool.isRequired + }), + getDialog: PropTypes.func.isRequired, + transformToSupported: PropTypes.func.isRequired, + pgAdmin: PropTypes.object.isRequired, + alertify: PropTypes.object.isRequired +}; diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ConnectionBar.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ConnectionBar.jsx new file mode 100644 index 000000000..22df72e3c --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ConnectionBar.jsx @@ -0,0 +1,57 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import gettext from 'sources/gettext'; +import PropTypes from 'prop-types'; + +export const STATUS = { + CONNECTED: 1, + DISCONNECTED: 2, + CONNECTING: 3, + FAILED: 4, +} + +/* The connection bar component */ +export default function ConnectionBar({statusId, status, bgcolor, fgcolor, title}) { + return ( +
+
+ +
+
+
+ {status == STATUS.CONNECTING ? '(' + gettext('Obtaining connection...') + ') ' : ''} + {status == STATUS.FAILED ? '(' + gettext('Connection failed') + ') ' : ''} + {title} +
+
+
+ ) +} + +ConnectionBar.propTypes = { + statusId: PropTypes.string.isRequired, + status: PropTypes.oneOf(Object.values(STATUS)).isRequired, + bgcolor: PropTypes.string, + fgcolor: PropTypes.string, + title: PropTypes.string.isRequired, +}; diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/FloatingNote.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/FloatingNote.jsx new file mode 100644 index 000000000..a66cc4d0b --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/FloatingNote.jsx @@ -0,0 +1,71 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React, { useEffect, useState } from 'react'; +import Tippy from '@tippyjs/react'; +import gettext from 'sources/gettext'; +import PropTypes from 'prop-types'; +import { TableNodeModel } from '../nodes/TableNode'; +import CustomPropTypes from 'sources/custom_prop_types'; + +/* The note component of ERD. It uses tippy to create the floating note */ +export default function FloatingNote({open, onClose, reference, rows, noteNode, ...tippyProps}) { + const textRef = React.useRef(null); + const [text, setText] = useState(''); + const [header, setHeader] = useState(''); + useEffect(()=>{ + if(noteNode) { + setText(noteNode.getNote()); + let [schema, name] = noteNode.getSchemaTableName(); + setHeader(`${name} (${schema})`); + } + + if(open) { + textRef?.current.focus(); + textRef?.current.dispatchEvent(new KeyboardEvent('keypress')); + } + }, [noteNode, open]); + + return ( + ( +
+
{gettext('Note')}:
+
+
{header}
+ +
+ +
+
+
+ )} + visible={open} + interactive={true} + animation={false} + reference={reference} + placement='auto-end' + {...tippyProps} + /> + ); +} + +FloatingNote.propTypes = { + open: PropTypes.bool.isRequired, + onClose: PropTypes.func.isRequired, + reference: CustomPropTypes.ref, + rows: PropTypes.number, + noteNode: PropTypes.object, +}; diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/Loader.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/Loader.jsx new file mode 100644 index 000000000..1934db2fe --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/Loader.jsx @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React from 'react'; +import PropTypes from 'prop-types'; + +/* The loader/spinner component */ +export default function Loader({message, autoEllipsis=false}) { + if(message || message == '') { + return ( +
+
+
+
+
+
{message}{autoEllipsis ? '...':''}
+
+
+ ); + } else { + return null; + } +} + +Loader.propTypes = { + message: PropTypes.string, + autoEllipsis: PropTypes.bool, +}; diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ToolBar.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ToolBar.jsx new file mode 100644 index 000000000..6e025d3a3 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/ToolBar.jsx @@ -0,0 +1,136 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import React, { forwardRef } from 'react'; +import Tippy from '@tippyjs/react'; +import {isMac} from 'sources/keyboard_shortcuts'; +import gettext from 'sources/gettext'; +import PropTypes from 'prop-types'; +import CustomPropTypes from 'sources/custom_prop_types'; + +/* The base icon button. +React does not pass ref prop to child component hierarchy. +Use forwardRef for the same +*/ +const BaseIconButton = forwardRef((props, ref)=>{ + const {icon, text, className, ...otherProps} = props; + + return( + + ); +}); + +BaseIconButton.propTypes = { + icon: PropTypes.string, + text: PropTypes.string, + className: PropTypes.string, + ref: CustomPropTypes.ref, +} + + +/* The tooltip content to show shortcut details */ +export function Shortcut({shortcut}) { + let keys = []; + shortcut.alt && keys.push((isMac() ? 'Option' : 'Alt')); + shortcut.control && keys.push('Ctrl'); + shortcut.shift && keys.push('Shift'); + keys.push(shortcut.key.char.toUpperCase()); + return ( +
+ {keys.map((key, i)=>{ + return
{key}
+ })} +
+ ) +} + +const shortcutPropType = PropTypes.shape({ + alt: PropTypes.bool, + control: PropTypes.bool, + shift: PropTypes.bool, + key: PropTypes.shape({ + char: PropTypes.string, + }), +}); + +Shortcut.propTypes = { + shortcut: shortcutPropType, +}; + +/* The icon button component which can have a tooltip based on props. +React does not pass ref prop to child component hierarchy. +Use forwardRef for the same +*/ +export const IconButton = forwardRef((props, ref) => { + const {title, shortcut, className, ...otherProps} = props; + + if (title) { + return ( + + {
{title}
} + {shortcut && } + + }> + +
+ ); + } else { + return + } +}); + +IconButton.propTypes = { + title: PropTypes.string, + shortcut: shortcutPropType, + className: PropTypes.string, +} + +/* Toggle button, icon changes based on value */ +export function DetailsToggleButton({showDetails, ...props}) { + return ( + + ); +} + +DetailsToggleButton.propTypes = { + showDetails: PropTypes.bool, +} + +/* Button group container */ +export function ButtonGroup({className, children}) { + return ( +
+ {children} +
+ ) +} + +ButtonGroup.propTypes = { + className: PropTypes.string, +} + +/* Toolbar container */ +export default function ToolBar({id, children}) { + return ( + + ) +} + +ButtonGroup.propTypes = { + id: PropTypes.string, +} diff --git a/web/pgadmin/tools/erd/static/js/erd_tool_hook.js b/web/pgadmin/tools/erd/static/js/erd_tool_hook.js new file mode 100644 index 000000000..fce76270c --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/erd_tool_hook.js @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +define([ + 'sources/pgadmin', 'pgadmin.tools.erd/erd_tool', 'pgadmin.browser', + 'pgadmin.browser.server.privilege', 'pgadmin.node.database', 'pgadmin.node.primary_key', + 'pgadmin.node.foreign_key', 'pgadmin.browser.datamodel', 'pgadmin.file_manager', +], function( + pgAdmin, ERDToolModule +) { + var pgTools = pgAdmin.Tools = pgAdmin.Tools || {}; + var ERDTool = ERDToolModule.default; + + /* Return back, this has been called more than once */ + if (pgTools.ERDToolHook) + return pgTools.ERDToolHook; + + pgTools.ERDToolHook = { + load: function(params) { + /* Create the ERD Tool object and render it */ + let erdObj = new ERDTool('#erd-tool-container', params); + erdObj.render(); + }, + }; + + return pgTools.ERDToolHook; +}); + + diff --git a/web/pgadmin/tools/erd/static/js/index.js b/web/pgadmin/tools/erd/static/js/index.js new file mode 100644 index 000000000..b968a5223 --- /dev/null +++ b/web/pgadmin/tools/erd/static/js/index.js @@ -0,0 +1,23 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import gettext from 'sources/gettext'; +import url_for from 'sources/url_for'; +import $ from 'jquery'; +import _ from 'underscore'; +import pgAdmin from 'sources/pgadmin'; +import pgBrowser from 'top/browser/static/js/browser'; +import * as csrfToken from 'sources/csrf'; +import {initialize} from './erd_module'; +var wcDocker = window.wcDocker; + +let pgBrowserOut = initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser, wcDocker); + +module.exports = { + pgBrowser: pgBrowserOut, +}; diff --git a/web/pgadmin/tools/erd/static/scss/_erd.scss b/web/pgadmin/tools/erd/static/scss/_erd.scss new file mode 100644 index 000000000..733dd53c6 --- /dev/null +++ b/web/pgadmin/tools/erd/static/scss/_erd.scss @@ -0,0 +1,189 @@ +.shortcut-key { + padding: 0 0.25rem; + border: 1px solid $border-color; + margin-right: 0.125rem; + border-radius: $btn-border-radius; +} + +#erd-tool-container { + width: 100%; + height: 100%; + + .file-input-hidden { + height: 0; + width: 0; + visibility: hidden; + } + + .text-icon { + font-weight: bold; + } + + .erd-hint-bar { + background: $sql-gutters-bg; + padding: 0.25rem 0.5rem; + } + + .diagram-container { + position: relative; + width: 100%; + height: 100%; + } + + .floating-note { + width: 250px; + border: $panel-border; + border-radius: $panel-border-radius; + box-shadow: $dialog-box-shadow; + background-color: $alert-dialog-body-bg !important; + color: $color-fg !important; + + .note-header { + padding: 0.25rem 0.5rem; + background-color: $alert-header-bg; + font-size: $font-size-base; + font-weight: bold; + color: $alert-header-fg; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + border-radius: 0rem; + border-top-left-radius: $panel-border-radius; + border-top-right-radius: $panel-border-radius; + border-bottom: none; + margin: -$alertify-borderremove-margin; //-24px is default by alertify + margin-bottom: 0px; + } + + .note-body { + & textarea { + width: 100%; + border: none; + border-bottom: $border-width solid $erd-node-border-color; + border-top: $border-width solid $erd-node-border-color; + } + + & .pg_buttons { + padding: 0.25rem; + } + } + } + + .diagram-canvas{ + width: 100%; + height: 100%; + color: $color-fg; + font-family: sans-serif; + background-image: $erd-bg-grid; + cursor: unset; + + .table-node { + background-color: $input-bg; + border: $border-width solid $erd-node-border-color; + border-radius: $input-border-radius; + position: relative; + width: 175px; + font-size: 0.8em; + + &.selected { + border-color: $input-focus-border-color; + box-shadow: $input-btn-focus-box-shadow; + } + + .table-toolbar { + background: $editor-toolbar-bg; + border-bottom: $border-width solid $erd-node-border-color; + padding: 0.125rem; + border-top-left-radius: inherit; + border-top-right-radius: inherit; + display: flex; + + .btn { + &:not(:first-of-type) { + margin-left: 0.125rem; + } + } + } + + .table-schema { + border-bottom: $border-width solid $erd-node-border-color; + padding: $erd-row-padding; + font-weight: bold; + } + + .table-name { + border-bottom: $border-width*2 solid $erd-node-border-color; + padding: $erd-row-padding; + font-weight: bold; + } + + .table-cols { + .col-row { + border-bottom: $border-width solid $erd-node-border-color; + .col-row-data { + padding: $erd-row-padding; + width: 100%; + + .col-name { + word-break: break-all; + } + } + .col-row-port { + padding: 0; + min-height: 0; + } + } + } + } + + .svg-link-ele { + stroke: $erd-link-color; + } + + .svg-link-ele.path { + pointer-events: all; + } + + @keyframes svg-link-ele-selected { + from { stroke-dashoffset: 24; } to { stroke-dashoffset: 0; } + } + + .svg-link-ele.selected { + stroke: $erd-link-selected-color; + stroke-dasharray: 10, 2; + animation: svg-link-ele-selected 1s linear infinite; + } + + .svg-link-ele.svg-otom-circle { + fill: $erd-link-color; + } + + .custom-node-color{ + position: absolute; + top: 50%; + left: 50%; + width: 20px; + height: 20px; + transform: translate(-50%, -50%); + border-radius: 10px; + } + + .circle-port{ + width: 12px; + height: 12px; + margin: 2px; + border-radius: 4px; + background: darkgray; + cursor: pointer; + } + + .circle-port:hover{ + background: mediumpurple; + } + + .port { + display: inline-block; + margin: auto; + } + } +} diff --git a/web/pgadmin/tools/erd/templates/erd/index.html b/web/pgadmin/tools/erd/templates/erd/index.html new file mode 100644 index 000000000..10a0896f5 --- /dev/null +++ b/web/pgadmin/tools/erd/templates/erd/index.html @@ -0,0 +1,55 @@ +{% extends "base.html" %} +{% block title %}{{title}}{% endblock %} + +{% block css_link %} + +{% endblock %} +{% block body %} + +
+
+{% endblock %} +{% block init_script %} + try { + require( + ['sources/generated/browser_nodes', 'sources/generated/codemirror'], + function() { + require(['sources/generated/erd_tool'], function(erdToolHook) { + var erdToolHook = erdToolHook || pgAdmin.Tools.ERDToolHook; + erdToolHook.load({{ params|safe }}); + + if(window.opener) { + $(window).on('unload', function(ev) { + $.ajax({ + method: 'DELETE', + url: '{{close_url}}' + }); + }); + } else { + $(window).on('beforeunload', function(ev) { + $.ajax({ + method: 'DELETE', + url: '{{close_url}}' + }); + }); + } + }, function() { + console.log(arguments); + }); + }, + function() { + console.log(arguments); + }); + } catch (err) { + console.log(err); + } +{% endblock %} diff --git a/web/pgadmin/tools/erd/tests/__init__.py b/web/pgadmin/tools/erd/tests/__init__.py new file mode 100644 index 000000000..8c8c486cc --- /dev/null +++ b/web/pgadmin/tools/erd/tests/__init__.py @@ -0,0 +1,15 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.utils.route import BaseTestGenerator + + +class ERDGenerateTestCase(BaseTestGenerator): + def runTest(self): + return diff --git a/web/pgadmin/tools/erd/tests/sql/12_plus/test_sql_output.sql b/web/pgadmin/tools/erd/tests/sql/12_plus/test_sql_output.sql new file mode 100644 index 000000000..e3d6ab762 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/sql/12_plus/test_sql_output.sql @@ -0,0 +1,25 @@ + + +CREATE TABLE public.newtable1 +( + id integer, + col1 character varying(50), + PRIMARY KEY (id) +); + +CREATE TABLE public.newtable2 +( + table1_id integer, + col2 character varying(50), + PRIMARY KEY (id) +); + +CREATE TABLE public.newtable3 +( +) +; + +ALTER TABLE public.newtable2 + ADD FOREIGN KEY (table1_id) + REFERENCES public.newtable1 (id) + NOT VALID; diff --git a/web/pgadmin/tools/erd/tests/sql/default/test_sql_output.sql b/web/pgadmin/tools/erd/tests/sql/default/test_sql_output.sql new file mode 100644 index 000000000..330e81443 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/sql/default/test_sql_output.sql @@ -0,0 +1,34 @@ + + +CREATE TABLE public.newtable1 +( + id integer, + col1 character varying(50), + PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +); + +CREATE TABLE public.newtable2 +( + table1_id integer, + col2 character varying(50), + PRIMARY KEY (id) +) +WITH ( + OIDS = FALSE +); + +CREATE TABLE public.newtable3 +( +) + +WITH ( + OIDS = FALSE +); + +ALTER TABLE public.newtable2 + ADD FOREIGN KEY (table1_id) + REFERENCES public.newtable1 (id) + NOT VALID; diff --git a/web/pgadmin/tools/erd/tests/test_close.py b/web/pgadmin/tools/erd/tests/test_close.py new file mode 100644 index 000000000..008ddab39 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_close.py @@ -0,0 +1,55 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils + + +class ERDClose(BaseTestGenerator): + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = '/erd/initialize/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.post(url) + self.assertEqual(response.status_code, 200) + + url = '/erd/close/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.delete(url) + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/erd/tests/test_initialize.py b/web/pgadmin/tools/erd/tests/test_initialize.py new file mode 100644 index 000000000..d586bb3b6 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_initialize.py @@ -0,0 +1,54 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils + + +class ERDInitialize(BaseTestGenerator): + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = '/erd/initialize/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.post(url) + self.assertEqual(response.status_code, 200) + response_data = json.loads(response.data.decode('utf-8')) + self.assertEqual(response_data['data'], { + 'connId': '123344', + 'serverVersion': self.server_information['server_version'], + }) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/erd/tests/test_panel.py b/web/pgadmin/tools/erd/tests/test_panel.py new file mode 100644 index 000000000..ad44d004a --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_panel.py @@ -0,0 +1,44 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils + + +class ERDPanel(BaseTestGenerator): + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + url = '/erd/panel/{trans_id}?sgid={sgid}&sid={sid}&server_type=pg' \ + '&did={did}&gen=false'.\ + format(trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.post( + url, data={"title": "panel_title", "close_url": "the/close/url"}, + content_type="application/x-www-form-urlencoded") + self.assertEqual(response.status_code, 200) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/erd/tests/test_prequisite.py b/web/pgadmin/tools/erd/tests/test_prequisite.py new file mode 100644 index 000000000..fed6a0652 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_prequisite.py @@ -0,0 +1,52 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils + + +class ERDPrequisite(BaseTestGenerator): + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + + def runTest(self): + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = '/erd/prequisite/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.get(url) + self.assertEqual(response.status_code, 200) + response_data = json.loads(response.data.decode('utf-8')) + self.assertIn('col_types', response_data['data']) + self.assertIn('schemas', response_data['data']) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/erd/tests/test_sql.py b/web/pgadmin/tools/erd/tests/test_sql.py new file mode 100644 index 000000000..172795c61 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_sql.py @@ -0,0 +1,90 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.utils.versioned_template_loader import \ + get_version_mapping_directories +from os import path + + +class ERDSql(BaseTestGenerator): + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + self.sgid = config_data["server_group"] + self.maxDiff = None + + def get_expected_sql(self): + sql_base_path = path.join( + path.dirname(path.realpath(__file__)), 'sql') + + # Iterate the version mapping directories. + for version_mapping in \ + get_version_mapping_directories(self.server['type']): + if version_mapping['number'] > \ + self.server_information['server_version']: + continue + + complete_path = path.join( + sql_base_path, version_mapping['name']) + + if not path.exists(complete_path): + complete_path = path.join(sql_base_path, 'default') + break + + data_sql = '' + with open(path.join(complete_path, 'test_sql_output.sql')) as fp: + data_sql = fp.read() + + return data_sql + + def runTest(self): + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = '/erd/sql/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + curr_dir = path.dirname(__file__) + + data_json = None + with open(path.join(curr_dir, 'test_sql_input_data.json')) as fp: + data_json = fp.read() + + response = self.tester.post(url, + data=data_json, + content_type='html/json') + self.assertEqual(response.status_code, 200) + + data_sql = self.get_expected_sql() + + resp_sql = json.loads(response.data.decode('utf-8'))['data'] + self.assertEqual(resp_sql, data_sql) + + def tearDown(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) diff --git a/web/pgadmin/tools/erd/tests/test_sql_input_data.json b/web/pgadmin/tools/erd/tests/test_sql_input_data.json new file mode 100644 index 000000000..3c8182e68 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_sql_input_data.json @@ -0,0 +1,106 @@ +{ + "nodes": { + "1d9dc56e-e4f9-48b9-889b-6084ec6446bf": { + "columns": [ + { + "name": "id", + "attnum": 0, + "cltype": "integer", + "is_primary_key": true, + "attnotnull": false, + "attlen": null, + "attprecision": null, + "attidentity": "a", + "colconstype": "n" + }, + { + "name": "col1", + "attnum": 1, + "cltype": "character varying", + "min_val_attlen": 1, + "max_val_attlen": 2147483647, + "is_primary_key": false, + "attnotnull": false, + "attlen": 50, + "attprecision": null, + "attidentity": "a", + "colconstype": "n" + } + ], + "name": "newtable1", + "schema": "public", + "primary_key": [ + { + "columns": [ + { + "column": "id" + } + ], + "include": [] + } + ] + }, + "c4fee4ad-cf32-4fc6-bb87-98b896bcab60": { + "name": "newtable2", + "schema": "public", + "columns": [ + { + "name": "table1_id", + "attnum": 0, + "cltype": "integer", + "is_primary_key": false, + "attnotnull": false, + "attlen": null, + "attprecision": null, + "attidentity": "a", + "colconstype": "n", + "old_attidentity": "a" + }, + { + "name": "col2", + "attnum": 1, + "cltype": "character varying", + "min_val_attlen": 1, + "max_val_attlen": 2147483647, + "is_primary_key": false, + "attnotnull": false, + "attlen": 50, + "attprecision": null, + "attidentity": "a", + "colconstype": "n", + "old_attidentity": "a" + } + ], + "primary_key": [ + { + "columns": [ + { + "column": "id" + } + ], + "include": [] + } + ] + }, + "f001a770-d6fa-4572-b88b-11dd5e38d30c": { + "columns": [], + "name": "newtable3", + "schema": "public", + "primary_key": [] + } + }, + "links": { + "998de19a-caa0-431e-9cf7-97827f01022b": { + "schema": "public", + "table": "newtable2", + "remote_schema": "public", + "remote_table": "newtable1", + "columns": [ + { + "local_column": "table1_id", + "referenced": "id" + } + ] + } + } +} diff --git a/web/pgadmin/tools/erd/tests/test_tables.py b/web/pgadmin/tools/erd/tests/test_tables.py new file mode 100644 index 000000000..b8de11646 --- /dev/null +++ b/web/pgadmin/tools/erd/tests/test_tables.py @@ -0,0 +1,79 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +import json +import uuid + +from pgadmin.utils.route import BaseTestGenerator +from regression.python_test_utils import test_utils as utils +from regression import parent_node_dict +from regression.test_setup import config_data +from pgadmin.browser.server_groups.servers.databases.tests import utils as \ + database_utils +from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \ + import utils as tables_utils +from pgadmin.browser.server_groups.servers.databases.schemas.tests import \ + utils as schema_utils + + +class ERDTables(BaseTestGenerator): + + def dropDB(self): + connection = utils.get_db_connection(self.server['db'], + self.server['username'], + self.server['db_password'], + self.server['host'], + self.server['port']) + utils.drop_database(connection, self.db_name) + + def setUp(self): + self.db_name = "erdtestdb" + self.sid = parent_node_dict["server"][-1]["server_id"] + self.did = utils.create_database(self.server, self.db_name) + + try: + self.sgid = config_data["server_group"] + self.tables = [ + ["erd1", "table_1"], ["erd2", "table_2"] + ] + + for tab in self.tables: + connection = utils.get_db_connection( + self.db_name, self.server['username'], + self.server['db_password'], self.server['host'], + self.server['port']) + schema_utils.create_schema(connection, tab[0]) + tables_utils.create_table(self.server, self.db_name, tab[0], + tab[1]) + connection.close() + except Exception as _: + self.dropDB() + raise + + def runTest(self): + db_con = database_utils.connect_database(self, + self.sgid, + self.sid, + self.did) + + if not db_con["info"] == "Database connected.": + raise Exception("Could not connect to database to add the schema.") + + url = '/erd/tables/{trans_id}/{sgid}/{sid}/{did}'.format( + trans_id=123344, sgid=self.sgid, sid=self.sid, did=self.did) + + response = self.tester.get(url) + self.assertEqual(response.status_code, 200) + + response = json.loads(response.data.decode('utf-8')) + self.assertEqual(self.tables, [[tab['schema'], tab['name']] + for tab in response['data']]) + + def tearDown(self): + self.dropDB() diff --git a/web/pgadmin/tools/erd/utils.py b/web/pgadmin/tools/erd/utils.py new file mode 100644 index 000000000..1999a71e5 --- /dev/null +++ b/web/pgadmin/tools/erd/utils.py @@ -0,0 +1,71 @@ +########################################################################## +# +# pgAdmin 4 - PostgreSQL Tools +# +# Copyright (C) 2013 - 2020, The pgAdmin Development Team +# This software is released under the PostgreSQL Licence +# +########################################################################## + +from pgadmin.browser.server_groups.servers.databases.schemas.tables.utils \ + import BaseTableView +from pgadmin.browser.server_groups.servers.databases.schemas.utils \ + import get_schemas +from pgadmin.browser.server_groups.servers.databases.schemas.utils \ + import DataTypeReader + + +class ERDTableView(BaseTableView, DataTypeReader): + def __init__(self): + super(BaseTableView, self).__init__(cmd='erd') + + @BaseTableView.check_precondition + def sql(self, conn_id=None, did=None, sid=None, data={}): + return BaseTableView.get_sql(self, did, None, None, data, None) + + @BaseTableView.check_precondition + def get_types(self, conn_id=None, did=None, sid=None): + condition = self.get_types_condition_sql(False) + return DataTypeReader.get_types(self, self.conn, condition, True) + + @BaseTableView.check_precondition + def fetch_all_tables(self, conn_id=None, did=None, sid=None): + status, schemas = get_schemas(self.conn, show_system_objects=False) + if not status: + return status, schemas + + all_tables = [] + for row in schemas['rows']: + status, res = \ + BaseTableView.fetch_tables(self, sid, did, row['oid']) + if not status: + return status, res + + all_tables.extend(res.values()) + + return True, all_tables + + +class ERDHelper: + def __init__(self, conn_id, sid, did): + self.conn_id = conn_id + self.did = did + self.sid = sid + self.table_view = ERDTableView() + self.link_view = None + + def get_types(self): + return self.table_view.get_types( + conn_id=self.conn_id, did=self.did, sid=self.sid) + + def get_table_sql(self, data): + SQL, name = self.table_view.sql( + conn_id=self.conn_id, did=self.did, sid=self.sid, + data=data) + return SQL + + def get_all_tables(self): + status, res = self.table_view.fetch_all_tables( + conn_id=self.conn_id, did=self.did, sid=self.sid) + + return status, res diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js index 612612c30..48364f6c5 100644 --- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js @@ -2651,6 +2651,12 @@ define('tools.querytool', [ } }); + } else if(url_params.sql_id) { + let sqlValue = localStorage.getItem(url_params.sql_id); + localStorage.removeItem(url_params.sql_id); + if(sqlValue) { + self.gridView.query_tool_obj.setValue(sqlValue); + } } } else { @@ -2668,7 +2674,7 @@ define('tools.querytool', [ }, set_value_to_editor: function(query) { - if (this.gridView && this.gridView.query_tool_obj && !_.isUndefined(query)) { + if (this.gridView && this.gridView.query_tool_obj && !_.isUndefined(query) && query != '') { this.gridView.query_tool_obj.setValue(query); } }, diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py index 12a94a541..23abfffaf 100644 --- a/web/pgadmin/utils/csrf.py +++ b/web/pgadmin/utils/csrf.py @@ -36,7 +36,8 @@ class _PGCSRFProtect(CSRFProtect): 'pgadmin.tools.debugger.direct_new', 'pgadmin.tools.schema_diff.panel', 'pgadmin.tools.schema_diff.ddl_compare', - 'pgadmin.authenticate.login' + 'pgadmin.authenticate.login', + 'pgadmin.tools.erd.panel', ] for exempt in exempt_views: diff --git a/web/regression/javascript/erd/erd_core_spec.js b/web/regression/javascript/erd/erd_core_spec.js new file mode 100644 index 000000000..c488ffdf2 --- /dev/null +++ b/web/regression/javascript/erd/erd_core_spec.js @@ -0,0 +1,382 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore'; +import * as createEngineLib from '@projectstorm/react-diagrams'; +import TEST_TABLES_DATA from './test_tables'; + +describe('ERDCore', ()=>{ + let eleFactory = jasmine.createSpyObj('nodeFactories', { + 'registerFactory': null, + 'getFactory': jasmine.createSpyObj('getFactory', ['generateModel', 'calculateRoutingMatrix']), + }); + let erdEngine = jasmine.createSpyObj('engine', { + 'getNodeFactories': eleFactory, + 'getLinkFactories': eleFactory, + 'getPortFactories': eleFactory, + 'getActionEventBus': jasmine.createSpyObj('actionBus', ['fireAction', 'deregisterAction', 'registerAction']), + 'setModel': null, + 'getModel': jasmine.createSpyObj('modelObj', { + 'addNode': null, + 'clearSelection': null, + 'getNodesDict': null, + 'getLinks': null, + 'serialize': ()=>({ + 'data': 'serialized', + }), + 'addLink': null, + 'getNodes': null, + 'setZoomLevel': null, + 'getZoomLevel': null, + 'fireEvent': null, + 'registerListener': null, + }), + 'repaintCanvas': null, + 'zoomToFit': null, + 'fireEvent': null, + }); + + beforeAll(()=>{ + spyOn(createEngineLib, 'default').and.returnValue(erdEngine); + }); + + it('initialization', ()=>{ + spyOn(ERDCore.prototype, 'initializeEngine').and.callThrough(); + spyOn(ERDCore.prototype, 'initializeModel').and.callThrough(); + spyOn(ERDCore.prototype, 'computeTableCounter').and.callThrough(); + let erdCoreObj = new ERDCore(); + expect(erdCoreObj.initializeEngine).toHaveBeenCalled(); + expect(erdCoreObj.initializeModel).toHaveBeenCalled(); + expect(erdCoreObj.computeTableCounter).toHaveBeenCalled(); + }); + + describe('functions', ()=>{ + let erdCoreObj; + + beforeAll(()=>{ + erdCoreObj = new ERDCore(); + }); + + describe('cache check', ()=>{ + it('for single value', ()=>{ + erdCoreObj.setCache('key1', 'value1'); + expect(erdCoreObj.getCache('key1')).toEqual('value1'); + }); + + it('for multiple value', ()=>{ + erdCoreObj.setCache({'key1': 'valuem1', 'key2': 'valuem2'}); + expect(erdCoreObj.getCache('key1')).toEqual('valuem1'); + expect(erdCoreObj.getCache('key2')).toEqual('valuem2'); + }); + }); + + it('registerModelEvent', ()=>{ + let fn = ()=>{}; + erdCoreObj.registerModelEvent('someEvent', fn); + expect(erdCoreObj.getModel().registerListener).toHaveBeenCalledWith({ + 'someEvent': fn, + }); + }); + + it('getNextTableName', ()=>{ + expect(erdCoreObj.getNextTableName()).toEqual('newtable1'); + expect(erdCoreObj.getNextTableName()).toEqual('newtable2'); + }); + + it('getEngine', ()=>{ + expect(erdCoreObj.getEngine()).toBe(erdEngine); + }); + + it('getNewNode', ()=>{ + let data = {name: 'table1'}; + erdCoreObj.getNewNode(data); + + expect(erdEngine.getNodeFactories().getFactory().generateModel).toHaveBeenCalledWith({ + initialConfig: { + otherInfo: { + data:data, + }, + }, + }); + }); + + it('getNewLink', ()=>{ + let data = {name: 'link1'}; + erdCoreObj.getNewLink('linktype', data); + + expect(erdEngine.getLinkFactories().getFactory).toHaveBeenCalledWith('linktype'); + expect(erdEngine.getLinkFactories().getFactory().generateModel).toHaveBeenCalledWith({ + initialConfig: { + data: data, + }, + }); + }); + + it('getNewPort', ()=>{ + let data = {name: 'link1'}; + let options = {opt1: 'val1'}; + erdCoreObj.getNewPort('porttype', data, options); + + expect(erdEngine.getPortFactories().getFactory).toHaveBeenCalledWith('porttype'); + expect(erdEngine.getPortFactories().getFactory().generateModel).toHaveBeenCalledWith({ + initialConfig: { + data:data, + options:options, + }, + }); + }); + + it('addNode', ()=>{ + let newNode = jasmine.createSpyObj('newNode', ['setPosition']); + spyOn(erdCoreObj, 'getNewNode').and.returnValue(newNode); + spyOn(erdCoreObj, 'clearSelection'); + + let data = {name: 'link1'}; + + /* Without position */ + erdCoreObj.addNode(data); + expect(erdCoreObj.getNewNode).toHaveBeenCalledWith(data); + expect(erdEngine.getModel().addNode).toHaveBeenCalledWith(newNode); + expect(erdCoreObj.clearSelection).toHaveBeenCalled(); + + /* With position */ + erdCoreObj.addNode(data, [108, 108]); + expect(erdCoreObj.getNewNode().setPosition).toHaveBeenCalledWith(108, 108); + }); + + + it('addLink', ()=>{ + let nodesDict = { + 'id1': { + serializeData: function(){ return { + 'name': 'table1', + };}, + getPortName: function(attnum) { + return `port-${attnum}`; + }, + getPort: function() { + return null; + }, + addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj), + }, + 'id2': { + serializeData: function(){ return { + 'name': 'table2', + };}, + getPortName: function(attnum) { + return `port-${attnum}`; + }, + getPort: function() { + return null; + }, + addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj), + }, + }; + let link = jasmine.createSpyObj('link', ['setSourcePort', 'setTargetPort']); + spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue(nodesDict); + spyOn(erdCoreObj, 'getNewLink').and.callFake(function() { + return link; + }); + spyOn(erdCoreObj, 'getNewPort').and.callFake(function(type, initData, options) { + return { + name: options.name, + }; + }); + + erdCoreObj.addLink({ + 'referenced_column_attnum': 1, + 'referenced_table_uid': 'id1', + 'local_column_attnum': 3, + 'local_table_uid': 'id2', + }, 'onetomany'); + + expect(nodesDict['id1'].addPort).toHaveBeenCalledWith({name: 'port-1'}); + expect(nodesDict['id2'].addPort).toHaveBeenCalledWith({name: 'port-3'}); + expect(link.setSourcePort).toHaveBeenCalledWith({name: 'port-1'}); + expect(link.setTargetPort).toHaveBeenCalledWith({name: 'port-3'}); + + }); + + it('serialize', ()=>{ + let retVal = erdCoreObj.serialize(); + expect(retVal.hasOwnProperty('version')).toBeTruthy(); + expect(retVal.hasOwnProperty('data')).toBeTruthy(); + expect(erdEngine.getModel().serialize).toHaveBeenCalled(); + }); + + it('deserialize', ()=>{ + let deserialValue = { + 'version': 123, + 'data': { + 'key': 'serialized', + }, + }; + spyOn(erdCoreObj, 'initializeModel'); + erdCoreObj.deserialize(deserialValue); + expect(erdCoreObj.initializeModel).toHaveBeenCalledWith(deserialValue.data); + }); + + it('serializeData', ()=>{ + spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue({ + 'id1': { + serializeData: function(){ return { + 'name': 'table1', + };}, + }, + 'id2': { + serializeData: function(){ return { + 'name': 'table2', + };}, + }, + }); + spyOn(erdEngine.getModel(), 'getLinks').and.returnValue([ + { + serializeData: function(){ return { + 'name': 'link1', + };}, + getID: function(){ return 'lid1'; }, + }, + { + serializeData: function(){ return { + 'name': 'link2', + };}, + getID: function(){ return 'lid2'; }, + }, + ]); + expect(JSON.stringify(erdCoreObj.serializeData())).toEqual(JSON.stringify({ + nodes: { + 'id1': {'name': 'table1'}, + 'id2': {'name': 'table2'}, + }, + links: { + 'lid1': {'name': 'link1'}, + 'lid2': {'name': 'link2'}, + }, + })); + }); + + it('deserializeData', (done)=>{ + let nodesDict = {}; + TEST_TABLES_DATA.forEach((table)=>{ + nodesDict[`id-${table.name}`] = { + getColumns: function() { + return table.columns; + }, + getPortName: function(attnum) { + return `port-${attnum}`; + }, + getPort: function(name) { + return {'name': name}; + }, + addPort: function() { + + }, + }; + }); + spyOn(erdEngine.getModel(), 'getNodesDict').and.returnValue(nodesDict); + + spyOn(erdCoreObj, 'getNewLink').and.callFake(function() { + return { + setSourcePort: function() {}, + setTargetPort: function() {}, + }; + }); + spyOn(erdCoreObj, 'getNewPort').and.returnValue({id: 'id'}); + spyOn(erdCoreObj, 'addNode').and.callFake(function(data) { + return { + getID: function() { + return `id-${data.name}`; + }, + }; + }); + spyOn(erdCoreObj, 'addLink'); + spyOn(erdCoreObj, 'dagreDistributeNodes'); + + erdCoreObj.deserializeData(TEST_TABLES_DATA); + expect(erdCoreObj.addNode).toHaveBeenCalledTimes(TEST_TABLES_DATA.length); + expect(erdCoreObj.addLink).toHaveBeenCalledTimes(1); + + setTimeout(()=>{ + expect(erdCoreObj.dagreDistributeNodes).toHaveBeenCalled(); + done(); + }, 10); + }); + + it('clearSelection', ()=>{ + erdCoreObj.clearSelection(); + expect(erdEngine.getModel().clearSelection).toHaveBeenCalled(); + }); + + it('repaint', ()=>{ + erdCoreObj.repaint(); + expect(erdEngine.repaintCanvas).toHaveBeenCalled(); + }); + + it('getNodesData', ()=>{ + spyOn(erdEngine.getModel(), 'getNodes').and.returnValue([ + {getData: function () {return {name:'node1'};}}, + {getData: function () {return {name:'node2'};}}, + ]); + expect(JSON.stringify(erdCoreObj.getNodesData())).toEqual(JSON.stringify([ + {name:'node1'}, {name:'node2'}, + ])); + }); + + it('dagreDistributeNodes', ()=>{ + spyOn(erdCoreObj.dagre_engine, 'redistribute'); + erdCoreObj.dagreDistributeNodes(); + expect(erdEngine.getLinkFactories().getFactory().calculateRoutingMatrix).toHaveBeenCalled(); + expect(erdCoreObj.dagre_engine.redistribute).toHaveBeenCalledWith(erdEngine.getModel()); + }); + + it('zoomIn', ()=>{ + spyOn(erdEngine.getModel(), 'getZoomLevel').and.returnValue(100); + spyOn(erdCoreObj, 'repaint'); + erdCoreObj.zoomIn(); + expect(erdEngine.getModel().setZoomLevel).toHaveBeenCalledWith(125); + expect(erdCoreObj.repaint).toHaveBeenCalled(); + }); + + it('zoomOut', ()=>{ + spyOn(erdEngine.getModel(), 'getZoomLevel').and.returnValue(100); + spyOn(erdCoreObj, 'repaint'); + erdCoreObj.zoomOut(); + expect(erdEngine.getModel().setZoomLevel).toHaveBeenCalledWith(75); + expect(erdCoreObj.repaint).toHaveBeenCalled(); + }); + + it('zoomToFit', ()=>{ + erdCoreObj.zoomToFit(); + expect(erdEngine.zoomToFit).toHaveBeenCalled(); + }); + + it('fireAction', ()=>{ + erdCoreObj.fireAction({key: 'xyz'}); + expect(erdEngine.getActionEventBus().fireAction).toHaveBeenCalled(); + }); + + it('fireEvent', ()=>{ + erdCoreObj.fireEvent({key: 'xyz'}, 'someevent', false); + expect(erdEngine.fireEvent).toHaveBeenCalledWith({key: 'xyz'}, 'someevent'); + + erdCoreObj.fireEvent({key: 'xyz'}, 'someevent', true); + expect(erdEngine.getModel().fireEvent).toHaveBeenCalledWith({key: 'xyz'}, 'someevent'); + }); + + it('registerKeyAction', ()=>{ + erdCoreObj.registerKeyAction({key: 'xyz'}); + expect(erdEngine.getActionEventBus().registerAction).toHaveBeenCalledWith({key: 'xyz'}); + }); + + it('deregisterKeyAction', ()=>{ + let action = {key: 'xyz'}; + erdCoreObj.deregisterKeyAction(action); + expect(erdEngine.getActionEventBus().deregisterAction).toHaveBeenCalledWith({key: 'xyz'}); + }); + }); +}); diff --git a/web/regression/javascript/erd/erd_model_spec.js b/web/regression/javascript/erd/erd_model_spec.js new file mode 100644 index 000000000..cfdcc0983 --- /dev/null +++ b/web/regression/javascript/erd/erd_model_spec.js @@ -0,0 +1,34 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import ERDModel from 'pgadmin.tools.erd/erd_tool/ERDModel'; + +describe('ERDModel', ()=>{ + it('getNodesDict', ()=>{ + let model = new ERDModel(); + + spyOn(model, 'getNodes').and.returnValue([ + { + name: 'test1', + getID: function() { + return 'id1'; + }, + }, + { + name: 'test2', + getID: function() { + return 'id2'; + }, + }, + ]); + expect(JSON.stringify(model.getNodesDict())).toBe(JSON.stringify({ + 'id1': {name: 'test1'}, + 'id2': {name: 'test2'}, + })); + }); +}); diff --git a/web/regression/javascript/erd/keyboard_shortcut_action_spec.js b/web/regression/javascript/erd/keyboard_shortcut_action_spec.js new file mode 100644 index 000000000..3134795ea --- /dev/null +++ b/web/regression/javascript/erd/keyboard_shortcut_action_spec.js @@ -0,0 +1,61 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2020, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// +import {KeyboardShortcutAction} from 'pgadmin.tools.erd/erd_tool/ui_components/BodyWidget'; + +describe('KeyboardShortcutAction', ()=>{ + let keyAction = null; + let key1 = { + alt: true, + control: true, + shift: false, + key: { + key_code: 65, + }, + }; + let key2 = { + alt: false, + control: true, + shift: false, + key: { + key_code: 66, + }, + }; + let handler1 = jasmine.createSpy('handler1'); + let handler2 = jasmine.createSpy('handler2'); + + beforeAll(()=>{ + spyOn(KeyboardShortcutAction.prototype, 'shortcutKey').and.callThrough(); + keyAction = new KeyboardShortcutAction([ + [key1, handler1], + [key2, handler2], + ]); + }); + + it('init', ()=>{ + expect(Object.keys(keyAction.shortcuts).length).toBe(2); + }); + + it('shortcutKey', ()=>{ + expect(keyAction.shortcutKey(true, true, true, true, 65)).toBe('true:true:true:true:65'); + expect(keyAction.shortcutKey(true, false, true, true, 65)).toBe('true:false:true:true:65'); + expect(keyAction.shortcutKey(true, true, false, true, 65)).toBe('true:true:false:true:65'); + expect(keyAction.shortcutKey(true, true, true, false, 65)).toBe('true:true:true:false:65'); + expect(keyAction.shortcutKey(false, true, true, true, 65)).toBe('false:true:true:true:65'); + }); + + it('callHandler', ()=>{ + let keyEvent = {altKey: key1.alt, ctrlKey: key1.control, shiftKey: key1.shift, metaKey: false, keyCode:key1.key.key_code}; + keyAction.callHandler(keyEvent); + expect(handler1).toHaveBeenCalled(); + + keyEvent = {altKey: key2.alt, ctrlKey: key2.control, shiftKey: key2.shift, metaKey: false, keyCode:key2.key.key_code}; + keyAction.callHandler(keyEvent); + expect(handler2).toHaveBeenCalled(); + }); +}); diff --git a/web/regression/javascript/erd/onetomany_link_spec.js b/web/regression/javascript/erd/onetomany_link_spec.js new file mode 100644 index 000000000..a7590db64 --- /dev/null +++ b/web/regression/javascript/erd/onetomany_link_spec.js @@ -0,0 +1,133 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {mount} from 'enzyme'; +import '../helper/enzyme.helper'; +import { + RightAngleLinkModel, +} from '@projectstorm/react-diagrams'; + +import OneToManyPortModel from 'pgadmin.tools.erd/erd_tool/ports/OneToManyPort'; +import {OneToManyLinkModel, OneToManyLinkWidget, OneToManyLinkFactory} from 'pgadmin.tools.erd/erd_tool/links/OneToManyLink'; + + +describe('ERD OneToManyLinkModel', ()=>{ + let modelObj = null; + beforeAll(()=>{ + spyOn(RightAngleLinkModel.prototype, 'serialize').and.returnValue({'key': 'value'}); + }); + beforeEach(()=>{ + modelObj = new OneToManyLinkModel({ + data: { + local_table_uid: 'id1', + local_column_attnum: 0, + referenced_table_uid: 'id2', + referenced_column_attnum: 1, + }, + }); + }); + + it('init', ()=>{ + expect(modelObj.getData()).toEqual({ + local_table_uid: 'id1', + local_column_attnum: 0, + referenced_table_uid: 'id2', + referenced_column_attnum: 1, + }); + }); + + it('setData', ()=>{ + modelObj.setData({ + local_column_attnum: 2, + referenced_column_attnum: 4, + }); + expect(modelObj.getData()).toEqual({ + local_column_attnum: 2, + referenced_column_attnum: 4, + }); + }); + + it('serializeData', ()=>{ + let nodesDict = { + 'id1': { + getData: function(){ return { + 'name': 'table1', + 'schema': 'erd1', + 'columns': [ + {'name': 'col11', attnum: 0}, + {'name': 'col12', attnum: 1}, + ], + };}, + }, + 'id2': { + getData: function(){ return { + 'name': 'table2', + 'schema': 'erd2', + 'columns': [ + {'name': 'col21', attnum: 0}, + {'name': 'col22', attnum: 1}, + ], + };}, + }, + }; + + expect(modelObj.serializeData(nodesDict)).toEqual({ + 'schema': 'erd1', + 'table': 'table1', + 'remote_schema': 'erd2', + 'remote_table': 'table2', + 'columns': [{ + 'local_column': 'col11', + 'referenced': 'col22', + }], + }); + }); + + it('serialize', ()=>{ + let retVal = modelObj.serialize(); + expect(RightAngleLinkModel.prototype.serialize).toHaveBeenCalled(); + expect(retVal).toEqual({ + key: 'value', + data: { + local_table_uid: 'id1', + local_column_attnum: 0, + referenced_table_uid: 'id2', + referenced_column_attnum: 1, + }, + }); + }); +}); + +describe('ERD OneToManyLinkWidget', ()=>{ + let linkFactory = new OneToManyLinkFactory(); + let engine = { + getFactoryForLink: ()=>linkFactory, + }; + let link = null; + + beforeEach(()=>{ + jasmineEnzyme(); + + link = new OneToManyLinkModel({ + color: '#000', + data: { + local_table_uid: 'id1', + local_column_attnum: 0, + referenced_table_uid: 'id2', + referenced_column_attnum: 1, + }, + }); + link.setSourcePort(new OneToManyPortModel({options: {}})); + link.setTargetPort(new OneToManyPortModel({options: {}})); + }); + + it('render', ()=>{ + let linkWidget = mount( + + ); + + let paths = linkWidget.find('g g'); + expect(paths.at(0).find('polyline').length).toBe(1); + expect(paths.at(paths.length-1).find('polyline').length).toBe(1); + expect(paths.at(paths.length-1).find('circle').length).toBe(1); + }); +}); diff --git a/web/regression/javascript/erd/onetomany_port_spec.js b/web/regression/javascript/erd/onetomany_port_spec.js new file mode 100644 index 000000000..0ad4831ef --- /dev/null +++ b/web/regression/javascript/erd/onetomany_port_spec.js @@ -0,0 +1,21 @@ +import { PortModel } from '@projectstorm/react-diagrams-core'; +import OneToManyPortModel from 'pgadmin.tools.erd/erd_tool/ports/OneToManyPort'; +import {OneToManyLinkModel} from 'pgadmin.tools.erd/erd_tool/links/OneToManyLink'; + +describe('ERD OneToManyPortModel', ()=>{ + it('removeAllLinks', ()=>{ + let link1 = jasmine.createSpyObj('link1', ['remove']); + let link2 = jasmine.createSpyObj('link2', ['remove']); + spyOn(PortModel.prototype, 'getLinks').and.returnValue([link1, link2]); + + let portObj = new OneToManyPortModel({options: {}}); + portObj.removeAllLinks(); + expect(link1.remove).toHaveBeenCalled(); + expect(link2.remove).toHaveBeenCalled(); + }); + + it('createLinkModel', ()=>{ + let portObj = new OneToManyPortModel({options: {}}); + expect(portObj.createLinkModel()).toBeInstanceOf(OneToManyLinkModel); + }); +}); diff --git a/web/regression/javascript/erd/table_node_spec.js b/web/regression/javascript/erd/table_node_spec.js new file mode 100644 index 000000000..d8edcdb44 --- /dev/null +++ b/web/regression/javascript/erd/table_node_spec.js @@ -0,0 +1,305 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {mount} from 'enzyme'; +import '../helper/enzyme.helper'; +import { DefaultNodeModel } from '@projectstorm/react-diagrams'; + +import {TableNodeModel, TableNodeWidget} from 'pgadmin.tools.erd/erd_tool/nodes/TableNode'; +import { IconButton, DetailsToggleButton } from 'pgadmin.tools.erd/erd_tool/ui_components/ToolBar'; + + +describe('ERD TableNodeModel', ()=>{ + let modelObj = null; + beforeAll(()=>{ + spyOn(DefaultNodeModel.prototype, 'serialize').and.returnValue({'key': 'value'}); + }); + beforeEach(()=>{ + modelObj = new TableNodeModel({ + color: '#000', + otherInfo: { + note: 'some note', + data: { + name: 'table1', + schema: 'erd', + }, + }, + }); + }); + + it('init', ()=>{ + expect(modelObj.getData()).toEqual({ + columns: [], + name: 'table1', + schema: 'erd', + }); + expect(modelObj.getNote()).toBe('some note'); + expect(modelObj.getColumns()).toEqual([]); + }); + + it('getPortName', ()=>{ + expect(modelObj.getPortName(2)).toBe('coll-port-2'); + }); + + it('setNote', ()=>{ + modelObj.setNote('some note to test'); + expect(modelObj.getNote()).toBe('some note to test'); + }); + + it('addColumn', ()=>{ + modelObj.addColumn({name: 'col1', not_null:false, attnum: 0}); + expect(modelObj.getColumns()).toEqual([{name: 'col1', not_null:false, attnum: 0}]); + }); + + it('getColumnAt', ()=>{ + modelObj.addColumn({name: 'col1', not_null:false, attnum: 0}); + modelObj.addColumn({name: 'col2', not_null:false, attnum: 1}); + expect(modelObj.getColumnAt(0)).toEqual({name: 'col1', not_null:false, attnum: 0}); + expect(modelObj.getColumnAt(1)).toEqual({name: 'col2', not_null:false, attnum: 1}); + expect(modelObj.getColumnAt(2)).toBeUndefined(); + }); + + it('setName', ()=>{ + modelObj.setName('changedName'); + expect(modelObj.getData().name).toBe('changedName'); + }); + + it('cloneData', ()=>{ + modelObj.addColumn({name: 'col1', not_null:false, attnum: 0}); + expect(modelObj.cloneData('clonedNode')).toEqual({ + name: 'clonedNode', + schema: 'erd', + columns: [{name: 'col1', not_null:false, attnum: 0}], + }); + }); + + describe('setData', ()=>{ + let existPort = jasmine.createSpyObj('port', ['removeAllLinks']); + + beforeEach(()=>{ + modelObj._data.columns = [ + {name: 'col1', not_null:false, attnum: 0}, + {name: 'col2', not_null:false, attnum: 1}, + {name: 'col3', not_null:false, attnum: 2}, + ]; + + spyOn(modelObj, 'getPort').and.callFake((portName)=>{ + /* If new port added there will not be any port */ + if(portName !== 'coll-port-3') { + return existPort; + } + }); + spyOn(modelObj, 'removePort'); + spyOn(modelObj, 'getPortName'); + }); + + it('add columns', ()=>{ + existPort.removeAllLinks.calls.reset(); + modelObj.setData({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col1', not_null:false, attnum: 0}, + {name: 'col2', not_null:false, attnum: 1}, + {name: 'col3', not_null:false, attnum: 2}, + {name: 'col4', not_null:false, attnum: 3}, + ], + }); + expect(modelObj.getData()).toEqual({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col1', not_null:false, attnum: 0}, + {name: 'col2', not_null:false, attnum: 1}, + {name: 'col3', not_null:false, attnum: 2}, + {name: 'col4', not_null:false, attnum: 3}, + ], + }); + expect(existPort.removeAllLinks).not.toHaveBeenCalled(); + }); + + it('update columns', ()=>{ + existPort.removeAllLinks.calls.reset(); + modelObj.setData({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col1', not_null:false, attnum: 0}, + {name: 'col2updated', not_null:false, attnum: 1}, + {name: 'col3', not_null:true, attnum: 2}, + ], + }); + expect(modelObj.getData()).toEqual({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col1', not_null:false, attnum: 0}, + {name: 'col2updated', not_null:false, attnum: 1}, + {name: 'col3', not_null:true, attnum: 2}, + ], + }); + expect(existPort.removeAllLinks).not.toHaveBeenCalled(); + }); + + it('remove columns', ()=>{ + existPort.removeAllLinks.calls.reset(); + modelObj.setData({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col2', not_null:false, attnum: 1}, + {name: 'col3', not_null:false, attnum: 2}, + ], + }); + expect(modelObj.getData()).toEqual({ + name: 'noname', + schema: 'erd', + columns: [ + {name: 'col2', not_null:false, attnum: 1}, + {name: 'col3', not_null:false, attnum: 2}, + ], + }); + + expect(modelObj.getPortName).toHaveBeenCalledWith(0); + expect(existPort.removeAllLinks).toHaveBeenCalled(); + expect(modelObj.removePort).toHaveBeenCalledWith(existPort); + }); + }); + + it('getSchemaTableName', ()=>{ + expect(modelObj.getSchemaTableName()).toEqual(['erd', 'table1']); + }); + + it('serializeData', ()=>{ + modelObj.addColumn({name: 'col1', not_null:false, attnum: 0}); + expect(modelObj.serializeData()).toEqual({ + name: 'table1', + schema: 'erd', + columns: [{name: 'col1', not_null:false, attnum: 0}], + }); + }); + + it('serialize', ()=>{ + let retVal = modelObj.serialize(); + expect(DefaultNodeModel.prototype.serialize).toHaveBeenCalled(); + expect(retVal).toEqual({ + key: 'value', + otherInfo: { + data: { + columns: [], + name: 'table1', + schema: 'erd', + }, + note: 'some note', + }, + }); + }); +}); + +describe('ERD TableNodeWidget', ()=>{ + let node = null; + + beforeEach(()=>{ + jasmineEnzyme(); + + node = new TableNodeModel({ + color: '#000', + otherInfo: { + note: 'some note', + data: { + name: 'table1', + schema: 'erd', + columns: [{ + attnum: 0, + is_primary_key: true, + name: 'id', + cltype: 'integer', + attlen: null, + attprecision: null, + }, { + attnum: 1, + is_primary_key: false, + name: 'amount', + cltype: 'number', + attlen: 10, + attprecision: 5, + }, { + attnum: 2, + is_primary_key: false, + name: 'desc', + cltype: 'character varrying', + attlen: 50, + attprecision: null, + }], + }, + }, + }); + }); + + it('render', ()=>{ + let nodeWidget = mount(); + expect(nodeWidget.getDOMNode().className).toBe('table-node '); + expect(nodeWidget.find('.table-node .table-toolbar').length).toBe(1); + expect(nodeWidget.find('.table-node .table-schema').text()).toBe('erd'); + expect(nodeWidget.find('.table-node .table-name').text()).toBe('table1'); + expect(nodeWidget.find('.table-node .table-cols').length).toBe(1); + expect(nodeWidget.find(DetailsToggleButton).length).toBe(1); + expect(nodeWidget.find(IconButton).findWhere(n => n.prop('title')=='Check note').length).toBe(1); + }); + + it('node selected', ()=>{ + spyOn(node, 'isSelected').and.returnValue(true); + let nodeWidget = mount(); + expect(nodeWidget.getDOMNode().className).toBe('table-node selected'); + }); + + it('remove note', ()=>{ + node.setNote(''); + let nodeWidget = mount(); + expect(nodeWidget.find(IconButton).findWhere(n => n.prop('title')=='Check note').length).toBe(0); + }); + + describe('generateColumn', ()=>{ + let nodeWidget = null; + + beforeEach(()=>{ + nodeWidget = mount(); + }); + + it('count', ()=>{ + expect(nodeWidget.find('.table-node .table-cols .col-row').length).toBe(3); + }); + + it('icons', ()=>{ + let cols = nodeWidget.find('.table-node .table-cols .col-row-data'); + expect(cols.at(0).find('.wcTabIcon').hasClass('icon-primary_key')).toBeTrue(); + expect(cols.at(1).find('.wcTabIcon').hasClass('icon-column')).toBeTrue(); + expect(cols.at(2).find('.wcTabIcon').hasClass('icon-column')).toBeTrue(); + }); + + it('column names', ()=>{ + let cols = nodeWidget.find('.table-node .table-cols .col-row-data'); + expect(cols.at(0).find('.col-name').text()).toBe('id'); + expect(cols.at(1).find('.col-name').text()).toBe('amount'); + expect(cols.at(2).find('.col-name').text()).toBe('desc'); + }); + + it('data types', ()=>{ + let cols = nodeWidget.find('.table-node .table-cols .col-row-data'); + expect(cols.at(0).find('.col-datatype').text()).toBe('integer'); + expect(cols.at(1).find('.col-datatype').text()).toBe('number(10,5)'); + expect(cols.at(2).find('.col-datatype').text()).toBe('character varrying(50)'); + }); + + it('show_details', (done)=>{ + nodeWidget.setState({show_details: false}); + expect(nodeWidget.find('.table-node .table-cols .col-row-data .col-datatype').length).toBe(0); + + nodeWidget.instance().toggleShowDetails(jasmine.createSpyObj('event', ['preventDefault'])); + /* Dummy set state to wait for toggleShowDetails -> setState to complete */ + nodeWidget.setState({}, ()=>{ + expect(nodeWidget.find('.table-node .table-cols .col-row-data .col-datatype').length).toBe(3); + done(); + }); + }); + }); +}); diff --git a/web/regression/javascript/erd/test_tables.js b/web/regression/javascript/erd/test_tables.js new file mode 100644 index 000000000..e2dc43ef8 --- /dev/null +++ b/web/regression/javascript/erd/test_tables.js @@ -0,0 +1,651 @@ +export default [ + { + 'oid': 123456, + 'name': 'test1', + 'spcoid': 0, + 'relacl_str': null, + 'spcname': 'pg_default', + 'schema': 'schema1', + 'relowner': 'postgres', + 'relkind': 'r', + 'is_partitioned': false, + 'relhassubclass': false, + 'reltuples': '0', + 'description': null, + 'conname': null, + 'conkey': null, + 'isrepl': false, + 'triggercount': '0', + 'coll_inherits': [], + 'inherited_tables_cnt': '0', + 'relpersistence': false, + 'fillfactor': null, + 'parallel_workers': null, + 'toast_tuple_target': null, + 'autovacuum_enabled': 'x', + 'autovacuum_vacuum_threshold': null, + 'autovacuum_vacuum_scale_factor': null, + 'autovacuum_analyze_threshold': null, + 'autovacuum_analyze_scale_factor': null, + 'autovacuum_vacuum_cost_delay': null, + 'autovacuum_vacuum_cost_limit': null, + 'autovacuum_freeze_min_age': null, + 'autovacuum_freeze_max_age': null, + 'autovacuum_freeze_table_age': null, + 'toast_autovacuum_enabled': 'x', + 'toast_autovacuum_vacuum_threshold': null, + 'toast_autovacuum_vacuum_scale_factor': null, + 'toast_autovacuum_analyze_threshold': null, + 'toast_autovacuum_analyze_scale_factor': null, + 'toast_autovacuum_vacuum_cost_delay': null, + 'toast_autovacuum_vacuum_cost_limit': null, + 'toast_autovacuum_freeze_min_age': null, + 'toast_autovacuum_freeze_max_age': null, + 'toast_autovacuum_freeze_table_age': null, + 'reloptions': null, + 'toast_reloptions': null, + 'reloftype': 0, + 'typname': null, + 'typoid': null, + 'rlspolicy': false, + 'forcerlspolicy': false, + 'hastoasttable': false, + 'seclabels': null, + 'is_sys_table': false, + 'partition_scheme': '', + 'autovacuum_custom': false, + 'toast_autovacuum': false, + 'rows_cnt': 0, + 'vacuum_settings_str': '', + 'vacuum_table': [ + { + 'name': 'autovacuum_analyze_scale_factor', + 'setting': '0.1', + 'label': 'ANALYZE scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_analyze_threshold', + 'setting': '50', + 'label': 'ANALYZE base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_max_age', + 'setting': '200000000', + 'label': 'FREEZE maximum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_delay', + 'setting': '2', + 'label': 'VACUUM cost delay', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_limit', + 'setting': '-1', + 'label': 'VACUUM cost limit', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_scale_factor', + 'setting': '0.2', + 'label': 'VACUUM scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_vacuum_threshold', + 'setting': '50', + 'label': 'VACUUM base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_min_age', + 'setting': '50000000', + 'label': 'FREEZE minimum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_table_age', + 'setting': '150000000', + 'label': 'FREEZE table age', + 'column_type': 'integer', + }, + ], + 'vacuum_toast': [ + { + 'name': 'autovacuum_freeze_max_age', + 'setting': '200000000', + 'label': 'FREEZE maximum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_delay', + 'setting': '2', + 'label': 'VACUUM cost delay', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_limit', + 'setting': '-1', + 'label': 'VACUUM cost limit', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_scale_factor', + 'setting': '0.2', + 'label': 'VACUUM scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_vacuum_threshold', + 'setting': '50', + 'label': 'VACUUM base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_min_age', + 'setting': '50000000', + 'label': 'FREEZE minimum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_table_age', + 'setting': '150000000', + 'label': 'FREEZE table age', + 'column_type': 'integer', + }, + ], + 'columns': [{ + 'name': 'id', + 'atttypid': 23, + 'attlen': null, + 'attnum': 1, + 'attndims': 0, + 'atttypmod': -1, + 'attacl': [], + 'attnotnull': true, + 'attoptions': null, + 'attstattarget': -1, + 'attstorage': 'p', + 'attidentity': '', + 'defval': null, + 'typname': 'integer', + 'displaytypname': 'integer', + 'cltype': 'integer', + 'elemoid': 23, + 'typnspname': 'pg_catalog', + 'defaultstorage': 'p', + 'description': null, + 'indkey': '1', + 'isdup': false, + 'collspcname': '', + 'is_fk': false, + 'seclabels': null, + 'is_sys_column': false, + 'colconstype': 'n', + 'genexpr': null, + 'relname': 'tab1', + 'is_view_only': false, + 'seqrelid': null, + 'seqtypid': null, + 'seqstart': null, + 'seqincrement': null, + 'seqmax': null, + 'seqmin': null, + 'seqcache': null, + 'seqcycle': null, + 'is_pk': true, + 'is_primary_key': true, + 'attprecision': null, + 'edit_types': [ + 'bigint', + 'double precision', + 'information_schema.cardinal_number', + 'integer', + 'money', + 'numeric', + 'oid', + 'real', + 'regclass', + 'regconfig', + 'regdictionary', + 'regnamespace', + 'regoper', + 'regoperator', + 'regproc', + 'regprocedure', + 'regrole', + 'regtype', + 'smallint', + ], + }], + 'primary_key': [], + 'unique_constraint': [], + 'check_constraint': [], + 'index': {}, + 'rule': {}, + 'trigger': {}, + 'row_security_policy': {}, + }, + { + 'oid': 408229, + 'name': 'test2', + 'spcoid': 0, + 'relacl_str': null, + 'spcname': 'pg_default', + 'schema': 'erd', + 'relowner': 'postgres', + 'relkind': 'r', + 'is_partitioned': false, + 'relhassubclass': false, + 'reltuples': '0', + 'description': null, + 'conname': 'tab1_pkey', + 'conkey': [ + 1, + ], + 'isrepl': false, + 'triggercount': '0', + 'coll_inherits': [], + 'inherited_tables_cnt': '0', + 'relpersistence': false, + 'fillfactor': null, + 'parallel_workers': null, + 'toast_tuple_target': null, + 'autovacuum_enabled': 'x', + 'autovacuum_vacuum_threshold': null, + 'autovacuum_vacuum_scale_factor': null, + 'autovacuum_analyze_threshold': null, + 'autovacuum_analyze_scale_factor': null, + 'autovacuum_vacuum_cost_delay': null, + 'autovacuum_vacuum_cost_limit': null, + 'autovacuum_freeze_min_age': null, + 'autovacuum_freeze_max_age': null, + 'autovacuum_freeze_table_age': null, + 'toast_autovacuum_enabled': 'x', + 'toast_autovacuum_vacuum_threshold': null, + 'toast_autovacuum_vacuum_scale_factor': null, + 'toast_autovacuum_analyze_threshold': null, + 'toast_autovacuum_analyze_scale_factor': null, + 'toast_autovacuum_vacuum_cost_delay': null, + 'toast_autovacuum_vacuum_cost_limit': null, + 'toast_autovacuum_freeze_min_age': null, + 'toast_autovacuum_freeze_max_age': null, + 'toast_autovacuum_freeze_table_age': null, + 'reloptions': null, + 'toast_reloptions': null, + 'reloftype': 0, + 'typname': null, + 'typoid': null, + 'rlspolicy': false, + 'forcerlspolicy': false, + 'hastoasttable': false, + 'seclabels': null, + 'is_sys_table': false, + 'partition_scheme': '', + 'autovacuum_custom': false, + 'toast_autovacuum': false, + 'rows_cnt': 0, + 'vacuum_settings_str': '', + 'vacuum_table': [ + { + 'name': 'autovacuum_analyze_scale_factor', + 'setting': '0.1', + 'label': 'ANALYZE scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_analyze_threshold', + 'setting': '50', + 'label': 'ANALYZE base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_max_age', + 'setting': '200000000', + 'label': 'FREEZE maximum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_delay', + 'setting': '2', + 'label': 'VACUUM cost delay', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_limit', + 'setting': '-1', + 'label': 'VACUUM cost limit', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_scale_factor', + 'setting': '0.2', + 'label': 'VACUUM scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_vacuum_threshold', + 'setting': '50', + 'label': 'VACUUM base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_min_age', + 'setting': '50000000', + 'label': 'FREEZE minimum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_table_age', + 'setting': '150000000', + 'label': 'FREEZE table age', + 'column_type': 'integer', + }, + ], + 'vacuum_toast': [ + { + 'name': 'autovacuum_freeze_max_age', + 'setting': '200000000', + 'label': 'FREEZE maximum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_delay', + 'setting': '2', + 'label': 'VACUUM cost delay', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_cost_limit', + 'setting': '-1', + 'label': 'VACUUM cost limit', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_vacuum_scale_factor', + 'setting': '0.2', + 'label': 'VACUUM scale factor', + 'column_type': 'number', + }, + { + 'name': 'autovacuum_vacuum_threshold', + 'setting': '50', + 'label': 'VACUUM base threshold', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_min_age', + 'setting': '50000000', + 'label': 'FREEZE minimum age', + 'column_type': 'integer', + }, + { + 'name': 'autovacuum_freeze_table_age', + 'setting': '150000000', + 'label': 'FREEZE table age', + 'column_type': 'integer', + }, + ], + 'columns': [ + { + 'name': 'id', + 'atttypid': 23, + 'attlen': null, + 'attnum': 1, + 'attndims': 0, + 'atttypmod': -1, + 'attacl': [], + 'attnotnull': true, + 'attoptions': null, + 'attstattarget': -1, + 'attstorage': 'p', + 'attidentity': '', + 'defval': null, + 'typname': 'integer', + 'displaytypname': 'integer', + 'cltype': 'integer', + 'elemoid': 23, + 'typnspname': 'pg_catalog', + 'defaultstorage': 'p', + 'description': null, + 'indkey': '1', + 'isdup': false, + 'collspcname': '', + 'is_fk': false, + 'seclabels': null, + 'is_sys_column': false, + 'colconstype': 'n', + 'genexpr': null, + 'relname': 'tab1', + 'is_view_only': false, + 'seqrelid': null, + 'seqtypid': null, + 'seqstart': null, + 'seqincrement': null, + 'seqmax': null, + 'seqmin': null, + 'seqcache': null, + 'seqcycle': null, + 'is_pk': true, + 'is_primary_key': true, + 'attprecision': null, + 'edit_types': [ + 'bigint', + 'double precision', + 'information_schema.cardinal_number', + 'integer', + 'money', + 'numeric', + 'oid', + 'real', + 'regclass', + 'regconfig', + 'regdictionary', + 'regnamespace', + 'regoper', + 'regoperator', + 'regproc', + 'regprocedure', + 'regrole', + 'regtype', + 'smallint', + ], + }, + { + 'name': 'col1col1col1col1col1col1col1col1', + 'atttypid': 23, + 'attlen': null, + 'attnum': 2, + 'attndims': 0, + 'atttypmod': -1, + 'attacl': [], + 'attnotnull': true, + 'attoptions': null, + 'attstattarget': -1, + 'attstorage': 'p', + 'attidentity': '', + 'defval': null, + 'typname': 'integer', + 'displaytypname': 'integer', + 'cltype': 'integer', + 'elemoid': 23, + 'typnspname': 'pg_catalog', + 'defaultstorage': 'p', + 'description': null, + 'indkey': '1', + 'isdup': false, + 'collspcname': '', + 'is_fk': true, + 'seclabels': null, + 'is_sys_column': false, + 'colconstype': 'n', + 'genexpr': null, + 'relname': 'tab1', + 'is_view_only': false, + 'seqrelid': null, + 'seqtypid': null, + 'seqstart': null, + 'seqincrement': null, + 'seqmax': null, + 'seqmin': null, + 'seqcache': null, + 'seqcycle': null, + 'is_pk': false, + 'is_primary_key': false, + 'attprecision': null, + 'edit_types': [ + 'bigint', + 'double precision', + 'information_schema.cardinal_number', + 'integer', + 'integer', + 'money', + 'numeric', + 'oid', + 'real', + 'regclass', + 'regconfig', + 'regdictionary', + 'regnamespace', + 'regoper', + 'regoperator', + 'regproc', + 'regprocedure', + 'regrole', + 'regtype', + 'smallint', + ], + }, + { + 'name': 'col2', + 'atttypid': 23, + 'attlen': null, + 'attnum': 3, + 'attndims': 0, + 'atttypmod': -1, + 'attacl': [], + 'attnotnull': false, + 'attoptions': null, + 'attstattarget': -1, + 'attstorage': 'p', + 'attidentity': '', + 'defval': null, + 'typname': 'integer', + 'displaytypname': 'integer', + 'cltype': 'integer', + 'elemoid': 23, + 'typnspname': 'pg_catalog', + 'defaultstorage': 'p', + 'description': null, + 'indkey': '1', + 'isdup': false, + 'collspcname': '', + 'is_fk': false, + 'seclabels': null, + 'is_sys_column': false, + 'colconstype': 'n', + 'genexpr': null, + 'relname': 'tab1', + 'is_view_only': false, + 'seqrelid': null, + 'seqtypid': null, + 'seqstart': null, + 'seqincrement': null, + 'seqmax': null, + 'seqmin': null, + 'seqcache': null, + 'seqcycle': null, + 'is_pk': false, + 'is_primary_key': false, + 'attprecision': null, + 'edit_types': [ + 'bigint', + 'double precision', + 'information_schema.cardinal_number', + 'integer', + 'integer', + 'integer', + 'money', + 'numeric', + 'oid', + 'real', + 'regclass', + 'regconfig', + 'regdictionary', + 'regnamespace', + 'regoper', + 'regoperator', + 'regproc', + 'regprocedure', + 'regrole', + 'regtype', + 'smallint', + ], + }, + ], + 'primary_key': [ + { + 'oid': 408232, + 'name': 'tab1_pkey', + 'col_count': 1, + 'spcname': 'pg_default', + 'comment': null, + 'condeferrable': false, + 'condeferred': false, + 'fillfactor': null, + 'columns': [ + { + 'column': 'id', + }, + ], + 'include': [], + }, + ], + 'unique_constraint': [], + 'foreign_key': [ + { + 'oid': 408239, + 'name': 'tab1_col1_fkey', + 'condeferrable': false, + 'condeferred': false, + 'confupdtype': 'a', + 'confdeltype': 'a', + 'confmatchtype': false, + 'conkey': [ + 2, + ], + 'confkey': [ + 1, + ], + 'confrelid': 408234, + 'fknsp': 'erd', + 'fktab': 'tab1', + 'refnsp': 'erd', + 'reftab': 'tab2', + 'comment': null, + 'convalidated': false, + 'columns': [ + { + 'local_column': 'col1col1col1col1col1col1col1col1', + 'references': 123456, + 'referenced': 'id', + 'references_table_name': 'schema1.test1', + }, + ], + 'remote_schema': 'schema1', + 'remote_table': 'test1', + 'coveringindex': null, + 'autoindex': true, + 'hasindex': false, + }, + ], + 'check_constraint': [], + 'index': {}, + 'rule': {}, + 'trigger': {}, + 'row_security_policy': {}, + }, +]; diff --git a/web/regression/javascript/erd/ui_components/body_widget_spec.js b/web/regression/javascript/erd/ui_components/body_widget_spec.js new file mode 100644 index 000000000..16928980f --- /dev/null +++ b/web/regression/javascript/erd/ui_components/body_widget_spec.js @@ -0,0 +1,514 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {mount} from 'enzyme'; +import '../../helper/enzyme.helper'; +import MockAdapter from 'axios-mock-adapter'; +import axios from 'axios/index'; + +import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore'; +import * as erdModule from 'pgadmin.tools.erd/erd_module'; +import erdPref from './erd_preferences'; +import BodyWidget from 'pgadmin.tools.erd/erd_tool/ui_components/BodyWidget'; +import * as ERDSqlTool from 'tools/datagrid/static/js/show_query_tool'; + +let pgAdmin = { + Browser: { + Events: { + on: jasmine.createSpy('on'), + }, + get_preferences_for_module: function() { + return erdPref; + }, + docker: { + findPanels: function() { + return [ + { + isVisible: function() { + return true; + }, + }, + ]; + }, + }, + onPreferencesChange: ()=>{}, + utils: { + app_version_int: 1234, + }, + }, + FileManager: { + init: jasmine.createSpy(), + show_dialog: jasmine.createSpy(), + }, +}; + +let alertify = jasmine.createSpyObj('alertify', { + 'success': null, + 'error': null, + 'confirm': null, + 'alert': { + 'set': ()=>{}, + }, +}); + +let tableDialog = jasmine.createSpyObj('TableDialog', ['show']); +let otmDialog = jasmine.createSpyObj('otmDialog', ['show']); +let mtmDialog = jasmine.createSpyObj('mtmDialog', ['show']); + +let getDialog = (dialogName)=>{ + switch(dialogName) { + case 'entity_dialog': return tableDialog; + case 'onetomany_dialog': return otmDialog; + case 'manytomany_dialog': return mtmDialog; + } +}; + +describe('ERD BodyWidget', ()=>{ + let body = null; + let bodyInstance = null; + let networkMock = null; + let serverVersion = 120000; + let colTypes = [ + {'label': 'integer', 'value': 'integer'}, + {'label': 'character varrying', 'value': 'character varrying'}, + ]; + let schemas = [ + {'oid': 111, 'name': 'erd1'}, + {'oid': 222, 'name': 'erd2'}, + ]; + let params = { + bgcolor: null, + client_platform: 'macos', + did: '13637', + fgcolor: null, + gen: true, + is_desktop_mode: true, + is_linux: false, + server_type: 'pg', + sgid: '1', + sid: '5', + title: 'postgres/postgres@PostgreSQL 12', + trans_id: 110008, + }; + + beforeAll(()=>{ + spyOn(erdModule, 'setPanelTitle'); + spyOn(ERDCore.prototype, 'repaint'); + spyOn(ERDCore.prototype, 'deserializeData'); + spyOn(ERDCore.prototype, 'addNode').and.returnValue({ + setSelected: ()=>{}, + getColumns: ()=>([{attnum: 0}, {attnum: 1}]), + getID: ()=>'newid1', + }); + spyOn(ERDCore.prototype, 'addLink').and.returnValue({ + setSelected: ()=>{}, + }); + spyOn(alertify, 'confirm').and.callFake((arg1, arg2, okCallback)=>{ + okCallback(); + }); + + networkMock = new MockAdapter(axios); + networkMock.onPost('/erd/initialize/110008/1/5/13637').reply(200, {'data': { + serverVersion: serverVersion, + }}); + networkMock.onGet('/erd/prequisite/110008/1/5/13637').reply(200, {'data': { + 'col_types': colTypes, + 'schemas': schemas, + }}); + networkMock.onGet('/erd/tables/110008/1/5/13637').reply(200, {'data': []}); + + networkMock.onPost('/erd/sql/110008/1/5/13637').reply(200, {'data': 'SELECT 1;'}); + + networkMock.onPost('/sqleditor/load_file/').reply(200, {'data': 'data'}); + networkMock.onPost('/sqleditor/save_file/').reply(200, {'data': 'data'}); + }); + + beforeEach(()=>{ + jasmineEnzyme(); + body = mount({}} alertify={alertify}/>); + bodyInstance = body.instance(); + }); + + afterAll(() => { + networkMock.restore(); + if(body) { + body.unmount(); + } + }); + + it('constructor', (done)=>{ + + expect(body.find('ToolBar').length).toBe(1); + expect(body.find('ConnectionBar').length).toBe(1); + expect(body.find('FloatingNote').length).toBe(1); + expect(body.find('.diagram-container Loader').length).toBe(1); + expect(body.find('.diagram-container CanvasWidget').length).toBe(1); + + body.instance().setState({}, ()=>{ + let instance = body.instance(); + + setTimeout(()=>{ + expect(body.state()).toEqual(jasmine.objectContaining({ + server_version: serverVersion, + preferences: erdPref, + })); + expect(instance.diagram.getCache('colTypes')).toEqual(colTypes); + expect(instance.diagram.getCache('schemas')).toEqual(schemas); + done(); + }); + }); + }); + + it('event offsetUpdated', (done)=>{ + bodyInstance.diagram.fireEvent({offsetX: 4, offsetY: 5}, 'offsetUpdated', true); + setTimeout(()=>{ + expect(bodyInstance.canvasEle.style.backgroundPosition).toBe('4px 5px'); + done(); + }); + }); + + it('event zoomUpdated', (done)=>{ + spyOn(bodyInstance.diagram.getModel(), 'getOptions').and.returnValue({gridSize: 15}); + bodyInstance.diagram.fireEvent({zoom: 20}, 'zoomUpdated', true); + setTimeout(()=>{ + expect(bodyInstance.canvasEle.style.backgroundSize).toBe('9px 9px'); + done(); + }); + }); + + it('event nodesSelectionChanged', (done)=>{ + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([{key:'value'}]); + bodyInstance.diagram.fireEvent({}, 'nodesSelectionChanged', true); + setTimeout(()=>{ + expect(body.state().single_node_selected).toBe(true); + expect(body.state().any_item_selected).toBe(true); + done(); + }); + }); + + it('event linksSelectionChanged', (done)=>{ + spyOn(bodyInstance.diagram, 'getSelectedLinks').and.returnValue([{key:'value'}]); + bodyInstance.diagram.fireEvent({}, 'linksSelectionChanged', true); + setTimeout(()=>{ + expect(body.state().single_link_selected).toBe(true); + expect(body.state().any_item_selected).toBe(true); + done(); + }); + }); + + it('event linksUpdated', (done)=>{ + bodyInstance.diagram.fireEvent({}, 'linksUpdated', true); + setTimeout(()=>{ + expect(body.state().dirty).toBe(true); + done(); + }); + }); + + it('event nodesUpdated', (done)=>{ + bodyInstance.diagram.fireEvent({}, 'nodesUpdated', true); + setTimeout(()=>{ + expect(body.state().dirty).toBe(true); + done(); + }); + }); + + it('event showNote', (done)=>{ + let noteNode = {key: 'value', getNote: ()=>'a note'}; + spyOn(bodyInstance, 'showNote'); + bodyInstance.diagram.fireEvent({node: noteNode}, 'showNote', true); + setTimeout(()=>{ + expect(bodyInstance.showNote).toHaveBeenCalledWith(noteNode); + done(); + }); + }); + + it('event editNode', (done)=>{ + let node = {key: 'value', getNote: ()=>'a note'}; + spyOn(bodyInstance, 'addEditNode'); + bodyInstance.diagram.fireEvent({node: node}, 'editNode', true); + setTimeout(()=>{ + expect(bodyInstance.addEditNode).toHaveBeenCalledWith(node); + done(); + }); + }); + + it('getDialog', ()=>{ + bodyInstance.getDialog('entity_dialog')(); + expect(tableDialog.show).toHaveBeenCalled(); + + bodyInstance.getDialog('onetomany_dialog')(); + expect(otmDialog.show).toHaveBeenCalled(); + + bodyInstance.getDialog('manytomany_dialog')(); + expect(mtmDialog.show).toHaveBeenCalled(); + }); + + it('addEditNode', ()=>{ + /* New */ + tableDialog.show.calls.reset(); + bodyInstance.addEditNode(); + expect(tableDialog.show).toHaveBeenCalled(); + + let saveCallback = tableDialog.show.calls.mostRecent().args[5]; + let newData = {key: 'value'}; + saveCallback(newData); + expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith(newData); + + /* Existing */ + tableDialog.show.calls.reset(); + let node = jasmine.createSpyObj('node',{ + getSchemaTableName: ['erd1', 'table1'], + setData: null, + getData: null, + }); + bodyInstance.addEditNode(node); + expect(tableDialog.show).toHaveBeenCalled(); + + saveCallback = tableDialog.show.calls.mostRecent().args[5]; + newData = {key: 'value'}; + saveCallback(newData); + expect(node.setData).toHaveBeenCalledWith(newData); + }); + + it('onEditNode', ()=>{ + let node = {key: 'value'}; + spyOn(bodyInstance, 'addEditNode'); + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]); + bodyInstance.onEditNode(); + expect(bodyInstance.addEditNode).toHaveBeenCalledWith(node); + }); + + it('onAddNewNode', ()=>{ + spyOn(bodyInstance, 'addEditNode'); + bodyInstance.onAddNewNode(); + expect(bodyInstance.addEditNode).toHaveBeenCalled(); + }); + + it('onCloneNode', ()=>{ + let node = jasmine.createSpyObj('node',{ + getSchemaTableName: ['erd1', 'table1'], + setData: null, + getData: null, + cloneData: {key: 'value'}, + getPosition: {x: 30, y: 30}, + }); + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]); + spyOn(bodyInstance.diagram, 'getNextTableName').and.returnValue('newtable1'); + bodyInstance.onCloneNode(); + expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith({key: 'value'}, [50, 50]); + }); + + it('onDeleteNode', (done)=>{ + let node = jasmine.createSpyObj('node',{ + getSchemaTableName: ['erd1', 'table1'], + setData: null, + getData: null, + cloneData: {key: 'value'}, + getPosition: {x: 30, y: 30}, + remove: null, + setSelected: null, + }); + let link = jasmine.createSpyObj('link', { + remove: null, + setSelected: null, + getTargetPort: jasmine.createSpyObj('port', ['remove']), + getSourcePort: jasmine.createSpyObj('port', ['remove']), + }); + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]); + spyOn(bodyInstance.diagram, 'getSelectedLinks').and.returnValue([link]); + + bodyInstance.onDeleteNode(); + setTimeout(()=>{ + expect(node.remove).toHaveBeenCalled(); + expect(link.remove).toHaveBeenCalled(); + done(); + }); + }); + + it('onAutoDistribute', ()=>{ + spyOn(bodyInstance.diagram, 'dagreDistributeNodes'); + bodyInstance.onAutoDistribute(); + expect(bodyInstance.diagram.dagreDistributeNodes).toHaveBeenCalled(); + }); + + it('onDetailsToggle', (done)=>{ + let node = jasmine.createSpyObj('node',['fireEvent']); + spyOn(bodyInstance.diagram, 'getModel').and.returnValue({ + 'getNodes': ()=>[node], + }); + + let show_details = body.state().show_details; + bodyInstance.onDetailsToggle(); + body.setState({}, ()=>{ + expect(body.state().show_details).toBe(!show_details); + expect(node.fireEvent).toHaveBeenCalledWith({show_details: !show_details}, 'toggleDetails'); + done(); + }); + }); + + it('onLoadDiagram', ()=>{ + bodyInstance.onLoadDiagram(); + expect(pgAdmin.FileManager.show_dialog).toHaveBeenCalled(); + }); + + it('openFile', (done)=>{ + spyOn(bodyInstance.diagram, 'deserialize'); + bodyInstance.openFile('test.pgerd'); + setTimeout(()=>{ + expect(body.state()).toEqual(jasmine.objectContaining({ + current_file: 'test.pgerd', + dirty: false, + })); + expect(bodyInstance.diagram.deserialize).toHaveBeenCalledWith({data: 'data'}); + done(); + }); + }); + + it('onSaveDiagram', (done)=>{ + body.setState({ + current_file: 'newfile.pgerd', + }); + bodyInstance.onSaveDiagram(); + setTimeout(()=>{ + expect(body.state()).toEqual(jasmine.objectContaining({ + current_file: 'newfile.pgerd', + dirty: false, + })); + done(); + }); + + bodyInstance.onSaveDiagram(true); + expect(pgAdmin.FileManager.show_dialog).toHaveBeenCalledWith({ + 'supported_types': ['pgerd'], + 'dialog_type': 'create_file', + 'dialog_title': 'Save File', + 'btn_primary': 'Save', + }); + }); + + it('onSaveAsDiagram', ()=>{ + spyOn(bodyInstance, 'onSaveDiagram'); + bodyInstance.onSaveAsDiagram(); + expect(bodyInstance.onSaveDiagram).toHaveBeenCalledWith(true); + }); + + it('onSQLClick', (done)=>{ + spyOn(bodyInstance.diagram, 'serializeData').and.returnValue({key: 'value'}); + spyOn(ERDSqlTool, 'showERDSqlTool'); + spyOn(localStorage, 'setItem'); + bodyInstance.onSQLClick(); + + setTimeout(()=>{ + let sql = '-- This script was generated by a beta version of the ERD tool in pgAdmin 4.\n' + + '-- Please log an issue at https://redmine.postgresql.org/projects/pgadmin4/issues/new if you find any bugs, including reproduction steps.\n' + + 'BEGIN;\nSELECT 1;\nEND;'; + + expect(localStorage.setItem).toHaveBeenCalledWith('erd'+params.trans_id, sql); + expect(ERDSqlTool.showERDSqlTool).toHaveBeenCalled(); + done(); + }); + }); + + it('onOneToManyClick', ()=>{ + let node = jasmine.createSpyObj('node',{ + getID: 'id1', + }); + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]); + + otmDialog.show.calls.reset(); + bodyInstance.onOneToManyClick(); + expect(otmDialog.show).toHaveBeenCalled(); + + let saveCallback = otmDialog.show.calls.mostRecent().args[4]; + let newData = {key: 'value'}; + saveCallback(newData); + expect(bodyInstance.diagram.addLink).toHaveBeenCalledWith(newData, 'onetomany'); + }); + + it('onManyToManyClick', ()=>{ + let node = jasmine.createSpyObj('node',{ + getID: 'id1', + }); + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([node]); + + mtmDialog.show.calls.reset(); + bodyInstance.onManyToManyClick(); + expect(mtmDialog.show).toHaveBeenCalled(); + + /* onSave */ + let nodesDict = { + 'id1': { + getID: ()=>'id1', + getData: ()=>({name: 'table1', schema: 'erd1'}), + getColumnAt: ()=>({name: 'col1', type: 'type1', attnum: 0}), + addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj), + }, + 'id2': { + getID: ()=>'id2', + getData: ()=>({name: 'table2', schema: 'erd2'}), + getColumnAt: ()=>({name: 'col2', type: 'type2', attnum: 1}), + addPort: jasmine.createSpy('addPort').and.callFake((obj)=>obj), + }, + }; + spyOn(bodyInstance.diagram, 'getModel').and.returnValue({ + 'getNodesDict': ()=>nodesDict, + }); + spyOn(bodyInstance.diagram, 'addLink'); + let saveCallback = mtmDialog.show.calls.mostRecent().args[4]; + let newData = { + left_table_uid: 'id1', + left_table_column_attnum: 1, + right_table_uid: 'id2', + right_table_column_attnum: 2, + }; + + bodyInstance.diagram.addNode.calls.reset(); + bodyInstance.diagram.addLink.calls.reset(); + saveCallback(newData); + expect(bodyInstance.diagram.addNode).toHaveBeenCalledWith({ + name: 'table1_table2', + schema: 'erd1', + columns: [ + { + type: 'type1', + name: 'table1_col1', + is_primary_key: false, + attnum: 0, + }, + { + type: 'type2', + name: 'table2_col2', + is_primary_key: false, + attnum: 1, + }, + ], + }); + + let linkData = { + local_table_uid: 'newid1', + local_column_attnum: 0, + referenced_table_uid: 'id1', + referenced_column_attnum : 1, + }; + expect(bodyInstance.diagram.addLink.calls.argsFor(0)).toEqual([linkData, 'onetomany']); + linkData = { + local_table_uid: 'newid1', + local_column_attnum: 1, + referenced_table_uid: 'id2', + referenced_column_attnum : 2, + }; + expect(bodyInstance.diagram.addLink.calls.argsFor(1)).toEqual([linkData, 'onetomany']); + }); + + it('onNoteClick', ()=>{ + let noteNode = {key: 'value', getNote: ()=>'a note'}; + spyOn(bodyInstance.diagram, 'getSelectedNodes').and.returnValue([noteNode]); + spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').and.returnValue(null); + spyOn(bodyInstance.diagram.getEngine(), 'getNodeElement').and.returnValue(null); + spyOn(bodyInstance, 'setState'); + bodyInstance.onNoteClick(); + expect(bodyInstance.setState).toHaveBeenCalledWith({ + note_node: noteNode, + note_open: true, + }); + }); +}); diff --git a/web/regression/javascript/erd/ui_components/connection_bar_spec.js b/web/regression/javascript/erd/ui_components/connection_bar_spec.js new file mode 100644 index 000000000..17398a54e --- /dev/null +++ b/web/regression/javascript/erd/ui_components/connection_bar_spec.js @@ -0,0 +1,25 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {mount} from 'enzyme'; +import '../../helper/enzyme.helper'; + +import ConnectionBar, {STATUS} from 'pgadmin.tools.erd/erd_tool/ui_components/ConnectionBar'; + +describe('ERD ConnectionBar', ()=>{ + beforeEach(()=>{ + jasmineEnzyme(); + }); + + it(' comp', ()=>{ + let connBar = mount(); + + expect(connBar.find('.editor-title').text()).toBe('test title'); + + connBar.setProps({status: STATUS.CONNECTING}); + expect(connBar.find('.editor-title').text()).toBe('(Obtaining connection...) test title'); + + connBar.setProps({bgcolor: '#000', fgcolor: '#fff'}); + expect(connBar.find('.editor-title').prop('style').backgroundColor).toBe('#000'); + expect(connBar.find('.editor-title').prop('style').color).toBe('#fff'); + }); +}); diff --git a/web/regression/javascript/erd/ui_components/erd_preferences.js b/web/regression/javascript/erd/ui_components/erd_preferences.js new file mode 100644 index 000000000..d91b158ce --- /dev/null +++ b/web/regression/javascript/erd/ui_components/erd_preferences.js @@ -0,0 +1,147 @@ +export default { + 'erd_new_browser_tab': false, + 'open_project': { + 'alt': false, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 79, + 'char': 'o', + }, + }, + 'save_project': { + 'alt': false, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 83, + 'char': 's', + }, + }, + 'save_project_as': { + 'alt': false, + 'shift': true, + 'control': true, + 'key': { + 'key_code': 83, + 'char': 's', + }, + }, + 'generate_sql': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 83, + 'char': 's', + }, + }, + 'download_image': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 73, + 'char': 'i', + }, + }, + 'add_table': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 65, + 'char': 'a', + }, + }, + 'edit_table': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 69, + 'char': 'e', + }, + }, + 'clone_table': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 67, + 'char': 'c', + }, + }, + 'drop_table': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 68, + 'char': 'd', + }, + }, + 'add_edit_note': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 78, + 'char': 'n', + }, + }, + 'one_to_many': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 79, + 'char': 'o', + }, + }, + 'many_to_many': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 77, + 'char': 'm', + }, + }, + 'auto_align': { + 'alt': true, + 'shift': false, + 'control': true, + 'key': { + 'key_code': 76, + 'char': 'l', + }, + }, + 'zoom_to_fit': { + 'alt': true, + 'shift': true, + 'control': false, + 'key': { + 'key_code': 70, + 'char': 'f', + }, + }, + 'zoom_in': { + 'alt': true, + 'shift': true, + 'control': false, + 'key': { + 'key_code': 187, + 'char': '+', + }, + }, + 'zoom_out': { + 'alt': true, + 'shift': true, + 'control': false, + 'key': { + 'key_code': 189, + 'char': '-', + }, + }, +}; diff --git a/web/regression/javascript/erd/ui_components/floating_note_spec.js b/web/regression/javascript/erd/ui_components/floating_note_spec.js new file mode 100644 index 000000000..f786267bf --- /dev/null +++ b/web/regression/javascript/erd/ui_components/floating_note_spec.js @@ -0,0 +1,39 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {mount} from 'enzyme'; +import '../../helper/enzyme.helper'; + +import FloatingNote from 'pgadmin.tools.erd/erd_tool/ui_components/FloatingNote'; + +describe('ERD FloatingNote', ()=>{ + + beforeEach(()=>{ + jasmineEnzyme(); + }); + + it(' on OK click', ()=>{ + let floatNote = null; + let onClose = jasmine.createSpy('onClose'); + let noteNode = { + getNote: function() { + return 'some note'; + }, + setNote: jasmine.createSpy('setNote'), + getSchemaTableName: function() { + return ['schema1', 'table1']; + }, + }; + + floatNote = mount(); + + floatNote.find('textarea').simulate('change', { + target: { + value: 'the new note', + }, + }); + floatNote.find('button[data-label="OK"]').simulate('click'); + expect(noteNode.setNote).toHaveBeenCalledWith('the new note'); + expect(onClose).toHaveBeenCalled(); + }); +}); diff --git a/web/regression/javascript/erd/ui_components/loader_spec.js b/web/regression/javascript/erd/ui_components/loader_spec.js new file mode 100644 index 000000000..b14ed30aa --- /dev/null +++ b/web/regression/javascript/erd/ui_components/loader_spec.js @@ -0,0 +1,23 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import {shallow} from 'enzyme'; +import '../../helper/enzyme.helper'; + +import Loader from 'pgadmin.tools.erd/erd_tool/ui_components/Loader'; + +describe('ERD Loader', ()=>{ + beforeEach(()=>{ + jasmineEnzyme(); + }); + + it(' comp', ()=>{ + let loaderComp = shallow(); + expect(loaderComp.isEmptyRender()).toBeTrue(); + + loaderComp.setProps({message: 'test message'}); + expect(loaderComp.find('.pg-sp-text').text()).toBe('test message'); + + loaderComp.setProps({autoEllipsis: true}); + expect(loaderComp.find('.pg-sp-text').text()).toBe('test message...'); + }); +}); diff --git a/web/regression/javascript/erd/ui_components/toolbar_spec.js b/web/regression/javascript/erd/ui_components/toolbar_spec.js new file mode 100644 index 000000000..0429d718d --- /dev/null +++ b/web/regression/javascript/erd/ui_components/toolbar_spec.js @@ -0,0 +1,76 @@ +import jasmineEnzyme from 'jasmine-enzyme'; +import React from 'react'; +import Tippy from '@tippyjs/react'; +import {mount, shallow} from 'enzyme'; +import '../../helper/enzyme.helper'; + +import ToolBar, {ButtonGroup, DetailsToggleButton, IconButton, Shortcut} from 'pgadmin.tools.erd/erd_tool/ui_components/ToolBar'; + +describe('ERD Toolbar', ()=>{ + beforeEach(()=>{ + jasmineEnzyme(); + }); + + it(' comp', ()=>{ + let toolBar = mount(
); + expect(toolBar.getDOMNode().id).toBe('id1'); + expect(toolBar.find('.test').length).toBe(1); + }); + + it(' comp', ()=>{ + let btnGrp = mount(
); + expect(btnGrp.getDOMNode().className).toBe('btn-group mr-1 '); + expect(btnGrp.find('.test').length).toBe(1); + btnGrp.unmount(); + + btnGrp = mount(); + expect(btnGrp.getDOMNode().className).toBe('btn-group mr-1 someclass'); + }); + + it(' comp', ()=>{ + let toggle = shallow(); + let btn = toggle.find(IconButton); + expect(btn.prop('icon')).toBe('far fa-eye'); + expect(btn.prop('title')).toBe('Show fewer details'); + + toggle.setProps({showDetails: false}); + btn = toggle.find(IconButton); + expect(btn.prop('icon')).toBe('fas fa-low-vision'); + expect(btn.prop('title')).toBe('Show more details'); + }); + + it(' comp', ()=>{ + let btn = mount(); + + let tippy = btn.find(Tippy); + expect(tippy.length).toBe(0); + + btn.setProps({title: 'test title'}); + tippy = btn.find(Tippy); + expect(tippy.length).toBe(1); + + expect(btn.find('button').getDOMNode().className).toBe('btn btn-sm btn-primary-icon '); + + btn.setProps({icon: 'fa fa-icon'}); + expect(btn.find('button .sql-icon-lg').getDOMNode().className).toBe('fa fa-icon sql-icon-lg'); + }); + + it(' comp', ()=>{ + let key = { + alt: true, + control: true, + shift: false, + key: { + key_code: 65, + char: 'a', + }, + }; + let shortcutComp = mount(); + + expect(shortcutComp.find('.shortcut-key').length).toBe(3); + + key.alt = false; + shortcutComp.setProps({shortcut: key}); + expect(shortcutComp.find('.shortcut-key').length).toBe(2); + }); +}); diff --git a/web/regression/javascript/fake_endpoints.js b/web/regression/javascript/fake_endpoints.js index d37b7ddb6..77894ac34 100644 --- a/web/regression/javascript/fake_endpoints.js +++ b/web/regression/javascript/fake_endpoints.js @@ -22,5 +22,11 @@ define(function () { 'search_objects.types': '/search_objects/types//', 'search_objects.search': '/search_objects/search//', 'dashboard.dashboard_stats': '/dashboard/dashboard_stats', + 'sqleditor.load_file': '/sqleditor/load_file/', + 'sqleditor.save_file': '/sqleditor/save_file/', + 'erd.initialize': '/erd/initialize////', + 'erd.sql': '/erd/sql////', + 'erd.prequisite': '/erd/prequisite////', + 'erd.tables': '/erd/tables////', }; }); diff --git a/web/webpack.config.js b/web/webpack.config.js index 96ef708ab..c225b31b8 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -355,6 +355,7 @@ module.exports = [{ sqleditor: './pgadmin/tools/sqleditor/static/js/sqleditor.js', debugger_direct: './pgadmin/tools/debugger/static/js/direct.js', schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js', + erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js', file_utils: './pgadmin/misc/file_manager/static/js/utility.js', 'pgadmin.style': pgadminCssStyles, pgadmin: pgadminScssStyles, @@ -501,7 +502,8 @@ module.exports = [{ ',pgadmin.node.pga_job' + ',pgadmin.tools.schema_diff' + ',pgadmin.tools.storage_manager' + - ',pgadmin.tools.search_objects', + ',pgadmin.tools.search_objects' + + ',pgadmin.tools.erd_module', }, }, { test: require.resolve('snapsvg'), diff --git a/web/webpack.shim.js b/web/webpack.shim.js index 6fc26021e..7d25a2d56 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -147,6 +147,10 @@ var webpackShimConfig = { 'color-picker': path.join(__dirname, './node_modules/@simonwep/pickr/dist/pickr.es5.min'), 'mousetrap': path.join(__dirname, './node_modules/mousetrap'), 'tablesorter-metric': path.join(__dirname, './node_modules/tablesorter/dist/js/parsers/parser-metric.min'), + 'pathfinding': path.join(__dirname, 'node_modules/pathfinding'), + 'dagre': path.join(__dirname, 'node_modules/dagre'), + 'graphlib': path.join(__dirname, 'node_modules/graphlib'), + 'react': path.join(__dirname, 'node_modules/react'), // AciTree 'jquery.acitree': path.join(__dirname, './node_modules/acitree/js/jquery.aciTree.min'), @@ -275,6 +279,8 @@ var webpackShimConfig = { 'pgadmin.tools.schema_diff_ui': path.join(__dirname, './pgadmin/tools/schema_diff/static/js/schema_diff_ui'), 'pgadmin.tools.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js/search_objects'), 'pgadmin.tools.storage_manager': path.join(__dirname, './pgadmin/tools/storage_manager/static/js/storage_manager'), + 'pgadmin.tools.erd_module': path.join(__dirname, './pgadmin/tools/erd/static/js/erd_module'), + 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), 'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'), 'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'), 'pgadmin.user_management.current_user': '/user_management/current_user', diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index 37557e0cc..7cc1923e9 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -113,6 +113,7 @@ module.exports = { 'pgadmin.browser.layout': path.join(__dirname, './pgadmin/browser/static/js/layout'), 'pgadmin.browser.preferences': path.join(__dirname, './pgadmin/browser/static/js/preferences'), 'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'), + 'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'), 'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'), 'tools': path.join(__dirname, './pgadmin/tools/'), }, diff --git a/web/yarn.lock b/web/yarn.lock index c9450d755..ada962e94 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -2,70 +2,54 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" - integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== dependencies: "@babel/highlight" "^7.10.4" -"@babel/core@^7.7.5": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" - integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== +"@babel/compat-data@^7.12.5", "@babel/compat-data@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.12.7.tgz#9329b4782a7d6bbd7eef57e11addf91ee3ef1e41" + integrity sha512-YaxPMGs/XIWtYqrdEOZOCPsVWfEoriXopnsz3/i7apYPXQ3698UFhS6dVT1KN5qOsWmVgw/FOrmQgpRaZayGsw== + +"@babel/core@^7.10.2", "@babel/core@^7.7.5": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.10.tgz#b79a2e1b9f70ed3d84bbfb6d8c4ef825f606bccd" + integrity sha512-eTAlQKq65zHfkHZV0sIVODCPGVgoo1HdBlbSLi9CqOzuZanMv2ihzY+4paiKr1mH+XmYESMAmJ/dpZ68eN6d8w== dependencies: "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.6" - "@babel/helper-module-transforms" "^7.11.0" - "@babel/helpers" "^7.10.4" - "@babel/parser" "^7.11.5" - "@babel/template" "^7.10.4" - "@babel/traverse" "^7.11.5" - "@babel/types" "^7.11.5" + "@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" - resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/core@~7.6.0": - version "7.6.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff" - integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ== +"@babel/generator@^7.12.10", "@babel/generator@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.12.11.tgz#98a7df7b8c358c9a37ab07a24056853016aba3af" + integrity sha512-Ggg6WPOJtSi8yYQvLVjG8F/TlpWDlKx0OpS4Kt+xMQPs5OaGYWy+v1A+1TvxI6sAMGZpKWWoAQ1DaeQbImlItA== dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.6.4" - "@babel/helpers" "^7.6.2" - "@babel/parser" "^7.6.4" - "@babel/template" "^7.6.0" - "@babel/traverse" "^7.6.3" - "@babel/types" "^7.6.3" - convert-source-map "^1.1.0" - debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/generator@^7.11.5", "@babel/generator@^7.11.6", "@babel/generator@^7.6.4": - version "7.11.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" - integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== - dependencies: - "@babel/types" "^7.11.5" + "@babel/types" "^7.12.11" jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" - integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== +"@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.10.tgz#54ab9b000e60a93644ce17b3f37d313aaf1d115d" + integrity sha512-XplmVbC1n+KY6jL8/fgLVXXUauDIB+lD5+GsQEh6F6GBF1dq1qy4DP4yXWzDKcoqXB3X58t61e85Fitoww4JVQ== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.10" "@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": version "7.10.4" @@ -75,43 +59,34 @@ "@babel/helper-explode-assignable-expression" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx-experimental@^7.10.4", "@babel/helper-builder-react-jsx-experimental@^7.11.5": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.11.5.tgz#4ea43dd63857b0a35cd1f1b161dc29b43414e79f" - integrity sha512-Vc4aPJnRZKWfzeCBsqTBnzulVNjABVdahSPhtdMD3Vs80ykx4a87jTHtF/VR+alSrDmNvat7l13yrRHauGcHVw== +"@babel/helper-compilation-targets@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.12.5.tgz#cb470c76198db6a24e9dbc8987275631e5d29831" + integrity sha512-+qH6NrscMolUlzOYngSBMIOQpKUGPPsc61Bu5W10mg84LxZ7cmvnBHzARKbDoFxVvqqAbj6Tg6N7bSrWSPXMyw== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-module-imports" "^7.10.4" - "@babel/types" "^7.11.5" + "@babel/compat-data" "^7.12.5" + "@babel/helper-validator-option" "^7.12.1" + browserslist "^4.14.5" + semver "^5.5.0" -"@babel/helper-builder-react-jsx@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" - integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/types" "^7.10.4" - -"@babel/helper-create-class-features-plugin@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" - integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== +"@babel/helper-create-class-features-plugin@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.12.1.tgz#3c45998f431edd4a9214c5f1d3ad1448a6137f6e" + integrity sha512-hkL++rWeta/OVOBTRJc9a5Azh5mt5WgZUGAKMD8JM141YsE08K//bp1unBBieO6rUKkIPyUE0USQ30jAy3Sk1w== dependencies: "@babel/helper-function-name" "^7.10.4" - "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-member-expression-to-functions" "^7.12.1" "@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" -"@babel/helper-create-regexp-features-plugin@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" - integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== +"@babel/helper-create-regexp-features-plugin@^7.12.1": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.12.7.tgz#2084172e95443fa0a09214ba1bb328f9aea1278f" + integrity sha512-idnutvQPdpbduutvi3JVfEgcVIHooQnhvhx0Nk9isOINOIGYkZea1Pk2JlJRiUnMefrlvr0vkByATBY/mB4vjQ== dependencies: "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - regexpu-core "^4.7.0" + regexpu-core "^4.7.1" "@babel/helper-define-map@^7.10.4": version "7.10.5" @@ -123,27 +98,27 @@ lodash "^4.17.19" "@babel/helper-explode-assignable-expression@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" - integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.12.1.tgz#8006a466695c4ad86a2a5f2fb15b5f2c31ad5633" + integrity sha512-dmUwH8XmlrUpVqgtZ737tK88v07l840z9j3OEhCLwKTkjlvKpfqXVIZ0wpK3aeOxspwGrf/5AP5qLx4rO3w5rA== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.1" -"@babel/helper-function-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" - integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== +"@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.12.11.tgz#1fd7738aee5dcf53c3ecff24f1da9c511ec47b42" + integrity sha512-AtQKjtYNolKNi6nNNVLQ27CP6D9oFR6bq/HPYSizlzbp7uC1M59XJe8L+0uXjbIaZaUJF99ruHqVGiKXU/7ybA== dependencies: - "@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@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" - integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== +"@babel/helper-get-function-arity@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.10.tgz#b158817a3165b5faa2047825dfa61970ddcc16cf" + integrity sha512-mm0n5BPjR06wh9mPQaDdXWDoll/j5UpCAPl1x8fS71GHm7HA6Ua2V4ylG1Ju8lvcTOietbPNNPaSilKj+pj+Ag== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.10" "@babel/helper-hoist-variables@^7.10.4": version "7.10.4" @@ -152,117 +127,115 @@ dependencies: "@babel/types" "^7.10.4" -"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" - integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== +"@babel/helper-member-expression-to-functions@^7.12.1", "@babel/helper-member-expression-to-functions@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.12.7.tgz#aa77bd0396ec8114e5e30787efa78599d874a855" + integrity sha512-DCsuPyeWxeHgh1Dus7APn7iza42i/qXqiFPWyBDdOFtvS581JQePsc1F/nD+fHrcswhLlRc2UpYS1NwERxZhHw== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.7" -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" - integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.1", "@babel/helper-module-imports@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz#1bfc0229f794988f76ed0a4d4e90860850b54dfb" + integrity sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.5" -"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" - integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== +"@babel/helper-module-transforms@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.12.1.tgz#7954fec71f5b32c48e4b303b437c34453fd7247c" + integrity sha512-QQzehgFAZ2bbISiCpmVGfiGux8YVFXQ0abBic2Envhej22DVXV9nCFaS5hIQbkyo1AdGb+gNME2TSh3hYJVV/w== dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" + "@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/types" "^7.11.0" + "@babel/traverse" "^7.12.1" + "@babel/types" "^7.12.1" lodash "^4.17.19" -"@babel/helper-optimise-call-expression@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" - integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== +"@babel/helper-optimise-call-expression@^7.10.4", "@babel/helper-optimise-call-expression@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.10.tgz#94ca4e306ee11a7dd6e9f42823e2ac6b49881e2d" + integrity sha512-4tpbU0SrSTjjt65UMWSrUOPZTsgvPgGG4S8QSTNHacKzpS51IVWGDj0yCwyeZND/i+LSN2g/O63jEXEWm49sYQ== dependencies: - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.10" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-regex@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" - integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== - dependencies: - lodash "^4.17.19" - -"@babel/helper-remap-async-to-generator@^7.10.4": - version "7.11.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" - integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== +"@babel/helper-remap-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.12.1.tgz#8c4dbbf916314f6047dc05e6a2217074238347fd" + integrity sha512-9d0KQCRM8clMPcDwo8SevNs+/9a8yWVVmaE80FGJcEP8N1qToREmWEGnBn8BUlJhYRFz6fqxeRL1sl5Ogsed7A== dependencies: "@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" -"@babel/helper-replace-supers@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" - integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== +"@babel/helper-replace-supers@^7.12.1": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.12.11.tgz#ea511658fc66c7908f923106dd88e08d1997d60d" + integrity sha512-q+w1cqmhL7R0FNzth/PLLp2N+scXEK/L2AHbXUyydxp828F4FEa5WcVoqui9vFRiHDQErj9Zof8azP32uGVTRA== dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.4" - "@babel/helper-optimise-call-expression" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@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" -"@babel/helper-simple-access@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" - integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== +"@babel/helper-simple-access@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.12.1.tgz#32427e5aa61547d38eb1e6eaf5fd1426fdad9136" + integrity sha512-OxBp7pMrjVewSSC8fXDFrHrBcJATOOFssZwv16F3/6Xtc138GHybBfPbm9kfiqQHKhYQrlamWILwlDCeyMFEaA== dependencies: - "@babel/template" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/types" "^7.12.1" -"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" - integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== +"@babel/helper-skip-transparent-expression-wrappers@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf" + integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.1" -"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" - integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.11.tgz#1b4cc424458643c47d37022223da33d76ea4603a" + integrity sha512-LsIVN8j48gHgwzfocYUSkO/hjYAOJqlpJEc7tGXcIm4cubjVUf8LGW6eWRyxEu7gA25q02p0rQUWoCI33HNS5g== dependencies: - "@babel/types" "^7.11.0" + "@babel/types" "^7.12.11" -"@babel/helper-validator-identifier@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" - integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== +"@babel/helper-validator-identifier@^7.10.4", "@babel/helper-validator-identifier@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz#c9a1f021917dcb5ccf0d4e453e399022981fc9ed" + integrity sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw== + +"@babel/helper-validator-option@^7.12.1", "@babel/helper-validator-option@^7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.11.tgz#d66cb8b7a3e7fe4c6962b32020a131ecf0847f4f" + integrity sha512-TBFCyj939mFSdeX7U7DDj32WtzYY7fDcalgq8v3fBZMNOJQNn7nOYzMaUCiPxPYfCup69mtIpqlKgMZLvQ8Xhw== "@babel/helper-wrap-function@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" - integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== + version "7.12.3" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.12.3.tgz#3332339fc4d1fbbf1c27d7958c27d34708e990d9" + integrity sha512-Cvb8IuJDln3rs6tzjW3Y8UeelAOdnpB8xtQ4sme2MSZ9wOxrbThporC0y/EtE16VAtoyEfLM404Xr1e0OOp+ow== dependencies: "@babel/helper-function-name" "^7.10.4" "@babel/template" "^7.10.4" "@babel/traverse" "^7.10.4" "@babel/types" "^7.10.4" -"@babel/helpers@^7.10.4", "@babel/helpers@^7.6.2": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" - integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== +"@babel/helpers@^7.12.5": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.12.5.tgz#1a1ba4a768d9b58310eda516c449913fe647116e" + integrity sha512-lgKGMQlKqA8meJqKsW6rUnc4MdUk35Ln0ATDqdM1a/UpARODdI4j5Y5lVfUScnSNkJcdCRAaWkspykNoFg9sJA== dependencies: "@babel/template" "^7.10.4" - "@babel/traverse" "^7.10.4" - "@babel/types" "^7.10.4" + "@babel/traverse" "^7.12.5" + "@babel/types" "^7.12.5" "@babel/highlight@^7.10.4": version "7.10.4" @@ -273,514 +246,735 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.6.4": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" - integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== +"@babel/parser@^7.12.10", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.7.0": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.12.11.tgz#9ce3595bcd74bc5c466905e86c535b8b25011e79" + integrity sha512-N3UxG+uuF4CMYoNj8AhnbAcJF0PiuJ9KHuy1lQmkYsxTer/MAH9UBNHsBoAX/4s6NvlDD047No8mYVGGzLL4hg== -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" - integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== +"@babel/plugin-proposal-async-generator-functions@^7.12.1": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.12.12.tgz#04b8f24fd4532008ab4e79f788468fd5a8476566" + integrity sha512-nrz9y0a4xmUrRq51bYkWJIO5SBZyG2ys2qinHsN0zHDHVsUaModrkpyWWWXfGqYQmOL3x9sQIcTNN/pBGpo09A== dependencies: "@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@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" - integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== +"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.12.1.tgz#a082ff541f2a29a4821065b8add9346c0c16e5de" + integrity sha512-cKp3dlQsFsEs5CWKnN7BnSHOd0EOW8EKpEjkoz1pO2E5KzIDNV9Ros1b0CnmbVgAGXJubOYVBOGCT1OmJwOI7w== dependencies: - "@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@^7.5.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" - integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== +"@babel/plugin-proposal-dynamic-import@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.12.1.tgz#43eb5c2a3487ecd98c5c8ea8b5fdb69a2749b2dc" + integrity sha512-a4rhUSZFuq5W8/OO8H7BL5zspjnc1FLd9hlOxIK/f7qG4a0qsqk8uvF/ywgBA8/OmjsapjpvaEOYItfGG1qIvQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-json-strings@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" - integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== +"@babel/plugin-proposal-export-namespace-from@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.12.1.tgz#8b9b8f376b2d88f5dd774e4d24a5cc2e3679b6d4" + integrity sha512-6CThGf0irEkzujYS5LQcjBx8j/4aQGiVv7J9+2f7pGfxqyKh3WnmVJYW3hdrQjyksErMGBPQrCnHfOtna+WLbw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.12.1.tgz#d45423b517714eedd5621a9dfdc03fa9f4eb241c" + integrity sha512-GoLDUi6U9ZLzlSda2Df++VSqDJg3CG+dR0+iWsv6XRw1rEq+zwt4DirM9yrxW6XWaTpmai1cWJLMfM8qQJf+yw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.0" -"@babel/plugin-proposal-object-rest-spread@^7.6.2": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" - integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== +"@babel/plugin-proposal-logical-assignment-operators@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.12.1.tgz#f2c490d36e1b3c9659241034a5d2cd50263a2751" + integrity sha512-k8ZmVv0JU+4gcUGeCDZOGd0lCIamU/sMtIiX3UWnUc5yzgq6YUGyEolNYD+MLYKfSzgECPcqetVcJP9Afe/aCA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.12.1.tgz#3ed4fff31c015e7f3f1467f190dbe545cd7b046c" + integrity sha512-nZY0ESiaQDI1y96+jk6VxMOaL4LPo/QDHBqL+SF3/vl6dHkTwHlOI8L4ZwuRBHgakRBw5zsVylel7QPbbGuYgg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.12.7.tgz#8bf253de8139099fea193b297d23a9d406ef056b" + integrity sha512-8c+uy0qmnRTeukiGsjLGy6uVs/TFjJchGXUeBqlG4VWYOdJWkhhVPdQ3uHwbmalfJwv2JsV0qffXP4asRfL2SQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.9.6": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== dependencies: "@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@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" - integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== +"@babel/plugin-proposal-optional-catch-binding@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.12.1.tgz#ccc2421af64d3aae50b558a71cede929a5ab2942" + integrity sha512-hFvIjgprh9mMw5v42sJWLI1lzU5L2sznP805zeT6rySVRA0Y18StRhDqhSxlap0oVgItRsB6WSROp4YnJTJz0g== dependencies: "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-unicode-property-regex@^7.6.2": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" - integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== +"@babel/plugin-proposal-optional-chaining@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.12.7.tgz#e02f0ea1b5dc59d401ec16fb824679f683d3303c" + integrity sha512-4ovylXZ0PWmwoOvhU2vhnzVNnm88/Sm9nx7V8BPgMvAzn5zDou3/Awy0EjglyubVHasJj+XCEkr/r1X3P5elCA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + +"@babel/plugin-proposal-private-methods@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.12.1.tgz#86814f6e7a21374c980c10d38b4493e703f4a389" + integrity sha512-mwZ1phvH7/NHK6Kf8LP7MYDogGV+DKB1mryFOEwx5EBNQrosvIczzZFTUmWaeujd5xT6G1ELYWUz3CutMhjE1w== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-async-generators@^7.2.0", "@babel/plugin-syntax-async-generators@^7.8.0": +"@babel/plugin-proposal-unicode-property-regex@^7.12.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.1.tgz#2a183958d417765b9eae334f47758e5d6a82e072" + integrity sha512-MYq+l+PvHuw/rKUz1at/vb6nCnQ2gmJBNaM62z0OgH7B2W1D9pvkpYtlti9bGtizNIU1K3zm4bZF9F91efVY0w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-async-generators@^7.8.0": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-dynamic-import@^7.2.0", "@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-class-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.1.tgz#bcb297c5366e79bebadef509549cd93b04f19978" + integrity sha512-U40A76x5gTwmESz+qiqssqmeEsKvcSyvtgktrm0uzcARAmM9I1jR221f6Oq+GmHrcD+LvZDag1UTOTe2fL3TeA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-dynamic-import@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-json-strings@^7.2.0", "@babel/plugin-syntax-json-strings@^7.8.0": +"@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + +"@babel/plugin-syntax-json-strings@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" - integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== +"@babel/plugin-syntax-jsx@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.2.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-catch-binding@^7.2.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.0": +"@babel/plugin-syntax-optional-catch-binding@^7.8.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" - integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-top-level-await@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.1.tgz#dd6c0b357ac1bb142d98537450a319625d13d2a0" + integrity sha512-i7ooMZFS+a/Om0crxZodrTzNEPJHZrlMVGMTEpFAj6rYY/bKCddB0Dk/YxfPuYXOopuhKk/e1jV6h+WUU9XN3A== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" - integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== - dependencies: - "@babel/helper-module-imports" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-remap-async-to-generator" "^7.10.4" - -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" - integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== +"@babel/plugin-transform-arrow-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.12.1.tgz#8083ffc86ac8e777fbe24b5967c4b2521f3cb2b3" + integrity sha512-5QB50qyN44fzzz4/qxDPQMBCTHgxg3n0xRBLJUmBlLoU/sFvxVWGZF/ZUfMVDQuJUKXaBhbupxIzIfZ6Fwk/0A== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.6.3": - version "7.11.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" - integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== +"@babel/plugin-transform-async-to-generator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.12.1.tgz#3849a49cc2a22e9743cbd6b52926d30337229af1" + integrity sha512-SDtqoEcarK1DFlRJ1hHRY5HvJUj5kX4qmtpMAm2QnhOlyuMC4TMdCRgW6WXpv93rZeYNeLP22y8Aq2dbcDRM1A== + dependencies: + "@babel/helper-module-imports" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.12.1" + +"@babel/plugin-transform-block-scoped-functions@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.1.tgz#f2a1a365bde2b7112e0a6ded9067fdd7c07905d9" + integrity sha512-5OpxfuYnSgPalRpo8EWGPzIYf0lHBWORCkj5M0oLBwHdlux9Ri36QqGW3/LR13RSVOAoUUMzoPI/jpE4ABcHoA== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-classes@^7.5.5": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" - integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== +"@babel/plugin-transform-block-scoping@^7.12.11": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.12.12.tgz#d93a567a152c22aea3b1929bb118d1d0a175cdca" + integrity sha512-VOEPQ/ExOVqbukuP7BYJtI5ZxxsmegTwzZ04j1aF0dkSypGo9XpDHuOrABsJu+ie+penpSJheDJ11x1BEZNiyQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-classes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.12.1.tgz#65e650fcaddd3d88ddce67c0f834a3d436a32db6" + integrity sha512-/74xkA7bVdzQTBeSUhLLJgYIcxw/dpEpCdRDiHgPJ3Mv6uC11UhjpOhl72CgqbBCmt1qtssCyB2xnJm1+PFjog== dependencies: "@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.10.4" + "@babel/helper-replace-supers" "^7.12.1" "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" - integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== +"@babel/plugin-transform-computed-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.12.1.tgz#d68cf6c9b7f838a8a4144badbe97541ea0904852" + integrity sha512-vVUOYpPWB7BkgUWPo4C44mUQHpTZXakEqFjbv8rQMg7TC6S6ZhGZ3otQcRH6u7+adSlE5i0sp63eMC/XGffrzg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.6.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" - integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== +"@babel/plugin-transform-destructuring@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.12.1.tgz#b9a570fe0d0a8d460116413cb4f97e8e08b2f847" + integrity sha512-fRMYFKuzi/rSiYb2uRLiUENJOKq4Gnl+6qOv5f8z0TZXg3llUwUhsNNwrwaT/6dUhJTzNpBr+CUvEWBtfNY1cw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.6.2": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" - integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== +"@babel/plugin-transform-dotall-regex@^7.12.1", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.1.tgz#a1d16c14862817b6409c0a678d6f9373ca9cd975" + integrity sha512-B2pXeRKoLszfEW7J4Hg9LoFaWEbr/kzo3teWHmtFCszjRNa/b40f9mfeqZsIDLLt/FjwQ6pz/Gdlwy85xNckBA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" - integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== +"@babel/plugin-transform-duplicate-keys@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.1.tgz#745661baba295ac06e686822797a69fbaa2ca228" + integrity sha512-iRght0T0HztAb/CazveUpUQrZY+aGKKaWXMJ4uf9YJtqxSUe09j3wteztCUDRHs+SRAL7yMuFqUsLoAKKzgXjw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" - integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== +"@babel/plugin-transform-exponentiation-operator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.1.tgz#b0f2ed356ba1be1428ecaf128ff8a24f02830ae0" + integrity sha512-7tqwy2bv48q+c1EHbXK0Zx3KXd2RVQp6OC7PbwFNt/dPTAV3Lu5sWtWuAj8owr5wqtWnqHfl2/mJlUmqkChKug== dependencies: "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-for-of@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" - integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== +"@babel/plugin-transform-for-of@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.12.1.tgz#07640f28867ed16f9511c99c888291f560921cfa" + integrity sha512-Zaeq10naAsuHo7heQvyV0ptj4dlZJwZgNAtBYBnu5nNKJoW62m0zKcIEyVECrUKErkUkg6ajMy4ZfnVZciSBhg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-function-name@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" - integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== +"@babel/plugin-transform-function-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.1.tgz#2ec76258c70fe08c6d7da154003a480620eba667" + integrity sha512-JF3UgJUILoFrFMEnOJLJkRHSk6LUSXLmEFsA23aR2O5CSLUxbeUX1IZ1YQ7Sn0aXb601Ncwjx73a+FVqgcljVw== dependencies: "@babel/helper-function-name" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-literals@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" - integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== +"@babel/plugin-transform-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.1.tgz#d73b803a26b37017ddf9d3bb8f4dc58bfb806f57" + integrity sha512-+PxVGA+2Ag6uGgL0A5f+9rklOnnMccwEBzwYFL3EUaKuiyVnUipyXncFcfjSkbimLrODoqki1U9XxZzTvfN7IQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" - integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== +"@babel/plugin-transform-member-expression-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.1.tgz#496038602daf1514a64d43d8e17cbb2755e0c3ad" + integrity sha512-1sxePl6z9ad0gFMB9KqmYofk34flq62aqMt9NqliS/7hPEpURUCMbyHXrMPlo282iY7nAvUB1aQd5mg79UD9Jg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" - integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== +"@babel/plugin-transform-modules-amd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.12.1.tgz#3154300b026185666eebb0c0ed7f8415fefcf6f9" + integrity sha512-tDW8hMkzad5oDtzsB70HIQQRBiTKrhfgwC/KkJeGsaNFTdWhKNt/BiE8c5yj19XiGyrxpbkOfH87qkNg1YGlOQ== dependencies: - "@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-commonjs@^7.6.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" - integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== +"@babel/plugin-transform-modules-commonjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.12.1.tgz#fa403124542636c786cf9b460a0ffbb48a86e648" + integrity sha512-dY789wq6l0uLY8py9c1B48V8mVL5gZh/+PQ5ZPrylPYsnAvnEMjqsUXkuoDVPeVK+0VyGar+D08107LzDQ6pag== dependencies: - "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-simple-access" "^7.12.1" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" - integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== +"@babel/plugin-transform-modules-systemjs@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.12.1.tgz#663fea620d593c93f214a464cd399bf6dc683086" + integrity sha512-Hn7cVvOavVh8yvW6fLwveFqSnd7rbQN3zJvoPNyNaQSvgfKmDBO9U1YL9+PCXGRlZD9tNdWTy5ACKqMuzyn32Q== dependencies: "@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/helper-validator-identifier" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" - integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== +"@babel/plugin-transform-modules-umd@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.12.1.tgz#eb5a218d6b1c68f3d6217b8fa2cc82fec6547902" + integrity sha512-aEIubCS0KHKM0zUos5fIoQm+AZUMt1ZvMpqz0/H5qAQ7vWylr9+PLYurT+Ic7ID/bKLd4q8hDovaG3Zch2uz5Q== dependencies: - "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-module-transforms" "^7.12.1" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.6.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" - integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.1.tgz#b407f5c96be0d9f5f88467497fa82b30ac3e8753" + integrity sha512-tB43uQ62RHcoDp9v2Nsf+dSM8sbNodbEicbQNA53zHz8pWUhsgHSJCGpt7daXxRydjb0KnfmB+ChXOv3oADp1Q== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-create-regexp-features-plugin" "^7.12.1" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" - integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== +"@babel/plugin-transform-new-target@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.1.tgz#80073f02ee1bb2d365c3416490e085c95759dec0" + integrity sha512-+eW/VLcUL5L9IvJH7rT1sT0CzkdUTvPrXC2PXTn/7z7tXLBuKvezYbGdxD5WMRoyvyaujOq2fWoKl869heKjhw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" - integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== +"@babel/plugin-transform-object-super@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.1.tgz#4ea08696b8d2e65841d0c7706482b048bed1066e" + integrity sha512-AvypiGJH9hsquNUn+RXVcBdeE3KHPZexWRdimhuV59cSoOt5kFBmqlByorAeUlGG2CJWd0U+4ZtNKga/TB0cAw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-replace-supers" "^7.12.1" -"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.4.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" - integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== - dependencies: - "@babel/helper-get-function-arity" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" - integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== +"@babel/plugin-transform-parameters@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.12.1.tgz#d2e963b038771650c922eff593799c96d853255d" + integrity sha512-xq9C5EQhdPK23ZeCdMxl8bbRnAgHFrw5EOC3KJUsSylZqdkCaFEXxGSBuTSObOpiiHHNyb82es8M1QYgfQGfNg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-display-name@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz#b5795f4e3e3140419c3611b7a2a3832b9aef328d" - integrity sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw== +"@babel/plugin-transform-property-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.1.tgz#41bc81200d730abb4456ab8b3fbd5537b59adecd" + integrity sha512-6MTCR/mZ1MQS+AwZLplX4cEySjCpnIF26ToWo942nqn8hXSm7McaHQNeGx/pt7suI1TWOWMfa/NgBhiqSnX0cQ== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-development@^7.10.4": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.11.5.tgz#e1439e6a57ee3d43e9f54ace363fb29cefe5d7b6" - integrity sha512-cImAmIlKJ84sDmpQzm4/0q/2xrXlDezQoixy3qoz1NJeZL/8PRon6xZtluvr4H4FzwlDGI5tCcFupMnXGtr+qw== - dependencies: - "@babel/helper-builder-react-jsx-experimental" "^7.11.5" - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.10.4" - -"@babel/plugin-transform-react-jsx-self@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz#cd301a5fed8988c182ed0b9d55e9bd6db0bd9369" - integrity sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg== +"@babel/plugin-transform-react-display-name@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.12.1.tgz#1cbcd0c3b1d6648c55374a22fc9b6b7e5341c00d" + integrity sha512-cAzB+UzBIrekfYxyLlFqf/OagTvHLcVBb5vpouzkYkBclRPraiygVnafvAoipErZLI8ANv8Ecn6E/m5qPXD26w== dependencies: "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-react-jsx-source@^7.10.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz#34f1779117520a779c054f2cdd9680435b9222b4" - integrity sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA== +"@babel/plugin-transform-react-jsx-development@^7.12.7": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.12.tgz#bccca33108fe99d95d7f9e82046bfe762e71f4e7" + integrity sha512-i1AxnKxHeMxUaWVXQOSIco4tvVvvCxMSfeBMnMM06mpaJt3g+MpxYQQrDfojUQldP1xxraPSJYSMEljoWM/dCg== dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx" "^7.10.4" + "@babel/plugin-transform-react-jsx" "^7.12.12" -"@babel/plugin-transform-react-jsx@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" - integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== +"@babel/plugin-transform-react-jsx@^7.12.10", "@babel/plugin-transform-react-jsx@^7.12.12": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.12.12.tgz#b0da51ffe5f34b9a900e9f1f5fb814f9e512d25e" + integrity sha512-JDWGuzGNWscYcq8oJVCtSE61a5+XAOos+V0HrxnDieUus4UMnBEosDnY1VJqU5iZ4pA04QY7l0+JvHL1hZEfsw== dependencies: - "@babel/helper-builder-react-jsx" "^7.10.4" - "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@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.10.4" + "@babel/plugin-syntax-jsx" "^7.12.1" + "@babel/types" "^7.12.12" -"@babel/plugin-transform-react-pure-annotations@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz#3eefbb73db94afbc075f097523e445354a1c6501" - integrity sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A== +"@babel/plugin-transform-react-pure-annotations@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42" + integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg== dependencies: "@babel/helper-annotate-as-pure" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" - integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== +"@babel/plugin-transform-regenerator@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.12.1.tgz#5f0a28d842f6462281f06a964e88ba8d7ab49753" + integrity sha512-gYrHqs5itw6i4PflFX3OdBPMQdPbF4bj2REIUxlMRUFk0/ZOAIpDFuViuxPjUL7YC8UPnf+XG7/utJvqXdPKng== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" - integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== +"@babel/plugin-transform-reserved-words@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.1.tgz#6fdfc8cc7edcc42b36a7c12188c6787c873adcd8" + integrity sha512-pOnUfhyPKvZpVyBHhSBoX8vfA09b7r00Pmm1sH+29ae2hMTKVmSp4Ztsr8KBKjLjx17H0eJqaRC3bR2iThM54A== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" - integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== +"@babel/plugin-transform-shorthand-properties@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.1.tgz#0bf9cac5550fce0cfdf043420f661d645fdc75e3" + integrity sha512-GFZS3c/MhX1OusqB1MZ1ct2xRzX5ppQh2JU1h2Pnfk88HtFTM+TWQqJNfwkmxtPQtb/s1tk87oENfXJlx7rSDw== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-spread@^7.6.2": - version "7.11.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" - integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== +"@babel/plugin-transform-spread@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.12.1.tgz#527f9f311be4ec7fdc2b79bb89f7bf884b3e1e1e" + integrity sha512-vuLp8CP0BE18zVYjsEBZ5xoCecMK6LBMMxYzJnh01rxQRvhNhH1csMMmBfNo5tGpGO+NhdSNW2mzIvBu3K1fng== dependencies: "@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-transform-sticky-regex@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" - integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/helper-regex" "^7.10.4" - -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.10.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" - integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.10.4" - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" - integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== +"@babel/plugin-transform-sticky-regex@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.7.tgz#560224613ab23987453948ed21d0b0b193fa7fad" + integrity sha512-VEiqZL5N/QvDbdjfYQBhruN0HYjSPjC4XkeqW4ny/jNtH9gcbgaqBIXYEZCNnESMAGs0/K/R7oFGMhOyu/eIxg== dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.6.2": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" - integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== +"@babel/plugin-transform-template-literals@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.12.1.tgz#b43ece6ed9a79c0c71119f576d299ef09d942843" + integrity sha512-b4Zx3KHi+taXB1dVRBhVJtEPi9h1THCeKmae2qP0YdUHIFhVjtpqqNfxeVAa1xeHVhAy4SbHxEwx5cltAu5apw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.4" "@babel/helper-plugin-utils" "^7.10.4" -"@babel/preset-env@~7.6.0": - version "7.6.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.3.tgz#9e1bf05a2e2d687036d24c40e4639dc46cef2271" - integrity sha512-CWQkn7EVnwzlOdR5NOm2+pfgSNEZmvGjOhlCHBDq0J8/EStr+G+FvPEiz9B56dR6MoiUFjXhfE4hjLoAKKJtIQ== +"@babel/plugin-transform-typeof-symbol@^7.12.10": + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.10.tgz#de01c4c8f96580bd00f183072b0d0ecdcf0dec4b" + integrity sha512-JQ6H8Rnsogh//ijxspCjc21YPd3VLVoYtAwv3zQmqAt8YGYUtdo5usNhdl4b9/Vir2kPFZl6n1h0PfUz4hJhaA== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-async-generator-functions" "^7.2.0" - "@babel/plugin-proposal-dynamic-import" "^7.5.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.6.2" - "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.6.2" - "@babel/plugin-syntax-async-generators" "^7.2.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" - "@babel/plugin-transform-arrow-functions" "^7.2.0" - "@babel/plugin-transform-async-to-generator" "^7.5.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.6.3" - "@babel/plugin-transform-classes" "^7.5.5" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.6.0" - "@babel/plugin-transform-dotall-regex" "^7.6.2" - "@babel/plugin-transform-duplicate-keys" "^7.5.0" - "@babel/plugin-transform-exponentiation-operator" "^7.2.0" - "@babel/plugin-transform-for-of" "^7.4.4" - "@babel/plugin-transform-function-name" "^7.4.4" - "@babel/plugin-transform-literals" "^7.2.0" - "@babel/plugin-transform-member-expression-literals" "^7.2.0" - "@babel/plugin-transform-modules-amd" "^7.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.6.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@babel/plugin-transform-modules-umd" "^7.2.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.6.3" - "@babel/plugin-transform-new-target" "^7.4.4" - "@babel/plugin-transform-object-super" "^7.5.5" - "@babel/plugin-transform-parameters" "^7.4.4" - "@babel/plugin-transform-property-literals" "^7.2.0" - "@babel/plugin-transform-regenerator" "^7.4.5" - "@babel/plugin-transform-reserved-words" "^7.2.0" - "@babel/plugin-transform-shorthand-properties" "^7.2.0" - "@babel/plugin-transform-spread" "^7.6.2" - "@babel/plugin-transform-sticky-regex" "^7.2.0" - "@babel/plugin-transform-template-literals" "^7.4.4" - "@babel/plugin-transform-typeof-symbol" "^7.2.0" - "@babel/plugin-transform-unicode-regex" "^7.6.2" - "@babel/types" "^7.6.3" - browserslist "^4.6.0" - core-js-compat "^3.1.1" - invariant "^2.2.2" - js-levenshtein "^1.1.3" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-escapes@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.1.tgz#5232b9f81ccb07070b7c3c36c67a1b78f1845709" + integrity sha512-I8gNHJLIc7GdApm7wkVnStWssPNbSRMPtgHdmH3sRM1zopz09UWPS4x5V4n1yz/MIWTVnJ9sp6IkuXdWM4w+2Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.1.tgz#cc9661f61390db5c65e3febaccefd5c6ac3faecb" + integrity sha512-SqH4ClNngh/zGwHZOOQMTD+e8FGWexILV+ePMyiDJttAWRh5dhDL8rcl5lSgU3Huiq6Zn6pWTMvdPAb21Dwdyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.12.1" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.10.2": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.12.11.tgz#55d5f7981487365c93dbbc84507b1c7215e857f9" + integrity sha512-j8Tb+KKIXKYlDBQyIOy4BLxzv1NUOwlHfZ74rvW+Z0Gp4/cI2IMDPBWAgWceGcE7aep9oL/0K9mlzlMGxA8yNw== + dependencies: + "@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/preset-modules@^0.1.3": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== + dependencies: + "@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@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.4.tgz#92e8a66d816f9911d11d4cc935be67adfc82dbcf" - integrity sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw== + version "7.12.10" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.12.10.tgz#4fed65f296cbb0f5fb09de6be8cddc85cc909be9" + integrity sha512-vtQNjaHRl4DUpp+t+g4wvTHsLQuye+n0H/wsXIZRn69oz/fvNC7gQ4IK73zGJBaxvHoxElDvnYCthMcT7uzFoQ== dependencies: "@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/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@^7.8.4": - version "7.11.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" - integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== +"@babel/runtime-corejs3@^7.9.6": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.12.5.tgz#ffee91da0eb4c6dae080774e94ba606368e414f4" + integrity sha512-roGr54CsTmNPPzZoCP1AmDXuBoNao7tnSA83TXTwt+UK5QVyh1DIJnrgYRPWKCF2flqZQXwa7Yr8v7VmLzF0YQ== + dependencies: + core-js-pure "^3.0.0" + regenerator-runtime "^0.13.4" + +"@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": + version "7.12.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" + integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.4", "@babel/template@^7.6.0": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" - integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== +"@babel/template@^7.10.4", "@babel/template@^7.12.7": + version "7.12.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.12.7.tgz#c817233696018e39fbb6c491d2fb684e05ed43bc" + integrity sha512-GkDzmHS6GV7ZeXfJZ0tLRBhZcMcY0/Lnb+eEbXDBfCAcZCjrZKe6p3J4we/D24O9Y8enxWAg1cWwof59yLh2ow== dependencies: "@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@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.6.3": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" - integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== +"@babel/traverse@^7.10.4", "@babel/traverse@^7.12.1", "@babel/traverse@^7.12.10", "@babel/traverse@^7.12.5", "@babel/traverse@^7.7.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.12.12.tgz#d0cd87892704edd8da002d674bc811ce64743376" + integrity sha512-s88i0X0lPy45RrLM8b9mz8RPH5FqO9G9p7ti59cToE44xFm1Q+Pjh5Gq4SXBbtb88X7Uy7pexeqRIQDDMNkL0w== dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.11.5" - "@babel/helper-function-name" "^7.10.4" - "@babel/helper-split-export-declaration" "^7.11.0" - "@babel/parser" "^7.11.5" - "@babel/types" "^7.11.5" + "@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@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.6.3": - version "7.11.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" - integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.12.1", "@babel/types@^7.12.10", "@babel/types@^7.12.11", "@babel/types@^7.12.12", "@babel/types@^7.12.5", "@babel/types@^7.12.7", "@babel/types@^7.4.4", "@babel/types@^7.7.0": + version "7.12.12" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.12.12.tgz#4608a6ec313abbd87afa55004d373ad04a96c299" + integrity sha512-lnIX7piTxOH22xE7fDXDbSHg9MM1/6ORnafpJmov5rs0kX5g4BZxeXNJLXsMRiO0U5Rb8/FvMS6xlTnTHvxonQ== dependencies: - "@babel/helper-validator-identifier" "^7.10.4" + "@babel/helper-validator-identifier" "^7.12.11" lodash "^4.17.19" to-fast-properties "^2.0.0" +"@emotion/cache@^10.0.27": + version "10.0.29" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" + integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== + dependencies: + "@emotion/sheet" "0.9.4" + "@emotion/stylis" "0.8.5" + "@emotion/utils" "0.11.3" + "@emotion/weak-memoize" "0.2.5" + +"@emotion/core@^10.0.14": + version "10.1.1" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.1.1.tgz#c956c1365f2f2481960064bcb8c4732e5fb612c3" + integrity sha512-ZMLG6qpXR8x031NXD8HJqugy/AZSkAuMxxqB46pmAR7ze47MhNJ56cdoX243QPZdGctrdfo+s08yZTiwaUcRKA== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" + +"@emotion/css@^10.0.27": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" + integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== + dependencies: + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + babel-plugin-emotion "^10.0.27" + +"@emotion/hash@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + +"@emotion/is-prop-valid@0.8.8": + version "0.8.8" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" + integrity sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA== + dependencies: + "@emotion/memoize" "0.7.4" + +"@emotion/memoize@0.7.4": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" + integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== + +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": + version "0.11.16" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" + integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== + dependencies: + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/unitless" "0.7.5" + "@emotion/utils" "0.11.3" + csstype "^2.5.7" + +"@emotion/sheet@0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" + integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== + +"@emotion/styled-base@^10.0.27": + version "10.0.31" + resolved "https://registry.yarnpkg.com/@emotion/styled-base/-/styled-base-10.0.31.tgz#940957ee0aa15c6974adc7d494ff19765a2f742a" + integrity sha512-wTOE1NcXmqMWlyrtwdkqg87Mu6Rj1MaukEoEmEkHirO5IoHDJ8LgCQL4MjJODgxWxXibGR3opGp1p7YvkNEdXQ== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/is-prop-valid" "0.8.8" + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + +"@emotion/styled@^10.0.14": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" + integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== + dependencies: + "@emotion/styled-base" "^10.0.27" + babel-plugin-emotion "^10.0.27" + +"@emotion/stylis@0.8.5": + version "0.8.5" + resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" + integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== + +"@emotion/unitless@0.7.5": + version "0.7.5" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" + integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== + +"@emotion/utils@0.11.3": + version "0.11.3" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" + integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== + +"@emotion/weak-memoize@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" + integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== + "@fortawesome/fontawesome-free@^5.14.0": version "5.15.1" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.1.tgz#ccfef6ddbe59f8fe8f694783e1d3eb88902dc5eb" @@ -791,12 +985,62 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.2.tgz#26520bf09abe4a5644cd5414e37125a8954241dd" integrity sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw== -"@simonwep/pickr@^1.5.1": - version "1.7.4" - resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.7.4.tgz#b14fcd945890388b870cd6db4d6c78d531f25141" - integrity sha512-fq7jgKJT21uWGC1mARBHvvd1JYlEf93o7SuVOB4Lr0x/2UPuNC9Oe9n/GzVeg4oVtqMDfh1wIEJpsdOJEZb+3g== +"@popperjs/core@^2.4.4": + version "2.6.0" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.6.0.tgz#f022195afdfc942e088ee2101285a1d31c7d727f" + integrity sha512-cPqjjzuFWNK3BSKLm0abspP0sp/IGOli4p5I5fKFAzdS8fvjdOwDCfZqAaIiXd9lPkOWi3SUUfZof3hEb7J/uw== + +"@projectstorm/geometry@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/geometry/-/geometry-6.3.0.tgz#2c37dee4b907ed0086e91680b815cd16188353f0" + integrity sha512-Fc2JVAkZPnQMAKdn4FtAApvl40S+sUL9E2usRoXcnqRbwmhD3WHBLhmDIvUTArIyKJJOTzyQW4+O7+NcyrK9/Q== + +"@projectstorm/react-canvas-core@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/react-canvas-core/-/react-canvas-core-6.3.0.tgz#dfe3072bb3817910c650a1fa004ce439f5bd0669" + integrity sha512-mChKZpdfrTWdGvg1OB0EOaCz5ovC6spY/MJfGtxYek5gU36mjoAXE+L6uLzjELTM3J/TJhDkm3Wd7jW9vCNUyA== dependencies: - core-js "^3.6.5" + "@projectstorm/geometry" "^6.3.0" + +"@projectstorm/react-diagrams-core@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/react-diagrams-core/-/react-diagrams-core-6.3.0.tgz#4e225e86a0389f383020b4a9e8bbce2e55781cd2" + integrity sha512-xdAA+Rz5vE0adNa/rloXvjDQ2MFlicmdcZHEFTrPH+nV8miAqhHimzbCge8ypAwQyVXS8CLdxUF2RQA/1B8Sng== + dependencies: + "@projectstorm/geometry" "^6.3.0" + "@projectstorm/react-canvas-core" "^6.3.0" + +"@projectstorm/react-diagrams-defaults@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/react-diagrams-defaults/-/react-diagrams-defaults-6.3.0.tgz#2479de1abb3e638df04f33f09413d326b27e29ea" + integrity sha512-5qBFg9sSl3OlIt5Edv45uECgkjqjpg+PSRYderOXJjEQi3SYhf9l0YlfMzpTvt5GmVnyX7gQProyt/p/e4e9rQ== + dependencies: + "@projectstorm/react-diagrams-core" "^6.3.0" + +"@projectstorm/react-diagrams-routing@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/react-diagrams-routing/-/react-diagrams-routing-6.3.0.tgz#38b8973ac35e40639dde7490840217d8cb1e66fb" + integrity sha512-kgq0MNrjbeEcpQceOORL/5bOQJNF70c/If2x/jqdEKfswzGC9VeUYOKZvzYCRhxsOcpn9hCA6+6Wkd8e4zFzYQ== + dependencies: + "@projectstorm/geometry" "^6.3.0" + "@projectstorm/react-diagrams-core" "^6.3.0" + "@projectstorm/react-diagrams-defaults" "^6.3.0" + +"@projectstorm/react-diagrams@^6.3.0": + version "6.3.0" + resolved "https://registry.yarnpkg.com/@projectstorm/react-diagrams/-/react-diagrams-6.3.0.tgz#bd435699f04b63ff57b8434a259aa2dc3b494129" + integrity sha512-qHPhlTBsZk/iwXAPXMh6qzmk66+7U4cShSwXM/3OqDkrBi6yI7nLtdY5VhioO0qBhhOyR8v1C8oeYGFqY0pa8Q== + dependencies: + "@projectstorm/react-diagrams-core" "^6.3.0" + "@projectstorm/react-diagrams-defaults" "^6.3.0" + "@projectstorm/react-diagrams-routing" "^6.3.0" + +"@simonwep/pickr@^1.5.1": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.8.0.tgz#adbff9a4f7f0e59dec9946508c5e481b7abae0f8" + integrity sha512-VaSD7TwktOsro5nQ/FjRx5JAJ09k5CNfGRHacgVRxeVPolUQwelz1SjL8HAOKZwTSmcnIObptpHABQS4zgN7sw== + dependencies: + core-js "^3.8.0" nanopop "^2.1.0" "@sindresorhus/is@^0.7.0": @@ -804,21 +1048,43 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== +"@tippyjs/react@^4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.2.0.tgz#a1cb369d0051099e8a7e4ceb59f809abd9955283" + integrity sha512-T6UcHtwtGkvgsBQ4bNp8BtXGxa2ujfOkWUogYkRtN4UVJ2QRgDdFoJeaPxdndnVYFEa2uTVxSFxs8QkSkZ2Gdw== + dependencies: + tippy.js "^6.2.0" + +"@types/estree@*": + version "0.0.45" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.45.tgz#e9387572998e5ecdac221950dab3e8c3b16af884" + integrity sha512-jnqIUKDUqJbDIUxm0Uj7bnlMnRm1T/eZ9N+AVMqhPgzrba2GhGG5o/jCTwmdPK709nEZsGoMzXEDUjcXHa3W0g== + "@types/json-schema@^7.0.5": version "7.0.6" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== "@types/node@*": - version "14.11.5" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.11.5.tgz#fecad41c041cae7f2404ad4b2d0742fdb628b305" - integrity sha512-jVFzDV6NTbrLMxm4xDSIW/gKnk8rQLF9wAzLWIOg+5nU6ACrIMndeBdXci0FGtqJbP9tQvm6V39eshc96TO2wQ== + version "14.14.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" + integrity sha512-naXYePhweTi+BMv11TgioE2/FXU4fSl29HAH1ffxVciNsH3rYXjNP2yM8wqmSm7jS20gM8TIklKiTen+1iVncw== + +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== "@types/q@^1.5.1": version "1.5.4" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/raf@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@types/raf/-/raf-3.4.0.tgz#2b72cbd55405e071f1c4d29992638e022b20acc2" + integrity sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw== + "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -1023,7 +1289,7 @@ acorn@^6.0.7, acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== -acorn@^7.0.0, acorn@^7.1.1: +acorn@^7.0.0, acorn@^7.1.0, acorn@^7.1.1: version "7.4.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== @@ -1077,9 +1343,9 @@ ajv@^5.0.0: json-schema-traverse "^0.3.0" ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.9.1: - version "6.12.5" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.5.tgz#19b0e8bae8f476e5ba666300387775fb1a00a4da" - integrity sha512-lRF8RORchjpKG50/WFf8xmg7sgCLFiYNNnqdKflk63whMQcWR5ngGjiSXkL9bjxy6B2npOK2HSMN49jEBMSkag== + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== dependencies: fast-deep-equal "^3.1.1" fast-json-stable-stringify "^2.0.0" @@ -1088,7 +1354,7 @@ ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.4, ajv@^6.9.1: "alertifyjs@git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263": version "1.7.1" - resolved "git+https://github.com/EnterpriseDB/AlertifyJS.git#72c1d794f5b6d4ec13a68d123c08f19021afe263" + resolved "git+https://github.com/EnterpriseDB/AlertifyJS/#72c1d794f5b6d4ec13a68d123c08f19021afe263" alphanum-sort@^1.0.0: version "1.0.2" @@ -1161,9 +1427,9 @@ aproba@^1.1.1: integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== arch@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf" - integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== archive-type@^4.0.0: version "4.0.0" @@ -1209,13 +1475,15 @@ array-flatten@1.1.1: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-includes@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348" - integrity sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ== +array-includes@^3.1.1, array-includes@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.2.tgz#a8db03e0b88c8c6aeddc49cb132f9bcab4ebf9c8" + integrity sha512-w2GspexNQpx+PutG3QpT437/BenZBj0M/MZGn5mzv/MofYqo0xmRHzn4lFsoDlWJ+THYsGJmFlW68WlDFx7VRw== dependencies: + 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" array-union@^1.0.1: @@ -1244,20 +1512,22 @@ array.prototype.find@^2.1.1: es-abstract "^1.17.4" array.prototype.flat@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123" + integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.1" array.prototype.flatmap@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.3.tgz#1c13f84a178566042dd63de4414440db9222e443" - integrity sha512-OOEk+lkePcg+ODXIpvuU9PAryCikCJyo7GlDG1upleEpQRx6mzL9puEBkozQ5iAx20KV0l3DbyQwqciJtqe5Pg== + version "1.2.4" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9" + integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q== dependencies: + 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" arraybuffer.slice@~0.0.7: @@ -1334,11 +1604,11 @@ autoprefixer@^9.6.4: postcss-value-parser "^4.1.0" axios-mock-adapter@^1.17.0: - version "1.18.2" - resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.18.2.tgz#01fa9e88e692e8f1bbc1ad1200dde672486e03c7" - integrity sha512-e5aTsPy2Viov22zNpFTlid76W1Scz82pXeEwwCXdtO85LROhHAF8pHF2qDhiyMONLxKyY3lQ+S4UCsKgrlx8Hw== + version "1.19.0" + resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.19.0.tgz#9d72e321a6c5418e1eff067aa99761a86c5188a4" + integrity sha512-D+0U4LNPr7WroiBDvWilzTMYPYTuZlbo6BI8YHZtj7wYQS8NkARlP9KBt8IWWHTQJ0q/8oZ0ClPBtKCCkx8cQg== dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^3.1.3" is-buffer "^2.0.3" axios@^0.18.1: @@ -1358,6 +1628,18 @@ babel-code-frame@^6.26.0: esutils "^2.0.2" js-tokens "^3.0.2" +babel-eslint@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.1.0.tgz#6968e568a910b78fb3779cdd8b6ac2f479943232" + integrity sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.7.0" + "@babel/traverse" "^7.7.0" + "@babel/types" "^7.7.0" + eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" + babel-generator@^6.18.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" @@ -1372,91 +1654,15 @@ babel-generator@^6.18.0: source-map "^0.5.7" trim-right "^1.0.1" -babel-helper-call-delegate@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" - integrity sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340= +babel-loader@^8.1.0: + version "8.2.2" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" + integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== dependencies: - babel-helper-hoist-variables "^6.24.1" - babel-runtime "^6.22.0" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-define-map@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" - integrity sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-function-name@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" - integrity sha1-00dbjAPtmCQqJbSDUasYOZ01gKk= - dependencies: - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-helper-get-function-arity@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" - integrity sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-hoist-variables@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" - integrity sha1-HssnaJydJVE+rbyZFKc/VAi+enY= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-optimise-call-expression@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" - integrity sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-helper-regex@^6.24.1: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" - integrity sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI= - dependencies: - babel-runtime "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" - -babel-helper-replace-supers@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" - integrity sha1-v22/5Dk40XNpohPKiov3S2qQqxo= - dependencies: - babel-helper-optimise-call-expression "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-loader@~8.0.5: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" + find-cache-dir "^3.3.1" + loader-utils "^1.4.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" babel-messages@^6.23.0: version "6.23.0" @@ -1465,13 +1671,6 @@ babel-messages@^6.23.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-check-es2015-constants@^6.3.13: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" - integrity sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o= - dependencies: - babel-runtime "^6.22.0" - babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" @@ -1479,233 +1678,37 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-syntax-object-rest-spread@7.0.0-beta.3: - version "7.0.0-beta.3" - resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-7.0.0-beta.3.tgz#7f781c180899dafd88f132f69472397549be48e5" - integrity sha512-21/MnmUFduLr4JzxrKMm/MeF+Jjyi5UdZo38IqzrP0sLhmPbal5ZAUJ4HgWH4339SdjnYgENacbY5wfk/zxTGg== - -babel-plugin-transform-es2015-arrow-functions@^6.3.13: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" - integrity sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE= +babel-plugin-emotion@^10.0.27: + version "10.0.33" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03" + integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ== dependencies: - babel-runtime "^6.22.0" + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/serialize" "^0.11.16" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" -babel-plugin-transform-es2015-block-scoped-functions@^6.3.13: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" - integrity sha1-u8UbSflk1wy42OC5ToICRs46YUE= +babel-plugin-macros@^2.0.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== dependencies: - babel-runtime "^6.22.0" + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" -babel-plugin-transform-es2015-block-scoping@^6.9.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" - integrity sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8= - dependencies: - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-traverse "^6.26.0" - babel-types "^6.26.0" - lodash "^4.17.4" +babel-plugin-syntax-jsx@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= -babel-plugin-transform-es2015-classes@^6.9.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" - integrity sha1-WkxYpQyclGHlZLSyo7+ryXolhNs= - dependencies: - babel-helper-define-map "^6.24.1" - babel-helper-function-name "^6.24.1" - babel-helper-optimise-call-expression "^6.24.1" - babel-helper-replace-supers "^6.24.1" - babel-messages "^6.23.0" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-computed-properties@^6.3.13: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" - integrity sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM= - dependencies: - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-destructuring@^6.9.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" - integrity sha1-mXux8auWf2gtKwh2/jWNYOdlxW0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-duplicate-keys@^6.6.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" - integrity sha1-c+s9MQypaePvnskcU3QabxV2Qj4= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-for-of@^6.6.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" - integrity sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-function-name@^6.9.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" - integrity sha1-g0yJhTvDaxrw86TF26qU/Y6sqos= - dependencies: - babel-helper-function-name "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-literals@^6.3.13: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" - integrity sha1-T1SgLWzWbPkVKAAZox0xklN3yi4= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-modules-amd@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" - integrity sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ= - dependencies: - babel-plugin-transform-es2015-modules-commonjs "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - -babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.6.0: - version "6.26.2" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" - integrity sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q== - dependencies: - babel-plugin-transform-strict-mode "^6.24.1" - babel-runtime "^6.26.0" - babel-template "^6.26.0" - babel-types "^6.26.0" - -babel-plugin-transform-es2015-object-super@^6.3.13: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" - integrity sha1-JM72muIcuDp/hgPa0CH1cusnj40= - dependencies: - babel-helper-replace-supers "^6.24.1" - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-parameters@^6.9.0: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" - integrity sha1-V6w1GrScrxSpfNE7CfZv3wpiXys= - dependencies: - babel-helper-call-delegate "^6.24.1" - babel-helper-get-function-arity "^6.24.1" - babel-runtime "^6.22.0" - babel-template "^6.24.1" - babel-traverse "^6.24.1" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-shorthand-properties@^6.3.13: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" - integrity sha1-JPh11nIch2YbvZmkYi5R8U3jiqA= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-spread@^6.3.13: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" - integrity sha1-1taKmfia7cRTbIGlQujdnxdG+NE= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-sticky-regex@^6.3.13: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" - integrity sha1-AMHNsaynERLN8M9hJsLta0V8zbw= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-plugin-transform-es2015-template-literals@^6.6.0: - version "6.22.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" - integrity sha1-qEs0UPfp+PH2g51taH2oS7EjbY0= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-typeof-symbol@^6.6.0: - version "6.23.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" - integrity sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I= - dependencies: - babel-runtime "^6.22.0" - -babel-plugin-transform-es2015-unicode-regex@^6.3.13: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" - integrity sha1-04sS9C6nMj9yk4fxinxa4frrNek= - dependencies: - babel-helper-regex "^6.24.1" - babel-runtime "^6.22.0" - regexpu-core "^2.0.0" - -babel-plugin-transform-object-rest-spread@^7.0.0-beta.3: - version "7.0.0-beta.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-7.0.0-beta.3.tgz#5c409f3cd70819dbb3382d2056971c5ebe01393a" - integrity sha512-NOlhrq1CmxyuI94vNsqMhRPMuL5VG2EKUOIJQ0bwNiXBiwWRLdPoWyPT+Irrx5g4g0PkFgA46tnRj7Dc4ZGsxg== - dependencies: - babel-plugin-syntax-object-rest-spread "7.0.0-beta.3" - -babel-plugin-transform-regenerator@^6.9.0: - version "6.26.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" - integrity sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8= - dependencies: - regenerator-transform "^0.10.0" - -babel-plugin-transform-strict-mode@^6.24.1: - version "6.24.1" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" - integrity sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g= - dependencies: - babel-runtime "^6.22.0" - babel-types "^6.24.1" - -babel-preset-es2015-without-strict@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/babel-preset-es2015-without-strict/-/babel-preset-es2015-without-strict-0.0.4.tgz#88c9f36e79d4762c58347b1a698a07c35b6bda5d" - integrity sha1-iMnzbnnUdixYNHsaaYoHw1tr2l0= - dependencies: - babel-plugin-check-es2015-constants "^6.3.13" - babel-plugin-transform-es2015-arrow-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoped-functions "^6.3.13" - babel-plugin-transform-es2015-block-scoping "^6.9.0" - babel-plugin-transform-es2015-classes "^6.9.0" - babel-plugin-transform-es2015-computed-properties "^6.3.13" - babel-plugin-transform-es2015-destructuring "^6.9.0" - babel-plugin-transform-es2015-duplicate-keys "^6.6.0" - babel-plugin-transform-es2015-for-of "^6.6.0" - babel-plugin-transform-es2015-function-name "^6.9.0" - babel-plugin-transform-es2015-literals "^6.3.13" - babel-plugin-transform-es2015-modules-commonjs "^6.6.0" - babel-plugin-transform-es2015-object-super "^6.3.13" - babel-plugin-transform-es2015-parameters "^6.9.0" - babel-plugin-transform-es2015-shorthand-properties "^6.3.13" - babel-plugin-transform-es2015-spread "^6.3.13" - babel-plugin-transform-es2015-sticky-regex "^6.3.13" - babel-plugin-transform-es2015-template-literals "^6.6.0" - babel-plugin-transform-es2015-typeof-symbol "^6.6.0" - babel-plugin-transform-es2015-unicode-regex "^6.3.13" - babel-plugin-transform-regenerator "^6.9.0" - -babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: +babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= @@ -1713,7 +1716,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0: core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: +babel-template@^6.16.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= @@ -1724,7 +1727,7 @@ babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: +babel-traverse@^6.18.0, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= @@ -1739,7 +1742,7 @@ babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: +babel-types@^6.18.0, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= @@ -1823,10 +1826,15 @@ base64-arraybuffer@0.1.5: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= -base64-js@^1.0.2: - version "1.3.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" - integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== +base64-arraybuffer@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45" + integrity sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ== + +base64-js@^1.0.2, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== base64id@1.0.0: version "1.0.0" @@ -1966,7 +1974,7 @@ bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.9.tgz#26d556829458f9d1e81fc48952493d0ba3507828" integrity sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw== -bn.js@^5.1.1: +bn.js@^5.0.0, bn.js@^5.1.1: version "5.1.3" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.3.tgz#beca005408f642ebebea80b042b4d18d2ac0ee6b" integrity sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ== @@ -2004,10 +2012,10 @@ bootstrap4-toggle@3.4.0: resolved "https://registry.yarnpkg.com/bootstrap4-toggle/-/bootstrap4-toggle-3.4.0.tgz#58264d4c7fd24eb2e09cca5156a338b2b22a4792" integrity sha512-vKfBgsjICW6mOqb264qwwbbGtpcOx+p9jOlQmLfRZ07iGE+b5YbQlY4ft9aAhPulh7V3oKOtEuuq0FcSKAI4bQ== -bootstrap@>=4.1.2, bootstrap@^4.3.1: - version "4.5.2" - resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.2.tgz#a85c4eda59155f0d71186b6e6ad9b875813779ab" - integrity sha512-vlGn0bcySYl/iV+BGA544JkkZP5LB3jsmkeKLFQakCOwCM3AOk7VkldBz4jrzSe+Z0Ezn99NVXa1o45cQY4R6A== +bootstrap@^4.3.1, bootstrap@^4.5.2: + version "4.5.3" + resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.5.3.tgz#c6a72b355aaf323920be800246a6e4ef30997fe6" + integrity sha512-o9ppKQioXGqhw8Z7mah6KdTYpNQY//tipnkxppWhPbiSWdD+1raYsnhwEZjkTHYbGee4cVQ0Rx65EhOY/HNLcQ== bowser@2.1.2: version "2.1.2" @@ -2108,11 +2116,11 @@ browserify-des@^1.0.0: safe-buffer "^5.1.2" browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" - integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== dependencies: - bn.js "^4.1.0" + bn.js "^5.0.0" randombytes "^2.0.1" browserify-sign@^4.0.0: @@ -2137,7 +2145,61 @@ browserify-zlib@^0.2.0, browserify-zlib@~0.2.0: dependencies: pako "~1.0.5" -browserify@^16.1.0, browserify@~16.2.3: +browserify@^16.1.0: + version "16.5.2" + resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.5.2.tgz#d926835e9280fa5fd57f5bc301f2ef24a972ddfe" + integrity sha512-TkOR1cQGdmXU9zW4YukWzWVSJwrxmNdADFbqbE3HFgQWe5wqZmOawqZ7J/8MPCwk/W8yY7Y0h+7mOtcZxLP23g== + dependencies: + JSONStream "^1.0.3" + assert "^1.4.0" + browser-pack "^6.0.1" + browser-resolve "^2.0.0" + browserify-zlib "~0.2.0" + buffer "~5.2.1" + cached-path-relative "^1.0.0" + concat-stream "^1.6.0" + console-browserify "^1.1.0" + constants-browserify "~1.0.0" + crypto-browserify "^3.0.0" + defined "^1.0.0" + deps-sort "^2.0.0" + domain-browser "^1.2.0" + duplexer2 "~0.1.2" + events "^2.0.0" + glob "^7.1.0" + has "^1.0.0" + htmlescape "^1.1.0" + https-browserify "^1.0.0" + inherits "~2.0.1" + insert-module-globals "^7.0.0" + labeled-stream-splicer "^2.0.0" + mkdirp-classic "^0.5.2" + module-deps "^6.2.3" + os-browserify "~0.3.0" + parents "^1.0.1" + path-browserify "~0.0.0" + process "~0.11.0" + punycode "^1.3.2" + querystring-es3 "~0.2.0" + read-only-stream "^2.0.0" + readable-stream "^2.0.2" + resolve "^1.1.4" + shasum "^1.0.0" + shell-quote "^1.6.1" + stream-browserify "^2.0.0" + stream-http "^3.0.0" + string_decoder "^1.1.1" + subarg "^1.0.0" + syntax-error "^1.1.1" + through2 "^2.0.0" + timers-browserify "^1.0.1" + tty-browserify "0.0.1" + url "~0.11.0" + util "~0.10.1" + vm-browserify "^1.0.0" + xtend "^4.0.0" + +browserify@~16.2.3: version "16.2.3" resolved "https://registry.yarnpkg.com/browserify/-/browserify-16.2.3.tgz#7ee6e654ba4f92bce6ab3599c3485b1cc7a0ad0b" integrity sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ== @@ -2191,15 +2253,16 @@ browserify@^16.1.0, browserify@~16.2.3: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.0, browserslist@^4.8.5: - version "4.14.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.5.tgz#1c751461a102ddc60e40993639b709be7f2c4015" - integrity sha512-Z+vsCZIvCBvqLoYkBFTwEYH3v5MCQbsAjp50ERycpOjnPmolg1Gjy4+KaWWpm8QOJt9GHkhdqAl14NpCX73CWA== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.15.0: + version "4.16.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.0.tgz#410277627500be3cb28a1bfe037586fbedf9488b" + integrity sha512-/j6k8R0p3nxOC6kx5JGAxsnhc9ixaWJfYc+TNTzxg6+ARaESAvQGV7h0uNOB4t+pLQJZWzcrMxXOxjgsCj3dqQ== dependencies: - caniuse-lite "^1.0.30001135" - electron-to-chromium "^1.3.571" - escalade "^3.1.0" - node-releases "^1.1.61" + caniuse-lite "^1.0.30001165" + colorette "^1.2.1" + electron-to-chromium "^1.3.621" + escalade "^3.1.1" + node-releases "^1.1.67" buffer-alloc-unsafe@^1.1.0: version "1.1.0" @@ -2244,9 +2307,17 @@ buffer@^4.3.0: isarray "^1.0.0" buffer@^5.0.2, buffer@^5.2.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +buffer@~5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6" + integrity sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg== dependencies: base64-js "^1.0.2" ieee754 "^1.1.4" @@ -2339,6 +2410,14 @@ cached-path-relative@^1.0.0, cached-path-relative@^1.0.2: resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.2.tgz#a13df4196d26776220cc3356eb147a52dba2c6db" integrity sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg== +call-bind@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.0.tgz#24127054bb3f9bdcb4b1fb82418186072f77b8ce" + integrity sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.0" + caller-callsite@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" @@ -2396,10 +2475,22 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001135: - version "1.0.30001146" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001146.tgz#c61fcb1474520c1462913689201fb292ba6f447c" - integrity sha512-VAy5RHDfTJhpxnDdp2n40GPPLp3KqNrXz1QqFv4J64HvArKs8nuNMOWkB3ICOaBTU/Aj4rYAo/ytdQDDFF/Pug== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001165: + version "1.0.30001170" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001170.tgz#0088bfecc6a14694969e391cc29d7eb6362ca6a7" + integrity sha512-Dd4d/+0tsK0UNLrZs3CvNukqalnVTRrxb5mcQm8rHL49t7V5ZaTygwXkrq+FB+dVDf++4ri8eJnFEJAB8332PA== + +canvg@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/canvg/-/canvg-3.0.7.tgz#e45b87a64116af906917f7cad57d370ea372d682" + integrity sha512-4sq6iL5Q4VOXS3PL1BapiXIZItpxYyANVzsAKpTPS5oq4u3SKbGfUcbZh2gdLCQ3jWpG/y5wRkMlBBAJhXeiZA== + dependencies: + "@babel/runtime-corejs3" "^7.9.6" + "@types/raf" "^3.4.0" + raf "^3.4.1" + rgbcolor "^1.0.1" + stackblur-canvas "^2.0.0" + svg-pathdata "^5.0.5" caw@^2.0.0, caw@^2.0.1: version "2.0.1" @@ -2445,9 +2536,9 @@ chardet@^0.7.0: integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== chart.js@^2.9.3: - version "2.9.3" - resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.3.tgz#ae3884114dafd381bc600f5b35a189138aac1ef7" - integrity sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw== + version "2.9.4" + resolved "https://registry.yarnpkg.com/chart.js/-/chart.js-2.9.4.tgz#0827f9563faffb2dc5c06562f8eb10337d5b9684" + integrity sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A== dependencies: chartjs-color "^2.1.0" moment "^2.10.2" @@ -2472,19 +2563,46 @@ check-types@^8.0.3: resolved "https://registry.yarnpkg.com/check-types/-/check-types-8.0.3.tgz#3356cca19c889544f2d7a95ed49ce508a0ecf552" integrity sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ== -cheerio@^1.0.0-rc.3: - version "1.0.0-rc.3" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6" - integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA== +cheerio-select-tmp@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/cheerio-select-tmp/-/cheerio-select-tmp-0.1.1.tgz#55bbef02a4771710195ad736d5e346763ca4e646" + integrity sha512-YYs5JvbpU19VYJyj+F7oYrIE2BOll1/hRU7rEy/5+v9BzkSo3bK81iAeeQEMI92vRIxz677m72UmJUiVwwgjfQ== dependencies: - css-select "~1.2.0" - dom-serializer "~0.1.1" - entities "~1.1.1" - htmlparser2 "^3.9.1" - lodash "^4.15.0" - parse5 "^3.0.1" + css-select "^3.1.2" + css-what "^4.0.0" + domelementtype "^2.1.0" + domhandler "^4.0.0" + domutils "^2.4.4" -"chokidar@>=2.0.0 <4.0.0", chokidar@^2.1.1, chokidar@^2.1.8: +cheerio@^1.0.0-rc.3: + version "1.0.0-rc.5" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.5.tgz#88907e1828674e8f9fee375188b27dadd4f0fa2f" + integrity sha512-yoqps/VCaZgN4pfXtenwHROTp8NG6/Hlt4Jpz2FEP0ZJQ+ZUkVDd0hAPDNKhj3nakpfPt/CNs57yEtxD1bXQiw== + dependencies: + cheerio-select-tmp "^0.1.0" + dom-serializer "~1.2.0" + domhandler "^4.0.0" + entities "~2.1.0" + htmlparser2 "^6.0.0" + parse5 "^6.0.0" + parse5-htmlparser2-tree-adapter "^6.0.0" + +"chokidar@>=2.0.0 <4.0.0", chokidar@^3.0.0, chokidar@^3.4.1: + version "3.4.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.3.tgz#c1df38231448e45ca4ac588e6c79573ba6a57d5b" + integrity sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.5.0" + optionalDependencies: + fsevents "~2.1.2" + +chokidar@^2.1.1, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -2503,21 +2621,6 @@ cheerio@^1.0.0-rc.3: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.0.0, chokidar@^3.4.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - 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" - optionalDependencies: - fsevents "~2.1.2" - chownr@^1.1.1, chownr@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -2595,6 +2698,13 @@ clone-response@1.0.2: dependencies: mimic-response "^1.0.0" +closest@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/closest/-/closest-0.0.1.tgz#26da6f80b3e0e17e71f80f12782819e9f653495c" + integrity sha1-JtpvgLPg4X5x+A8SeCgZ6fZTSVw= + dependencies: + matches-selector "0.0.1" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -2610,9 +2720,9 @@ coa@^2.0.2: q "^1.1.2" codemirror@^5.54.0: - version "5.58.1" - resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.58.1.tgz#ec6bf38ad2a17f74c61bd00cc6dc5a69bd167854" - integrity sha512-UGb/ueu20U4xqWk8hZB3xIfV2/SFqnSLYONiM3wTMDqko0bsYrsAkGGhqUzbRkYm89aBKPyHtuNEbVWF9FTFzw== + version "5.59.0" + resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.0.tgz#6d8132055459aabf21d04cae5cf5c430e5c57bb9" + integrity sha512-UGzSkCacY9z0rSpQ3wnTWRN2nvRE6foDXnJltWW8pazInR/R+3gXHrao4IFQMv/bSBvFBxt8/HPpkpKAS54x5Q== collection-visit@^1.0.0: version "1.0.0" @@ -2636,31 +2746,31 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@1.1.3, color-name@^1.0.0: +color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== +color-string@^1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.4.tgz#dd51cd25cfee953d138fe4002372cc3d0e504cb6" + integrity sha512-57yF5yt8Xa3czSEW1jfQDE79Idk0+AkN/4KWad6tbdxUmAs3MvjxlWSWD4deYytcRfoZ9nhKyFl1kj5tBvidbw== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" color@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10" - integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg== + version "3.1.3" + resolved "https://registry.yarnpkg.com/color/-/color-3.1.3.tgz#ca67fb4e7b97d611dcde39eceed422067d91596e" + integrity sha512-xgXAcTHa2HeFCGLE9Xs/R82hujGtu9Jd9x4NW3T34+OMs7VoPsjwzRczKHvTAHeJwWFwX5j15+MgAppE8ztObQ== dependencies: color-convert "^1.9.1" - color-string "^1.5.2" + color-string "^1.5.4" colorette@^1.2.1: version "1.2.1" @@ -2688,9 +2798,9 @@ commander@^2.12.2, commander@^2.18.0, commander@^2.19.0, commander@^2.20.0, comm integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== commander@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.1.0.tgz#f8d722b78103141006b66f4c7ba1e97315ba75bc" - integrity sha512-wl7PNrYWd2y5mp1OK/LhTlv8Ff4kQJQRXXAvF+uU/TPNiVJUxZLRYGj/B0y/lPGAVcSbJqH2Za/cvHmrPMC8mA== + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== commondir@^1.0.1: version "1.0.1" @@ -2777,18 +2887,18 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.1.0, convert-source-map@^1.1.3, convert-source-map@~1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" - integrity sha1-SCnId+n+SbMWHzvzZziI4gRpmGA= - -convert-source-map@^1.5.0, convert-source-map@^1.7.0: +convert-source-map@^1.1.3, convert-source-map@^1.5.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" +convert-source-map@~1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.1.3.tgz#4829c877e9fe49b3161f3bf3673888e204699860" + integrity sha1-SCnId+n+SbMWHzvzZziI4gRpmGA= + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -2839,23 +2949,28 @@ copy-webpack-plugin@^5.1.0: serialize-javascript "^4.0.0" webpack-log "^2.0.0" -core-js-compat@^3.1.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== +core-js-compat@^3.8.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.8.1.tgz#8d1ddd341d660ba6194cbe0ce60f4c794c87a36e" + integrity sha512-a16TLmy9NVD1rkjUGbwuyWkiDoN0FDpAwrfLONvHFQx0D9k7J9y0srwMT8QP/Z6HE3MIFaVynEeYwZwPX1o5RQ== dependencies: - browserslist "^4.8.5" + browserslist "^4.15.0" semver "7.0.0" -core-js@^2.4.0: - version "2.6.11" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.11.tgz#38831469f9922bded8ee21c9dc46985e0399308c" - integrity sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg== +core-js-pure@^3.0.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.8.1.tgz#23f84048f366fdfcf52d3fd1c68fec349177d119" + integrity sha512-Se+LaxqXlVXGvmexKGPvnUIYC1jwXu1H6Pkyb3uBM5d8/NELMYCHs/4/roD7721NxrTLyv7e5nXd5/QLBO+10g== -core-js@^3.2.1, core-js@^3.6.5: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.6.5.tgz#7395dc273af37fb2e50e9bd3d9fe841285231d1a" - integrity sha512-vZVEEwZoIsI+vPEuoF9Iqf5H7/M3eeQqWlQnYa8FSKKePuYTf5MWnxb5SDAzCa60b3JBRS5g9b+Dq7b1y/RCrA== +core-js@^2.4.0: + version "2.6.12" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" + integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== + +core-js@^3.2.1, core-js@^3.8.0: + version "3.8.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.8.1.tgz#f51523668ac8a294d1285c3b9db44025fda66d47" + integrity sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg== core-util-is@~1.0.0: version "1.0.2" @@ -2872,6 +2987,17 @@ cosmiconfig@^5.0.0: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@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" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -2960,6 +3086,13 @@ css-declaration-sorter@^4.0.1: postcss "^7.0.1" timsort "^0.3.0" +css-line-break@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-1.1.1.tgz#d5e9bdd297840099eb0503c7310fd34927a026ef" + integrity sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA== + dependencies: + base64-arraybuffer "^0.2.0" + css-loader@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-2.1.0.tgz#42952ac22bca5d076978638e9813abce49b8f0cc" @@ -2991,15 +3124,16 @@ css-select@^2.0.0: domutils "^1.7.0" nth-check "^1.0.2" -css-select@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858" - integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg= +css-select@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-3.1.2.tgz#d52cbdc6fee379fba97fb0d3925abbd18af2d9d8" + integrity sha512-qmss1EihSuBNWNNhHjxzxSfJoFBM/lERB/Q4EnsJQQC62R2evJDW481091oAdOr9uh46/0n4nrg0It5cAnj1RA== dependencies: - boolbase "~1.0.0" - css-what "2.1" - domutils "1.5.1" - nth-check "~1.0.1" + boolbase "^1.0.0" + css-what "^4.0.0" + domhandler "^4.0.0" + domutils "^2.4.3" + nth-check "^2.0.0" css-tree@1.0.0-alpha.37: version "1.0.0-alpha.37" @@ -3009,23 +3143,23 @@ css-tree@1.0.0-alpha.37: mdn-data "2.0.4" source-map "^0.6.1" -css-tree@1.0.0-alpha.39: - version "1.0.0-alpha.39" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb" - integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA== +css-tree@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5" + integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ== dependencies: - mdn-data "2.0.6" + mdn-data "2.0.14" source-map "^0.6.1" -css-what@2.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2" - integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg== - css-what@^3.2.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.1.tgz#81cb70b609e4b1351b1e54cbc90fd9c54af86e2e" - integrity sha512-wHOppVDKl4vTAOWzJt5Ek37Sgd9qq1Bmj/T1OjvicWbU5W7ru7Pqbn0Jdqii3Drx/h+dixHKXNhZYx7blthL7g== + version "3.4.2" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4" + integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ== + +css-what@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-4.0.0.tgz#35e73761cab2eeb3d3661126b23d7aa0e8432233" + integrity sha512-teijzG7kwYfNVsUh2H/YN62xW3KK9YhXEgSlbxMlcyjPNvdKJqFx5lrwlJgoFP1ZHlB89iGDlo/JyshKeRhv5A== cssesc@^3.0.0: version "3.0.0" @@ -3101,11 +3235,16 @@ cssnano@^4.1.10: postcss "^7.0.0" csso@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.0.3.tgz#0d9985dc852c7cc2b2cacfbbe1079014d1a8e903" - integrity sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ== + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== dependencies: - css-tree "1.0.0-alpha.39" + css-tree "^1.1.2" + +csstype@^2.5.7: + version "2.6.14" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.14.tgz#004822a4050345b55ad4dcc00be1d9cf2f4296de" + integrity sha512-2mSc+VEpGPblzAxyeR+vZhJKgYg0Og0nnRi7pmRXFYYxSfnOnW8A5wwQb4n4cE2nIOzqKOAzLCaEX6aBmNEv8A== cubic2quad@^1.0.0: version "1.1.1" @@ -3138,6 +3277,14 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +dagre@^0.8.4: + version "0.8.5" + resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee" + integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== + dependencies: + graphlib "^2.1.8" + lodash "^4.17.15" + dash-ast@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-1.0.0.tgz#12029ba5fb2f8aa6f0a861795b23c1b4b6c27d37" @@ -3163,16 +3310,16 @@ debug@=3.1.0, debug@~3.1.0: ms "2.0.0" debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.2.0.tgz#7f150f93920e94c58f5574c2fd01a3110effe7f1" - integrity sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== dependencies: ms "2.1.2" @@ -3391,40 +3538,46 @@ dom-serialize@^2.2.0: extend "^3.0.0" void-elements "^2.0.0" -dom-serializer@0, dom-serializer@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" - integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA== +dom-serializer@0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" + integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g== dependencies: - domelementtype "^1.3.0" - entities "^1.1.1" + domelementtype "^2.0.1" + entities "^2.0.0" + +dom-serializer@^1.0.1, dom-serializer@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.2.0.tgz#3433d9136aeb3c627981daa385fc7f32d27c48f1" + integrity sha512-n6kZFH/KlCrqs/1GHMOd5i2fd/beQHuehKdWvNNffbGHTr/almdhuVvTVFb3V7fglz+nC50fFusu3lY33h12pA== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + entities "^2.0.0" domain-browser@^1.1.1, domain-browser@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== -domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1: +domelementtype@1: version "1.3.1" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f" integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w== -domhandler@^2.3.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803" - integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA== - dependencies: - domelementtype "1" +domelementtype@^2.0.1, domelementtype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.1.0.tgz#a851c080a6d1c3d94344aed151d99f669edf585e" + integrity sha512-LsTgx/L5VpD+Q8lmsXSHW2WpA+eBlZ9HPf3erD1IoPF00/3JKHZ3BknUVA2QGDNu69ZNmyFmCWBSO45XjYKC5w== -domutils@1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" - integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8= +domhandler@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.0.0.tgz#01ea7821de996d85f69029e81fa873c21833098e" + integrity sha512-KPTbnGQ1JeEMQyO1iYXoagsI6so/C96HZiFyByU3T6iAzpXn8EGEvct6unm1ZGoed8ByO2oirxgwxBmqKF9haA== dependencies: - dom-serializer "0" - domelementtype "1" + domelementtype "^2.1.0" -domutils@^1.5.1, domutils@^1.7.0: +domutils@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a" integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg== @@ -3432,6 +3585,15 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^2.4.3, domutils@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.4.tgz#282739c4b150d022d34699797369aad8d19bbbd3" + integrity sha512-jBC0vOsECI4OMdD0GC9mGn7NXPLb+Qt6KW1YDQzeQYRUFKmNG8lh7mO5HiELfr+lLQE7loDVI4QcAxV80HS+RA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + dot-prop@^5.2.0: version "5.3.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" @@ -3521,10 +3683,10 @@ ejs@~3.0.2: resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.0.2.tgz#745b01cdcfe38c1c6a2da3bbb2d9957060a31226" integrity sha512-IncmUpn1yN84hy2shb0POJ80FWrfGNY0cxO9f4v+/sG7qcBvAtVWUA1IdzY/8EYUmOVhoKJVdJjNd3AZcnxOjA== -electron-to-chromium@^1.3.571: - version "1.3.578" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.578.tgz#e6671936f4571a874eb26e2e833aa0b2c0b776e0" - integrity sha512-z4gU6dA1CbBJsAErW5swTGAaU2TBzc2mPAonJb00zqW1rOraDo2zfBMDRvaz9cVic+0JEZiYbHWPw/fTaZlG2Q== +electron-to-chromium@^1.3.621: + version "1.3.633" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.633.tgz#16dd5aec9de03894e8d14a1db4cda8a369b9b7fe" + integrity sha512-bsVCsONiVX1abkWdH7KtpuDAhsQ3N3bjPYhROSAXE78roJKet0Y5wznA14JE9pzbwSZmSMAW6KiKYf1RvbTJkA== elliptic@^6.5.3: version "6.5.3" @@ -3615,10 +3777,10 @@ ent@~2.2.0: resolved "https://registry.yarnpkg.com/ent/-/ent-2.2.0.tgz#e964219325a21d05f44466a2f686ed6ce5f5dd1d" integrity sha1-6WQhkyWiHQX0RGai9obtbOX13R0= -entities@^1.1.1, entities@~1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56" - integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w== +entities@^2.0.0, entities@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" + integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== enzyme-adapter-react-16@^1.15.2: version "1.15.5" @@ -3636,14 +3798,15 @@ enzyme-adapter-react-16@^1.15.2: semver "^5.7.0" enzyme-adapter-utils@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.13.1.tgz#59c1b734b0927543e3d8dc477299ec957feb312d" - integrity sha512-5A9MXXgmh/Tkvee3bL/9RCAAgleHqFnsurTYCbymecO4ohvtNO5zqIhHxV370t7nJAwaCfkgtffarKpC0GPt0g== + version "1.14.0" + resolved "https://registry.yarnpkg.com/enzyme-adapter-utils/-/enzyme-adapter-utils-1.14.0.tgz#afbb0485e8033aa50c744efb5f5711e64fbf1ad0" + integrity sha512-F/z/7SeLt+reKFcb7597IThpDp0bmzcH1E9Oabqv+o01cID2/YInlqHbFl7HzWBl4h3OdZYedtwNDOmSKkk0bg== dependencies: 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" @@ -3692,9 +3855,9 @@ enzyme@^3.11.0: string.prototype.trim "^1.2.1" errno@^0.1.3, errno@~0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" - integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" @@ -3705,7 +3868,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.17.5: +es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.4: version "1.17.7" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.7.tgz#a4de61b2f66989fc7421676c1cb9787573ace54c" integrity sha512-VBl/gnfcJ7OercKA9MVaegWsBHFjV492syMudcnQZvt/Dw8ezpcOHYZXa/J96O8vx+g4x65YKhxOwDUh63aS5g== @@ -3749,10 +3912,10 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -escalade@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" - integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== escape-html@~1.0.3: version "1.0.3" @@ -3765,20 +3928,20 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= eslint-plugin-react@^7.20.5: - version "7.21.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.21.3.tgz#71655d2af5155b19285ec929dd2cdc67a4470b52" - integrity sha512-OI4GwTCqyIb4ipaOEGLWdaOHCXZZydStAsBEPB2e1ZfNM37bojpgO1BoOQbFb0eLVz3QLDx7b+6kYcrxCuJfhw== + version "7.21.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz#50b21a412b9574bfe05b21db176e8b7b3b15bff3" + integrity sha512-8MaEggC2et0wSF6bUeywF7qQ46ER81irOdWS4QWxnnlAEsnzeBevk1sWh7fhpCghPpXb+8Ks7hvaft6L/xsR6g== dependencies: 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" eslint-scope@^4.0.2, eslint-scope@^4.0.3: @@ -4103,7 +4266,7 @@ fast-deep-equal@^1.0.0: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" integrity sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ= -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -4249,7 +4412,7 @@ finalhandler@1.1.2, finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: +find-cache-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== @@ -4267,6 +4430,11 @@ find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -4329,13 +4497,18 @@ flush-write-stream@^1.0.0: inherits "^2.0.3" readable-stream "^2.3.6" -follow-redirects@1.5.10, follow-redirects@^1.0.0: +follow-redirects@1.5.10: version "1.5.10" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== dependencies: debug "=3.1.0" +follow-redirects@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.1.tgz#5f69b813376cee4fd0474a3aba835df04ab763b7" + integrity sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg== + for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -4427,29 +4600,30 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -function.prototype.name@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.2.tgz#5cdf79d7c05db401591dfde83e3b70c5123e9a45" - integrity sha512-C8A+LlHBJjB2AdcRPorc5JvJ5VUoWlXdEHLOJdCI7kjHEtGTpHQUiqMvCIKUwIsGwZX2jZJy761AXsn356bJQg== +function.prototype.name@^1.1.2, function.prototype.name@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.3.tgz#0bb034bb308e7682826f215eb6b2ae64918847fe" + integrity sha512-H51qkbNSp8mtkJt+nyW1gyStBiKZxfRqySNUR99ylq6BPXHKI4SEvIlTKp4odLfjRKJV04DFWMU3G/YRlQOsag== dependencies: + 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" functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -functions-have-names@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.1.tgz#a981ac397fa0c9964551402cdc5533d7a4d52f91" - integrity sha512-j48B/ZI7VKs3sgeI2cZp7WXWmZXu7Iq5pl5/vptV5N2mq+DGFuS/ulaDjtaoLpYzuD6u8UgrUKHfgo7fDTSiBA== +functions-have-names@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.2.tgz#98d93991c39da9361f8e50b337c4f6e41f120e21" + integrity sha512-bLgc3asbWdwPbx2mNk2S49kmJCuQeu0nfmaOgbs8WIyzzkw3r4htszdIi9Q9EMezDPTYuJx2wvjZ/EwgAthpnA== gensync@^1.0.0-beta.1: - version "1.0.0-beta.1" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" - integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== geometry-interfaces@^1.1.4: version "1.1.4" @@ -4466,6 +4640,15 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.0, get-intrinsic@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.0.2.tgz#6820da226e50b24894e08859469dc68361545d49" + integrity sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + get-proxy@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" @@ -4657,6 +4840,13 @@ graceful-fs@^4.1.10, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1. resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +graphlib@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" + integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== + dependencies: + lodash "^4.17.15" + gzip-size@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-5.1.1.tgz#cb9bee692f87c0612b232840a873904e4c135274" @@ -4771,6 +4961,11 @@ hat@^0.0.3: resolved "https://registry.yarnpkg.com/hat/-/hat-0.0.3.tgz#bb014a9e64b3788aed8005917413d4ff3d502d8a" integrity sha1-uwFKnmSzeIrtgAWRdBPU/z1QLYo= +heap@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.5.tgz#713b65590ebcc40fcbeeaf55e851694092b39af1" + integrity sha1-cTtlWQ68xA/L7q9V6FFpQJKzmvE= + hex-color-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" @@ -4829,29 +5024,39 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== +html-to-image@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-0.1.3.tgz#9661a54c30ed9c4b269f4612416b1c7e887de3a7" + integrity sha512-8JTGEAAdJGL/nlp3wb/WI8fLMx2dHKOFZMdsvdon23D45ZdtsXDeRm39Wddf04ludQe3OPmvjMJ9nPjI/7hPlg== + +html2canvas@^1.0.0-rc.7: + version "1.0.0-rc.7" + resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.0.0-rc.7.tgz#70c159ce0e63954a91169531894d08ad5627ac98" + integrity sha512-yvPNZGejB2KOyKleZspjK/NruXVQuowu8NnV2HYG7gW7ytzl+umffbtUI62v2dCHQLDdsK6HIDtyJZ0W3neerA== + dependencies: + css-line-break "1.1.1" + htmlescape@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/htmlescape/-/htmlescape-1.1.1.tgz#3a03edc2214bca3b66424a3e7959349509cb0351" integrity sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E= -htmlparser2@^3.9.1: - version "3.10.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f" - integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ== +htmlparser2@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.0.0.tgz#c2da005030390908ca4c91e5629e418e0665ac01" + integrity sha512-numTQtDZMoh78zJpaNdJ9MXb2cv5G3jwUoe3dMQODubZvLoGvTE/Ofp6sHvH8OGKcN/8A47pGLi/k58xHP/Tfw== dependencies: - domelementtype "^1.3.1" - domhandler "^2.3.0" - domutils "^1.5.1" - entities "^1.1.1" - inherits "^2.0.1" - readable-stream "^3.1.1" + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.4.4" + entities "^2.0.0" http-cache-semantics@3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== -http-errors@1.7.2, http-errors@~1.7.2: +http-errors@1.7.2: version "1.7.2" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== @@ -4862,6 +5067,17 @@ http-errors@1.7.2, http-errors@~1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-proxy@^1.13.0: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" @@ -4906,10 +5122,10 @@ icss-utils@^4.0.0: dependencies: postcss "^7.0.14" -ieee754@^1.1.4: - version "1.1.13" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" - integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== +ieee754@^1.1.13, ieee754@^1.1.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== iferr@^0.1.5: version "0.1.5" @@ -5027,10 +5243,10 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" - integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== +import-fresh@^3.0.0, import-fresh@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -5103,7 +5319,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -5119,9 +5335,9 @@ inherits@2.0.3: integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= ini@^1.3.4, ini@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" - integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== inline-source-map@~0.6.0: version "0.6.2" @@ -5150,9 +5366,9 @@ inquirer@^6.2.2: through "^2.3.6" insert-module-globals@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.0.tgz#ec87e5b42728479e327bd5c5c71611ddfb4752ba" - integrity sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw== + version "7.2.1" + resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.1.tgz#d5e33185181a4e1f33b15f7bf100ee91890d5cb3" + integrity sha512-ufS5Qq9RZN+Bu899eA9QCAYThY+gGW7oRkmb0vC93Vlyu/CFGcH0OYPEjVkDXA5FEbTt1+VWzdoOD3Ny9N+8tg== dependencies: JSONStream "^1.0.3" acorn-node "^1.5.2" @@ -5227,6 +5443,13 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-any-array@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-0.1.0.tgz#e5a27965e3371610c10c66bca3be37ee177bdf8e" + integrity sha512-6Kkl1RnvfdkmXM6ZlP+kELGBMA74Nq5pSOm9gIKDaPRe9KQlIJzonrOgq0Jzn/iElB6F2/olpLgWYeVySzrSRg== + dependencies: + rollup "^1.31.1" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -5252,9 +5475,11 @@ is-binary-path@~2.1.0: binary-extensions "^2.0.0" is-boolean-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.1.tgz#10edc0900dd127697a92f6f9807c7617d68ac48e" - integrity sha512-TqZuVwa/sppcrhUCAYkGBk7w0yxfQQnxq28fjkO53tnK9FQXmdwz2JS5+GjsWQ6RByES1K40nI+yDic5c9/aAQ== + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0" + integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA== + dependencies: + call-bind "^1.0.0" is-buffer@^1.1.0, is-buffer@^1.1.5: version "1.1.6" @@ -5262,9 +5487,9 @@ is-buffer@^1.1.0, is-buffer@^1.1.5: integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== is-buffer@^2.0.2, is-buffer@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" - integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.2: version "1.2.2" @@ -5283,6 +5508,13 @@ is-color-stop@^1.0.0: rgb-regex "^1.0.1" rgba-regex "^1.0.0" +is-core-module@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a" + integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ== + dependencies: + has "^1.0.3" + is-cwebp-readable@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-cwebp-readable/-/is-cwebp-readable-2.0.1.tgz#afb93b0c0abd0a25101016ae33aea8aedf926d26" @@ -5396,9 +5628,9 @@ is-natural-number@^4.0.1: integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= is-negative-zero@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461" - integrity sha1-lVOxIbD6wohp2p7UWeIMdUN4hGE= + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.1.tgz#3de746c18dda2319241a53675908d8f766f11c24" + integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w== is-number-object@^1.0.4: version "1.0.4" @@ -5423,9 +5655,9 @@ is-obj@^2.0.0: integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== is-object@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" - integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: version "1.1.0" @@ -5628,7 +5860,12 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jasmine-core@^3.3, jasmine-core@~3.3.0: +jasmine-core@^3.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.6.0.tgz#491f3bb23941799c353ceb7a45b38a950ebc5a20" + integrity sha512-8uQYa7zJN8hq9z+g8z1bqCfdC8eoDAeVnM5sfqs7KHv9/ifoJ500m018fpFc7RDaO6SWCLCXwo/wPSNcdYTgcw== + +jasmine-core@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.3.0.tgz#dea1cdc634bc93c7e0d4ad27185df30fa971b10e" integrity sha512-3/xSmG/d35hf80BEN66Y6g9Ca5l/Isdeg/j6zvbTYlTzeKinzmaTM4p9am5kYqOmE05D7s1t8FGjzdSnbUbceA== @@ -5660,16 +5897,11 @@ jquery-ui@>=1.8.0, jquery-ui@^1.12.1: resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.12.1.tgz#bcb4045c8dd0539c134bc1488cdd3e768a7a9e51" integrity sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE= -jquery@>=1.2.6, "jquery@>=1.7.1 <4.0.0", jquery@>=1.8.0, jquery@^3.0, jquery@^3.3.1, jquery@^3.5.0, jquery@^3.5.1: +jquery@>=1.2.6, "jquery@>=1.7.1 <4.0.0", jquery@>=1.8.0, jquery@^3.3.1, jquery@^3.5.0, jquery@^3.5.1: version "3.5.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.5.1.tgz#d7b4d08e1bfdb86ad2f1a3d039ea17304717abb5" integrity sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg== -js-levenshtein@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.6.tgz#c6cee58eb3550372df8deb85fad5ce66ce01d59d" - integrity sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g== - js-string-escape@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" @@ -5686,9 +5918,9 @@ js-tokens@^3.0.2: integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= js-yaml@^3.12.0, js-yaml@^3.13.1: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== dependencies: argparse "^1.0.7" esprima "^4.0.0" @@ -5730,6 +5962,11 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" @@ -5759,7 +5996,7 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.2: +json5@^2.1.2: version "2.1.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== @@ -5783,13 +6020,13 @@ jsonparse@^1.2.0: resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= -jsx-ast-utils@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-2.4.1.tgz#1114a4c1209481db06c690c2b4f488cc665f657e" - integrity sha512-z1xSldJ6imESSzOjd3NNkieVJKRlKYSOtMG8SFyCj2FIrvSaSuli/WjpBkEzCBoR9bYYYFgqJw61Xhu7Lcgk+w== +"jsx-ast-utils@^2.4.1 || ^3.0.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" + integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q== dependencies: - array-includes "^3.1.1" - object.assign "^4.1.0" + array-includes "^3.1.2" + object.assign "^4.1.2" karma-babel-preprocessor@^8.0.0: version "8.0.1" @@ -5963,6 +6200,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -6093,7 +6335,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash@^4.14.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5: +lodash@4.*, lodash@^4.14.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5: version "4.17.20" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== @@ -6192,7 +6434,7 @@ make-dir@^2.0.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.0, make-dir@^3.0.2: +make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -6217,9 +6459,14 @@ map-visit@^1.0.0: object-visit "^1.0.0" marked@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.0.tgz#7221ce2395fa6cf6d722e6f2871a32d3513c85ca" - integrity sha512-tiRxakgbNPBr301ihe/785NntvYyhxlqcL3YaC8CaxJQh7kiaEtrN9B/eK2I2943Yjkh5gw25chYFDQhOMCwMA== + version "1.2.7" + resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.7.tgz#6e14b595581d2319cdcf033a24caaf41455a01fb" + integrity sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA== + +matches-selector@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/matches-selector/-/matches-selector-0.0.1.tgz#1df5262243ae341c1a0804dd302048267ac713bb" + integrity sha1-HfUmIkOuNBwaCATdMCBIJnrHE7s= md5.js@^1.3.4: version "1.3.5" @@ -6230,16 +6477,16 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== -mdn-data@2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.6.tgz#852dc60fcaa5daa2e8cf6c9189c440ed3e042978" - integrity sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA== - media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -6347,9 +6594,9 @@ mime@1.6.0: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.0.3, mime@^2.3.1, mime@^2.4.4: - version "2.4.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" - integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== + version "2.4.7" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.7.tgz#962aed9be0ed19c91fd7dc2ece5d7f4e89a90d74" + integrity sha512-dhNd1uA2u397uQk3Nv5LM4lm93WYDUXFn3Fu291FJerns4jyTudqhIWe4W04YLy7Uk1tm1Ore04NpjRvQp/NPA== mimic-fn@^1.0.0: version "1.2.0" @@ -6449,6 +6696,11 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" +mkdirp-classic@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -6456,7 +6708,37 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: dependencies: minimist "^1.2.5" -module-deps@^6.0.0: +ml-array-max@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ml-array-max/-/ml-array-max-1.2.0.tgz#141595131fe10208dd89897ce98ab7fd382a3951" + integrity sha512-3UH7XCdjINxbtBWj1EuHMeI242Q3uLuC4rTpSybBWUpGjnG/BefAFxmTolUCuXDM59mJ/G/re80CQbaVIuMjQA== + dependencies: + is-any-array "^0.1.0" + +ml-array-min@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ml-array-min/-/ml-array-min-1.2.0.tgz#6880ea319250a99ec73bc2799ac005c10a0f0489" + integrity sha512-Wgf2+lCndLy1SbeOZSUqlkxD9T1CXPT7CIlNGAZRRQI35wsqvfuNtLNH4qKFx8kNjlq3VGXKOSBHeiXR31vaTA== + dependencies: + is-any-array "^0.1.0" + +ml-array-rescale@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ml-array-rescale/-/ml-array-rescale-1.3.2.tgz#ebdeaaa84d15f714dbb00e94a6a9336ddcf10413" + integrity sha512-kiXwdVCGrer7rLnjR6Q9ZgP6e9rbnmQvYVUMLXyqNg4+zOs+jek8yBupqPZPDr+NvlSE5OuMnfAbP1oA63kHBA== + dependencies: + is-any-array "^0.1.0" + ml-array-max "^1.2.0" + ml-array-min "^1.2.0" + +ml-matrix@^6.5.0: + version "6.5.3" + resolved "https://registry.yarnpkg.com/ml-matrix/-/ml-matrix-6.5.3.tgz#0c4bb26714607cac76d289b943171c7083418eed" + integrity sha512-wXrn+ccApJ6gHktxmosOzs6B6M0huadahDpcgPYIAJggpqN7CtV4Vd7zpW6Lel/1oM5yCULcrbRJ1A5gF/GYDA== + dependencies: + ml-array-rescale "^1.3.2" + +module-deps@^6.0.0, module-deps@^6.2.3: version "6.2.3" resolved "https://registry.yarnpkg.com/module-deps/-/module-deps-6.2.3.tgz#15490bc02af4b56cf62299c7c17cba32d71a96ee" integrity sha512-fg7OZaQBcL4/L+AK5f4iVqf9OMbCclXfy/znXRxTVhJSeW5AIlS9AwheYwDaXM3lVW7OBeaeUEY3gbaC6cLlSA== @@ -6477,25 +6759,23 @@ module-deps@^6.0.0: through2 "^2.0.0" xtend "^4.0.0" -moment-timezone@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.4.1.tgz#81f598c3ad5e22cdad796b67ecd8d88d0f5baa06" - integrity sha1-gfWYw61eIs2teWtn7NjYjQ9bqgY= - dependencies: - moment ">= 2.6.0" - -moment-timezone@^0.5.11, moment-timezone@^0.5.23: - version "0.5.31" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05" - integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA== +moment-timezone@^0.5.23, moment-timezone@^0.5.28, moment-timezone@^0.5.31: + version "0.5.32" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.32.tgz#db7677cc3cc680fd30303ebd90b0da1ca0dfecc2" + integrity sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA== dependencies: moment ">= 2.9.0" -"moment@>= 2.6.0", "moment@>= 2.9.0", moment@^2.10.2, moment@^2.22.2, moment@^2.24.0: +"moment@>= 2.9.0", moment@^2.10.2, moment@^2.24.0, moment@^2.29.0: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== +moment@~2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + moo@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" @@ -6537,20 +6817,25 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@2.1.2, ms@^2.1.1: +ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + mute-stream@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= nan@^2.12.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" - integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== + version "2.14.2" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" + integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ== nanomatch@^1.2.9: version "1.2.13" @@ -6580,15 +6865,14 @@ natural-compare@^1.4.0: integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= nearley@^2.7.10: - version "2.19.7" - resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.19.7.tgz#eafbe3e2d8ccfe70adaa5c026ab1f9709c116218" - integrity sha512-Y+KNwhBPcSJKeyQCFjn8B/MIe+DDlhaaDgjVldhy5xtFewIbiQgcbZV8k2gCVwkI1ZsKCnjIYZbR+0Fim5QYgg== + version "2.20.1" + resolved "https://registry.yarnpkg.com/nearley/-/nearley-2.20.1.tgz#246cd33eff0d012faf197ff6774d7ac78acdd474" + integrity sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ== dependencies: commander "^2.19.0" moo "^0.5.0" railroad-diagrams "^1.0.0" randexp "0.4.6" - semver "^5.4.1" neatequal@^1.0.0: version "1.0.0" @@ -6641,10 +6925,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.61: - version "1.1.61" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" - integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== +node-releases@^1.1.67: + version "1.1.67" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.67.tgz#28ebfcccd0baa6aad8e8d4d8fe4cbc49ae239c12" + integrity sha512-V5QF9noGFl3EymEwUYzO+3NTDpGfQB4ve6Qfnzf3UNydMhjQRVPR1DZTuvWiLzaFJYw2fmDwAfnRNEVb64hSIg== normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: version "2.5.0" @@ -6702,13 +6986,20 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -nth-check@^1.0.2, nth-check@~1.0.1: +nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg== dependencies: boolbase "~1.0.0" +nth-check@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.0.tgz#1bb4f6dac70072fc313e8c9cd1417b5074c0a125" + integrity sha512-i4sc/Kj8htBrAiH1viZ0TgU8Y5XqCaV/FziYK6TBczxmeKm3AEFWqqF3195yKudrarqy7Zu80Ra5dobFjn9X/Q== + dependencies: + boolbase "^1.0.0" + null-check@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/null-check/-/null-check-1.0.0.tgz#977dffd7176012b9ec30d2a39db5cf72a0439edd" @@ -6739,17 +7030,17 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.7.0, object-inspect@^1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" - integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.9.0.tgz#c90521d74e1127b67266ded3394ad6116986533a" + integrity sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw== object-is@^1.0.2, object-is@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.3.tgz#2e3b9e65560137455ee3bd62aec4d90a2ea1cc81" - integrity sha512-teyqLvFWzLkq5B9ki8FVWA902UER2qkxmdA4nLf+wjOLAWgxzCWZNCxpDq9MvE8MmhWNr+I8w3BN49Vx36Y6Xg== + version "1.1.4" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.4.tgz#63d6c83c00a43f4cbc9434eb9757c8a5b8565068" + integrity sha512-1ZvAZ4wlF7IyPVOcE1Omikt7UpaFlOQq0HlSti+ZvDH3UiD2brwGMwDbyV43jao2bKJ+4+WdPJHSd7kgzKYVqg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.1" object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -6763,42 +7054,44 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0, object.assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.1.tgz#303867a666cdd41936ecdedfb1f8f3e32a478cdd" - integrity sha512-VT/cxmx5yaoHSOTSyrCygIDFco+RsibY2NM0a4RdEeY/4KgqezwFtK1yr3U67xYhqJSlASm2pKhLVzPj2lr4bA== +object.assign@^4.1.0, object.assign@^4.1.1, object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" has-symbols "^1.0.1" object-keys "^1.1.1" object.entries@^1.1.1, object.entries@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" - integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA== + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.3.tgz#c601c7f168b62374541a07ddbd3e2d5e4f7711a6" + integrity sha512-ym7h7OZebNS96hn5IJeyUmaWhaSM4SVtAPPfNLQEI2MYWCO2egsITb9nab2+i/Pwibx+R0mtn+ltKJXRSeTMGg== dependencies: + 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" -object.fromentries@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.2.tgz#4a09c9b9bb3843dd0f89acdb517a794d4f355ac9" - integrity sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ== +object.fromentries@^2.0.2, object.fromentries@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.3.tgz#13cefcffa702dc67750314a3305e8cb3fad1d072" + integrity sha512-IDUSMXs6LOSJBWE++L0lzIbSqHl9KDCfff2x/JSEIDtEUavUnyMYC2ZGay/04Zq4UT8lvd4xNhU4/YHKibAOlw== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.18.0-next.1" has "^1.0.3" object.getownpropertydescriptors@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz#369bf1f9592d8ab89d712dced5cb81c7c5352649" - integrity sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg== + version "2.1.1" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz#0dfda8d108074d9c563e80490c883b6661091544" + integrity sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" + es-abstract "^1.18.0-next.1" object.pick@^1.3.0: version "1.3.0" @@ -6808,13 +7101,13 @@ object.pick@^1.3.0: isobject "^3.0.1" object.values@^1.1.0, object.values@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== + version "1.1.2" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.2.tgz#7a2015e06fcb0f546bd652486ce8583a4731c731" + integrity sha512-MYC0jvJopr8EK6dPBiO8Nb9mvjdypOachO5REGk6MXzujbBrAisKo3HmdEI6kZDL6fC31Mwee/5YbtMebixeag== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" + es-abstract "^1.18.0-next.1" has "^1.0.3" on-finished@~2.3.0: @@ -7061,17 +7354,32 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.1.0.tgz#f96088cdf24a8faa9aea9a009f2d9d942c999646" + integrity sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ== + dependencies: + "@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" + parse-passwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse5@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" - integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA== +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== dependencies: - "@types/node" "*" + parse5 "^6.0.1" + +parse5@^6.0.0, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== parseqs@0.0.5: version "0.0.5" @@ -7170,6 +7478,23 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +pathfinding@^0.4.18: + version "0.4.18" + resolved "https://registry.yarnpkg.com/pathfinding/-/pathfinding-0.4.18.tgz#a9990f6fa22b7ef196e5651b049165403a045fe8" + integrity sha1-qZkPb6IrfvGW5WUbBJFlQDoEX+g= + dependencies: + heap "0.2.5" + +paths-js@^0.4.9: + version "0.4.11" + resolved "https://registry.yarnpkg.com/paths-js/-/paths-js-0.4.11.tgz#b2a9d5f94ee9949aa8fee945f78a12abff44599e" + integrity sha512-3mqcLomDBXOo7Fo+UlaenG6f71bk1ZezPQy2JCmYHy2W2k5VKpP+Jbin9H0bjXynelTbglCqdFhSEkeIkKTYUA== + pbkdf2@^3.0.3: version "3.1.1" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.1.tgz#cb8724b0fada984596856d1a6ebafd3584654b94" @@ -7247,7 +7572,7 @@ pngquant-bin@^5.0.0: execa "^0.10.0" logalot "^2.0.0" -popper.js@^1.14.3, popper.js@^1.14.7: +popper.js@^1.14.7, popper.js@^1.16.1: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== @@ -7621,11 +7946,6 @@ prepend-http@^2.0.0: resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= -private@^0.1.6: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -7823,18 +8143,18 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" -raw-loader@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-1.0.0.tgz#3f9889e73dadbda9a424bce79809b4133ad46405" - integrity sha512-Uqy5AqELpytJTRxYT4fhltcKPj0TyaEpzJDcGz7DFJi+pQOOi3GjR/DOdxTkTsF+NzhnldIoG6TORaBlInUuqA== +raw-loader@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-3.1.0.tgz#5e9d399a5a222cc0de18f42c3bc5e49677532b3f" + integrity sha512-lzUVMuJ06HF4rYveaz9Tv0WRlUMxJ0Y1hgSkkgg+50iEdaI0TthyEDe08KIHb0XsF6rn8WYTqPCaGTZg3sX+qA== dependencies: loader-utils "^1.1.0" - schema-utils "^1.0.0" + schema-utils "^2.0.1" react-dom@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f" - integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag== + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" + integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -7847,19 +8167,26 @@ react-is@^16.13.1, react-is@^16.8.1, react-is@^16.8.6: integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== react-test-renderer@^16.0.0-0: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.13.1.tgz#de25ea358d9012606de51e012d9742e7f0deabc1" - integrity sha512-Sn2VRyOK2YJJldOqoh8Tn/lWQ+ZiKhyZTPtaO0Q6yNj+QDbmRkVFap6pZPy3YQk8DScRDfyqm/KxKYP9gCMRiQ== + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.14.0.tgz#e98360087348e260c56d4fe2315e970480c228ae" + integrity sha512-L8yPjqPE5CZO6rKsKXRO/rVPiaCOy0tQQJbC+UjPNlobl5mad59lvPjwFsQHTvL03caVDIVr9x9/OSgDe6I5Eg== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" react-is "^16.8.6" scheduler "^0.19.1" +react-to-print@^2.10.3: + version "2.12.1" + resolved "https://registry.yarnpkg.com/react-to-print/-/react-to-print-2.12.1.tgz#120f3116fef55a141f553548388624b976596835" + integrity sha512-+zGNUYQKaae7Wp0JL2JcoWM0lDd5csasRmTqRZlJLOj6F4sRmJsT7ZPgH0SL6ZQ7gWz0hwglhLlLoyF85lGgHw== + dependencies: + prop-types "^15.7.2" + react@^16.13.1: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e" - integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w== + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -7912,7 +8239,7 @@ readable-stream@^1.0.33: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^3.1.1, readable-stream@^3.6.0: +readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -7930,10 +8257,10 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== +readdirp@~3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e" + integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ== dependencies: picomatch "^2.2.1" @@ -7957,10 +8284,10 @@ regenerate-unicode-properties@^8.2.0: dependencies: regenerate "^1.4.0" -regenerate@^1.2.1, regenerate@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" - integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== +regenerate@^1.4.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== regenerator-runtime@^0.11.0: version "0.11.1" @@ -7972,15 +8299,6 @@ regenerator-runtime@^0.13.4: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew== -regenerator-transform@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" - integrity sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q== - dependencies: - babel-runtime "^6.18.0" - babel-types "^6.19.0" - private "^0.1.6" - regenerator-transform@^0.14.2: version "0.14.5" resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" @@ -8009,16 +8327,7 @@ regexpp@^2.0.1: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== -regexpu-core@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" - integrity sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA= - dependencies: - regenerate "^1.2.1" - regjsgen "^0.2.0" - regjsparser "^0.1.4" - -regexpu-core@^4.7.0: +regexpu-core@^4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== @@ -8030,23 +8339,11 @@ regexpu-core@^4.7.0: unicode-match-property-ecmascript "^1.0.4" unicode-match-property-value-ecmascript "^1.2.0" -regjsgen@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" - integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= - regjsgen@^0.5.1: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== -regjsparser@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" - integrity sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw= - dependencies: - jsesc "~0.5.0" - regjsparser@^0.6.4: version "0.6.4" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" @@ -8101,6 +8398,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +resize-observer-polyfill@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464" + integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -8136,11 +8438,12 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.4, resolve@^1.10.0, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.4.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== +resolve@^1.1.4, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.4.0: + version "1.19.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" + integrity sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg== dependencies: + is-core-module "^2.1.0" path-parse "^1.0.6" responselike@1.0.2: @@ -8178,6 +8481,11 @@ rgba-regex@^1.0.0: resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3" integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM= +rgbcolor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/rgbcolor/-/rgbcolor-1.0.1.tgz#d6505ecdb304a6595da26fa4b43307306775945d" + integrity sha1-1lBezbMEplldom+ktDMHMGd1lF0= + rimraf@2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" @@ -8200,6 +8508,15 @@ ripemd160@^2.0.0, ripemd160@^2.0.1: hash-base "^3.0.0" inherits "^2.0.1" +rollup@^1.31.1: + version "1.32.1" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.32.1.tgz#4480e52d9d9e2ae4b46ba0d9ddeaf3163940f9c4" + integrity sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A== + dependencies: + "@types/estree" "*" + "@types/node" "*" + acorn "^7.1.0" + rst-selector-parser@^2.2.3: version "2.2.3" resolved "https://registry.yarnpkg.com/rst-selector-parser/-/rst-selector-parser-2.2.3.tgz#81b230ea2fcc6066c89e3472de794285d9b03d91" @@ -8271,9 +8588,9 @@ sass-resources-loader@^2.0.0: loader-utils "^2.0.0" sass@^1.24.4: - version "1.27.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.27.0.tgz#0657ff674206b95ec20dc638a93e179c78f6ada2" - integrity sha512-0gcrER56OkzotK/GGwgg4fPrKuiFlPNitO7eUJ18Bs+/NBlofJfMxmxqpqJxjae9vu0Wq8TZzrSyxZal00WDig== + version "1.30.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.30.0.tgz#60bbbbaf76ba10117e61c6c24f00161c3d60610e" + integrity sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw== dependencies: chokidar ">=2.0.0 <4.0.0" @@ -8306,7 +8623,7 @@ schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^2.6.6: +schema-utils@^2.0.1, schema-utils@^2.6.5, schema-utils@^2.6.6: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== @@ -8472,7 +8789,7 @@ shim-loader@^1.0.1: precond "^0.2.3" webpack-sources "^0.2.3" -side-channel@^1.0.2: +side-channel@^1.0.2, side-channel@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.3.tgz#cdc46b057550bbab63706210838df5d4c19519c3" integrity sha512-A6+ByhlLkksFoUepsGxfj5x1gTSrs+OydsRptUxeNCabQpCFUvcwIczgOigI8vhY/OJCnPnyE9rGiwgvr9cS1g== @@ -8698,9 +9015,9 @@ spdx-expression-parse@^3.0.0: spdx-license-ids "^3.0.0" spdx-license-ids@^3.0.0: - version "3.0.6" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.6.tgz#c80757383c28abf7296744998cbc106ae8b854ce" - integrity sha512-+orQK83kyMva3WyPf59k1+Y525csj5JejicWut55zeTWANuN17qSiSLUXWtzHeNWORSvT7GLDJ/E/XiIWoXBTw== + version "3.0.7" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" + integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" @@ -8753,6 +9070,11 @@ stable@^0.1.8: resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +stackblur-canvas@^2.0.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/stackblur-canvas/-/stackblur-canvas-2.4.0.tgz#2b2eba910cb46f6feae918e1c402f863d602c01b" + integrity sha512-Z+HixfgYV0ss3C342DxPwc+UvN1SYWqoz7Wsi3xEDWEnaBkSCL3Ey21gF4io+WlLm8/RIrSnCrDBIEcH4O+q5Q== + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" @@ -8801,6 +9123,16 @@ stream-http@^2.0.0, stream-http@^2.7.2: to-arraybuffer "^1.0.0" xtend "^4.0.0" +stream-http@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564" + integrity sha512-S7OqaYu0EkFpgeGFb/NPOoPLxFko7TPqtEeFg5DXPB4v/KETHG0Ln6fRFrNezoelpaDKmycEmmZ81cC9DAwgYg== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.4" + readable-stream "^3.6.0" + xtend "^4.0.2" + stream-shift@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" @@ -8858,40 +9190,42 @@ string.prototype.codepointat@^0.2.0: integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg== string.prototype.matchall@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.2.tgz#48bb510326fb9fdeb6a33ceaa81a6ea04ef7648e" - integrity sha512-N/jp6O5fMf9os0JU3E72Qhf590RSRZU/ungsL/qJUYVTNv7hTG0P/dbPjxINVN9jpscu3nzYwKESU3P3RY5tOg== + version "4.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.3.tgz#24243399bc31b0a49d19e2b74171a15653ec996a" + integrity sha512-OBxYDA2ifZQ2e13cP82dWFMaCV9CGF8GzmN4fljBVw5O5wep0lu4gacm1OL6MjROoUnB8VbkWRThqkV2YFLNxw== dependencies: + 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" string.prototype.trim@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.2.tgz#f538d0bacd98fc4297f0bef645226d5aaebf59f3" - integrity sha512-b5yrbl3BXIjHau9Prk7U0RRYcUYdN4wGSVaqoBQS50CCE3KBuYU0TYRNPFCP7aVoNMX87HKThdMRVIP3giclKg== + version "1.2.3" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.3.tgz#d23a22fde01c1e6571a7fadcb9be11decd8061a7" + integrity sha512-16IL9pIBA5asNOSukPfxX2W68BaBvxyiRK16H3RA/lWW9BDosh+w7f+LhomPHpXJ82QEe7w7/rY/S1CV97raLg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.18.0-next.0" + es-abstract "^1.18.0-next.1" string.prototype.trimend@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" - integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz#a22bd53cca5c7cf44d7c9d5c732118873d6cd18b" + integrity sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.5" string.prototype.trimstart@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" - integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz#9b4cb590e123bb36564401d59824298de50fd5aa" + integrity sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg== dependencies: + call-bind "^1.0.0" define-properties "^1.1.3" - es-abstract "^1.17.5" string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" @@ -9021,7 +9355,7 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -svg-pathdata@^5.0.0: +svg-pathdata@^5.0.0, svg-pathdata@^5.0.5: version "5.0.5" resolved "https://registry.yarnpkg.com/svg-pathdata/-/svg-pathdata-5.0.5.tgz#65e8d765642ba15fe15434444087d082bc526b29" integrity sha512-TAAvLNSE3fEhyl/Da19JWfMAdhSXTYeviXsLSoDT1UM76ADj5ndwAPX1FKQEgB/gFMPavOy6tOqfalXKUiXrow== @@ -9134,24 +9468,24 @@ tempfile@^2.0.0: uuid "^3.0.1" tempusdominus-bootstrap-4@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/tempusdominus-bootstrap-4/-/tempusdominus-bootstrap-4-5.1.2.tgz#3c9906ca6e5d563faa0b81b2fdc6aa79cad9c0be" - integrity sha512-ksD8qc4wOJeE19wvryXmEpRzMUSZu4wSOdG6zKSn8l4ccad16249KOX1j0CccyZpuuES/n4FLqLAUB+Dd1LTBA== + version "5.39.0" + resolved "https://registry.yarnpkg.com/tempusdominus-bootstrap-4/-/tempusdominus-bootstrap-4-5.39.0.tgz#f13dcfec6c41b37c5fe509f08bd513590c64411f" + integrity sha512-vYnkmQYQq4+A51WyRc/6e03eM0BHDoPaxd556K1pd4Nhr0eGeB3+Mi9b+3CDx4189fg3gQlrsKzgJiHPRwSX3Q== dependencies: - bootstrap ">=4.1.2" - jquery "^3.0" - moment "^2.22.2" - moment-timezone "^0.5.11" - popper.js "^1.14.3" + bootstrap "^4.5.2" + jquery "^3.5.1" + moment "^2.29.0" + moment-timezone "^0.5.31" + popper.js "^1.16.1" tempusdominus-core@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/tempusdominus-core/-/tempusdominus-core-5.0.3.tgz#808642e47a83f45d7ef18c1597fd7b1d413d69e5" - integrity sha512-52lClmU33gb6J6I/S9uGDrgQwccq3Yw9SlZerTgGLOzOB3Sc9pgIVBirfPMsMcx8nPsg6mA5ItFAH/5BZiQThg== + version "5.19.0" + resolved "https://registry.yarnpkg.com/tempusdominus-core/-/tempusdominus-core-5.19.0.tgz#ccbd2c35109b0a4b96c61513e53e0175ec4896bd" + integrity sha512-7a4oBQw4cjz6C87BLRg3KHVvzpnPlnRTkuDZ7SwcJayQQ4QgOryX5u6wj0q07TXhgtMQLCntZO6nVhHIKPaeUw== dependencies: - jquery "^3.0" - moment "^2.22.2" - moment-timezone "^0.4.0" + jquery "^3.5.0" + moment "~2.24.0" + moment-timezone "^0.5.28" terser-webpack-plugin@^1.4.3: version "1.4.5" @@ -9223,9 +9557,9 @@ timers-browserify@^1.0.1: process "~0.11.0" timers-browserify@^2.0.4: - version "2.0.11" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.11.tgz#800b1f3eee272e5bc53ee465a04d0e804c31211f" - integrity sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ== + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== dependencies: setimmediate "^1.0.4" @@ -9234,6 +9568,13 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tippy.js@^6.2.0: + version "6.2.7" + resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.2.7.tgz#62fb34eda23f7d78151ddca922b62818c1ab9869" + integrity sha512-k+kWF9AJz5xLQHBi3K/XlmJiyu+p9gsCyc5qZhxxGaJWIW8SMjw1R+C7saUnP33IM8gUhDA2xX//ejRSwqR0tA== + dependencies: + "@popperjs/core" "^2.4.4" + tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -9331,9 +9672,9 @@ tryer@^1.0.1: integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== tslib@^1.9.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.0.tgz#d624983f3e2c5e0b55307c3dd6c86acd737622c6" - integrity sha512-+Zw5lu0D9tvBMjGP8LpvMb0u2WW2QV3y+D8mO6J+cNzCYIN4sVy43Bf9vl92nqFahutN0I8zHa7cc4vihIshnw== + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== ttf2woff@2.0.1: version "2.0.1" @@ -9411,9 +9752,9 @@ undeclared-identifiers@^1.1.2: xtend "^4.0.1" underscore@>=1.7.0, underscore@>=1.8.3, underscore@^1.8.0, underscore@^1.8.3, underscore@^1.9.1: - version "1.11.0" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.11.0.tgz#dd7c23a195db34267186044649870ff1bab5929e" - integrity sha512-xY96SsN3NA461qIRKZ/+qox37YXPtSBswMGfiNptr+wrt6ds4HaMw23TP612fEyGekRE6LNRiLYr/aqbHXNedw== + version "1.12.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.12.0.tgz#4814940551fc80587cef7840d1ebb0f16453be97" + integrity sha512-21rQzss/XPMjolTiIezSu3JAjgagXKROtNrYFEOWK109qY1Uv2tVjPTZ1ci2HgvQDA16gHYSthQIJfB+XId/rQ== unicode-canonical-property-names-ecmascript@^1.0.4: version "1.0.4" @@ -9608,9 +9949,9 @@ uuid@^3.0.1, uuid@^3.3.2: integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== v8-compile-cache@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" - integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== + version "2.2.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz#9471efa3ef9128d2f7c6a7ca39c4dd6b5055b132" + integrity sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q== validate-npm-package-license@^3.0.1: version "3.0.4" @@ -9660,23 +10001,23 @@ watchify@~3.11.1: through2 "^2.0.0" xtend "^4.0.0" -watchpack-chokidar2@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz#9948a1866cbbd6cb824dea13a7ed691f6c8ddff0" - integrity sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA== +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== dependencies: chokidar "^2.1.8" watchpack@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.4.tgz#6e9da53b3c80bb2d6508188f5b200410866cd30b" - integrity sha512-aWAgTW4MoSJzZPAicljkO1hsi1oKj/RRq/OJQh2PKI2UKL04c2Bs+MBOB+BBABHTXJpf9mCwHN7ANCvYsvY2sg== + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== dependencies: graceful-fs "^4.1.2" neo-async "^2.5.0" optionalDependencies: chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.0" + watchpack-chokidar2 "^2.0.1" "webcabin-docker@git+https://github.com/EnterpriseDB/wcDocker/#c4a3398b89588408dc705895675bce7bd7660d36": version "2.2.4-dev" @@ -9706,7 +10047,7 @@ webpack-bundle-analyzer@^3.5.1: opener "^1.5.1" ws "^6.0.0" -webpack-cli@^3.2.3: +webpack-cli@^3.3.11: version "3.3.12" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a" integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag== @@ -9724,9 +10065,9 @@ webpack-cli@^3.2.3: yargs "^13.3.2" webpack-dev-middleware@^3.7.0: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== dependencies: memory-fs "^0.4.1" mime "^2.4.4" @@ -9743,9 +10084,9 @@ webpack-log@^2.0.0: uuid "^3.3.2" webpack-require-from@^1.8.0: - version "1.8.1" - resolved "https://registry.yarnpkg.com/webpack-require-from/-/webpack-require-from-1.8.1.tgz#18fd6fc18f0920a097a6f43855ac335f486bfb06" - integrity sha512-jKpr/6CH6sW3QH4E5cf/UNK4Dpsk4E1x6IpiIjeZQ9rOhr5jqpGCyFW6e/LEFpJ3U9AzRtaUHgahR7QFQnttLQ== + version "1.8.2" + resolved "https://registry.yarnpkg.com/webpack-require-from/-/webpack-require-from-1.8.2.tgz#d0c6838553315bb8802f879ab43c29309f5c80fb" + integrity sha512-N9kDFNGNEnmuM/riUm/yNXhefAUCUG50sVV509n0WtCdKlIjMYebVwGsEujDKRRiy539J84oOZlrZim9FJXNPA== webpack-sources@^0.2.3: version "0.2.3" @@ -9881,9 +10222,9 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + version "4.0.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4" + integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ== yallist@^2.1.2: version "2.1.2" @@ -9900,6 +10241,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yaml@^1.7.2: + version "1.10.0" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" + integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"