From 5a332f6abf2d9da83942d570a0f733a9698d55e5 Mon Sep 17 00:00:00 2001 From: tristanliu <37809633+sevenliu1896@users.noreply.github.com> Date: Fri, 24 May 2024 17:08:10 +0800 Subject: [PATCH] [improvement][headless-fe] Migrating scaffold version to @umi/max (#1030) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [improvement][semantic-fe] Add model alias setting & Add view permission restrictions to the model permission management tab. [improvement][semantic-fe] Add permission control to the action buttons for the main domain; apply high sensitivity filtering to the authorization of metrics/dimensions. [improvement][semantic-fe] Optimize the editing mode in the dimension/metric/datasource components to use the modelId stored in the database for data, instead of relying on the data from the state manager. * [improvement][semantic-fe] Add time granularity setting in the data source configuration. * [improvement][semantic-fe] Dictionary import for dimension values supported in Q&A visibility * [improvement][semantic-fe] Modification of data source creation prompt wording" * [improvement][semantic-fe] metric market experience optimization * [improvement][semantic-fe] enhance the analysis of metric trends * [improvement][semantic-fe] optimize the presentation of metric trend permissions * [improvement][semantic-fe] add metric trend download functionality * [improvement][semantic-fe] fix the dimension initialization issue in metric correlation * [improvement][semantic-fe] Fix the issue of database changes not taking effect when creating based on an SQL data source. * [improvement][semantic-fe] Optimizing pagination logic and some CSS styles * [improvement][semantic-fe] Fixing the API for the indicator list by changing "current" to "pageNum" * [improvement][semantic-fe] Fixing the default value setting for the indicator list * [improvement][semantic-fe] Adding batch operations for indicators/dimensions/models * [improvement][semantic-fe] Replacing the single status update API for indicators/dimensions with a batch update API * [improvement][semantic-fe] Redesigning the indicator homepage to incorporate trend charts and table functionality for indicators * [improvement][semantic-fe] Optimizing the logic for setting dimension values and editing data sources, and adding system settings functionality * [improvement][semantic-fe] Upgrading antd version to 5.x, extracting the batch operation button component, optimizing the interaction for system settings, and expanding the configuration generation types for list-to-select component. * [improvement][semantic-fe] Adding the ability to filter dimensions based on whether they are tags or not. * [improvement][semantic-fe] Adding the ability to edit relationships between models in the canvas. * [improvement][semantic-fe] Updating the datePicker component to use dayjs instead. * [improvement][semantic-fe] Fixing the issue with passing the model ID for dimensions in the indicator market. * [improvement][semantic-fe] Fixing the abnormal state of the popup when creating a model. * [improvement][semantic-fe] Adding permission logic for bulk operations in the indicator market. * [improvement][semantic-fe] Adding the ability to download and transpose data. * [improvement][semantic-fe] Fixing the initialization issue with the date selection component in the indicator details page when switching time granularity. * [improvement][semantic-fe] Fixing the logic error in the dimension value setting. * [improvement][semantic-fe] Fixing the synchronization issue with the question and answer settings information. * [improvement][semantic-fe] Optimizing the canvas functionality for better performance and user experience. * [improvement][semantic-fe] Optimizing the update process for drawing model relationship edges in the canvas. * [improvement][semantic-fe] Changing the line type for canvas connections. * [improvement][semantic-fe] Replacing the initialization variable from "semantic" to "headless". * [improvement][semantic-fe] Fixing the missing migration issue for default drill-down dimension configuration in model editing. Additionally, optimizing the data retrieval method for initializing fields in the model. * [improvement][semantic-fe] Updating the logic for the fieldName. * [improvement][semantic-fe] Adjusting the position of the metrics tab. * [improvement][semantic-fe] Changing the 字段名称 to 英文名称. * [improvement][semantic-fe] Fix metric measurement deletion. * [improvement][semantic-fe] UI optimization for metric details page. * [improvement][semantic-fe] UI optimization for metric details page. * [improvement][semantic-fe] UI adjustment for metric details page. * [improvement][semantic-fe] The granularity field in the time type of model editing now supports setting it as empty. * [improvement][semantic-fe] Added field type and metric type to the metric creation options. * [improvement][semantic-fe] The organization structure selection feature has been added to the permission management. * [improvement][semantic-fe] Improved user experience for the metric list. * [improvement][semantic-fe] fix update the metric list. * [improvement][headless-fe] Added view management functionality. * [improvement][headless-fe] The view management functionality has been added. This feature allows users to create, edit, and manage different views within the system. * [improvement][headless-fe] Added model editing side effect detection. * [improvement][headless-fe] Fixed the logic error in view editing. * [improvement][headless-fe] Fixed the issue with initializing dimension associations in metric settings. * [improvement][headless-fe] Added the ability to hide the Q&A settings entry point. * [improvement][headless-fe] Fixed the issue with selecting search results in metric field creation. * [improvement][headless-fe] Added search functionality to the field list in model editing. * [improvement][headless-fe] fix the field list in model editing * [improvement][headless-fe] Restructured the data for the dimension value settings interface. * [improvement][headless-fe] Added dynamic variable functionality to model creation based on SQL scripts. * [improvement][headless-fe] Added support for passing dynamic variables as parameters in the executeSql function. * [improvement][headless-fe] Resolved the issue where users were unable to select all options for dimensions, metrics, and fields in the metric generation process. * [improvement][headless-fe] Replaced the term "view" with "dataset" * [improvement][headless-fe] Added the ability to export metrics and dimensions to a specific target. * [improvement][headless-fe] Enhanced dataset creation to support the tag mode. * [improvement][headless-fe] Added tag value setting. * [improvement][headless-fe] Optimized the tag setting system. * [improvement][headless-fe] Optimized the tag setting system. * [improvement][headless-fe] Updated the data initialization for model editing to use API requests instead. * [improvement][headless-fe] Added search functionality to model management. * [improvement][headless-fe] Removed field null validation during model editing. * [improvement][headless-fe] Updated the batch operation button component. * [improvement][headless-fe] Optimized the logic for initializing indicators in dimension value settings. * [improvement][headless-fe] Adjusted the length of the input field for model editing names. * [improvement][headless-fe] Lock the version of the @ant-design/pro-table component and replace it with @ant-design/pro-components. * [improvement][headless-fe] Optimized the style of the metrics market and tags market. * [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling. * [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling * [improvement][headless-fe] The quick creation of model fields now defaults to using the "comment" field for filling. * [improvement][headless-fe] Fixed the issue where the conditions for metric measurement creation were not being saved correctly. * [improvement][headless-fe] Default value setting for hiding dimensions. * [improvement][headless-fe] Updated the file imports in the project. * [improvement][headless-fe] Adjusted the logic for displaying the tab in the theme domain. * [improvement][headless-fe] Added term management functionality. * [improvement][headless-fe] When creating a model, the current metric operator now allows for clearance. * [improvement][headless-fe] Term management interface transformation * [improvement][headless-fe] Migrating scaffold version to @umi/max --- .../packages/supersonic-fe/config/config.ts | 208 +- .../packages/supersonic-fe/config/routes.ts | 37 +- .../supersonic-fe/config/themeSettings.ts | 5 + webapp/packages/supersonic-fe/package.json | 57 +- .../supersonic-fe/public/scripts/loading.js | 196 + webapp/packages/supersonic-fe/src/access.ts | 6 +- webapp/packages/supersonic-fe/src/app.tsx | 95 +- .../src/assets/fonts/DINPro.woff2 | Bin 0 -> 28384 bytes .../src/assets/fonts/TencentSans-W7.woff | Bin 0 -> 5528180 bytes .../supersonic-fe/src/assets/icon/vector.svg | 3 + .../src/assets/style/color/bezierEasing.less | 110 - .../src/assets/style/color/colorPalette.less | 85 - .../src/assets/style/color/colors.less | 162 - .../src/assets/style/color/tinyColor.less | 1184 - .../src/assets/style/compact.less | 4 - .../src/assets/style/core/base.less | 10 - .../src/assets/style/core/global.less | 491 - .../src/assets/style/core/iconfont.less | 22 - .../src/assets/style/core/index.less | 5 - .../src/assets/style/core/motion.less | 22 - .../src/assets/style/core/motion/fade.less | 34 - .../src/assets/style/core/motion/move.less | 129 - .../src/assets/style/core/motion/other.less | 51 - .../src/assets/style/core/motion/slide.less | 131 - .../src/assets/style/core/motion/zoom.less | 179 - .../supersonic-fe/src/assets/style/css.js | 1 - .../supersonic-fe/src/assets/style/dark.less | 4 - .../src/assets/style/default.css | 1248 - .../src/assets/style/default.less | 4 - .../src/assets/style/index-pure.less | 2 - .../supersonic-fe/src/assets/style/index.css | 1248 - .../supersonic-fe/src/assets/style/index.d.ts | 1 - .../supersonic-fe/src/assets/style/index.js | 1 - .../supersonic-fe/src/assets/style/index.less | 3 - .../src/assets/style/mixins/box.less | 7 - .../src/assets/style/mixins/clearfix.less | 16 - .../style/mixins/compact-item-vertical.less | 41 - .../src/assets/style/mixins/compact-item.less | 133 - .../assets/style/mixins/compatibility.less | 13 - .../src/assets/style/mixins/customize.less | 181 - .../src/assets/style/mixins/iconfont.less | 29 - .../src/assets/style/mixins/index.less | 16 - .../src/assets/style/mixins/modal-mask.less | 30 - .../src/assets/style/mixins/motion.less | 33 - .../assets/style/mixins/operation-unit.less | 15 - .../src/assets/style/mixins/reset.less | 11 - .../assets/style/mixins/rounded-arrow.less | 44 - .../src/assets/style/mixins/size.less | 10 - .../src/assets/style/mixins/typography.less | 58 - .../src/assets/style/themes/compact.less | 295 - .../src/assets/style/themes/dark.less | 457 - .../src/assets/style/themes/default.less | 1084 - .../src/assets/style/themes/index.less | 7 - .../src/assets/style/themes/variable.less | 1139 - .../src/assets/style/variable.less | 4 - .../BatchCtrlDropDownButton/index.tsx | 7 + .../components/FormHelper/FormItemTitle.tsx | 4 +- .../src/components/FormHelper/index.less | 6 + .../RightContent/AvatarDropdown.tsx | 2 +- .../src/components/RightContent/index.less | 18 +- .../src/components/SelectTMEPerson/index.tsx | 41 +- .../supersonic-fe/src/enum/models/base.ts | 5 - webapp/packages/supersonic-fe/src/global.less | 136 +- .../supersonic-fe/src/locales/zh-CN/menu.ts | 1 + .../supersonic-fe/src/models/allUserData.ts | 25 + .../src/pages/ChatPage/index.tsx | 6 +- .../Datasource/components/ModelCreateForm.tsx | 40 +- .../Datasource/components/SqlDetail.tsx | 20 +- .../src/pages/SemanticModel/DomainManager.tsx | 12 +- .../SemanticModel/HeadlessFlows/index.tsx | 11 +- .../pages/SemanticModel/Insights/Detail.tsx | 9 +- .../pages/SemanticModel/Insights/Market.tsx | 19 +- .../Insights/components/ClassTagTable.tsx | 21 +- .../Insights/components/TagInfoCreateForm.tsx | 23 +- .../Insights/components/TagInfoSider.tsx | 8 +- .../Insights/components/TagObjectTable.tsx | 26 +- .../components/TagValueSettingModal.tsx | 17 +- .../pages/SemanticModel/Insights/index.tsx | 9 +- .../pages/SemanticModel/Insights/style.less | 1 + .../src/pages/SemanticModel/Metric/Detail.tsx | 7 +- .../src/pages/SemanticModel/Metric/Edit.tsx | 127 + .../src/pages/SemanticModel/Metric/Market.tsx | 96 +- .../Metric/MetricInfoEditSider.tsx | 161 + .../SemanticModel/Metric/MetricInfoSider.tsx | 7 +- .../Metric/components/MetricCardList.tsx | 10 +- .../components/MetricInfoCreateForm.tsx | 944 + .../components/MetricInfoCreateSqlConfig.tsx | 540 + .../pages/SemanticModel/Metric/constants.ts | 11 + .../src/pages/SemanticModel/Metric/index.tsx | 9 +- .../src/pages/SemanticModel/Metric/style.less | 167 +- .../pages/SemanticModel/OverviewContainer.tsx | 154 +- .../XflowJsonSchemaFormDrawerForm.tsx | 15 +- .../SemanticModel/SemanticFlows/index.tsx | 20 +- .../SemanticModel/SemanticFlows/utils.tsx | 3 +- .../SemanticGraph/components/GraphLegend.tsx | 8 +- .../SemanticGraph/components/GraphToolBar.tsx | 8 +- .../components/NodeInfoDrawer.tsx | 11 +- .../SemanticModel/SemanticGraph/index.tsx | 72 +- .../SemanticModel/SemanticGraphCanvas.tsx | 10 +- .../View/components/DataSetTable.tsx | 18 +- .../src/pages/SemanticModel/View/index.tsx | 9 +- .../components/ClassDimensionTable.tsx | 58 +- .../components/ClassMetricTable.tsx | 50 +- .../components/ClassModelTypeModal.tsx | 30 +- .../DimensionMetricRelationTableTransfer.tsx | 13 +- .../components/DimensionValueSettingModal.tsx | 10 +- .../SemanticModel/components/DomainList.tsx | 34 +- .../components/DomainManagerTab.tsx | 34 +- .../DimensionMetricVisibleTableTransfer.tsx | 9 +- .../Entity/DimensionValueSettingForm.tsx | 18 +- .../Entity/RecommendedQuestionsSection.tsx | 17 +- .../components/MetricInfoCreateForm.tsx | 6 +- .../components/MetricMeasuresFormTable.tsx | 12 +- .../SemanticModel/components/ModelTable.tsx | 61 +- .../SemanticModel/components/OverView.tsx | 9 +- .../Permission/PermissionAdminForm.tsx | 22 +- .../Permission/PermissionCreateDrawer.tsx | 17 +- .../Permission/PermissionSection.tsx | 11 +- .../components/Permission/PermissionTable.tsx | 40 +- .../components/Term/TermTable.tsx | 35 +- .../pages/SemanticModel/components/style.less | 102 +- .../src/pages/SemanticModel/data.d.ts | 1 + .../src/pages/SemanticModel/model.ts | 197 - .../SemanticModel/models/databaseData.ts | 25 + .../SemanticModel/models/dimensionData.ts | 27 + .../pages/SemanticModel/models/domainData.ts | 16 + .../pages/SemanticModel/models/metricData.ts | 31 + .../pages/SemanticModel/models/modelData.ts | 44 + .../src/pages/SemanticModel/service.ts | 7 + .../supersonic-fe/src/services/request.ts | 10 +- .../supersonic-fe/src/services/user.ts | 2 +- .../packages/supersonic-fe/src/utils/curd.ts | 108 - webapp/pnpm-lock.yaml | 40035 +++++++--------- 133 files changed, 21767 insertions(+), 31559 deletions(-) create mode 100644 webapp/packages/supersonic-fe/public/scripts/loading.js create mode 100644 webapp/packages/supersonic-fe/src/assets/fonts/DINPro.woff2 create mode 100644 webapp/packages/supersonic-fe/src/assets/fonts/TencentSans-W7.woff create mode 100644 webapp/packages/supersonic-fe/src/assets/icon/vector.svg delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/color/bezierEasing.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/color/colorPalette.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/color/colors.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/color/tinyColor.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/compact.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/base.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/global.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/iconfont.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/index.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion/fade.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion/move.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion/other.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion/slide.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/core/motion/zoom.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/css.js delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/dark.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/default.css delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/default.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/index-pure.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/index.css delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/index.d.ts delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/index.js delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/index.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/box.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/clearfix.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/compact-item-vertical.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/compact-item.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/compatibility.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/customize.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/iconfont.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/index.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/modal-mask.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/motion.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/operation-unit.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/reset.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/rounded-arrow.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/size.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/mixins/typography.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/themes/compact.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/themes/dark.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/themes/default.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/themes/index.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/themes/variable.less delete mode 100644 webapp/packages/supersonic-fe/src/assets/style/variable.less create mode 100644 webapp/packages/supersonic-fe/src/models/allUserData.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Edit.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/MetricInfoEditSider.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateForm.tsx create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricInfoCreateSqlConfig.tsx delete mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/model.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/models/databaseData.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/models/dimensionData.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/models/domainData.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/models/metricData.ts create mode 100644 webapp/packages/supersonic-fe/src/pages/SemanticModel/models/modelData.ts delete mode 100644 webapp/packages/supersonic-fe/src/utils/curd.ts diff --git a/webapp/packages/supersonic-fe/config/config.ts b/webapp/packages/supersonic-fe/config/config.ts index 7fc8db70d..a0e37e162 100644 --- a/webapp/packages/supersonic-fe/config/config.ts +++ b/webapp/packages/supersonic-fe/config/config.ts @@ -1,19 +1,16 @@ // https://umijs.org/config/ -import { defineConfig } from 'umi'; -import defaultSettings, { publicPath } from './defaultSettings'; -import themeSettings from './themeSettings'; +import { defineConfig } from '@umijs/max'; +// import { join } from 'path'; +import defaultSettings from './defaultSettings'; import proxy from './proxy'; import routes from './routes'; -import moment from 'moment'; +import dayjs from 'dayjs'; +const { REACT_APP_ENV = 'dev', RUN_TYPE } = process.env; + +const publicPath = '/webapp/'; import ENV_CONFIG from './envConfig'; -import CompressionWebpackPlugin from 'compression-webpack-plugin' - - -const { REACT_APP_ENV, RUN_TYPE } = process.env; export default defineConfig({ - webpack5: {}, - mfsu: false, define: { // 添加这个自定义的环境变量 // 'process.env.REACT_APP_ENV': process.env.REACT_APP_ENV, // * REACT_APP_ENV 本地开发环境:dev,测试服:test,正式服:prod @@ -28,68 +25,161 @@ export default defineConfig({ metas: [ { name: 'app_version', - content: moment().format('YYYY-MM-DD HH:mm:ss'), + content: dayjs().format('YYYY-MM-DD HH:mm:ss'), }, ], - devServer: { port: 8002 }, + /** + * @name 开启 hash 模式 + * @description 让 build 之后的产物包含 hash 后缀。通常用于增量发布和避免浏览器加载缓存。 + * @doc https://umijs.org/docs/api/config#hash + */ hash: true, - // history: { type: 'hash' }, - antd: {}, - dva: { - hmr: true, + + /** + * @name 兼容性设置 + * @description 设置 ie11 不一定完美兼容,需要检查自己使用的所有依赖 + * @doc https://umijs.org/docs/api/config#targets + */ + // targets: { + // ie: 11, + // }, + /** + * @name 路由的配置,不在路由中引入的文件不会编译 + * @description 只支持 path,component,routes,redirect,wrappers,title 的配置 + * @doc https://umijs.org/docs/guides/routes + */ + // umi routes: https://umijs.org/docs/routing + routes, + /** + * @name 主题的配置 + * @description 虽然叫主题,但是其实只是 less 的变量设置 + * @doc antd的主题设置 https://ant.design/docs/react/customize-theme-cn + * @doc umi 的theme 配置 https://umijs.org/docs/api/config#theme + */ + theme: { + // 如果不想要 configProvide 动态设置主题需要把这个设置为 default + // 只有设置为 variable, 才能使用 configProvide 动态设置主色调 + 'root-entry-name': 'variable', + // 'primary-color': '#f87653', + 'primary-color': '#1672fa', }, + /** + * @name Dayjs 的国际化配置 + * @description 如果对国际化没有要求,打开之后能减少js的包大小 + * @doc https://umijs.org/docs/api/config#ignoremomentlocale + */ + ignoreMomentLocale: true, + /** + * @name 代理配置 + * @description 可以让你的本地服务器代理到你的服务器上,这样你就可以访问服务器的数据了 + * @see 要注意以下 代理只能在本地开发时使用,build 之后就无法使用了。 + * @doc 代理介绍 https://umijs.org/docs/guides/proxy + * @doc 代理配置 https://umijs.org/docs/api/config#proxy + */ + proxy: proxy[REACT_APP_ENV as keyof typeof proxy], + base: publicPath, + publicPath, + outputPath: RUN_TYPE === 'local' ? 'supersonic-webapp' : 'dist', + /** + * @name 快速热更新配置 + * @description 一个不错的热更新组件,更新时可以保留 state + */ + fastRefresh: true, + //============== 以下都是max的插件配置 =============== + /** + * @name 数据流插件 + * @@doc https://umijs.org/docs/max/data-flow + */ + model: {}, + /** + * 一个全局的初始数据流,可以用它在插件之间共享数据 + * @description 可以用来存放一些全局的数据,比如用户信息,或者一些全局的状态,全局初始状态在整个 Umi 项目的最开始创建。 + * @doc https://umijs.org/docs/max/data-flow#%E5%85%A8%E5%B1%80%E5%88%9D%E5%A7%8B%E7%8A%B6%E6%80%81 + */ + initialState: {}, + /** + * @name layout 插件 + * @doc https://umijs.org/docs/max/layout-menu + */ + title: 'TME内容库', layout: { - name: '', locale: true, - siderWidth: 208, ...defaultSettings, }, + /** + * @name moment2dayjs 插件 + * @description 将项目中的 Dayjs 替换为 Dayjs + * @doc https://umijs.org/docs/max/moment2dayjs + */ + // moment2dayjs: { + // preset: 'antd', + // plugins: ['duration'], + // }, + /** + * @name 国际化插件 + * @doc https://umijs.org/docs/max/i18n + */ locale: { // default zh-CN default: 'zh-CN', antd: true, // default true, when it is true, will use `navigator.language` overwrite default - baseNavigator: false, + baseNavigator: true, }, - // dynamicImport: { - // loading: '@ant-design/pro-layout/es/PageLoading', - // }, - targets: { - ie: 11, - }, - // umi routes: https://umijs.org/docs/routing - routes, - // Theme for antd: https://ant.design/docs/react/customize-theme-cn - theme: { - ...themeSettings, - }, - alias: { - 'antd/es/style': '@/assets/style', - }, - esbuild: {}, - title: false, - ignoreMomentLocale: true, - proxy: proxy[REACT_APP_ENV || 'dev'], - manifest: { - basePath: '/', - }, - base: publicPath, - publicPath, - outputPath: RUN_TYPE === 'local' ? 'supersonic-webapp' : 'dist', - resolve: { - includes: ['src/components'], - }, - chainWebpack: (config) => { - if (process.env.NODE_ENV === 'production') { // 生产模式开启 - config.plugin('compression-webpack-plugin').use( - new CompressionWebpackPlugin({ - algorithm: 'gzip', - test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$'), - threshold: 10240, - minRatio: 0.6, - deleteOriginalAssets: false, // 不删除源文件 - }) - ); - } + /** + * @name antd 插件 + * @description 内置了 babel import 插件 + * @doc https://umijs.org/docs/max/antd#antd + */ + antd: {}, + /** + * @name 网络请求配置 + * @description 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。 + * @doc https://umijs.org/docs/max/request + */ + request: {}, + /** + * @name 权限插件 + * @description 基于 initialState 的权限插件,必须先打开 initialState + * @doc https://umijs.org/docs/max/access + */ + access: {}, + /** + * @name
中额外的 script + * @description 配置 中额外的 script + */ + headScripts: [ + // 解决首次加载时白屏的问题 + { src: '/webapp/scripts/loading.js', async: true }, + ], + + //================ pro 插件配置 ================= + presets: ['umi-presets-pro'], + /** + * @name openAPI 插件的配置 + * @description 基于 openapi 的规范生成serve 和mock,能减少很多样板代码 + * @doc https://pro.ant.design/zh-cn/docs/openapi/ + */ + // openAPI: [ + // { + // requestLibPath: "import { request } from '@umijs/max'", + // // 或者使用在线的版本 + // // schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json" + // schemaPath: join(__dirname, 'oneapi.json'), + // mock: false, + // }, + // { + // requestLibPath: "import { request } from '@umijs/max'", + // schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json', + // projectName: 'swagger', + // }, + // ], + // 将insights-flow相关包排除出mfsu编译,在pnpm link 模式下保持热更新 + mfsu: { + strategy: 'normal', + // exclude: ['supersonic-insights-flow-components', 'supersonic-insights-flow-core'], }, + requestRecord: {}, + exportStatic: {}, + // esbuildMinifyIIFE: true, }); diff --git a/webapp/packages/supersonic-fe/config/routes.ts b/webapp/packages/supersonic-fe/config/routes.ts index 1b12c69c4..3aa98a6e0 100644 --- a/webapp/packages/supersonic-fe/config/routes.ts +++ b/webapp/packages/supersonic-fe/config/routes.ts @@ -41,12 +41,40 @@ const ROUTES = [ envEnableList: [ENV_KEY.CHAT], }, { - path: '/model/:domainId?/:modelId?/:menuKey?', + path: '/model/metric/edit/:metricId', + name: 'metricEdit', + hideInMenu: true, + component: './SemanticModel/Metric/Edit', + envEnableList: [ENV_KEY.SEMANTIC], + }, + { + path: '/model/', component: './SemanticModel/DomainManager', name: 'semanticModel', envEnableList: [ENV_KEY.SEMANTIC], + routes: [ + { + path: '/model/:domainId/:modelId', + component: './SemanticModel/DomainManager', + // name: 'semanticModel', + envEnableList: [ENV_KEY.SEMANTIC], + }, + { + path: '/model/:domainId/:modelId/:menuKey', + component: './SemanticModel/DomainManager', + // name: 'semanticModel', + envEnableList: [ENV_KEY.SEMANTIC], + }, + ], }, + // { + // path: '/model/:domainId/:modelId/:menuKey', + // component: './SemanticModel/DomainManager', + // name: 'semanticModel', + // envEnableList: [ENV_KEY.SEMANTIC], + // }, + { path: '/metric', name: 'metric', @@ -70,6 +98,13 @@ const ROUTES = [ component: './SemanticModel/Metric/Detail', envEnableList: [ENV_KEY.SEMANTIC], }, + { + path: '/metric/detail/edit/:metricId', + name: 'metricDetail', + hideInMenu: true, + component: './SemanticModel/Metric/Edit', + envEnableList: [ENV_KEY.SEMANTIC], + }, ], }, diff --git a/webapp/packages/supersonic-fe/config/themeSettings.ts b/webapp/packages/supersonic-fe/config/themeSettings.ts index 32daca44d..a316d7f32 100644 --- a/webapp/packages/supersonic-fe/config/themeSettings.ts +++ b/webapp/packages/supersonic-fe/config/themeSettings.ts @@ -57,6 +57,11 @@ export const configProviderTheme = { Radio: { colorPrimary: '#3182ce', }, + Checkbox: { + colorPrimary: '#3182ce', + borderRadiusSM: 0, + checkboxSize: 24, + }, Table: { headerBg: '#f9fafb', headerColor: '#667085', diff --git a/webapp/packages/supersonic-fe/package.json b/webapp/packages/supersonic-fe/package.json index be02d11ee..8f64cdae5 100644 --- a/webapp/packages/supersonic-fe/package.json +++ b/webapp/packages/supersonic-fe/package.json @@ -4,23 +4,23 @@ "private": true, "description": "data chat", "scripts": { - "analyze": "cross-env ANALYZE=1 umi build", + "analyze": "cross-env ANALYZE=1 max build", "build": "npm run build:os", - "build:os": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource umi build", - "build:os-local": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource RUN_TYPE=local umi build", - "build:inner": "cross-env REACT_APP_ENV=prod APP_TARGET=inner umi build", - "build:test": "cross-env REACT_APP_ENV=test umi build", + "build:os": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource max build", + "build:os-local": "cross-env REACT_APP_ENV=prod APP_TARGET=opensource RUN_TYPE=local max build", + "build:inner": "cross-env REACT_APP_ENV=prod APP_TARGET=inner max build", + "build:test": "cross-env REACT_APP_ENV=test max build", "deploy": "npm run site && npm run gh-pages", "dev": "npm run start:osdev", "dev:os": "npm run start:osdev", "dev:inner": "npm run start:dev", "no:dev:os": "NODE_OPTIONS=--openssl-legacy-provider npm run start:osdev", "no:dev:inner": "NODE_OPTIONS=--openssl-legacy-provider npm run start:dev", - "no:build:inner": "cross-env NODE_OPTIONS=--openssl-legacy-provider REACT_APP_ENV=prod APP_TARGET=inner umi build", + "no:build:inner": "cross-env NODE_OPTIONS=--openssl-legacy-provider REACT_APP_ENV=prod APP_TARGET=inner max build", "gh-pages": "gh-pages -d dist", "i18n-remove": "pro i18n-remove --locale=zh-CN --write", - "postinstall": "umi g tmp", - "lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier", + "postinstall": "max setup", + "lint": "max g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier", "lint-staged": "lint-staged", "lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ", "lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style", @@ -29,17 +29,17 @@ "lint:style": "stylelint --fix \"src/**/*.less\" --syntax less", "precommit": "lint-staged", "prettier": "prettier -c --write \"src/**/*\"", - "start": "NODE_OPTIONS=--openssl-legacy-provider npm run start:osdev", - "start:dev": "cross-env REACT_APP_ENV=dev MOCK=none APP_TARGET=inner umi dev", - "start:osdev": "cross-env REACT_APP_ENV=dev PORT=9000 MOCK=none APP_TARGET=opensource umi dev", - "start:no-mock": "cross-env MOCK=none umi dev", - "start:no-ui": "cross-env UMI_UI=none umi dev", - "start:pre": "cross-env REACT_APP_ENV=pre umi dev", - "start:test": "cross-env REACT_APP_ENV=test MOCK=none umi dev", + "start": "npm run start:osdev", + "start:dev": "cross-env PORT=8002 REACT_APP_ENV=dev MOCK=none APP_TARGET=inner max dev", + "start:osdev": "cross-env REACT_APP_ENV=dev PORT=9000 MOCK=none APP_TARGET=opensource max dev", + "start:no-mock": "cross-env MOCK=none max dev", + "start:no-ui": "cross-env UMI_UI=none max dev", + "start:pre": "cross-env REACT_APP_ENV=pre max dev", + "start:test": "cross-env REACT_APP_ENV=test MOCK=none max dev", "pretest": "node ./tests/beforeTest", - "test": "umi test", + "test": "max test", "test:all": "node ./tests/run-tests.js", - "test:component": "umi test ./src/components", + "test:component": "max test ./src/components", "tsc": "tsc --noEmit" }, "lint-staged": { @@ -67,7 +67,7 @@ "@types/numeral": "^2.0.2", "@types/react-draft-wysiwyg": "^1.13.2", "@types/react-syntax-highlighter": "^13.5.0", - "@umijs/route-utils": "^1.0.33", + "@umijs/route-utils": "2.2.2", "ace-builds": "^1.4.12", "ahooks": "^3.7.7", "antd": "5.11.2", @@ -87,6 +87,7 @@ "omit.js": "^2.0.2", "path-to-regexp": "^2.4.0", "qs": "^6.9.0", + "query-string": "^9.0.0", "react": "^17.0.0", "react-ace": "^9.4.1", "react-dev-inspector": "^1.8.4", @@ -97,10 +98,9 @@ "react-split-pane": "^2.0.3", "react-syntax-highlighter": "^15.4.3", "sql-formatter": "^2.3.3", - "supersonic-chat-sdk": "^1.0.10", - "supersonic-insights-flow-components": "^1.4.6", - "umi": "3.5", - "umi-request": "^1.4.0" + "supersonic-chat-sdk": "^1.1.6", + "supersonic-insights-flow-components": "^1.4.9", + "umi-request": "1.4.0" }, "devDependencies": { "@ant-design/pro-cli": "^2.0.2", @@ -117,13 +117,9 @@ "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@types/react-helmet": "^6.1.0", - "@umijs/fabric": "^2.4.0", - "@umijs/plugin-blocks": "^2.0.5", - "@umijs/plugin-esbuild": "^1.0.1", - "@umijs/preset-ant-design-pro": "^1.2.0", - "@umijs/preset-dumi": "^1.1.0-rc.6", - "@umijs/preset-react": "^1.7.4", - "@umijs/yorkie": "^2.0.3", + "@umijs/max": "^4.2.5", + "@umijs/fabric": "^4.0.1", + "@umijs/plugin-model": "^2.6.2", "carlo": "^0.9.46", "cross-port-killer": "^1.1.1", "detect-installer": "^1.0.1", @@ -138,7 +134,8 @@ "pro-download": "1.0.1", "puppeteer-core": "^5.0.0", "stylelint": "^13.0.0", - "typescript": "^4.0.3" + "typescript": "^4.0.3", + "umi-presets-pro": "2.0.2" }, "engines": { "node": ">=16.0.0 <20.0.0" diff --git a/webapp/packages/supersonic-fe/public/scripts/loading.js b/webapp/packages/supersonic-fe/public/scripts/loading.js new file mode 100644 index 000000000..60be08e70 --- /dev/null +++ b/webapp/packages/supersonic-fe/public/scripts/loading.js @@ -0,0 +1,196 @@ +/** + * loading 占位 + * 解决首次加载时白屏的问题 + */ + (function () { + const _root = document.querySelector('#root'); + if (_root && _root.innerHTML === '') { + _root.innerHTML = ` + + +_Haw2_w*F@*N$QiTN6e zCZi|yfIYrrZyOd;U}!DtC}~b3sr>5Lx(Rbj z=$T)@+W^Pvdi-Me4QVWMS}RQ{h?I`VL<3Z^xz@>TWUXi2BsR9j{AwhrvS&1(;-Z6r zGR&sabkwa&JiTOUt81;!TaG-8tp)yorUpgDrri>5r &3 ZG{K?e4hO_MWSTEp>-D0{9YZ_{O`405$ECJ!Rs`P{JhtRO4SHTWulF>Yem%7r$&S zRA6+}&@;Sx5S21vvKuF`r|wSl%E|A(6Mc%8*3rT;+_8o(UW6@guz1So%3Uu!_o<)Q z2;D^_Z}TN+1)BUFTrYc`z22~YWDf!jQ64xs)- UBzsa`vP+DzwYs*~WY>YN(KDh%0k7GZkeVpxojwSN=xpb^bII{y`VI}#(+ZN=A zS!r~w(!$IFDv81AbF!I!J6|2D9-|*O!!!xeSJWIKMh%JxbI02k9<{_!Yz!G{yp(?S zC=5W oQHU5wOTE8S-f83JSGD zu49Sm5jnf3s?E?awoqX5?GwD6b0{?%sp4OQM=6@f8_vO20)^T?W+K-cM}A)!X^v7; zx!pC~AHVt9Yf3KM1(qI6joJb!VaeNZqt%95!mP!~%SRgOIo18jEnx5c4ys&6$96Eo z%U9O$g|2d8Lt)D)@E)nJM}Lx0JTTs63sR#-q*<*8(JQ|BO;45HQ4Kbtk1VUR(W_*( z!24Aczn{o{H+fHNpFNd1u*-o5rava1MOEaD=c#&IgKKz^jrinWSv|6~HKwCT?{HF` zt6n`Q??!aLU4sr#i+t2SDfqjIr8F5I4$_5k2in=h3_#u1#?)ozScW{<^PUxHc2-+T z(1K0VsV}+q3AYBP2@+9Id+uU^0qHk3SS4b+7L&{sydr`^C354Krd``Fy?6E#ULj@G z`tr&&&Cs)?K*_41Ka@+B{0L6OEbB6l8izHC9DrGsma>XI*WNj9fHJPE 2m&(*btrR61Qp!$w<@PQlMFqFRxdk;6@jI-rtybJh9AA5)s`7M+!8*(h#%!uDjK zjle}yJLAqG8V`3WA@C)-Ht~WZP7Q~h<}e&p6=t*(nw~sYZdJBa{u*i+#WV|4y89Pu z&rC^@IM@ZBwj&HuCk8f`PQ=&i2gXUG=8Tqx6Fo_8B?*AlmPy>j<;mKYXn{1UJif!5 zL0 QIK3Ewqm&r z#=#3&WmX5H$bQpPY^CX1nGdz1kcg?`P!DnJ5ZACa$<^p_jON9dk@=Q%6g>&3G}sWS z*cR8M;r&c8^O6Z|TNO;=KT$m+Ar4KGD5t{XN;d_ehiDety5}?!$!-^i_OkHl1hyuI zqx=d9V$SFs9hc*@B;3IoH3T!))PRHt3aXwKt`si{li3mpl*hz)pgIP-P+spDHkJi9 z&L!ShznTYU)Ej*yMX~X_Ek-xadDt+RzifQeF9!*bCR|wDMZ!0;(}l-Cb2I$Y*@uzn zR`vc#Si;;HpYXGGQK}QD4;aFF;(Ef4i?C3jKLIaA4?!P`l&dGpRMlzTI`Up9uSszl zBZ{--Ag^F` -a#>QUz_ar2oQ35EU4b~Y z7N)ztxK5Pv1kWCnwL6s%hW;E4@%z4b<%9zn2}BA~5Wkli7dzqh$0NPDdcNBONt=D% zN>mQRL0pEjv7QRAq!-@O*l1T7&ITJsOrv>*^P+iT1YY|_O}2e5HpYnd)_Cm+d-_9- zh;~fc2q%ypF~u*#jcEA`=$I2xq58a^e23uv;t0qpft=H3niP8hyc~|Uz^($J*C($^ zd8|_kUBT)*rXI_j^c2_yqDz>) #+8nz61%V3D zJ-MOh7k-P&aIdz}p&zn2P)Ru*ysJ@@-56xCC_Zv{&i7>$G(#B@;@sS`BLz=2jXn=p zR3euI9uTnnXbzC|{zU=P>lXD>2r|LSfO_^bULWD>Io3`_r~CnY^`Y{!%FLJ=&Wx69 zHRw@N7Th!eVF*f40sY(aylK%)&nOe; a;cnryDC39MKk9+FWGup9ncv sDYVgGS#JPs-!Y>KUz|@OGU1^ zUum@?B9WBAS<>mW3O+0;u8=d+sc^~DXq|8AO<3Knk4 OSPR>sXO|Mu;J*`8;dD}5e zyX>mjoJTk_#6~cGp@0i3NE5UBmEj~)bu1Cl%#5jj<496vdw12=E>Z$Qn@pCQ@$v zsgF2t`8xvHyaLC{kfoubA<4!n-`nG5XFdYhe&|A{3YJX;i-)p8X}izzoeQTT3hY1` z@`8T=jz*%cALk+0nL!=LdX&$RMa-9MZuG^gWyluLrK~xW)PitcD?* tdd zJx4XT4nE%4l}tHN JVttn3B&Q^AWID=3VLi&EMh( >5D zXU>zDlsD94l|%2oyb+bq-Vw#A<8;H5+AMC5V}LkUGEvx`3i0)M+s%C2R$T0#MPP%% z{jSrzRXyoVL9Kp<5``U84%;#^Q~o)r?sGJmC=XDSn{Q+(O^YE)b&y&|gOv@E6%E6{ z9HF*vsYFh2EIu(RwPBvy0>AW&SL~SmacJtmRhM(lY7#Y}78Tc8QMlvuI+9sr90uYq z6-LDDgMYk0H#wo_fQ8Mnryl uVoxJD=0pW`RHy^- zt!e+910Hdf6oKlhb*JQZ_54N0)P{%N&@ozrX{l)}4c%ED)+`XC5AEvRzo4@+E+K-i z>(=giQ(*Zk(Y1I?uas1>{ozldr9TpVonS3V7u%p|1rjCyr|l2awuv)ndW=ORsywnq zI{R9bfKq@aY&O`bXM=%S9F2KVI4o-ucWH*w0v5j?r^!lvp{V60`K;Ah6&ga2fpdT% zFlkx83XTbo&aK|x9vYnU0`e-JbztEhqdgpfReth2hhEcsEfq;%!mY91QnO{GNfl;TNAh_xVCYdQannZU zt*$e HUbi*U-wB*(~o@B<>tJVops~yW|@}GxU9W`BD_K z9Z-go d!_W^;$mEhlVy=rKS|MJmTR#DbvJsl3l z6+6aWaVslMm0ORzYV+}lgG+mQ9ixQEXI*X&faJfF+8eKyL;3dLXnEMk3fZHDztUju zQam!jwaUDpmG%Q@oCS!ET (*G@H>a8yA&^c_XP7Y-1H;@j;& zB}K_}*~-RDu)8++*(4D7kF!7Bjv(Gf;ykgGZ)}O!^R*Ikt$%7wlr#3`$^FJ1KZTnU zL(y %!e`P3BB6XomIZ8rui;-mb}`Ue2m>ATrl=KDB6y5G z&Nuo%P#fs}i2!Lpx5R^Ko%rHX7Zv#s&o}cZRz=Uw;Nh6>Pa$RUv)pTz9L>PeaV1Rn zPJG9bXtWWtzAkEM<3l0e3~Ldn83|_N `zdXyr=KS^Ek_wYbYLxT>!Rj=LOs zCgy!{vO!aD_)KRSFu?%*?$l+EQ_gJeiz7qRfCS1wi~B5ybTp+EptAG_^^p_hJGM^` zHj08Th!w*Zw4J0pw8dnB9*c)vvqei20W4t@T0X<}*b4aemNfpvc{1FAoI3CflO=S7 z*mrz%0}M TjQ~6ChNJ~B8G$8z$N_->`JNJ{i`R!V5{w-#OHN=`qUW* ztNGDAy*C``e1mOB mM113fK87731ygL3jjmpDJy1e9&^7WM`VyYyqZElDW(}tbPw3M)Y_{P6g+`)b z;abta4W`;-PS8Y0rlyS@8~E&k3e}Ez6v*O#k=vIVF+HgC5RjW(dnq{j+`XXqo@{); zn^fh>0_n`Hh^WBqS#A~Ap|079cTOSE3;>GLh_Yr?^2ZwG^%$u={_PpFKqtxMzP}Y$ zgQd;^1T+Baet8uHqOx052er6yLjXhK$Rb(6<-Cm(vBJ~>pZv&{#s`j?!vlKu-bK-G z3y}GPkS~MJy4{iPSpSUA(QI4tvrh@{l-WXgm{B@nRdJZ(!YpP7fAT>gUaTjU4DBA% zCohNXc<+*_&&^h~jRW1rt$#aX+;p#B3sRTiEc?x*bRjt5VkZJX)seez|5O=6BD@ zOT8Tz6Hj0Pz=L#7Wev@(a^nnkV-ql3{IsW&^oz=VpZ`x=fio`0erR0FhCS&{WHMVJ z&t~UC;8OU&ju@)jnG(adUH`X&kR>(r*si~2E!RLsw)>H9-_PL8PdK5wv%rN{>qKCH z*axDd$K<9QX}*zlNsiE2bosj(thynVi!WWQM2Ntk0^q^FP@dxA7L}mO_djlN| zYAQs`YSl4q&Jx`s{6WH<2R*Q$eMThdARR$j+K+}a MK#WK=KvwBskm?D #s0&}bVli1EV<*jDa1cMH F>ee9^dO>z3gW)o_vE!d>Ki~N +D_JI>jc{EMVZ52IfM=d2>2W? zov{nd@wjigbzvlBZc3 QL-x}dT~e4y #% zoO=l(Ips?4m*ATv43U`Yu?p7tTZg7#M@WZ_xg|hX(Xa==zffhms)h><)6dVl7JPZ2 zC%wCsv1&W5tml@>d~?aFf2>CAJ}#S|>BOBsWoWF>LjX^&1+gmi2AOhy)$t_%FON|# zY_CD`zVkbwN3H3fY;Q+?S%dd`f0+K$uk| wR j>8V!@m87D<4KZMQTA-#-=B#^y);8to2e z6oru=VLadF`41}ADfX9#WM?IoRrewHCrlU^nRaY*HW_(}l@k)F0z&Uju5wLB8%oZT z&|K>DLR_>m**Wa)W!_6)qyXX?2o6Ph)q$8?HXR0wq0=|RPG=n`KS+RicD1UhCRdCn zoq6)g#mfv`d&qRmOvmsHy-NdakJaP^?rJ*%7a$4{DD1$E=vYXqI@OTzz-rgz_!R)w zL$;gk?Abk1pSZQo?CeR;hmqibU{Ak;(P)B@RfoJ=Q`5)<&cnk~V`4$YODRjjX5Iom zl!}$1F31`*ci551klo^TU9f*uRK-Uj&2(Ze n9KJWfsKlsl}K 6haE_- zN&2IbE*h~=R1%V?o~4o12eCE0mA5>2B&pke$`|p6++te8F W_xB=kyX^yoPv(^UKl&r>fXrj$ns zhA6zOL=m;wAa#A!Y_N0D^D&TjF=C@$qm{Xgd$Pa3eI72m=E$D+;kPyNRjgS>&}VcL ztHp|V&r1z7i556#trw&T=u+sfcOgFObgQirs%~Xraf~|yj2EMIamg5(8?j(8wAhkG znkv{@cxll30}lI3&~FLO(+;|WkIbqr?@i^-sJ7*ms GFBT 4yGAwx9RC;`{WG?LxvP7RqlGT>89JJ}$t z*0vh@>Ot{B$!U7>su(Fv9#NzLu}F6cifw$d_;`eJ;D2!S-~Xn0nTZhBoRy_4z`MJk z^j#Z4hncO_!!!h|@D?bPbHaI6J9t+^;+&fT|3zQ}rw<|ca)Ky1o!-d6ff%NpxgIF) z#^5a@_gv~#j6CC-M=sDh&xR$rF>!DCk+HSEmgkQQd ?61(c=>!_vYNPLD0>{mD zu4>?XqfV5yG=cME@O-(XzcAYb+T&nom`R;?~PKVzuW(xwZ?IxRVefa;9w;x;qs)|+1_w^%$i@zPZ zFVlK`H>@_GOY;eMjX9rvwLS)2NA&;uLo&%(7o-OjxYD!MGT(B+;H$j;=YG7HQ2rbO z X z a zE^;!J#YP`4cCtO-W~$&;mqr3xU%uF9R+{2P_Q4irxidZ9vowCqPNNKg@?a~F3%KSO zL$1v-8zV5X9S-g%B59Icmn9N0LE4v2g~)-y3+@w{;KK?Z6qex89hzG)7QqNh Lq;a7Pe)a1YKP1p zXOHBweko|3R}>=vku^AC4-@Z>6Z soS7}f>!>j-MECiJmLv(2$6pVI;KQ0+#nZ@Aps@j6lU5$~ zoeu)kVMq^=k}1!0t_Gm%)hMzkMQXP6GL0$#akQzRa<*DeM3Xm}rs_wHGNof#CvN<& zJb7Wij6JMkVQef|Mfw?LD@fKL-d8zW7Xn~W*BT6I;Qvuv$G)D~0?{{MZWE`jW5=#L zcr-SIFV2hOLBjdFp4q X(|!QD=T!8(T&*wsm^)O-dFxch#_vb9bONRvA^ zdiR(_RGK(@=vCR!UC=)mRPL(WcVv9RaF50;s7V+E t(u4-U%k1cdmX~EXA;VTE9wVf3*U~esYE+Be%G# zmJK1RUDAF#5vXJg2A^+RVB_(J26=qV0u7H>kEdFs;zOo)HUhI;DtT5REeHPgWno%L z>vDXbq;D7=j@96ow@S3j!)jNNSCGNoeUJ$<$Ylq&rVz;TJZ&_jD9srx)gTqt$Z6>K zZ!t8nFMH-9^wI-cK^bf0<>l_k(;@g4C!q>`D~clUVb5HQ&Rd56?QSfl|9CR)ct0kg z{}NcCH^7El#cA&Vx9m&8_3L-B7CisFW!nez=;pC(1z&E455jFk&fWK*5<|rEoA7)h zrV=zH%OmR;yp%~|DmRl^7!*AxF$_B^Zx7uMzj>je5oP3%iQH7R2bdoB{Q2`|jYWk; zMc*3cr4|f5N}ca!Yv?eO}dCdAxkpc#V$eq0h7T&lff vQ$LwFbuO_!Hf$#e}c Q#$FD73lgg}Lajz128+L!zI!MXJbYJL(rX05kd?5q4~mR{Mij~sC?XQ-1Mwa& zo;Ma%8HJ6rp5@x&qGCIsv`g&rJlMAdvFU>JUEJl-N+b4Ay;7izP3fh(!`*?sUdy|S z$lT~u2j* ~2C?L&VnH`LbHoz42IvF6wt`f~$?qXmBA z9GHwVa{%`O>F{>_+4^i}r9^i=bhPbi^RZLxQ6}>K$el$hnv>}Tg&4Y87G}KatbB~` zxFE0IGgl-uw*8kOPzs1&TKOiKhq1WcI-N(osA|8pK)K*SyKYy&RC?1eY?)_iZ{8wF z3uX3&JsU7xb@euMF@+}bHvV@aN9^Kel^&@Tcjx?A)>GA*X<#QiLCtWokC@pILQ^Cc zt7$)n)(}inrW6AvV6l~XHSyA(s04a{71NZOK%1Thyprts_AlfpdAF%`F&P#Wc~0It zWOKr_MzV1w`7+7bV@>t>Lp|^qJbx(PqZ=`)|4siNrcY~x^H%dxwI~!;8aEK>86FlP z4-M;#jOy$n!4;1A({rn=7DKsOExHA+CHc%p5q-nQrr26BLC8*Y!y=#*nm5a#CWd!` zQaZ{XCdMSM3@)t-PlA2)$h*H2^%RLn5tc!0ljcMQfsxbjS3A{Od_y))J9 9p)$!y8 z<}=8DO4wwJx1VW2`VM7jDP|Jyz!E&^b66IJxgU=E(G!jt4=>2Y?oqEVL&cqjeS{@g z2+MA9-w^)zXX->5PrAExDfe?#H$M}B!wk>$h-_j~0~=FgjC^?MD^S>Q#&HLpmb={4 zx_gR;ixfrT>aA^Z9C#WoU!cLe%#4^YOEPV$L{| ^4Lt;VL}W9mI~E aXByhaO& 8?D6f>XU>k(!q&TW3`V^h}* zFuo3U+3sv!9-16Ki5vJM;n=eycV!f0N`t7~Rfo^sTfE~3cQV%&lUx znje-Qy_`&B5XF! lMzs%|x$HHiyTE0CtErZZVL8Yz;|!SwuN zDRp%jNfAWh_{T)oapf_X)6-e;Mi$xv<8YSVES}JSXppBL7}gGBp$}}dh8_O~n41F3 z992ycHi^6cI!~LpIY3xE(1JNT9;uw?GlmGRBK9SDQ?qSI9S-D{CGGQnfqXq?E6+l) zaIidP@O%Esbj;J#@3r;}r7Wk6&!3o8(?}0;m7nY8^Ec0>oX*u;i!epp)}CJDFdL#( zH%z1B@gTWeb^CxmMI^13Bu$Z)Rk}%eiVQC+rr6~jwU2g1`<85(oo|#FJ 8fm z&zzHj?87cb^fPUjIZ}!!0uZw+*MF0|I0>m}ZVP}`7GmGc;H5gpeL^>YRk{FjCNI^} z&cYpVN8N@DUaC|4IYR_|sE)XktL4s3T$D47?CLTp^I{9ID4u6zV56jyvN5Z-mYqmy zTo2+dGI&V$NQw~iR-j+V2y#hP9S^iNVriA)e^SXuwTLzEh{b5FK1t4 C9 zk7@e9p=)MA?l4cB&Tv5PJ|x^v?>tp+mTb)aYyX;Z!QS_95MMc%o;Gmx|4&;Dl{gZ* z&nBtTIYBxng(Mesctj; 2g9>A&t({PdW#?3e{wm9_6k#LRVP zRqR`%jnP>eTzJ7wvn_r(1cuWMuwfqeZ}rmodIl=3O=azE_OhO94((%CHMnp{JX^|0 z9P5q#@y3T~<1e{WNUwjO$b8;A5c9Iu*}8SO#6#P^BQs-1zlXL&KRx?})meKvmvaQ! z*+Y<#@D G5PPvsc^2FQcosd3=oOoyw?$X} zX*YWpDfvD!AHCU?+jZrrd8DpPvYSVH@X7>IxFDba9{b>X^w|D~2uogU4iTE|x~<{8 z|I3d~BY!<#IXHH3z`tNbC~Ts_)Fz>DWTAVD!oj$j ;8^@H+?k!gs73n9%T03>V}|NpigE z*8~Dm8Xqpkp1|96eqENQZWWY^cxqATZ(T90QW2ji^e0i-OK}lVtbm{w(MCyD>RP`b zBAO|o>aJx7D4LIBS@0wfEz>Ux+(RaCgTy1FHSAs@Zo+5iGcsh_^msx^kJ?M(rS2&q z#800Vg8U54U`(2#=)!j_f$L>Wb*oxiOt8AiD+_f-Sf{nAqgxnCi!w%G{~SS9Q_Ble zD-u)jG-51)!b{7@5P(Zx_D=j^{bSDrTnE>};E~(R+eNme)mFniozLFkE}cSmzNNTG zm%nWz#K2_1Xm(_?tGyIB*-Z#G3ks`>m-c}#W5p#SnD$ &D`Y|Q;{<$NS06Op8p_^YXwVmGLTLA$b-_@uv+n*|O`+aUxIL6T-D(YYnA0~B zj~*FyXn&>qdp8(C$B#@5K-_Y3=daLT>cH3V($GBF4`j0iKK>%WGKvk+M(obG@97&% zu*ZXMSkO!IwqSxQWG7$7 )6Gu#m6>w=P29k%A(=(b +e)hQdb<(8&)1n4Y;v;43w>(JqQiX)@Nb!J3S~ywiGUC zvP1S-WLZzSf!inv57oRx$ua~)E!SalL1RG!G+Tz_iupbKs@l-1uRFHy&9=_j_5%BC zYiINK{O{3bvtP{mg7pH7T>d>D?EhZvicu8fy4S4f#uZ}}uGOT#;++&)PA+NXv-M LvLXB*WhcGRkm#QPLf3}j8n?s@P3@j#-F3yhgN71w}DbcP__}-m}vnD8l zxEcZ-q+JxJ#}}ca6vu#%fbIyHBo$5;qQ)xGY~Z$|8I+zF8! 8_CKs(AY<{7BlW!_CDkba7ERY8i9!eg)>$`AG&&HYx^Ot8M> zdCP~=1sMYv_bpv9O+L>{imsa LbFPWyz?M5PJMW37cK=Y~s;mNY z3blUzi;tDtntGdn+CEq~I5r07qw--;P=Q @c~uFan{cEM~q zv@PH57LlGw8JZZP&@+J2Zm2A_qQ+*KYYMb*PGS+Rc2(~0gu(Ga0{4gY6=B;S+X%h% z)Pot&`lswUuFja;wfQPU(cqrJLPUn9)4l(f5zOrlubU>F`%SJWQGAupnIa9V>+-6q zE~y4_PUe2p!1nnirwKArNi=f0US}k1#V6B=m3)T1 u>9i@MfUN=}dQ3-)IJXA>Nyb zqycpwc#eGr66wj7I-3CYNN)3XFJ)#@`zQJ-wjyr DMoxj2C z?zhS2(c);zz{G%qH#`QPT6!SZyat$|=@8BUjPa2Y-&NzT!FC~?OxscK$w5f}$^C>7 zd9dqu(B2*lnWS1v#NwZ2TKP1A87}9yByWBNz;CcN_*6aQ3!m_X^8*SIhBm3+wH>MR zx7G9d^x9;x`(RO&)>AcmA)Q&=@1e_z)q2Y253~(zchi7W-}%06YvcdnL0n5y4dgLa z;%9!_Pi175GHDbGtD5^OlhitifNc=VyQ6T1H1q%of0t&B&f(qIW$llx*Y{YdnP8?G zyYnBj?aAdN+zFqYT+;C*JuN5I@^El-VB_cN^SLez7DD$(>@Z_8J=&i|{w|70l-!}G zFJJti06bg5kc+rqzkcK>_!%M&N)k~#KO{G@zO7z3Wo6jh$d<(|k)7bD4Nr%luYB-u zgM3*Mbb|jjOEbi|Yw6&3nC}wCf|`oK(+51{;trbi+fhYCT4mMT_PWaXR!h~K@;v`( za|_4>fj?+$yy$xTP2IuwAM!sOdS7?^&A4mhY3C{VQ^3yUta6oXo|KnHvnbKD=rC56 zNGy!nhYF=7G9eO;Pihbs@Muwu!QxBcU&wgd0DXnBZfhZMd<@A}(dH^?lXQ&kv3s|! zqxoO+Kb(BuaQ@A0*XD6&a0eP%u|hhl_-J -3edf0sPg+jolwBs`y=~qU$s?a`*;P5JN4X}>$n@2 zeCpX9?a+mx;#Px+uLE`WW$}HN{m-xK)OUpmOM*KFt=kS_MdXa~XjK+YR1Qwip-fq7 zaozl;`ugsol=4i7#hAY;v}x qydJ6TW^MP!Y19;p}B-TJ; z8~SvR*lxMOe{Hb(As( 6Fhq M7RuZ(4k C%ObW?J!LJ_0VeK&j&cvI?iqLlM7EE z9XfI01V3#$1v-t56VVw{x2i6t6Z{3uO66m5MffhCu25#QsmGXj>wVV;hG55ry*OTb z1uy$M%pGgVPbUIc#Uq7?bb7hS0v @IhJCt=GW7d(`@zt% zZj wd5+C&J)4na@MYtt$;|y_O-5|l0_qdKp9T^={Lranp!i!c z0N?P+pI@0*DinGJ%G0?_mWIXTQiEhbC@i&hS9;}_+64@9W v)lcLnx-Ce47!)v>!sn#`|G-Dda*n0DfRvw!v#Zx=UxX#OC+%c_DzP$e5@I;ncJqN}s3t0PPE%KR!z1L}1vh!L7B z*c=I*t;o{8%6&yT9H;F9q@JtymVwaY&Sbi~ffsr`I$p1T0RX-nr_+O%9>+-c7l>OV zz(1m+^|}|p-JQj9cSpR?8vwyO#?9>o(CgySdi_f`cX0hP+gFcl(CHhHzIryt*N7<4 zaQI0$GA}*z?@5*hQwqx(^KF_7@5f`~#@}~S#>I}C|5i#pUSdPp;9vg-U&qI@POm!I zl4UpZ2U*tPY$>ra8xrmyQIP&Tq}uYO%t9J++5xa$xxGfSJV$9!<(cG0ORv!)H>vW5 zRM-?bcTe#sG&6jZGa4TB9CG4Z2%ia!6gTzd&kQe!`Cda?eF9IQ6=rFKWNiZXw>l9S zcsGu|i%q15{uk<-G%{%~V=+Xba%j^=A8*Q`unk?0ZOYsvsP0J`D?Mj{*777LG5=r( zPOmNBt21bwsazRZz6S;?I4wG5;hvun>uQt7&US cG$Y<3}gc0L&5sn zd*}n?&|IP~Ng`IlytkA4T+3{sl=UvHZGXFM_rtA%0 R{VDvL_;qY0=01YZ|&5- zzst&?#P?zn>^MkU3uoyni d*~XIE*`C@^p_Vsc!{Lc_dPeMC%2)(rUjL4IR%p0%N_ zASVqT!IkVv1UOAuoz0d;laL4uVGBb5i&)_G|1&B|$or(xlgHEGty#5u+X|Ce0xr2T zxTKZZ a$^Mcd2nj@6Xc G2U2X5x2jks=0 z18?io*8VldWxk?w{_%Etlbhq!!fls#Xm=r~3GDio2S^oyhON8WRKsKjUBIJ-j<_-- zG(iC@*`1XJK|{6!+-+>z`cwDX8#mT&IX|{N(~XsR_TPU_j5_}KWyg&%@s^mHkeDMl z4|Vgb7+Xl}1=M(fz%;R1S)r!8Rj8F*-UJ+{WA}TgZ+ocwAG|nt0x)NBgN!pp@|yIX z98 143TRaz8 K_w6rmDX=b zL?n78dL|x0b$ucdK_a+`Lu+-+Y|SAoab{m+-%KJFoZXzpi~;q4C_<#Y6&Wohqa*(+ zPjJNr-6|h|M2Hr>s|9z?g*o4f?VL}8m8-6Kvx$Ynj+P`_=l7mnAt;bK$d1Yf@#)p6 z4 v4-yr%d>^ Fs}=k$|v^x*f}LVTM)a_{UQHNi%J2%0jq2XBBN<>&zS41VU-f+|ef zPyW5?{ha-jGJWhmH1U4IF8V7eczXOEcjyhi4$H&lVGkBix1*F&_Vg6zWwQ`@_S-D& zC~`Fn(!D3N)AWX=djsn!ixV2YyroS?FS$o=Ma-VGN&9OY=cy8<>lGfJtFMRW6dlld z;ZJundu8gV$En1FKBn7wIp{-k3IOV^N=s|AwOkD)S7!TVAFCru+LLHRXq7o`$zcx3 zh#W?{KDnC~(6M(9e$738hE~p8EU3-3E2obaB>!ax|1%|(jxtDP^}(0ODJTBl4AaMd zLW?4wuFk6Cx>MYHz(Q`+>Gnr(fHo%N2 FQ_pIdj| zuSUp0$m1fRar1a`50ncfuO8C~q1i|;dq7Tv);!p%uS{=+>kEjU+|I~h!xc-O1gmiz zLW>AEc@1Tif0Zn0v_tkxLu?AqS4XT~Qp0aU;}qo9Ir2HL })8RwN0l<0MQ zR8JZDEH(B7#E85fOWr)BglSfTWeu^2HlHrTen6IPV^90IxZf6JmC8=Fk*oN^i@pt| zSX)qjT_l&22CqqR{zmDHf`}Omip#5 9D6=<89>bc|;ra|r!6uZd0vCr0QyL>z6LxN#;TCL8kuv_RPpk-_39<+-^##z- zqYNnNv#8j~h#0ePn1!K3!O4Ac=}E?DFm;VL!Is G`S=RHlEvvp%{GHGXazlxmRvXgB^hh>3$s3s z$)PzhoOL-0Lw%KX=2(gEzp3;z!r+rZ0-XwGs0au4>-78g!JCGSCWqZvozTKgcW8-$ z0$Tp+k_6SHvRpKT`G?!)?LPv3W0tsN$YU{QzI9|sfqPa@5X ^Zl^n=r(|y3>+vq=BiYeFteb~0&yFf_8h)7~@7_ufWd{3$S zYJc6;r0AGzPv5@Z+_ckvs?`FV=Z{U|%>Q02ZaFlNYsSZpO+Ejh1mvENi;B9MpP8ME z$@YyqT7R`9DxIIo%vKBk{0ae|WmPe&Be?R#e97-2xAO!I0SXAz1O^Gx!>F9)dOOHS z<49RnMIX>O+hWI`wqy@u1uBXNn#m=hlQr?a+0Jw~?iYoj(<|JU2JjNCs>}g)xy!UF z4rih%?s>AfrU{XwFu(a2rvyvY{+$*^_c0lWuDgPpTM*OL^Qr02F!t)mrXI4wbU7Mp zmrQ7#Ih-Rl7RvZr$Jz|fn(u@2{1`0i%j?shkBqxfbNH)~x6S)`v%j?XR=HV8(t@vh z? ?f&0{;eY^LQg?x0|PadS)wV$g0$8Ae*$#sQ)G)>>C_4{droRRD&pS8kmKUROH zADIL^l@0UWSW-JLdG#M#osth`o+h|S*8v4|k-9oL4s3{%23UV5qn{xu(1U6jki0Z+ zafLs%sV(n$9e##hHvszP#(HB>`|N@M1V8+H7&pOHr2Q8z4u2x|^Izzr>LwTNuBY;O z2OuP*M6efaHT~If07s{UKn?2mBazecz4%|huVcP5d&fu`#41 46 z*>ma5k}^+{jbP4)WKDqHtQ{bg$b=Rl6G^6|XGu#^umy#br&VmS!0i!Q6{fa^v1-iL zR`kNp{I%@cx#*RB;ns4OjK#q?*PPDN@tS05558L>B&^=dFhzJyC!b3U(?fA87Iu1? zaVy##9~D!F1OBZt@AdFF@;yh?ndAZw8&6D8EeX>jr-EghI=NXS4zYbo$Pu>lM{Ys= z 1Jqzv!Giapdw z(Oqk@5Qp597S3T#I*>k27cROPFLIRwqjreaKqu #f3Dmij3*Swa| z!)6@{0@Kz_o$Np> !KqFSaicpom^*>?-)pwQSw=zxCQ6|*bqK|6}_b{xP7!x z^f vas?A@C~?*5=GV{Jgs7QpOVdP)*v6XU&r5BB zk0l=Ym!MKv?97N=PX{q#A8`KT{vgUnm&*-r3J#z`1}?NUkMX4^J-toJla!tD1oh#z zL_Z@6!k N-T zPxchxZ~WqtpX_!7t4o;k{Si$hFWwjJFqhpjMI%O~gyl17Ct>tt92SFXjzm=c9T@ zYX&q=lOUKEJvi!{Q^8W7!j_9p0*^x=FM}Wb!3j*LM@+ZRIOfSEa|O%DrSzLKeo0dF zD)8f;2$E+9%9NsbVV++rw@v&xMtG{kA>H~ofHBZ<8cQeW6+NOSdtY9ZbXyPo41V^+ zkt|LpL;5wJ$i1`5*gu-cx{L<9JX44CxT2~Q^)LYX!#Y~i>lt>SO}Gjg bW=pEefkm7l_5`N#Ia{;{z7X5f)>b{EKKhQ-Xo=oNw z;;b3VliZ0=_1#}ofW!b(L*scSQoA7R5#%h1-*>XWJtr~CaM~9(70i;BvqT`Jaw~(p z9ioVwN6pp0jm S_$G*k<9Eg7-* zQ4l9d3Yk-BQsr!eBvnFtb8@6I 0oZ%agq zqBO#kuo4|EM_Fy-_ ) zcmRJfr72_3j@nLq6v92$3E`fq>4Yisg(dKhot7oA$(GBWzB>xvmGX@PBP-=lN4Ggr zoSB?xIVz-(GQhck&r~isKeU7@McudN_SAErjAxqr1W;pYca$afm7QU}v1uQRJ&RTf zU#2|bz}BX7Xk3FF>DDJs3_FoXAqD2#s fQ3&&rcxOU@xT~`YLwWA z)OhOcT}IgL0w@sqLczUn1_f;I6o4oZ%*>5N9sDg*J-(2*@B}QCv*`Wvy^a~10CO|=evs#`TYAFE+EO)0M0i|}+2dG`P7;IR4&!`2Kl{JqwTp~6x zg)~^Y6Hp+bgE>d_4VXh=(=ySV#ZZA }Uv3pt>$EN0F3N=S~C-jQOBpmyqW!0ZPDTtE*)GjLD8 LCw~Ixd9#+4x z8FRs9#5>z7kn5Ot%d=a)cb2*7hTj$V+Z*#0DO4P6&r*ZRR4A9Cw@Qs_wd(w(UW3^h zHEVL%2CZ7OY4_TMqcC_FE<*=|mxGZ12?}p$2qFPgc975hU+_W}IuwG2C2~<18mEl) z#jV8+4W#kpBn>; -oqZTFXOkSdt1(&-pg16QZ7hlSoCx5_up#(BO}R5jjj+hym9-EfS64 z>v1fJG_pyoGDL?(tAk9Ox7F@+q4vs3rnC8CiMPkML Ws(qT z;fM(pT>ueTP<1{HA%(bd=lGSAF*-AuEmoV|;Y=^fG~}mmiS7zl4kjIX^;I>((+$Yw z`Aa005Q9`ES146#+_9gTNGljj@PZ36g$k_p)CEG3SR$3l6-t#_gW9ojW{cHkcQ{>c z9;i8oXxzoc^5P);zWeGH>J>Borzo}uu=09xYs5tkAw1#i#he2>CKyvUZvl+{Rtt}& z)xudd(=ginx{oBOFq5~GCC8`l^a`pRJA!2PrXm_jrYoZp5Hdv^bBUkhyQw=O$eGkB zXH)E46PIvF&P?5$9yjzyc%ksKcrV>AqT&ZY_2Ys z@n9vwy)$w5+i%9U34=+gyk=$oO0F&@us e>R2!D7En=dfT)J!T8|T{eKWwR{M5R@m7n z&c<=JCE)sv*_7sU9oT|4wVf}4K!W*vs-0<*lj+jL9(Nt@jaFw0lrA8uTEY^U2b3;W z1i()0ENAD)Zvv=}{VEXHCMdA9O!6F|?a#fa@vypNK_9^sg%iqhLuQR@*Bg>nec~(H zj2Xblu9?uEE+yQYQ||JA&MXWx#9}pF ztGx}~T>Dpbz)#pL#L~|Gp`80EnxaeFg{?rRzb^dN@9eK wE;98&@ z;VW)U`F<8Z1trd}VTA&?=!P6d^mFL!K!1F35fKEa5%xxgQY%4gA`BZq#DEo05@M(X zL rYV%c0-{)n<4oAm>)jmgW>`e!A-bFQR$OCVewo_&y_1mc4KQT>IzsHpmQE!=; z5Gw_Ux{5%8T)Wa|Y>^*qMBu(8Yyt703kSNHUlF}d)?*kn>kjcMp$>F&%!^Js6-yif z-=Gwwi^HVHBxA?%8BiS}+ete}VZ&~gY@ObmK#A(n5Be^kAFW>+s5_jOKA@lJMt={S z9?s(|-kRXj`X{bF%GTjGxU$SV!kOINRJ=b9)GPf#4}F_NEVU~wa 7s2Zx6kN2A1 zEJD_DVIraP!u&-WhE4TGGHPheFbEx*u%UjXPI1>}Ib1t(6`?L+OFhx~07wVq3Z_*+ zhv~Ew+C`VrsefOSVdk!d)6*2BqTRb_It})qiLg<%D_F?TwUEn{xQV#cLZ$==5hm)M zGKdpePyiDNaPKQiBJL_ZU`_-U+^{V42obhn&^yj|e5H5o@!XQ0V<>>$yUUk)Qx0N3 zkN5PAJ$9(sZDstD4JB4)v>oRl%@1d^lN5K=!x=^Cn|vG52%dWAK~xaKC?O(1B=Hac zkmrDm1PH*sU6(8^$fX4>$e}qch@vi8+VoA!T0AP!h=#iUj1u@Wv3VpoQA{qDW`0;r Y>Ra`2z^)O dCO&lJ?f?xmu0E=<1RR910 literal 0 HcmV?d00001 diff --git a/webapp/packages/supersonic-fe/src/assets/fonts/TencentSans-W7.woff b/webapp/packages/supersonic-fe/src/assets/fonts/TencentSans-W7.woff new file mode 100644 index 0000000000000000000000000000000000000000..a921eb06b838f881aec2f5fa2d22c0a320043f27 GIT binary patch literal 5528180 zcmZs?cRXCr_diYqkti=DdWjyrM(?5rL83%if*^YDRtt&FYSBfD=q#e`CM2u(-aD(T zRaV<&_viij{` 0jamPbEJZfq@Jf?gi4_2t=8w2Be92gIey&MnE zauc7yUP;sVohqL3i6tJMv@agsr#gLan_&ZEVKF?s2c-A MreO=8}K2e~XZQ#8v_$T*r4EOZh>k6OE-PX+k&$un(UfvE5k1%6;dk^jD z;p2O6-}XJ`{vF^w$Nj<+^YnJ`yw_)Q&p-Mfc|O3W^8cSLZ(oex^BniYNeGEz_y3 B3_6QvW)6%`RV^%M~oZ9EZg z6tJ;b^zei1(!NQe`%nBDjkyt*6%o0`jk%)M5;h(Vc^3!M5NV_`QS(pPJ}>|Mn-uSf z?0<&;(|^<*kYm5#$9j3t{kXtqv^}K5v4iKbtbnX}eq|v>Z{3^rHnOWfy4~>I|HeUsnqD3rDS1W@curtRQ{|0mpaU zax>!1%L wrHl8y>{swss;cR*woFDN&OW ze_n6-8yEfJv}6*Qhe1*(u`Fx(W~}Om^8I?gW+{9Zd_DE&?WWShlsI9++KsQpGPfHx z&%5j=&;PuYemWexMoAhg{LpmgE_u>|J0)Q!^mXt{!^d^6YX1aYR~3ui))jN)lW_O0 ziS?0yH1yCsf6T6LiaA7?QJh%2|2`|(AI}goPk7{PK_&NbB5UCf`dFp<0*E;_%ubF^ z0ECsjIN3lCl-!@gjkOnHvbT}zRVOo(bya<|)NRqGWr_wwf*XwG020P1B~b@vG61 !C>n zrJMdHd0=p> *+zrm!MU~*b1nsabNjK zN06d(vf6}^^GxVfz{siYZpRoCuE!GBD6=ZrC!Bi~JUo$4%+re`t&8<|c>ln`e1VFV zPY(2gdzTqs?spriomg=zFkIwaVZBcB+pk +Yay;dw=+iWZ}L%4k4fR&5U3+;rgV21rTYQK FUS6+3)(CXp|S|mg_uLOh%Pzjj?AQ zq8=;YY|AK~7pQea`aauVN`(|0-{9bXq %i-O}0FMSrUbUF7LtzSlail}FEmMheNLR|+T z+v(F5QvrsXtu^H+Sts+Lqm~>L9W10hrLa$$zimkKHJSy4ZND)Hs=+aX6l2=acHCqo zN#Rs}IQQ`m4>BC@?13@&o#%d5&CEwP!TPBkKWQ&^c%~oPBO`pRZfZ|Qu1Nz3%g>%W zyvn+CC jy(~kupZJ{v&I{#*>;Hws0&hO~APKlrM18P|Q*~c$UNjn_zx`M_dFYXO_$*hE zi~}^>MJk+YzsP$ec77tozg32c%M9neGb{(}pxJzG1$}OdWw62JdOFaUt8n^0+-O*l zNLYc0o26KoC0e{$s5NHI!^u^qK=hpF#a+pUXz(B}y0ctK#BH8tRcvktWyigvBUOr9 zVDiXC0dqULos-w>CiAPNGR&)$=(}u=$v!K+MZdoOY@>KPvrc%9t%8q58*fz5+p)r+ zLf=mBTz0Rg%JrI8_36Vu3WQFa7y;j44fX?i2zw8Q^T1YUDAkb4WX%(W^j$r)d#_sP zAZmwk_x4>cb;exM6(h^XA=GK*$otiI?@4eTAb`()3fWk|VwaBsy7HqU_RxmywtYQu zgE5#iWd_twNS0RR6WEJ#`!=>|e=VT@Rex$OGlQ44+(0Jt=4VK`xAjL-a~3_*RoK zl;C{ZLWN_ ?<+X>2}c%=9j^E&-5_y5 zetN~@QtmL_50!64`gnbA!P+jnw-kD4J|Bo%GE&TWxy)2AxbaM{%08KXIpOtBsjAU3 znq_D#Ci=P$)L$8TE4v+LGa0LGvD;Daoe@HuDZd>&mM=BcEZ9|an(W3MMuxpB)REBv zMupzb*q_Re%9nQM9g>wClX1&s?|mT7$(65lN^e;utDap!+tS uCTAoJuX82#rT7tyw{Lc!jnkXuNOd#~lQBT!Qxz&9Yay$ j!iI}ab3-4n`JzZa_{=$30&s!jb2`xc^YG7FxplPMJCwc2oqk&+61Uu9EAz0PyV z-}U80Nap0(j=cWc)l8)OhdZIYDN<`&a*6Mu^=(~astfF0#&Nd{Zy-T6Lka7)gL~g} zZp!5GjbgmB-oz{`>#-ilu%A7WeLB*hMaycSia`;XRk42!6)Q$W`^fkikU z)(X2uew`uy1IIPZmh?6u^tF|)N9mn@Y28RBPzMwCu6%h%GOJ0_B#?}E$-R8JH58MH z%O2vrGq;c#ydXb2eo$n#t6llKkIS&g{ 3scci~jG03u8o z-c~LCh1gaNm<-!afRKxqlri0xyBXt7zi9=3mJ~p0!zPMK` Us(Ix|?y8jy0k`d2=``iSB)t+i$z zf^98QhrUdZd*b6r4rZsxTGJ}PQ(jq#)dUuLLJF&%OnkpB7b}~A+2P$j7lDP*+%edO zlf8o#CT4RFH|rniWu0IJ&X~(?CQY2Pn_g=y+OS}-RA^s@olzT7l<6Sn)u)qHv1G Tl>dG zvw~pT2W$T8c@GO6#+A-9{j<zTALRtaNgU2*KK4(A&S2#wKLV3D9-m^G9w{>$9x9 z0NUAHjqz3Harg2=K#yEXF@ 466V6cfng==96P60LX}-oF`|$-e_qxiBEe8n zKO(&hps?NTh)k}K&yOnAxUx}-Et~?Ku6knhVLwhzgkpE1@THTmRkVlAaJER@3YxpgD32>X32j)9Lt>>nc%MuYR8~Z=-G i~&QalF zcR@PwY>~djhSqx3LU9v%keGk)iT Rn<2!_QuB zbO}9J> Xk}m@I{tt_
ZoxkYOCD_0 zzq5#wG=)@=ATyQoB)t?L$x1&iRO@r$zs?fu=N67o{P@Nn)t0yvG&~nH-147K8~#lp zeu~ximyj lF5{pMDXFVtr8`AeKTadMy0b-ip1mKZ1qxO%|TrIm2rA_O+Aq71yw% zRa{4!1X3l}w0 Jq~#|hORF4dSeMcS^FU $I9|V-ynr z^H8}Iq%WdIv&ik&g)S^^^5Elmv o 3#*uf&$*p ziTHPric=hviwM_ce`zD{vDwX>fuxz3GDmq-g4kYAJU=(wGbHi_M|20XNPMI|XYR@X zPdq*V>&f?b{%%tyuMm5%9~YE(s=sNRECMjThO7 OcLaatB+n?OD#Mo#ldz5%@}L;aOr zNgI8IFRj+ zKk}K2 z-}yOJ3P XmC=H)#7qab)K{vlU_$tvL?kpaZy>b;e)U9~V*OP*4}sR ~Aw#o=@I4_)kjtYE1Uq*VepD6-!N}OejWVdrBPKHy*}# z{qmb#<@hmxm;n@Um j;Zsnq3c|IYA;ea&Ud)a6kY)pkY{Q4zj-WSm-y#P zChriIeQ0=F-C_8^BD*b82w_Oj?v*v0Pt=CXz9|=r*qac_79q+jSk;3qD*6g`knf15 z$QeS+HxcA-Dmf> t&@+Oo-ZFUN!FgOW0+px>+yar^!y)pOhUJ|$H zro7BirJglh4WD#VVG*`F{0TB1WQke2XkKsDk0^?8HJ^=O0sq-bbx{RWqV-DRk{XPc z@F|uf#g0EDAKS`@RZWiRbk>H45Z_%#{BLu5RC)_cZgC(*eIo3F6M~1tCMG0nc!!)U z`VAaX-oz;ml~}vYs}0+%a*6cOs7U4U-xdz97-o2Y><6+%X@yEH0iIo-QTud@aQytX z;xXZf*|Cz<5irq@qaQHDAH*HM(~#BCAK~I|16f9DbKqNuS&E-&-@I;Fk;TK>{t~Oj zMguw(a}S%uGApd=6@{~Viwa9g@CpbHCG4uUd+oO|RIDI%su1W~B4svLW_4hgEOZh` z2v!pun68|d?S*$*A5jNPtaa0wYD(yLipJ84R?bLbC1)qa=_>Q+s1tJPIf_lWGH&GI z?*vDe46*F9D6%%1>SL?LVv;?sT;$6iy&|wr uOE&cVlVZXj5~33PYL} zq*Gr=GgwJ}3;q>ca$sKQ<70AN>c=CTg|$*svg8WeD+5VoxY3m(c~-DGFhi+ 6$jpYC6v8#P*bXUiXj9LJ42@_8_;0Z5~`hd)>+ z7L%@Uibt-htl~a3VZxtXEORT^Mu;+$u#SER B`PqF>T`%Q{!u4lkIp zas0trUefZVFmSM_-L$xmONC*xK%Lo&d$Y#Qz2r geociQ~LT}kbqs%^hG!&>YQq} z->RnZ(5W)7e~S|AlfIpJ_X_GOw5+-?x``fZbXR(i8?udZnY>?V@qfK}L?1uxkcpy+ zE<2nEGp0b$XNkbvKXgk|blyFhqg-@jJ$EGZ@xbc}Qh=pTqF*|KUWBEoFU=Gu8NuiF z8tUu*NXvdbWwcH7Z hg?D+uws`qW` z8B#2+a@?b%vPc<|?|oQ>a;CWpi$Q*x;E4v)Mw6wL``Lka3nD{(R~DjmWK2%#o7XX_ z E*WH5;HzM5~cUw(qC&(@<8|D8k3OGV2 z6;M8=DuuL9TJjFoaZ!@fy3kfOtvjQd0dy5Dn)=oA(}ln}%;jvUIefPMbKnZ$GnaZW zyhbvN fuh0Wb812P1XkM-_rotk z29oGCks_v&%yu|Xx~}j%CG({RjoW;@_v X=`fIJi@$-<#9-^2gKzwA|;@M=LS;S6gV6Hj}|l>iInR WB~aQ z x*7cq$O*?&)y-Id$Q`ULuQMpA_0gyKi32w! zWiJ;R%)W2x%Q$_~$>fX+0J#xwm(EtGIOKHy;Mk^RU*k(TH!xPPnd7>H==gs^tT$$k z) =@HL7Os2A``E0$3cNdg) zd2SHNJy(kSqzrV-?}mayh-amCr`Bm-AgV*Uw8z<2_G)Bg3bqS8n*zU8BLZjD#b#rg zNsQ#4?qvE33!MY0++>p)m6E-B{ew&k3Tj)#qpZ>s_tb0rnw|DIz}gCzZxz Ll?e0Q#PTAMN>Aabsq_vy+Swy2qDGO4OFxH)*% 2_;U~n@atNY?;6cZ%uft-u5WlCSg3L zqiVHDOOY?-d#$7huvI&JIksaaeQlg=-%dZR8>x817HjWvEr9NtUBC`P3C<8xjVro) zPu5$c1|WNE>5*~ZxhH?JTV$XVZsPP7Q{cWOf5_X#zFFWY3Ec3^DS?1Nyu}*l2O2Gj zoc(FOcgW#Z?W1w0+$kzFEv4Z%4a!j(SBTf^`M&k1jJYzkPpSma$TA2Nj$&0V7|P-H zMgl&_3lx)0NcA8sIlry`H~0~zvl#|1RNTAd6RQ}zUvJp=kpo4mhX$u)MYPXiNp1h;%7|C zCYopznbi=`GFJ)5dacRh2cN^kuv=A_z&+079SBZsTCLBYwZO#)TgmL=BexP)vr;H! z>-uB$`0>rIWIFS2w%xblPCAnd5s#97CGSzf1|=>7!@vfI>`RX?td5BambffD;ML_t ztiF 2_e}CPK)34UDM|j0I;VgRC<5 z^tMAL;GrGJKqbA7rc}5e(fQBVTT@>*?KBERU!w+?o#NVk=z@P;+<% e)>j;#(lU|05?{97^H4tV1+lp%+=RkW$x!+tP zO#4T}m?bKUW|zCRjB6?O9-bX@tUbN<8>GA}J8FBrrGLjklV9`BsYftzpa#VDQ%D1& zg|=aJYf%PQzq)ncS#&7cCJCwx$O;1_Z~w6yH5or>ZtX8>CXr-ru{UT@cj!j=W{SC6 z{2brr9!}6tEC}9oWRy>Ql35=U!&c(Ut&&6K+=c|5bB^F>zSHCHTBIK>e3EyKPrZey zeph1a23@Wi^v1RkBRW!o%Ka1*Zf5tL8ZW#Mp4cbe^`PUc4+4HvYpZc~!mzU4N|ypO z?*a7v7vi_(UnV{OnbDVZEqXy2aYj%G(R `RwbP1_$yNfKesb50$TmMBX$<@eY-bjKXUM#-jcQ@1=6ezF$1B(#Ji=E zCE?#&t2wOZk>3k*(Vk5Itd;vdk5(Ci` YTO-j|9~)XFu+PdqG689us=3k?YN& qcblkU=6aqj>1zi3{KRsE=1<6@-rgz&779}l(%zOPZ-6>*xhlP3#U+6Cr zn<1)>!i1>zDLw?ftM+ICtBJ`9^<_;d4SD6=68~cINCPGoIcBZSfl2A_{SWxrY(VsX zPMv6qi)dgt-fi#m8`7gxOEtGOcQ(Nit7%iaZ^vu0+=5f*BX+9`%DB}iy&=6pjG%mU z&D#TUVkN0-) Skjk@5GRM5~v*r2sWn%kzoY9MZl4Je` zH+b7WnE#qOzDNq0qhD;pAd}P}OK;Tmi;*pp-7#1C@X>O8-#W#_@N`8Zru0QVBvbJI zZ@Jw8NQd%%#4+>4m3k$sVJF35TbMFtji9Y{sf7iNzu>5Vw^Y@aPf-!-lQ&wm8c*SL z@!+Mt#s@EQibvJR7o*6(u< MmtT>* zR3A;YQJemEztq=`Km|?c0z}Z*6W>CfuE@@Ef<+%%_%GeD0NydH{@X=n4LqO=;!S{a zSH=%komT|pKk6_NqvsOtHg- SK7%3 z6@NkpLvF(r!-c%- D4*)F642qgJ?tQLhb%+`A8N+7g3vLHNR=T4uOwh&6_p@iWLIlx5nd_ErabRu2Q17 zI@u-be@ jJ}P1Re-)`%Tb*sUsQNv0UbtW`r+n&}RC;JL<8 zCzL w{byLS;OPr?Akdk>_vD<((N*hu&1 zR?DKD;Y#47imDOtT}5}9B+*oWwm?zN_2WUUV{V+ZzJ_>kHnQ($hF1^hiJoattMZ&( z-)(QUu%6)(bM~*WKIGQj7S#|4wfZAKF?hI{PkXjO9{#?k)H%rU>XY%Yz8t|utqvWi zdwZ^25|K?pYliU6dj2GW;>!hyj#J_9bNjEs)+uPPEm^F)_AZ=2Kjp<*5lj))3Oap{ zhQ2;a*E=Ju?!9?FFfF%gJ1MiODp8Vj+!6!{wNCecSOJ=e^!jvGh^dP7_4MQP(GNji zrMfaJ;w|?v-N?* wxFeI+4f8+ON6sfrH$w(7bJsK5!8nmGz8jn&9z z-MU ktS|^oa>64qX2PT7H6kw`00AYH~#0{=Fz3 zEQAClg+=-{zmMa*X$x)F7S+7NumFA|KDxD356E2pT$Vfj7EtRg#E;x`gt&9mcnhnv zzKM$|*uDsBY2qzxpFY(dPbH~YqK4!68}8^h7?&0HLU>%Rn`qlgcF-zC_Wo(r53 zJ2! ZR?(cH3;sb5W<?BBrZf|2L&QIgxk2e67sgMX6FT*Kw~ zw;b%4-<*i5r%x24mQi|TZOQ=X_6m+_@yM;r;o4@EUFmn57SYeM9Cn1->?2`cGWp=- zP(tr(Ax#u2b(>Q?U9+Kvm$*ALqQjaqANur?c&NYm&xkH2H1?7&Zxj|2_6bo);H7Av zKONX%il`@DsrK^v?}K;D$0m=TY?f_c$F;I9_d(E;ne?#O4_R~RIH^Pb u aGCqP z)+?mF+l_9g>2G7>>{iV^GBe`LTjIzCeHpT=MLd}@&g|vv-|c=C97j4q{O{}QRH3a@ z*KKME@{}){Rps+vUsPUjMAS^6$14=DKfWHl&HYiE%LD b_N<3O=u^2`dIz_hZQ6eoLf2a^~i+fNt%y>)Rz?7xTn9bjK{Fldt z8VMwqIM>t3`vpB}cxS&XL0wn~ 7;+DV`^-mvY|qQ|FI)9&eBM+l<{u z=lq(IO;+|kIoyCucGzEmeScZyEuJ@Vl#`5!hBbv=N4lSw-IMz7M`t~LToB*+!$w8{ zgxV3IOC{PCoQ>uYlFO&0X9dMbN$V?qKiKjgs@03vbG$2x$m2c4aGw&IojY`|vC(T$ z4}3Nr6*3!~j0vvps(XeDqTSs@^uu~GaHt8UccDo9@qd~x+~X&gsIK$F6HB{#IWqmN zRjfP+EPl3s=oIopau=nT^q>%Itlu7Pbo@kK<86?Z =rc@d!(??ksCl{wUb>$31$=(;})wG l@x?3GpB^ zZv3D4oBZ@J&bw=F5M2v6qjaGyr5gjh`d0BZZi&nCb8wHy0l~@wH&Cj{DpgVeDN-dE z4jvurW8O{thxpN}7#wju$g!tZa;~|kxbuO%%2M?J(^a~YmCe%ICYU^zA!Fu=Qp1YJ z-E?Rino@7134)eOl0#`XI9!4zyIj `Bt;~u|JJfGsB0CKmWtMD%3L3YKXcy*G z1F<9f+AvMBjT#RsZpwci4S|WWlDXPSi`yat0^B1+gQc>76WN|A2^sU2VTzqSS(2-d zB)*z%zK$wV&m1?O4k~_?&s&lG(KuC>=%SzPeBpLj=3~tP+>*F4;+oi9vbXR{K-H J zzq%vFN2p+xu&46$S6t)2%sMKc=8|;jbyi9zG|H@taJUI%$qbh(?#cZ`aE2|?{ @$uY8A=u24Z?6v)c)V0VNbJ$^Il10Wr8D&Sj``F5qx9 zc6rf|#a5q5W(Az#Natb@D*^+76_IHIRKacw&2`d8H1yd)lZGFJ1(8=WuJ7oTSUCjf z1YM}ya{SFm&x$njAp#$#e#O81FmC&=f3d>t=e0q|-!V8#>)eL6Gn0n-Rq=VoDY+~0 zzq#hi>&V`L<{VIMu`z?e1G6bn#!7~saB}B-z5>%5-?;P4#=z%lF 6=;3t7Q@M8p%0vwu58D^D*jPl$hf^TGnPWk w5;a#`uYFUJPg z%t=cnHTeZ0lk)%g3}r1fB^v+i4>&BZc{|Kr*ED^E?rheYg>KfAwohUipigA^>3hR| znEq)=uylbIM(7zQ2i9@cHt+Yt;Kl_lJ5SDHUV0CVX!8!4$M^cOAVlJu0^~wik_ukj zO+^JQsQNmmY@#kV3mh91`B}5rgD%)_stbve7`QO>>jPQ^ `CRtdsNi2)k@`U3_WzN@ !^C$k?I&?uV~WZb@0VhB3jDl|kS7}h zA!E&}0St3K!vo%&wN!N*CB2B&y?DXg@AJ7N-$CZ_QxZG-eNFnuZeH+n`w%hp*1M+$ z{Rb^#UiVwwgg0eoSxbMX8t?XK>;dmD_0Fh&?gE>&Au@SpofqF0n|9&Mt zt9zEm0$0eQ;@R4ZH%y(>EO&XFU9myqO@#SZ)D?couDtUsemSGhrnt1P((QFkG(|u9 zB9PzDD-QgfX5;RiH1y1cxKQF9kgufrrI{v1K8#qjxZFx@Gf&K`p#B1?6DSKWJ1=Uw ztat4Lu`?Se?DNg9)qHhj&h6J=S8>oSS$RvmsujXtYZqOeBJc7%I8b@VA+OXu9Z1Yc zEB^(fW*$ORAeGkK-Jody-r$qcp?JWT;MX)}(c6$$pbF zww~iUFS )aNu8Xi)p z29HvMWKg_JiDb}|QSPz9D2h$Vpv9D|Ru(Fl$b`=l1>r3LO6_1O0kcP<^jzDH)C>D? zO!hf$`@urji%ad=Dd9u;CVwX09%XK*m `Gm0 z#Z#0%!iTI$t%>mK=HI6Nj^$d)=%d*&6kJ2_jkP(gL3QNSF6q{?$==6#gD*V{jaCBr zZ6otxIS(!)79+JV!qIKkem=&5Bj|ouL=(!c|DS$qV?9+&o;;DY`qqV>rqJl+yWy&( zd1Q5R*uyP@t@qWpeyOgcYyqu-3x_c~E2_a?xofBsuA#8UHJ@ul^a9J0^r81>7-XYH z|9%>$$0lp<*y(zTKGs8@uYWj`ib}8@U9RT8+iPIEb^~EKUA1C1QsPM^vdu_@xHJZ( zPyc9sFQN*qQ4-q^c+J-*Z%(1aU`et@YAv;Pe;7mf593B(bS3AV??Ot2yaCmk`y_JX z8sQb16cCIHH@aE+v w2+eBx3%^)tEZ1I+~F&$XjK=*tzf@E ztBu{6HYmKOjP=1<`rmoobiLp2=8OICmgsz5oJx&c6x|;WAxs_!-ZW-c;@!Jy=Dy1f zx_r$=2=GWwd7Cbep@g5Y`d vB$!bH$fehzE}Bi#KDEPSu|eV%D?h>c%kAiK)51x zVOH4l9mn_C)hy)u?6zSCH-v*Be=uX; N9OLK*@2vjO;X z=Wl6Yf(qJhGujT)(H`LZxpnbdyu}TwyM(24D%eTTyq429VdDkSI!+~c$+p$MkKL~j zV67|gFfGa6yF*{fz9;LBV@7!e=YxwnYx!LA>;LQ;0Aofh0v3gp_n`r4**)78AtNi{ zz@06}y?y4|y=RqiSs|vWVEOFst7mQ6MFr(vXL!d2+~(I@40Db@x?Ae&jjX`k!V_(# zPT`ia6$-*Dgi6=plQOvgd741iu_@`!*GRpo`3_|?T6dLBMmMa~Yn!|~C?IY3GN|6| zTWo%5qhBU$Oy-Q%XxXN2$lN3O6Tq6Q10BI%q)^DiQ0C(~VQV^cmCdWKo7MnH{*tZu z07(CzHO}pfWG*Koey;p>PXP9ZF)fMS&EeXoSkxdY+43^f4~Q4|S8bGBH}r#S>Rg|4 zUU0$c+gY&jQ#p1ZYn3MuNwQ}798j#c$gx`xIt=@=s=$qiTw~#WjTG2d0(^CqcjVtP zW*U*7*i8_sh`2C3V8`4=O)d4eoiwL<>&tXLbkWo~E%|VXqE1UXb!ilz(L7zT- ;SKqXD3G`Dq^Mcx(BPf3Hdm(q%xOSY?2Rogs z(j&XH1j5J6kx4kKzjvU~zR|%0o47vFnp%Ug &44wia566 zohf*VOGe#qe+@foXZa0=lQ5|U+C1*NujtY%IZ{Cx*7MMqJ}pHF73AxvHq*PACodA} z +)sPsluz^Mo~vbp*t_a^DEmPaTXrezs+R^c^AGOQ@*um3?<*%BiO%QY5mD_-X6WM z;RS>D%eC(Dn&bM?VpD-xFvXqtIDqJ@pekI3b--khQf7PPcFc-zo!4@o)|~9?;3+m_ zHzgV;fUUi%bUG%LU3%=IdnMGR^i|Sy_-k`n+_vn9x{!4dL@r5^o a&@LaBR>=i^DIY*)v #=tD!ESp7ZTP) z?6jsiqJG57vLC%dG5yDJh?moj_BppcXwizdu-cGI!tYDBMfyDxGY|w@CkX$H+LdQX zFlk9<`zYm^@K9@et1geNNWjE3Q)$QaR3MY5q=zK-om7%lrZL#g^?W(6SX5q5GFxq0 zGQLDKx(SY<21EFWu1Pl@fT{fB3n|h){KWSU(fQqVDBD8?Peb9!ptGESj-O?^zSd-O zq3b!wgH11L0qm;I_J=QXhObHBscwn$r27`R1!E;iDaF$DB$J?WZ9rDtrslG$|HjL0 z>J=^7Hlj}{40}Tk2q%d#q8?RUYM5T(QH~1 S?<`v_Q z6}i$t%PJzYBjf(c;t%ql!fusaMrDpBi#4KxM%%j9Tb@mB5I dgZWhx+1YHjzn_lVA^^cr7q zb^g;uLtYRBZe1M-vtq3E5PZ8zekP23-uY&PXKMp72RnTnb38M_q(!M0#*9gFnHFLj zxiIW`CT%srJh-SxUdX9p7Gq9ZZ8=$##yq1Kc;N5o;v9B0rfgCd?3791d^9a=J7O7A zze*FBAID7eec2eOkXfr2>A1=slyk