From 8db7edd5fd555aadcd6e3d747bff9ccea2fbffb5 Mon Sep 17 00:00:00 2001 From: bityutskiyAO <38612782+bityutskiyAO@users.noreply.github.com> Date: Thu, 8 Aug 2024 09:34:27 +0300 Subject: [PATCH] feat: create themes page (#216) --- next.config.js | 2 + package-lock.json | 782 +++++++-- package.json | 24 +- public/locales/en/common.json | 1 + public/locales/en/component.json | 1 + public/locales/en/themes.json | 35 + public/locales/ru/common.json | 1 + public/locales/ru/component.json | 1 + public/locales/ru/themes.json | 35 + src/[locale]/themes/index.tsx | 38 + src/assets/icons/gravity-ui.svg | 24 + src/assets/preview-card-1.png | Bin 0 -> 66923 bytes src/assets/preview-card-2.png | Bin 0 -> 91862 bytes src/assets/preview-card-3.png | Bin 0 -> 89858 bytes .../Examples/components/Showcase/Showcase.tsx | 8 +- .../ClipboardArea/ClipboardArea.scss | 8 + .../ClipboardArea/ClipboardArea.tsx | 1 + src/components/CodeExample/CodeExample.scss | 57 + src/components/CodeExample/CodeExample.tsx | 38 + .../ColorPickerInput/ColorPickerInput.scss | 20 - .../ColorPickerInput/ColorPickerInput.tsx | 112 -- .../ColorPickerInput/ColorPreview.tsx | 15 - .../ColorPickerInput/NativeColorPicker.tsx | 18 - src/components/ColorPickerInput/utils.ts | 16 - .../IconDialog/UsageExample/UsageExample.scss | 41 - .../IconDialog/UsageExample/UsageExample.tsx | 24 +- src/components/Libraries/Libraries.tsx | 2 +- src/components/Libraries/Tags/Tags.scss | 32 - src/components/Libraries/Tags/Tags.tsx | 40 - .../SelectableCard/SelectableCard.scss | 31 + .../SelectableCard/SelectableCard.tsx | 54 + src/components/Tags/Tags.scss | 16 + src/components/Tags/Tags.tsx | 44 + src/components/Themes/Themes.scss | 69 + src/components/Themes/Themes.tsx | 102 ++ src/components/Themes/hooks/index.ts | 4 + .../Themes/hooks/useThemeCreator.ts | 6 + .../Themes/hooks/useThemePalette.ts | 36 + .../hooks/useThemePrivateColorOptions.ts | 15 + .../Themes/hooks/useThemeUtilityColor.ts | 30 + src/components/Themes/lib/constants.ts | 333 ++++ .../Themes/lib/privateColors/constants.ts | 289 ++++ .../Themes/lib/privateColors/index.ts | 1 + .../Themes/lib/privateColors/utils.ts | 98 ++ .../Themes/lib/themeCreatorContext.ts | 60 + .../Themes/lib/themeCreatorExport.ts | 194 +++ .../Themes/lib/themeCreatorImport.ts | 1 + .../Themes/lib/themeCreatorUtils.ts | 869 ++++++++++ src/components/Themes/lib/types.ts | 130 ++ .../Themes/lib/typography/constants.ts | 214 +++ src/components/Themes/lib/typography/utils.ts | 80 + .../ui/BasicPalette/AddColorButton.scss | 14 + .../Themes/ui/BasicPalette/AddColorButton.tsx | 24 + .../Themes/ui/BasicPalette/BasicPalette.tsx | 61 + .../ui/BasicPalette/PaletteColorEditor.scss | 56 + .../ui/BasicPalette/PaletteColorEditor.tsx | 83 + .../BorderRadiusTab/BorderCard/BorderCard.tsx | 32 + .../BorderPresets/BorderPresets.tsx | 49 + .../ui/BorderRadiusTab/BorderRadiusTab.scss | 15 + .../ui/BorderRadiusTab/BorderRadiusTab.tsx | 34 + .../ComponentPreview/ComponentPreview.tsx | 23 + .../CustomRadius/CustomRadius.scss | 28 + .../CustomRadius/CustomRadius.tsx | 74 + .../ui/BorderRadiusTab/Showcase/Showcase.scss | 27 + .../ui/BorderRadiusTab/Showcase/Showcase.tsx | 127 ++ .../Themes/ui/BrandColors/BrandColors.scss | 65 + .../Themes/ui/BrandColors/BrandColors.tsx | 104 ++ .../ui/ColorPickerInput/ColorPickerInput.scss | 34 + .../ui/ColorPickerInput/ColorPickerInput.tsx | 139 ++ .../ui/ColorPickerInput/NativeColorPicker.tsx | 35 + .../Themes/ui/ColorPickerInput/utils.ts | 45 + .../Themes/ui/ColorPreview/ColorPreview.scss | 35 + .../Themes/ui/ColorPreview/ColorPreview.tsx | 22 + .../Themes/ui/ColorsTab/ColorsTab.scss | 12 + .../Themes/ui/ColorsTab/ColorsTab.tsx | 116 ++ .../ui/ComponentPreview/ComponentPreview.tsx | 37 + .../ExportThemeSection.scss | 11 + .../ExportThemeSection/ExportThemeSection.tsx | 27 + .../Themes/ui/MainSettings/MainSettings.scss | 28 + .../Themes/ui/MainSettings/MainSettings.tsx | 152 ++ .../PreviewTab/CardsPreview/CardsPreview.scss | 26 + .../PreviewTab/CardsPreview/CardsPreview.tsx | 59 + .../DashboardsPreview/DashboardPreview.scss | 18 + .../DashboardsPreview/DashboardPreview.tsx | 80 + .../PreviewTab/FormPreview/FormPreview.scss | 13 + .../ui/PreviewTab/FormPreview/FormPreview.tsx | 82 + .../Themes/ui/PreviewTab/PreviewTab.scss | 65 + .../Themes/ui/PreviewTab/PreviewTab.tsx | 249 +++ .../PreviewTab/TablePreview/TablePreview.scss | 19 + .../PreviewTab/TablePreview/TablePreview.tsx | 148 ++ .../Themes/ui/PreviewTab/constants.ts | 1501 +++++++++++++++++ .../PrivateColorSelect.scss | 31 + .../PrivateColorSelect/PrivateColorSelect.tsx | 145 ++ .../PrivateColorSelectPopupContent.scss | 71 + .../PrivateColorSelectPopupContent.tsx | 159 ++ .../Themes/ui/PrivateColorSelect/index.ts | 1 + .../Themes/ui/PrivateColorSelect/types.ts | 9 + .../PrivateColorsSettings.scss | 31 + .../PrivateColorsSettings.tsx | 81 + .../Themes/ui/PrivateColorsSettings/index.ts | 2 + .../ui/ThemableSettings/ThemableCard.scss | 51 + .../ui/ThemableSettings/ThemableCard.tsx | 73 + .../ui/ThemableSettings/ThemableSettings.scss | 28 + .../ui/ThemableSettings/ThemableSettings.tsx | 52 + .../ThemableSettingsRows.scss | 20 + .../ThemableSettings/ThemableSettingsRows.tsx | 45 + .../Themes/ui/ThemableSettings/types.ts | 10 + .../Themes/ui/ThemeCreatorContextProvider.tsx | 384 +++++ .../ThemeExportDialog/ThemeExportDialog.scss | 9 + .../ThemeExportDialog/ThemeExportDialog.tsx | 41 + .../Themes/ui/ThemePicker/ThemePicker.scss | 12 + .../Themes/ui/ThemePicker/ThemePicker.tsx | 47 + src/components/Themes/ui/ThemePicker/index.ts | 1 + src/components/Themes/ui/ThemeSection.scss | 24 + src/components/Themes/ui/ThemeSection.tsx | 25 + .../AdvanceTypographySettings.tsx | 166 ++ .../ui/TypographyTab/FontFamilyPicker.tsx | 456 +++++ .../Themes/ui/TypographyTab/Preview.tsx | 180 ++ .../ui/TypographyTab/TypographyTab.scss | 154 ++ .../Themes/ui/TypographyTab/TypographyTab.tsx | 42 + src/content/menu.ts | 4 + src/hooks/useOnLeavePageConfirmation.ts | 33 + src/pages/themes.tsx | 2 + 123 files changed, 9762 insertions(+), 448 deletions(-) create mode 100644 public/locales/en/themes.json create mode 100644 public/locales/ru/themes.json create mode 100644 src/[locale]/themes/index.tsx create mode 100644 src/assets/icons/gravity-ui.svg create mode 100644 src/assets/preview-card-1.png create mode 100644 src/assets/preview-card-2.png create mode 100644 src/assets/preview-card-3.png create mode 100644 src/components/CodeExample/CodeExample.scss create mode 100644 src/components/CodeExample/CodeExample.tsx delete mode 100644 src/components/ColorPickerInput/ColorPickerInput.scss delete mode 100644 src/components/ColorPickerInput/ColorPickerInput.tsx delete mode 100644 src/components/ColorPickerInput/ColorPreview.tsx delete mode 100644 src/components/ColorPickerInput/NativeColorPicker.tsx delete mode 100644 src/components/ColorPickerInput/utils.ts delete mode 100644 src/components/Libraries/Tags/Tags.scss delete mode 100644 src/components/Libraries/Tags/Tags.tsx create mode 100644 src/components/SelectableCard/SelectableCard.scss create mode 100644 src/components/SelectableCard/SelectableCard.tsx create mode 100644 src/components/Tags/Tags.scss create mode 100644 src/components/Tags/Tags.tsx create mode 100644 src/components/Themes/Themes.scss create mode 100644 src/components/Themes/Themes.tsx create mode 100644 src/components/Themes/hooks/index.ts create mode 100644 src/components/Themes/hooks/useThemeCreator.ts create mode 100644 src/components/Themes/hooks/useThemePalette.ts create mode 100644 src/components/Themes/hooks/useThemePrivateColorOptions.ts create mode 100644 src/components/Themes/hooks/useThemeUtilityColor.ts create mode 100644 src/components/Themes/lib/constants.ts create mode 100644 src/components/Themes/lib/privateColors/constants.ts create mode 100644 src/components/Themes/lib/privateColors/index.ts create mode 100644 src/components/Themes/lib/privateColors/utils.ts create mode 100644 src/components/Themes/lib/themeCreatorContext.ts create mode 100644 src/components/Themes/lib/themeCreatorExport.ts create mode 100644 src/components/Themes/lib/themeCreatorImport.ts create mode 100644 src/components/Themes/lib/themeCreatorUtils.ts create mode 100644 src/components/Themes/lib/types.ts create mode 100644 src/components/Themes/lib/typography/constants.ts create mode 100644 src/components/Themes/lib/typography/utils.ts create mode 100644 src/components/Themes/ui/BasicPalette/AddColorButton.scss create mode 100644 src/components/Themes/ui/BasicPalette/AddColorButton.tsx create mode 100644 src/components/Themes/ui/BasicPalette/BasicPalette.tsx create mode 100644 src/components/Themes/ui/BasicPalette/PaletteColorEditor.scss create mode 100644 src/components/Themes/ui/BasicPalette/PaletteColorEditor.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/BorderCard/BorderCard.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/BorderPresets/BorderPresets.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.scss create mode 100644 src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/ComponentPreview/ComponentPreview.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.scss create mode 100644 src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.tsx create mode 100644 src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.scss create mode 100644 src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.tsx create mode 100644 src/components/Themes/ui/BrandColors/BrandColors.scss create mode 100644 src/components/Themes/ui/BrandColors/BrandColors.tsx create mode 100644 src/components/Themes/ui/ColorPickerInput/ColorPickerInput.scss create mode 100644 src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx create mode 100644 src/components/Themes/ui/ColorPickerInput/NativeColorPicker.tsx create mode 100644 src/components/Themes/ui/ColorPickerInput/utils.ts create mode 100644 src/components/Themes/ui/ColorPreview/ColorPreview.scss create mode 100644 src/components/Themes/ui/ColorPreview/ColorPreview.tsx create mode 100644 src/components/Themes/ui/ColorsTab/ColorsTab.scss create mode 100644 src/components/Themes/ui/ColorsTab/ColorsTab.tsx create mode 100644 src/components/Themes/ui/ComponentPreview/ComponentPreview.tsx create mode 100644 src/components/Themes/ui/ExportThemeSection/ExportThemeSection.scss create mode 100644 src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx create mode 100644 src/components/Themes/ui/MainSettings/MainSettings.scss create mode 100644 src/components/Themes/ui/MainSettings/MainSettings.tsx create mode 100644 src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.scss create mode 100644 src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.tsx create mode 100644 src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.scss create mode 100644 src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx create mode 100644 src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.scss create mode 100644 src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.tsx create mode 100644 src/components/Themes/ui/PreviewTab/PreviewTab.scss create mode 100644 src/components/Themes/ui/PreviewTab/PreviewTab.tsx create mode 100644 src/components/Themes/ui/PreviewTab/TablePreview/TablePreview.scss create mode 100644 src/components/Themes/ui/PreviewTab/TablePreview/TablePreview.tsx create mode 100644 src/components/Themes/ui/PreviewTab/constants.ts create mode 100644 src/components/Themes/ui/PrivateColorSelect/PrivateColorSelect.scss create mode 100644 src/components/Themes/ui/PrivateColorSelect/PrivateColorSelect.tsx create mode 100644 src/components/Themes/ui/PrivateColorSelect/PrivateColorSelectPopupContent.scss create mode 100644 src/components/Themes/ui/PrivateColorSelect/PrivateColorSelectPopupContent.tsx create mode 100644 src/components/Themes/ui/PrivateColorSelect/index.ts create mode 100644 src/components/Themes/ui/PrivateColorSelect/types.ts create mode 100644 src/components/Themes/ui/PrivateColorsSettings/PrivateColorsSettings.scss create mode 100644 src/components/Themes/ui/PrivateColorsSettings/PrivateColorsSettings.tsx create mode 100644 src/components/Themes/ui/PrivateColorsSettings/index.ts create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableCard.scss create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableCard.tsx create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableSettings.scss create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableSettings.tsx create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableSettingsRows.scss create mode 100644 src/components/Themes/ui/ThemableSettings/ThemableSettingsRows.tsx create mode 100644 src/components/Themes/ui/ThemableSettings/types.ts create mode 100644 src/components/Themes/ui/ThemeCreatorContextProvider.tsx create mode 100644 src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.scss create mode 100644 src/components/Themes/ui/ThemeExportDialog/ThemeExportDialog.tsx create mode 100644 src/components/Themes/ui/ThemePicker/ThemePicker.scss create mode 100644 src/components/Themes/ui/ThemePicker/ThemePicker.tsx create mode 100644 src/components/Themes/ui/ThemePicker/index.ts create mode 100644 src/components/Themes/ui/ThemeSection.scss create mode 100644 src/components/Themes/ui/ThemeSection.tsx create mode 100644 src/components/Themes/ui/TypographyTab/AdvanceTypographySettings.tsx create mode 100644 src/components/Themes/ui/TypographyTab/FontFamilyPicker.tsx create mode 100644 src/components/Themes/ui/TypographyTab/Preview.tsx create mode 100644 src/components/Themes/ui/TypographyTab/TypographyTab.scss create mode 100644 src/components/Themes/ui/TypographyTab/TypographyTab.tsx create mode 100644 src/hooks/useOnLeavePageConfirmation.ts create mode 100644 src/pages/themes.tsx diff --git a/next.config.js b/next.config.js index dbb0599cc440..515f6ef41321 100644 --- a/next.config.js +++ b/next.config.js @@ -5,6 +5,8 @@ const {patchWebpackConfig} = require('next-global-css'); const withTM = require('next-transpile-modules')([ '@gravity-ui/page-constructor', '@gravity-ui/components', + '@gravity-ui/chartkit', + '@gravity-ui/yagr', ]); const plugins = [ diff --git a/package-lock.json b/package-lock.json index 88cdc542ef0c..ffa0189c77cf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,12 +8,14 @@ "name": "landing", "version": "0.1.0", "dependencies": { - "@diplodoc/transform": "^4.11.0", + "@diplodoc/transform": "^4.26.0", + "@gravity-ui/chartkit": "^5.10.1", "@gravity-ui/components": "^3.7.0", "@gravity-ui/date-components": "^2.8.0", "@gravity-ui/icons": "^2.10.0", + "@gravity-ui/navigation": "^2.21.0", "@gravity-ui/page-constructor": "^5.2.0", - "@gravity-ui/uikit": "^6.22.0", + "@gravity-ui/uikit": "^6.23.0", "@mdx-js/mdx": "^2.3.0", "@mdx-js/react": "^2.3.0", "@octokit/rest": "^20.1.1", @@ -21,11 +23,12 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "bem-cn-lite": "^4.1.0", + "chroma-js": "^2.4.2", "husky": "^8.0.3", "i18next": "^23.8.3", "javascript-time-ago": "^2.5.9", - "landing-icons": "npm:@gravity-ui/icons@^2.8.1", - "landing-uikit": "npm:@gravity-ui/uikit@^6.17.0", + "landing-icons": "npm:@gravity-ui/icons@^2.10.0", + "landing-uikit": "npm:@gravity-ui/uikit@^6.23.0", "lint-staged": "^14.0.1", "lodash": "^4.17.21", "micromatch": "^4.0.7", @@ -34,7 +37,7 @@ "next-i18next": "^15.2.0", "prismjs": "^1.29.0", "react": "^18.2.0", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-i18next": "^14.0.5", "react-time-ago": "^7.2.1", "rehype-autolink-headings": "^6.1.1", @@ -43,7 +46,8 @@ "remark-link-rewrite": "^1.0.7", "swiper": "^10.2.0", "typescript": "^5.1.6", - "url": "^0.11.0" + "url": "^0.11.0", + "uuid": "^10.0.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.614.0", @@ -52,6 +56,7 @@ "@gravity-ui/stylelint-config": "^2.0.0", "@gravity-ui/tsconfig": "^1.0.0", "@svgr/webpack": "^6.5.1", + "@types/chroma-js": "^2.4.4", "@types/jest": "^29.2.4", "@types/lodash": "^4.14.197", "@types/micromatch": "^4.0.7", @@ -60,6 +65,7 @@ "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@types/react-timeago": "^4.1.3", + "@types/uuid": "^10.0.0", "dotenv": "^16.0.3", "eslint": "^8.27.0", "eslint-plugin-testing-library": "^5.9.1", @@ -2927,9 +2933,9 @@ } }, "node_modules/@diplodoc/tabs-extension": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@diplodoc/tabs-extension/-/tabs-extension-2.1.0.tgz", - "integrity": "sha512-e3T6bmE/8K5mR4Kg8bucC1+7DvgCxwu/qJ0B38c2YpFhvT+R+lredULNdHNYLTU9jSvGRygP6bwsqYoNRixkIw==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@diplodoc/tabs-extension/-/tabs-extension-3.1.1.tgz", + "integrity": "sha512-FWywClCNtMUQGZAsd6Hr/Cs1TX9aOJ4t9SOR9pIuOVsJwVWXNihdUW7x2yaAT0WwP4bBqXg7GSUQ/DIVIde9Ww==", "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, @@ -2940,17 +2946,17 @@ } }, "node_modules/@diplodoc/transform": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@diplodoc/transform/-/transform-4.11.0.tgz", - "integrity": "sha512-3JRC/6ISrdhPhZIenwTNAZyUJmD+o3vGRkeh4CD7+/Nh5eAlrcQ4/aRkuNIdFqE5sM1WeZLjKgiMsS0lz5RpZg==", + "version": "4.26.0", + "resolved": "https://registry.npmjs.org/@diplodoc/transform/-/transform-4.26.0.tgz", + "integrity": "sha512-k6TxF3DzWkAdfPnjzfUBR4mNGiE4dQC5Cvk9flGazhX2aNOXetSYU1/Y1voSNNnG8EmTJqXOsTptGMLBxAz/hw==", "dependencies": { - "@diplodoc/tabs-extension": "^2.1.0", - "chalk": "4.1.2", + "@diplodoc/tabs-extension": "^3.0.0", + "chalk": "^4.1.2", "cheerio": "^1.0.0-rc.12", "css": "^3.0.0", "cssfilter": "0.0.10", "get-root-node-polyfill": "1.0.0", - "github-slugger": "1.4.0", + "github-slugger": "^1.5.0", "js-yaml": "^4.1.0", "lodash": "4.17.21", "markdown-it": "^13.0.2", @@ -2958,10 +2964,11 @@ "markdown-it-deflist": "2.1.0", "markdown-it-meta": "0.0.1", "markdown-it-sup": "1.0.0", - "markdownlint": "^0.25.1", + "markdownlint": "^0.32.1", "markdownlint-rule-helpers": "0.17.2", "sanitize-html": "^2.11.0", - "slugify": "1.6.5" + "slugify": "1.6.5", + "svgo": "^3.2.0" }, "peerDependencies": { "highlight.js": "^10.0.3 || ^11" @@ -3023,17 +3030,6 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/@diplodoc/transform/node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, "node_modules/@diplodoc/transform/node_modules/htmlparser2": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", @@ -3063,21 +3059,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/@diplodoc/transform/node_modules/markdown-it": { - "version": "13.0.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", - "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, "node_modules/@diplodoc/transform/node_modules/sanitize-html": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.12.1.tgz", @@ -3192,6 +3173,65 @@ "node": ">=14" } }, + "node_modules/@gravity-ui/chartkit": { + "version": "5.10.2", + "resolved": "https://registry.npmjs.org/@gravity-ui/chartkit/-/chartkit-5.10.2.tgz", + "integrity": "sha512-2PrnMgPZvcQYLoyD7O7DAoyI+m8nSxqKA1Ibps16Hq2oAaer6TeSB6fCA5Zi1jFZK3AW9VoFutYYrXLqhNO/rQ==", + "dependencies": { + "@bem-react/classname": "^1.6.0", + "@gravity-ui/date-utils": "^2.1.0", + "@gravity-ui/i18n": "^1.0.0", + "@gravity-ui/yagr": "^4.3.0", + "afterframe": "^1.0.2", + "d3": "^7.8.5", + "lodash": "^4.17.21", + "react-split-pane": "^0.1.92", + "tslib": "^2.6.2" + }, + "peerDependencies": { + "@gravity-ui/uikit": "^6.0.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@gravity-ui/chartkit/node_modules/react-dom": { + "version": "16.14.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", + "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/@gravity-ui/chartkit/node_modules/react-split-pane": { + "version": "0.1.92", + "resolved": "https://registry.npmjs.org/react-split-pane/-/react-split-pane-0.1.92.tgz", + "integrity": "sha512-GfXP1xSzLMcLJI5BM36Vh7GgZBpy+U/X0no+VM3fxayv+p1Jly5HpMofZJraeaMl73b3hvlr+N9zJKvLB/uz9w==", + "dependencies": { + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4", + "react-style-proptype": "^3.2.2" + }, + "peerDependencies": { + "react": "^16.0.0-0", + "react-dom": "^16.0.0-0" + } + }, + "node_modules/@gravity-ui/chartkit/node_modules/scheduler": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", + "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, "node_modules/@gravity-ui/components": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@gravity-ui/components/-/components-3.7.0.tgz", @@ -3299,6 +3339,23 @@ } } }, + "node_modules/@gravity-ui/navigation": { + "version": "2.21.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/navigation/-/navigation-2.21.0.tgz", + "integrity": "sha512-zdbuHaEuKeUao4HAbPiXrn+NaMQ87w+XgnOznZ7RPtE3TfkmlAHVG69Rz51cs3J127xZdn7gUkf1PfiegQl7Vg==", + "dependencies": { + "react-transition-group": "^4.4.1", + "tslib": "^2.4.0" + }, + "peerDependencies": { + "@bem-react/classname": "^1.6.0", + "@gravity-ui/components": "^3.0.0", + "@gravity-ui/icons": "^2.2.0", + "@gravity-ui/uikit": "^6.15.0", + "react": "^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/@gravity-ui/page-constructor": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@gravity-ui/page-constructor/-/page-constructor-5.2.0.tgz", @@ -3365,6 +3422,18 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, + "node_modules/@gravity-ui/page-constructor/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@gravity-ui/prettier-config": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@gravity-ui/prettier-config/-/prettier-config-1.0.1.tgz", @@ -3398,10 +3467,9 @@ "dev": true }, "node_modules/@gravity-ui/uikit": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.22.0.tgz", - "integrity": "sha512-F0PZovzGbBB4kG0O1F2dt5JFJjg8MtobY3CkY0yBP3yILuVFU/nnEPISqXe1fxdn4W5arAph5FnnYf1P1sl3wA==", - "license": "MIT", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.23.0.tgz", + "integrity": "sha512-v+1QPL+IdaGxv3tuEUHaRSzK5Hp/XNJv3EQxMIMFSV4ojtvio6sQAlzLIYALGN/IULWRwlfF0cqG/TavOo9yog==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/i18n": "^1.3.0", @@ -3425,6 +3493,17 @@ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/@gravity-ui/yagr": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/yagr/-/yagr-4.3.0.tgz", + "integrity": "sha512-mi7zj69Oci82xdkK0Hyc7IERntrV12sBCNX+Bf90c9z5bb++3CugvGr+29DrEtKh3UOQfZzEwaK9Pb4wk0S0Cw==", + "dependencies": { + "uplot": "1.6.27" + }, + "engines": { + "node": ">=16.0.0" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.11.8", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", @@ -4280,6 +4359,19 @@ "node": ">=16.0.0" } }, + "node_modules/@smithy/middleware-retry/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "dev": true, + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/@smithy/middleware-serde": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.3.tgz", @@ -5245,7 +5337,6 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, "engines": { "node": ">=10.13.0" } @@ -5269,6 +5360,12 @@ "integrity": "sha512-0WR3b8eaISjEW7RpZnclONaLFDf7buaowRHdqLp4vLj54AsSAYWfh3DRbfiYJY9XDxMgx1B4sE1Afw2PGpuHOA==", "dev": true }, + "node_modules/@types/chroma-js": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/chroma-js/-/chroma-js-2.4.4.tgz", + "integrity": "sha512-/DTccpHTaKomqussrn+ciEvfW4k6NAHzNzs/sts1TCqg333qNxOhy8TNIoQCmbGG3Tl8KdEhkGAssb1n3mTXiQ==", + "dev": true + }, "node_modules/@types/cookie": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", @@ -5539,6 +5636,12 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==" }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true + }, "node_modules/@types/yargs": { "version": "17.0.23", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.23.tgz", @@ -6049,6 +6152,11 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/afterframe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/afterframe/-/afterframe-1.0.2.tgz", + "integrity": "sha512-0JeMZI7dIfVs5guqLgidQNV7c6jBC2HO0QNSekAUB82Hr7PdU9QXNAF3kpFkvATvHYDDTGto7FPsRu1ey+aKJQ==" + }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -6798,6 +6906,11 @@ "node": ">= 6" } }, + "node_modules/chroma-js": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chroma-js/-/chroma-js-2.4.2.tgz", + "integrity": "sha512-U9eDw6+wt7V8z5NncY2jJfZa+hUH8XEj8FQHgFJTrUFnJfXYf4Ml4adI2vXZOjqRDpFWtYVWypDfZwnJ+HIR4A==" + }, "node_modules/chrome-trace-event": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", @@ -7144,7 +7257,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", - "dev": true, "dependencies": { "mdn-data": "2.0.30", "source-map-js": "^1.0.1" @@ -7198,7 +7310,6 @@ "version": "5.0.5", "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", - "dev": true, "dependencies": { "css-tree": "~2.2.0" }, @@ -7211,7 +7322,6 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", - "dev": true, "dependencies": { "mdn-data": "2.0.28", "source-map-js": "^1.0.1" @@ -7224,14 +7334,391 @@ "node_modules/csso/node_modules/mdn-data": { "version": "2.0.28", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", - "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", - "dev": true + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" }, "node_modules/csstype": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz", "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==" }, + "node_modules/d3": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz", + "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dispatch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", + "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-drag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz", + "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-selection": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, + "node_modules/d3-ease": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", + "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz", + "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-interpolate": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", + "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==", + "dependencies": { + "d3-color": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz", + "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-selection": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", + "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-timer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", + "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-transition": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz", + "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==", + "dependencies": { + "d3-color": "1 - 3", + "d3-dispatch": "1 - 3", + "d3-ease": "1 - 3", + "d3-interpolate": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "d3-selection": "2 - 3" + } + }, + "node_modules/d3-zoom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz", + "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "2 - 3", + "d3-transition": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/dayjs": { "version": "1.11.10", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", @@ -7355,6 +7842,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/delaunator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz", + "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==", + "dependencies": { + "robust-predicates": "^3.0.2" + } + }, "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", @@ -8875,9 +9370,9 @@ "integrity": "sha512-2REUOV3ue6NmT0QThhfzfYmeSoYpCG73+tL7Ir2C7P+gshRerI05WuIQuhDkE2Zlg5Wc39hc2DHj+pE23mGJvw==" }, "node_modules/github-slugger": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.4.0.tgz", - "integrity": "sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", + "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" }, "node_modules/glob": { "version": "7.2.3", @@ -9357,6 +9852,17 @@ "resolved": "https://registry.npmjs.org/i18next-fs-backend/-/i18next-fs-backend-2.3.1.tgz", "integrity": "sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==" }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -9454,6 +9960,14 @@ "node": ">= 0.4" } }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/is-alphabetical": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", @@ -10112,15 +10626,23 @@ }, "node_modules/landing-icons": { "name": "@gravity-ui/icons", - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/@gravity-ui/icons/-/icons-2.8.1.tgz", - "integrity": "sha512-cldaFAN3W2OAzEZBiurD7RsqyqGhS7xoVS9TC4DrOG9bXy8dWUvNEeeOnKgpIvZgAGFlTmg01BK6jMH0IFFSPw==" + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/icons/-/icons-2.10.0.tgz", + "integrity": "sha512-xS0G4+TM7cD2cCKS4wVc01c4lLe/OreKjm4sHwrOtJWH4EawaRbpkuwtgUDcUvY2EryIcI6lgV+8o714m6lcyQ==", + "peerDependencies": { + "react": "*" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + } + } }, "node_modules/landing-uikit": { "name": "@gravity-ui/uikit", - "version": "6.17.0", - "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.17.0.tgz", - "integrity": "sha512-aelbGQh0DxgZ/b3hbjZNBPc417mmoL4P5vq6yYOvUol/4GKimofgs7kOB2IjIVOAaEYivGgoVjmLQxREJfM15A==", + "version": "6.23.0", + "resolved": "https://registry.npmjs.org/@gravity-ui/uikit/-/uikit-6.23.0.tgz", + "integrity": "sha512-v+1QPL+IdaGxv3tuEUHaRSzK5Hp/XNJv3EQxMIMFSV4ojtvio6sQAlzLIYALGN/IULWRwlfF0cqG/TavOo9yog==", "dependencies": { "@bem-react/classname": "^1.6.0", "@gravity-ui/i18n": "^1.3.0", @@ -10732,10 +11254,9 @@ } }, "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", - "peer": true, + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.2.tgz", + "integrity": "sha512-FtwnEuuK+2yVU7goGn/MJ0WBZMM9ZPgU9spqlFs7/A/pDIUNSOQZhUgOqYCficIuR2QaFnrt8LHqBWsbTAoI5w==", "dependencies": { "argparse": "^2.0.1", "entities": "~3.0.1", @@ -10800,7 +11321,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "peer": true, "engines": { "node": ">=0.12" }, @@ -10818,14 +11338,26 @@ } }, "node_modules/markdownlint": { - "version": "0.25.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz", - "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==", + "version": "0.32.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.32.1.tgz", + "integrity": "sha512-3sx9xpi4xlHlokGyHO9k0g3gJbNY4DI6oNEeEYq5gQ4W7UkiJ90VDAnuDl2U+yyXOUa6BX+0gf69ZlTUGIBp6A==", "dependencies": { - "markdown-it": "12.3.2" + "markdown-it": "13.0.2", + "markdownlint-micromark": "0.1.7" }, "engines": { - "node": ">=12" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-micromark": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", + "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "engines": { + "node": ">=16" } }, "node_modules/markdownlint-rule-helpers": { @@ -10836,37 +11368,6 @@ "node": ">=12" } }, - "node_modules/markdownlint/node_modules/entities": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", - "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/markdownlint/node_modules/linkify-it": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", - "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/markdownlint/node_modules/markdown-it": { - "version": "12.3.2", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", - "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", - "dependencies": { - "argparse": "^2.0.1", - "entities": "~2.1.0", - "linkify-it": "^3.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -11165,8 +11666,7 @@ "node_modules/mdn-data": { "version": "2.0.30", "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", - "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", - "dev": true + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/mdurl": { "version": "1.0.1", @@ -13014,9 +13514,9 @@ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" }, "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "dependencies": { "loose-envify": "^1.1.0" }, @@ -13055,15 +13555,15 @@ } }, "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "dependencies": { "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" + "scheduler": "^0.23.2" }, "peerDependencies": { - "react": "^18.2.0" + "react": "^18.3.1" } }, "node_modules/react-fast-compare": { @@ -13113,6 +13613,11 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-lifecycles-compat": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", + "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" + }, "node_modules/react-monaco-editor": { "version": "0.53.0", "resolved": "https://registry.npmjs.org/react-monaco-editor/-/react-monaco-editor-0.53.0.tgz", @@ -13195,6 +13700,14 @@ "react-dom": "^0.14.0 || ^15.0.1 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-style-proptype": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/react-style-proptype/-/react-style-proptype-3.2.2.tgz", + "integrity": "sha512-ywYLSjNkxKHiZOqNlso9PZByNEY+FTyh3C+7uuziK0xFXu9xzdyfHwg4S9iyiRRoPCR4k2LqaBBsWVmSBwCWYQ==", + "dependencies": { + "prop-types": "^15.5.4" + } + }, "node_modules/react-time-ago": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/react-time-ago/-/react-time-ago-7.2.1.tgz", @@ -13784,6 +14297,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -13807,6 +14325,11 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/sade": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", @@ -13869,6 +14392,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sanitize-html": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-2.6.1.tgz", @@ -13938,9 +14466,9 @@ } }, "node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "version": "0.23.2", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", "dependencies": { "loose-envify": "^1.1.0" } @@ -14685,15 +15213,15 @@ "dev": true }, "node_modules/svgo": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", - "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", - "dev": true, + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.3.2.tgz", + "integrity": "sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", "css-select": "^5.1.0", - "css-tree": "^2.2.1", + "css-tree": "^2.3.1", + "css-what": "^6.1.0", "csso": "^5.0.5", "picocolors": "^1.0.0" }, @@ -14712,7 +15240,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, "engines": { "node": ">= 10" } @@ -15387,6 +15914,11 @@ "browserslist": ">= 4.21.0" } }, + "node_modules/uplot": { + "version": "1.6.27", + "resolved": "https://registry.npmjs.org/uplot/-/uplot-1.6.27.tgz", + "integrity": "sha512-78U4ss5YeU65kQkOC/QAKiyII+4uo+TYUJJKvuxRzeSpk/s5sjpY1TL0agkmhHBBShpvLtmbHIEiM7+C5lBULg==" + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -15432,9 +15964,9 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" diff --git a/package.json b/package.json index 6e9b93d8a941..8cf8fcc2dd29 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,14 @@ "private": true, "homepage": "https://gravity-ui.com/", "dependencies": { - "@diplodoc/transform": "^4.11.0", + "@diplodoc/transform": "^4.26.0", + "@gravity-ui/chartkit": "^5.10.1", "@gravity-ui/components": "^3.7.0", "@gravity-ui/date-components": "^2.8.0", "@gravity-ui/icons": "^2.10.0", + "@gravity-ui/navigation": "^2.21.0", "@gravity-ui/page-constructor": "^5.2.0", - "@gravity-ui/uikit": "^6.22.0", + "@gravity-ui/uikit": "^6.23.0", "@mdx-js/mdx": "^2.3.0", "@mdx-js/react": "^2.3.0", "@octokit/rest": "^20.1.1", @@ -17,11 +19,12 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "bem-cn-lite": "^4.1.0", + "chroma-js": "^2.4.2", "husky": "^8.0.3", "i18next": "^23.8.3", "javascript-time-ago": "^2.5.9", - "landing-icons": "npm:@gravity-ui/icons@^2.8.1", - "landing-uikit": "npm:@gravity-ui/uikit@^6.17.0", + "landing-icons": "npm:@gravity-ui/icons@^2.10.0", + "landing-uikit": "npm:@gravity-ui/uikit@^6.23.0", "lint-staged": "^14.0.1", "lodash": "^4.17.21", "micromatch": "^4.0.7", @@ -30,7 +33,7 @@ "next-i18next": "^15.2.0", "prismjs": "^1.29.0", "react": "^18.2.0", - "react-dom": "^18.2.0", + "react-dom": "^18.3.1", "react-i18next": "^14.0.5", "react-time-ago": "^7.2.1", "rehype-autolink-headings": "^6.1.1", @@ -39,7 +42,8 @@ "remark-link-rewrite": "^1.0.7", "swiper": "^10.2.0", "typescript": "^5.1.6", - "url": "^0.11.0" + "url": "^0.11.0", + "uuid": "^10.0.0" }, "devDependencies": { "@aws-sdk/client-s3": "^3.614.0", @@ -48,6 +52,7 @@ "@gravity-ui/stylelint-config": "^2.0.0", "@gravity-ui/tsconfig": "^1.0.0", "@svgr/webpack": "^6.5.1", + "@types/chroma-js": "^2.4.4", "@types/jest": "^29.2.4", "@types/lodash": "^4.14.197", "@types/micromatch": "^4.0.7", @@ -56,6 +61,7 @@ "@types/react": "^18.0.26", "@types/react-dom": "^18.0.9", "@types/react-timeago": "^4.1.3", + "@types/uuid": "^10.0.0", "dotenv": "^16.0.3", "eslint": "^8.27.0", "eslint-plugin-testing-library": "^5.9.1", @@ -73,6 +79,12 @@ "svgo": "^3.0.2", "undici": "^5.14.0" }, + "overrides": { + "react-split-pane": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + } + }, "scripts": { "prepare": "husky install", "start": "next dev", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index b2fbe5fab734..af08e007f8e3 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -8,6 +8,7 @@ "menu_components": "Components", "menu_design": "Design", "menu_icons": "Icons", + "menu_themes": "Themes", "roadmap_inProgress": "In progress", "navigation_previous": "Previous", "navigation_next": "Next", diff --git a/public/locales/en/component.json b/public/locales/en/component.json index f94dd7cd5ee7..2a8ec0011d63 100644 --- a/public/locales/en/component.json +++ b/public/locales/en/component.json @@ -5,6 +5,7 @@ "color-input_validation-format-error": "Incorrect format", "maintainers_one": "Maintainer:", "maintainers_other": "Maintainers:", + "maintainers": "Maintainers:", "theme": "Switch theme", "rtlOn": "Switch RTL on", "rtlOff": "Switch RTL off", diff --git a/public/locales/en/themes.json b/public/locales/en/themes.json new file mode 100644 index 000000000000..6d4b05d103ad --- /dev/null +++ b/public/locales/en/themes.json @@ -0,0 +1,35 @@ +{ + "title": "Themes", + "tags_colors": "Colors", + "tags_typography": "Typography", + "tags_borderRadius": "Border Radius", + "tags_preview": "Preview", + "btn_export_theme": "Export theme", + "custom_brand_palette": "Custom Brand Palette", + "page_background": "Page Background", + "brand_color": "Brand Color", + "hide_advanced_settings": "Hide Advanced Settings", + "advanced_settings": "Advanced Settings", + "theme": "Theme", + "basic_palette": "Basic Palette", + "add_color": "Add color", + "color-input_validation-format-error": "Incorrect format", + "palette_colors_description": "Support Colors for various cases and
states", + "dark_theme": "Dark theme", + "light_theme": "Light theme", + "advanced_brand_palette": "Advanced Brand Palette", + "additional_colors": "Additional Colors", + "component_preview": "Component preview", + "is_everything_set": "Is everything set?", + "cancel": "Cancel", + "export_theme_config": "Export theme config", + "radius": "Radius", + "radius_regular": "Regular", + "radius_circled": "Circled", + "radius_squared": "Squared", + "radius_custom": "Custom radius", + "choose_border_radius": "Choose border radius", + "label": "Label", + "input_placeholder": "Content", + "button": "Button" +} diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 867886b112ec..03868dceecc1 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -8,6 +8,7 @@ "menu_components": "Компоненты", "menu_design": "Дизайн", "menu_icons": "Иконки", + "menu_themes": "Темы", "roadmap_inProgress": "В работе", "navigation_previous": "Назад", "navigation_next": "Далее", diff --git a/public/locales/ru/component.json b/public/locales/ru/component.json index 08b64cfba887..e91f7fac739c 100644 --- a/public/locales/ru/component.json +++ b/public/locales/ru/component.json @@ -5,6 +5,7 @@ "color-input_validation-format-error": "Неверный формат", "maintainers_one": "Maintainer:", "maintainers_other": "Maintainers:", + "maintainers": "Maintainers:", "theme": "Переключить тему", "rtlOn": "Включить RTL", "rtlOff": "Выключить RTL", diff --git a/public/locales/ru/themes.json b/public/locales/ru/themes.json new file mode 100644 index 000000000000..09a7c078c348 --- /dev/null +++ b/public/locales/ru/themes.json @@ -0,0 +1,35 @@ +{ + "title": "Темы", + "tags_colors": "Цвета", + "tags_typography": "Шрифты", + "tags_borderRadius": "Радиусы границ", + "tags_preview": "Предпоказ", + "color-input_validation-format-error": "Неверный формат", + "btn_export_theme": "Экспортировать тему", + "custom_brand_palette": "Кастомная брендовая палитра", + "page_background": "Цвет фона", + "brand_color": "Брендовый цвет", + "hide_advanced_settings": "Скрыть расширенные настройки", + "advanced_settings": "Расширенные настройки", + "theme": "Тема", + "basic_palette": "Базовая палитра", + "add_color": "Добавить цвет", + "palette_colors_description": "Поддерживаемые цвета для различных случаев и состояний", + "dark_theme": "Тёмная тема", + "light_theme": "Светлая тема", + "advanced_brand_palette": "Расширенная брендовая палитра", + "additional_colors": "Дополнительные цвета", + "component_preview": "Предпросмотр компонентов", + "is_everything_set": "Все настроили?", + "cancel": "Закрыть", + "export_theme_config": "Экспорт конфигурации темы", + "radius": "Радиус", + "radius_regular": "Стандартный", + "radius_circled": "Круглый", + "radius_squared": "Без скругления", + "radius_custom": "Настроить скругление", + "choose_border_radius": "Выберите радиус скругления", + "label": "Ярлык", + "input_placeholder": "Контент", + "button": "Кнопка" +} diff --git a/src/[locale]/themes/index.tsx b/src/[locale]/themes/index.tsx new file mode 100644 index 000000000000..b424ca5f66f0 --- /dev/null +++ b/src/[locale]/themes/index.tsx @@ -0,0 +1,38 @@ +import {GetStaticPaths, GetStaticProps} from 'next'; +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {Layout} from '../../components/Layout/Layout'; +import {Themes} from '../../components/Themes/Themes'; +import {useLocaleRedirect} from '../../hooks/useLocaleRedirect'; +import {getI18nPaths, getI18nProps} from '../../utils/i18next'; + +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: getI18nPaths(), + fallback: false, + }; +}; + +export const getStaticProps: GetStaticProps = async (ctx) => { + const result = { + props: { + ...(await getI18nProps(ctx, ['themes'])), + }, + }; + return result; +}; + +export const ThemesPage = () => { + useLocaleRedirect(); + + const {t} = useTranslation(); + + return ( + + + + ); +}; + +export default ThemesPage; diff --git a/src/assets/icons/gravity-ui.svg b/src/assets/icons/gravity-ui.svg new file mode 100644 index 000000000000..64ca776a285e --- /dev/null +++ b/src/assets/icons/gravity-ui.svg @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/preview-card-1.png b/src/assets/preview-card-1.png new file mode 100644 index 0000000000000000000000000000000000000000..9dd9b39cde6b9fa870a79d85ad10d61b4a0b7fde GIT binary patch literal 66923 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
diff --git a/src/components/ClipboardArea/ClipboardArea.scss b/src/components/ClipboardArea/ClipboardArea.scss index 3eda23359706..71e124fa7906 100644 --- a/src/components/ClipboardArea/ClipboardArea.scss +++ b/src/components/ClipboardArea/ClipboardArea.scss @@ -7,6 +7,14 @@ $block: '.#{variables.$ns}clipboard-area'; #{$block} { display: flex; + &__popover { + width: 100%; + + .g-popover__handler { + width: 100%; + } + } + &__popup { --g-popup-background-color: #3e3235; --g-popup-border-color: #3e3235; diff --git a/src/components/ClipboardArea/ClipboardArea.tsx b/src/components/ClipboardArea/ClipboardArea.tsx index b2653065bd7b..161c5a630132 100644 --- a/src/components/ClipboardArea/ClipboardArea.tsx +++ b/src/components/ClipboardArea/ClipboardArea.tsx @@ -30,6 +30,7 @@ export const ClipboardArea: React.FC = ({ return isNeedPopup ? ( = ({code, tooltipContent, className}) => { + return ( + + {(status) => ( +
+
+
+ {code} +
+
+ +
+
+
+ )} +
+ ); +}; diff --git a/src/components/ColorPickerInput/ColorPickerInput.scss b/src/components/ColorPickerInput/ColorPickerInput.scss deleted file mode 100644 index dbd6883958f7..000000000000 --- a/src/components/ColorPickerInput/ColorPickerInput.scss +++ /dev/null @@ -1,20 +0,0 @@ -@use '../../variables.scss'; - -$block: '.#{variables.$ns}color-picker'; - -#{$block} { - &__preview { - width: 16px; - height: 16px; - margin-inline-start: var(--g-spacing-2); - margin-inline-end: var(--g-spacing-1); - border-radius: var(--g-border-radius-xs); - } - - &__input { - width: 100%; - height: 0; - opacity: 0; - border: 1px solid transparent; - } -} diff --git a/src/components/ColorPickerInput/ColorPickerInput.tsx b/src/components/ColorPickerInput/ColorPickerInput.tsx deleted file mode 100644 index d3dea9c30fd9..000000000000 --- a/src/components/ColorPickerInput/ColorPickerInput.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import {Palette} from 'landing-icons'; -import {Button, Flex, Icon, TextInput, TextInputProps} from 'landing-uikit'; -import {useTranslation} from 'next-i18next'; -import React, {ChangeEventHandler, useCallback, useRef, useState} from 'react'; - -import {block} from '../../utils'; - -import './ColorPickerInput.scss'; -import {ColorPreview} from './ColorPreview'; -import {NativeColorPicker} from './NativeColorPicker'; -import {hexRegexp, parseRgbStringToHex, rgbRegexp, rgbaRegexp} from './utils'; - -const b = block('color-picker'); - -export interface ColorPickerInputProps { - defaultValue: string; - name?: string; - value?: string; - onChange?: (color: string) => void; - errorMessage?: string; -} - -export const ColorPickerInput = ({ - name, - value, - onChange: onChangeExternal, - defaultValue, - errorMessage, -}: ColorPickerInputProps) => { - const {t} = useTranslation('component'); - - const [color, setColor] = useState(defaultValue); - const [inputValue, setInputValue] = useState(defaultValue); - const [validationError, setValidationError] = useState(); - - const colorInputRef = useRef(null); - - const managedValue = value || inputValue; - - const onChange: ChangeEventHandler = useCallback( - (event) => { - const newValue = event.target.value.replaceAll(' ', ''); - onChangeExternal?.(newValue); - setInputValue(newValue); - setValidationError(undefined); - - if ( - !newValue || - new RegExp(hexRegexp, 'g').test(newValue) || - new RegExp(rgbaRegexp, 'g').test(newValue) - ) { - setColor(newValue); - - return; - } - - if (new RegExp(rgbRegexp, 'g').test(newValue)) { - const hexColor = parseRgbStringToHex(newValue); - - setColor(hexColor); - return; - } - }, - [onChangeExternal], - ); - - const onNativeInputChange: ChangeEventHandler = useCallback((e) => { - const newValue = e.target.value.toUpperCase(); - - setColor(newValue); - setInputValue(newValue); - }, []); - - const onBlur = useCallback(() => { - if ( - !managedValue || - (!new RegExp(hexRegexp, 'g').test(managedValue) && - !new RegExp(rgbRegexp, 'g').test(managedValue) && - !new RegExp(rgbaRegexp, 'g').test(managedValue)) - ) { - setValidationError('invalid'); - } - }, [managedValue]); - - return ( - - } - endContent={ - - } - onBlur={onBlur} - /> - - - ); -}; diff --git a/src/components/ColorPickerInput/ColorPreview.tsx b/src/components/ColorPickerInput/ColorPreview.tsx deleted file mode 100644 index 29b23540590c..000000000000 --- a/src/components/ColorPickerInput/ColorPreview.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; - -import {block} from '../../utils'; - -import './ColorPickerInput.scss'; - -export interface ColorPreviewProps { - color: string; -} - -const b = block('color-picker__preview'); - -export const ColorPreview = ({color}: ColorPreviewProps) => { - return
; -}; diff --git a/src/components/ColorPickerInput/NativeColorPicker.tsx b/src/components/ColorPickerInput/NativeColorPicker.tsx deleted file mode 100644 index 2f30307dacc1..000000000000 --- a/src/components/ColorPickerInput/NativeColorPicker.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import React, {ChangeEventHandler, forwardRef} from 'react'; - -import {block} from '../../utils'; - -import './ColorPickerInput.scss'; - -export interface NativeColorPickerProps { - value: string; - onChange: ChangeEventHandler; -} - -const b = block('color-picker__input'); - -export const NativeColorPicker = forwardRef( - ({value, onChange}, ref) => { - return ; - }, -); diff --git a/src/components/ColorPickerInput/utils.ts b/src/components/ColorPickerInput/utils.ts deleted file mode 100644 index 7b44fa2fd1dd..000000000000 --- a/src/components/ColorPickerInput/utils.ts +++ /dev/null @@ -1,16 +0,0 @@ -export const hexRegexp = /^#[a-fA-F0-9]{6}$/; -export const rgbRegexp = /^rgb\((\d{1,3}, ?){2}(\d{1,3})\)$/; -export const rgbaRegexp = /^rgba\((\d{1,3}, ?){3}((0(,|\.)[0-9]{1,2})|1)\)$/; - -const numberRegexp = /\b\d+\b/g; - -export const parseRgbStringToHex = (rgbString: string) => { - let hexColor = '#'; - rgbString.match(new RegExp(numberRegexp, 'g'))?.forEach((val) => { - const hex = Number(val).toString(16); - - hexColor += hex?.length === 1 ? `0${hex}` : hex; - }); - - return hexColor; -}; diff --git a/src/components/Icons/IconDialog/UsageExample/UsageExample.scss b/src/components/Icons/IconDialog/UsageExample/UsageExample.scss index 177fd39ae791..f55d745ffa92 100644 --- a/src/components/Icons/IconDialog/UsageExample/UsageExample.scss +++ b/src/components/Icons/IconDialog/UsageExample/UsageExample.scss @@ -13,45 +13,4 @@ $block: '.#{variables.$ns}icon-usage-example'; margin-bottom: 12px; color: rgba(255, 255, 255, 0.7); } - - &__wrapper { - display: flex; - flex-direction: row; - width: 100%; - background: var(--g-color-base-background); - border-radius: 16px; - padding: 16px 48px 16px 16px; - position: relative; - - &:hover { - cursor: pointer; - - #{$block}__code { - color: #fff; - } - - #{$block}__copy-icon { - color: #fff; - } - } - } - - &__code { - @include pcStyles.text-size(code-2); - flex-grow: 1; - font-family: var(--g-font-family-monospace); - color: rgba(255, 255, 255, 0.7); - margin-right: 12px; - transition: color 0.1s ease-in-out; - - &_copied { - color: #fff; - } - } - - &__copy-button { - position: absolute; - right: 16px; - top: 16px; - } } diff --git a/src/components/Icons/IconDialog/UsageExample/UsageExample.tsx b/src/components/Icons/IconDialog/UsageExample/UsageExample.tsx index 3cf2c8ff4d8b..ab9f9ce2fca7 100644 --- a/src/components/Icons/IconDialog/UsageExample/UsageExample.tsx +++ b/src/components/Icons/IconDialog/UsageExample/UsageExample.tsx @@ -2,8 +2,7 @@ import {useTranslation} from 'next-i18next'; import React from 'react'; import {block} from '../../../../utils'; -import {ClipboardArea} from '../../../ClipboardArea/ClipboardArea'; -import {ClipboardIcon} from '../../../ClipboardIcon/ClipboardIcon'; +import {CodeExample} from '../../../CodeExample/CodeExample'; import type {IconItem} from '../../types'; import './UsageExample.scss'; @@ -29,29 +28,14 @@ export const UsageExample: React.FC = ({icon, variant}) => {
{variant === 'react' ? t('icons:usage_reactComponent') : t('icons:usage_svg')}
- - {(status) => ( -
-
- {importCode} -
-
- -
-
- )} -
+ />
); }; diff --git a/src/components/Libraries/Libraries.tsx b/src/components/Libraries/Libraries.tsx index 591a8245380d..f97f31fe7841 100644 --- a/src/components/Libraries/Libraries.tsx +++ b/src/components/Libraries/Libraries.tsx @@ -8,9 +8,9 @@ import starIcon from '../../assets/icons/star.svg'; import versionIcon from '../../assets/icons/version.svg'; import {block, getLibsList} from '../../utils'; import {Link} from '../Link'; +import {TagItem, Tags} from '../Tags/Tags'; import './Libraries.scss'; -import {TagItem, Tags} from './Tags/Tags'; const b = block('libraries'); diff --git a/src/components/Libraries/Tags/Tags.scss b/src/components/Libraries/Tags/Tags.scss deleted file mode 100644 index 6ec0c6b6d73a..000000000000 --- a/src/components/Libraries/Tags/Tags.scss +++ /dev/null @@ -1,32 +0,0 @@ -@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; -@use '../../../variables.scss'; - -$block: '.#{variables.$ns}tags'; - -#{$block} { - display: flex; - overflow-x: auto; - - --g-scrollbar-width: 0; - - &__tag { - padding: 11px 24px; - margin-left: 8px; - font-size: 15px; - line-height: 20px; - font-weight: 400; - border-radius: 34px; - border: 1px solid rgba(255, 255, 255, 0.15); - cursor: pointer; - - &:first-child { - margin-left: 0; - } - - &_active { - color: #ffbe5c; - background: rgba(255, 190, 92, 0.1); - border: 1px solid transparent; - } - } -} diff --git a/src/components/Libraries/Tags/Tags.tsx b/src/components/Libraries/Tags/Tags.tsx deleted file mode 100644 index 74c19a98dc93..000000000000 --- a/src/components/Libraries/Tags/Tags.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React from 'react'; - -import {block} from '../../../utils'; - -import './Tags.scss'; - -const b = block('tags'); - -export type TagItem = { - title: string; - value: string; -}; - -type Props = { - value: string; - items: TagItem[]; - onChange: (newValue: string) => void; -}; - -export const Tags: React.FC = ({value, items, onChange}) => { - return ( -
- {items.map((item) => { - return ( -
{ - onChange(item.value); - }} - className={b('tag', {active: item.value === value})} - > - {item.title} -
- ); - })} -
- ); -}; diff --git a/src/components/SelectableCard/SelectableCard.scss b/src/components/SelectableCard/SelectableCard.scss new file mode 100644 index 000000000000..0f25b2429d45 --- /dev/null +++ b/src/components/SelectableCard/SelectableCard.scss @@ -0,0 +1,31 @@ +@use '../../variables.scss'; + +$block: '.#{variables.$ns}selectable-card'; + +#{$block} { + position: relative; + display: flex; + padding: 22px 12px; + height: 80px; + align-items: center; + justify-content: center; + cursor: pointer; + text-align: center; + + &__icon { + position: absolute; + top: 4px; + right: 4px; + color: var(--g-color-base-brand); + } + + &__fake-button { + width: 69px; + height: 28px; + background-color: var(--g-color-base-brand); + display: flex; + align-items: center; + justify-content: center; + user-select: none; + } +} diff --git a/src/components/SelectableCard/SelectableCard.tsx b/src/components/SelectableCard/SelectableCard.tsx new file mode 100644 index 000000000000..2954300d40a6 --- /dev/null +++ b/src/components/SelectableCard/SelectableCard.tsx @@ -0,0 +1,54 @@ +import {CircleCheckFill} from '@gravity-ui/icons'; +import {Card, type CardProps, DOMProps, Text, TextProps} from '@gravity-ui/uikit'; +import React from 'react'; + +import {block} from '../../utils'; + +import './SelectableCard.scss'; + +const b = block('selectable-card'); + +export type SelecableCardProps = { + /** + * Text to display inside + */ + text: string; + /** + * Flag to show only text without decoration + */ + pureText?: boolean; + /** + * Props for inner Text component + */ + textProps?: TextProps; +} & Pick & + Pick; + +const CardContent = ({ + text, + pureText, + textProps, +}: Pick) => { + const props: Record = pureText + ? {variant: 'body-2'} + : {color: 'inverted-primary', className: b('fake-button')}; + return ( + + {text} + + ); +}; + +export const SelectableCard = ({ + selected, + pureText, + text, + onClick, + className, + textProps, +}: SelecableCardProps) => ( + + + {selected && } + +); diff --git a/src/components/Tags/Tags.scss b/src/components/Tags/Tags.scss new file mode 100644 index 000000000000..edd586f3da49 --- /dev/null +++ b/src/components/Tags/Tags.scss @@ -0,0 +1,16 @@ +@use '../../../node_modules/@gravity-ui/page-constructor/styles/variables' as pcVariables; +@use '../../variables'; + +$block: '.#{variables.$ns}tags'; + +#{$block} { + --g-scrollbar-width: 0; + + overflow-x: auto; + + &__tag { + &_selected { + --g-color-base-selection: var(--g-color-base-warning-light); + } + } +} diff --git a/src/components/Tags/Tags.tsx b/src/components/Tags/Tags.tsx new file mode 100644 index 000000000000..1df68dda9e59 --- /dev/null +++ b/src/components/Tags/Tags.tsx @@ -0,0 +1,44 @@ +import {Button, Flex} from '@gravity-ui/uikit'; +import React from 'react'; + +import {block} from '../../utils'; + +import './Tags.scss'; + +const b = block('tags'); + +export type TagItem = { + title: string; + value: T; +}; + +interface TagsProps { + value: T; + items: TagItem[]; + onChange: (newValue: T) => void; + className?: string; +} + +export function Tags({value, items, onChange, className}: TagsProps) { + return ( + + {items.map((item) => { + return ( + + ); + })} + + ); +} diff --git a/src/components/Themes/Themes.scss b/src/components/Themes/Themes.scss new file mode 100644 index 000000000000..53f417921deb --- /dev/null +++ b/src/components/Themes/Themes.scss @@ -0,0 +1,69 @@ +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '~@gravity-ui/uikit/styles/mixins' as ukitMixins; +@use '../../variables.scss'; + +$block: '.#{variables.$ns}themes'; + +#{$block} { + margin-block-start: calc(var(--g-spacing-base) * 16); + + &__title { + margin-block-end: var(--g-spacing-6); + + &__text { + @include ukitMixins.text-display-4(); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + @include ukitMixins.text-display-2(); + } + } + } + + &__header-actions { + margin-block-end: calc(var(--g-spacing-base) * 8); + justify-content: space-between; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md') - 1) { + flex-direction: column; + justify-content: flex-start; + } + } + + & &__tabs { + display: flex; + overflow: auto; + flex-wrap: wrap; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md') - 1) { + /* stylelint-disable */ + flex-wrap: nowrap !important; + margin: 0 -24px; + padding: 0 24px; + } + } + + &__export-theme-btn { + --g-button-border-radius: 8px; + width: fit-content; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md') - 1) { + margin-top: var(--g-spacing-6); + } + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + width: 100%; + } + } + + &__export-theme-btn { + border-radius: var(--g-border-radius-m); + } + + &__content { + padding: calc(var(--g-spacing-base) * 12) 0; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding: calc(var(--g-spacing-base) * 6) 0; + } + } +} diff --git a/src/components/Themes/Themes.tsx b/src/components/Themes/Themes.tsx new file mode 100644 index 000000000000..84e2bcac2756 --- /dev/null +++ b/src/components/Themes/Themes.tsx @@ -0,0 +1,102 @@ +import {Col, Grid, Row} from '@gravity-ui/page-constructor'; +import {ArrowUpFromSquare} from 'landing-icons'; +import {Button, Flex, Icon, Text} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {useMemo, useState} from 'react'; + +import {block} from '../../utils'; +import {TagItem, Tags} from '../Tags/Tags'; + +import './Themes.scss'; +import {DEFAULT_THEME} from './lib/constants'; +import {BorderRadiusTab} from './ui/BorderRadiusTab/BorderRadiusTab'; +import {ColorsTab} from './ui/ColorsTab/ColorsTab'; +import {PreviewTab} from './ui/PreviewTab/PreviewTab'; +import {ThemeCreatorContextProvider} from './ui/ThemeCreatorContextProvider'; +import {ThemeExportDialog} from './ui/ThemeExportDialog/ThemeExportDialog'; +import {TypographyTab} from './ui/TypographyTab/TypographyTab'; + +const b = block('themes'); + +enum ThemeTab { + Colors = 'colors', + Typography = 'typography', + BorderRadius = 'borderRadius', + Preview = 'preview', +} + +const tabToComponent: Record = { + [ThemeTab.Colors]: ColorsTab, + [ThemeTab.Typography]: TypographyTab, + [ThemeTab.BorderRadius]: BorderRadiusTab, + [ThemeTab.Preview]: PreviewTab, +}; + +export const Themes = () => { + const {t} = useTranslation('themes'); + + const [isExportDialogVisible, toggleExportDialog] = React.useReducer( + (isOpen) => !isOpen, + false, + ); + + const tags: TagItem[] = useMemo( + () => [ + { + value: ThemeTab.Colors, + title: t('tags_colors'), + }, + { + value: ThemeTab.Typography, + title: t('tags_typography'), + }, + { + value: ThemeTab.BorderRadius, + title: t('tags_borderRadius'), + }, + { + value: ThemeTab.Preview, + title: t('tags_preview'), + }, + ], + [t], + ); + + const [activeTab, setActiveTab] = useState(ThemeTab.Colors); + + const TabComponent = tabToComponent[activeTab]; + + return ( + + + + + {t('title')} + + + + + + + + + {TabComponent ? : null} + + + + + ); +}; diff --git a/src/components/Themes/hooks/index.ts b/src/components/Themes/hooks/index.ts new file mode 100644 index 000000000000..e68e06b27c8e --- /dev/null +++ b/src/components/Themes/hooks/index.ts @@ -0,0 +1,4 @@ +export {useThemeCreator, useThemeCreatorMethods} from './useThemeCreator'; +export {useThemePalette, useThemePaletteColor} from './useThemePalette'; +export {useThemeUtilityColor} from './useThemeUtilityColor'; +export {useThemePrivateColorOptions} from './useThemePrivateColorOptions'; diff --git a/src/components/Themes/hooks/useThemeCreator.ts b/src/components/Themes/hooks/useThemeCreator.ts new file mode 100644 index 000000000000..c7e62a37b0c3 --- /dev/null +++ b/src/components/Themes/hooks/useThemeCreator.ts @@ -0,0 +1,6 @@ +import React from 'react'; + +import {ThemeCreatorContext, ThemeCreatorMethodsContext} from '../lib/themeCreatorContext'; + +export const useThemeCreator = () => React.useContext(ThemeCreatorContext); +export const useThemeCreatorMethods = () => React.useContext(ThemeCreatorMethodsContext); diff --git a/src/components/Themes/hooks/useThemePalette.ts b/src/components/Themes/hooks/useThemePalette.ts new file mode 100644 index 000000000000..71ffd9536640 --- /dev/null +++ b/src/components/Themes/hooks/useThemePalette.ts @@ -0,0 +1,36 @@ +import React from 'react'; + +import {getThemePalette} from '../lib/themeCreatorUtils'; +import type {ThemeVariant} from '../lib/types'; + +import {useThemeCreator, useThemeCreatorMethods} from './useThemeCreator'; + +export const useThemePalette = () => { + const themeState = useThemeCreator(); + return React.useMemo(() => getThemePalette(themeState), [themeState]); +}; + +type UseThemePaletteColorParams = { + token: string; + theme: ThemeVariant; +}; + +export const useThemePaletteColor = ({token, theme}: UseThemePaletteColorParams) => { + const themeState = useThemeCreator(); + const {updateColor} = useThemeCreatorMethods(); + + const value = React.useMemo(() => themeState.palette[theme][token], [themeState, token, theme]); + + const updateValue = React.useCallback( + (newValue: string) => { + updateColor({ + theme, + title: token, + value: newValue, + }); + }, + [token, theme, updateColor], + ); + + return [value, updateValue] as const; +}; diff --git a/src/components/Themes/hooks/useThemePrivateColorOptions.ts b/src/components/Themes/hooks/useThemePrivateColorOptions.ts new file mode 100644 index 000000000000..6aa706b024cb --- /dev/null +++ b/src/components/Themes/hooks/useThemePrivateColorOptions.ts @@ -0,0 +1,15 @@ +import React from 'react'; + +import {getThemeColorOptions} from '../lib/themeCreatorUtils'; +import {ThemeVariant} from '../lib/types'; + +import {useThemeCreator} from './useThemeCreator'; + +export const useThemePrivateColorOptions = (themeVariant: ThemeVariant) => { + const themeState = useThemeCreator(); + + return React.useMemo( + () => getThemeColorOptions({themeState, themeVariant}), + [themeState, themeVariant], + ); +}; diff --git a/src/components/Themes/hooks/useThemeUtilityColor.ts b/src/components/Themes/hooks/useThemeUtilityColor.ts new file mode 100644 index 000000000000..2160797535e9 --- /dev/null +++ b/src/components/Themes/hooks/useThemeUtilityColor.ts @@ -0,0 +1,30 @@ +import React from 'react'; + +import type {ColorsOptions, ThemeVariant} from '../lib/types'; + +import {useThemeCreator, useThemeCreatorMethods} from './useThemeCreator'; + +type UseThemeColorParams = { + name: keyof ColorsOptions; + theme: ThemeVariant; +}; + +export const useThemeUtilityColor = ({name, theme}: UseThemeColorParams) => { + const themeState = useThemeCreator(); + const {changeUtilityColor} = useThemeCreatorMethods(); + + const value = React.useMemo(() => themeState.colors[theme][name], [themeState, name, theme]); + + const updateValue = React.useCallback( + (newValue: string) => { + changeUtilityColor({ + themeVariant: theme, + name, + value: newValue, + }); + }, + [name, theme, changeUtilityColor], + ); + + return [value, updateValue] as const; +}; diff --git a/src/components/Themes/lib/constants.ts b/src/components/Themes/lib/constants.ts new file mode 100644 index 000000000000..86b28a1aefb0 --- /dev/null +++ b/src/components/Themes/lib/constants.ts @@ -0,0 +1,333 @@ +import {RadiusPresetName, RadiusValue, type ThemeOptions, type ThemeVariant} from './types'; +import {defaultTypographyPreset} from './typography/constants'; + +export const THEME_COLOR_VARIABLE_PREFIX = '--g-color'; + +export const THEME_BORDER_RADIUS_VARIABLE_PREFIX = '--g-border-radius'; + +export const DEFAULT_NEW_COLOR_TITLE = 'New color'; + +export const DEFAULT_BRAND_COLORS = [ + 'rgb(203,255,92)', + 'rgb(0,41,255)', + 'rgb(49,78,60)', + 'rgb(108,145,201)', + 'rgb(255,190,92)', + 'rgb(255,92,92)', +] as const; + +export const TEXT_CONTRAST_COLORS: Record = { + dark: { + white: 'rgb(255, 255, 255)', + black: 'rgba(0, 0, 0, 0.9)', // --g-color-private-black-900 + }, + light: { + white: 'rgb(255, 255, 255)', + black: 'rgba(0, 0, 0, 0.85)', // --g-color-private-black-850 + }, +}; + +export const DEFAULT_PALETTE: ThemeOptions['palette'] = { + light: { + white: 'rgb(255, 255, 255)', + black: 'rgb(0, 0, 0)', + brand: DEFAULT_BRAND_COLORS[0], + orange: 'rgb(255, 119, 0)', + green: 'rgb(59, 201, 53)', + yellow: 'rgb(255, 219, 77)', + red: 'rgb(255, 4, 0)', + blue: 'rgb(82, 130, 255)', + 'cool-grey': 'rgb(107, 132, 153)', + purple: 'rgb(143, 82, 204)', + }, + dark: { + white: 'rgb(255, 255, 255)', + black: 'rgb(0, 0, 0)', + brand: DEFAULT_BRAND_COLORS[0], + orange: 'rgb(200, 99, 12)', + green: 'rgb(91, 181, 87)', + yellow: 'rgb(255, 203, 0)', + red: 'rgb(232, 73, 69)', + blue: 'rgb(82, 130, 255)', + 'cool-grey': 'rgb(96, 128, 156)', + purple: 'rgb(143, 82, 204)', + }, +}; + +export const DEFAULT_PALETTE_TOKENS = new Set(Object.keys(DEFAULT_PALETTE.light)); + +export const DEFAULT_RADIUS: RadiusValue = { + xs: '3', + s: '5', + m: '6', + l: '8', + xl: '10', +}; + +export const RADIUS_PRESETS: Record = { + [RadiusPresetName.Regular]: DEFAULT_RADIUS, + [RadiusPresetName.Circled]: { + xs: '10', + s: '12', + m: '14', + l: '18', + xl: '22', + }, + [RadiusPresetName.Squared]: { + xs: '0', + s: '0', + m: '0', + l: '0', + xl: '0', + }, + [RadiusPresetName.Custom]: DEFAULT_RADIUS, +}; + +// Default colors mappings (values from gravity-ui styles) +// https://github.com/gravity-ui/uikit/tree/main/styles/themes +export const DEFAULT_COLORS: ThemeOptions['colors'] = { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.black, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, +}; + +export const DEFAULT_THEME: ThemeOptions = { + palette: DEFAULT_PALETTE, + colors: DEFAULT_COLORS, + borders: { + preset: RadiusPresetName.Regular, + values: RADIUS_PRESETS[RadiusPresetName.Regular], + }, + typography: defaultTypographyPreset, +}; + +export type BrandPreset = { + brandColor: typeof DEFAULT_BRAND_COLORS[number]; + colors: ThemeOptions['colors']; +}; + +export const BRAND_COLORS_PRESETS: BrandPreset[] = [ + { + brandColor: 'rgb(203,255,92)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.black, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, + { + brandColor: 'rgb(0,41,255)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.white, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, + { + brandColor: 'rgb(49,78,60)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.white, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, + { + brandColor: 'rgb(108,145,201)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.white, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, + { + brandColor: 'rgb(255,190,92)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.black, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.black, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, + { + brandColor: 'rgb(255,92,92)', + colors: { + light: { + 'base-background': 'rgb(255,255,255)', + 'base-brand-hover': 'private.brand.600-solid', + 'base-selection': 'private.brand.200', + 'base-selection-hover': 'private.brand.300', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.700-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.light.white, + 'text-link': 'private.brand.600-solid', + 'text-link-hover': 'private.orange.800-solid', + 'text-link-visited': 'private.purple.550-solid', + 'text-link-visited-hover': 'private.purple.800-solid', + }, + dark: { + 'base-background': 'rgb(34,29,34)', + 'base-brand-hover': 'private.brand.650-solid', + 'base-selection': 'private.brand.150', + 'base-selection-hover': 'private.brand.200', + 'line-brand': 'private.brand.600-solid', + 'text-brand': 'private.brand.600-solid', + 'text-brand-heavy': 'private.brand.700-solid', + 'text-brand-contrast': TEXT_CONTRAST_COLORS.dark.white, + 'text-link': 'private.brand.550-solid', + 'text-link-hover': 'private.brand.700-solid', + 'text-link-visited': 'private.purple.700-solid', + 'text-link-visited-hover': 'private.purple.850-solid', + }, + }, + }, +]; diff --git a/src/components/Themes/lib/privateColors/constants.ts b/src/components/Themes/lib/privateColors/constants.ts new file mode 100644 index 000000000000..16569307cb00 --- /dev/null +++ b/src/components/Themes/lib/privateColors/constants.ts @@ -0,0 +1,289 @@ +export const themeXd = { + light: { + white: { + privateSolidVariables: [], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + colorsMap: { + 50: {a: 0.05, c: 1}, + 70: {a: 0.07, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + black: { + privateSolidVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 50, + ], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 50, + ], + colorsMap: { + 50: {a: 0.05, c: -1}, + 70: {a: 0.07, c: -1}, + 100: {a: 0.1, c: -1}, + 150: {a: 0.15, c: -1}, + 200: {a: 0.2, c: -1}, + 250: {a: 0.25, c: -1}, + 300: {a: 0.3, c: -1}, + 350: {a: 0.35, c: -1}, + 400: {a: 0.4, c: -1}, + 450: {a: 0.45, c: -1}, + 500: {a: 0.5, c: -1}, + 550: {a: 0.55, c: -1}, + 600: {a: 0.6, c: -1}, + 650: {a: 0.65, c: -1}, + 700: {a: 0.7, c: -1}, + 750: {a: 0.75, c: -1}, + 800: {a: 0.8, c: -1}, + 850: {a: 0.85, c: -1}, + 900: {a: 0.9, c: -1}, + 950: {a: 0.95, c: -1}, + 1000: {a: 1, c: -1}, + }, + }, + }, + dark: { + white: { + privateSolidVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + colorsMap: { + 50: {a: 0.05, c: -1}, + 70: {a: 0.07, c: -1}, + 100: {a: 0.1, c: -1}, + 150: {a: 0.15, c: -1}, + 200: {a: 0.2, c: -1}, + 250: {a: 0.25, c: -1}, + 300: {a: 0.3, c: -1}, + 350: {a: 0.35, c: -1}, + 400: {a: 0.4, c: -1}, + 450: {a: 0.45, c: -1}, + 500: {a: 0.5, c: -1}, + 550: {a: 0.55, c: -1}, + 600: {a: 0.6, c: -1}, + 650: {a: 0.65, c: -1}, + 700: {a: 0.7, c: -1}, + 750: {a: 0.75, c: -1}, + 800: {a: 0.8, c: -1}, + 850: {a: 0.85, c: -1}, + 900: {a: 0.9, c: -1}, + 950: {a: 0.95, c: -1}, + 1000: {a: 1, c: -1}, + }, + }, + black: { + privateSolidVariables: [], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 50, 20, + ], + colorsMap: { + 20: {a: 0.02, c: 1}, + 50: {a: 0.05, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + 'White Opaque': { + privateVariables: [150], + colorsMap: { + 50: {a: 0.05, c: 1}, + 70: {a: 0.07, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + }, + 'light-hc': { + white: { + privateSolidVariables: [], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + colorsMap: { + 50: {a: 0.05, c: 1}, + 70: {a: 0.07, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + Black: { + privateSolidVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 50, 20, + ], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + colorsMap: { + 20: {a: 0.02, c: 1}, + 50: {a: 0.05, c: 1}, + 70: {a: 0.07, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + }, + 'dark-hc': { + white: { + privateSolidVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 70, 50, + ], + colorsMap: { + 50: {a: 0.05, c: 1}, + 70: {a: 0.07, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + black: { + privateSolidVariables: [], + privateVariables: [ + 950, 900, 850, 800, 750, 700, 650, 600, 550, 500, 450, 400, 350, 300, 250, 200, 150, + 100, 50, 20, + ], + colorsMap: { + 20: {a: 0.02, c: 1}, + 50: {a: 0.05, c: 1}, + 100: {a: 0.1, c: 1}, + 150: {a: 0.15, c: 1}, + 200: {a: 0.2, c: 1}, + 250: {a: 0.25, c: 1}, + 300: {a: 0.3, c: 1}, + 350: {a: 0.35, c: 1}, + 400: {a: 0.4, c: 1}, + 450: {a: 0.45, c: 1}, + 500: {a: 0.5, c: 1}, + 550: {a: 0.55, c: 1}, + 600: {a: 0.6, c: 1}, + 650: {a: 0.65, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.75, c: 1}, + 800: {a: 0.8, c: 1}, + 850: {a: 0.85, c: 1}, + 900: {a: 0.9, c: 1}, + 950: {a: 0.95, c: 1}, + 1000: {a: 1, c: 1}, + }, + }, + }, +}; diff --git a/src/components/Themes/lib/privateColors/index.ts b/src/components/Themes/lib/privateColors/index.ts new file mode 100644 index 000000000000..af32a8c8b0d4 --- /dev/null +++ b/src/components/Themes/lib/privateColors/index.ts @@ -0,0 +1 @@ +export {generatePrivateColors} from './utils'; diff --git a/src/components/Themes/lib/privateColors/utils.ts b/src/components/Themes/lib/privateColors/utils.ts new file mode 100644 index 000000000000..0d27b14c2630 --- /dev/null +++ b/src/components/Themes/lib/privateColors/utils.ts @@ -0,0 +1,98 @@ +import chroma from 'chroma-js'; + +import {themeXd} from './constants'; + +const privateSolidVariables = [ + 1000, 950, 900, 850, 800, 750, 700, 650, 600, 500, 450, 400, 350, 300, 250, 200, 150, 100, 50, +]; +const privateVariables = [500, 450, 400, 350, 300, 250, 200, 150, 100, 50]; +const colorsMap = { + 50: {a: 0.1, c: -1}, + 100: {a: 0.15, c: -1}, + 150: {a: 0.2, c: -1}, + 200: {a: 0.3, c: -1}, + 250: {a: 0.4, c: -1}, + 300: {a: 0.5, c: -1}, + 350: {a: 0.6, c: -1}, + 400: {a: 0.7, c: -1}, + 450: {a: 0.8, c: -1}, + 500: {a: 0.9, c: -1}, + 550: {a: 1, c: 1}, + 600: {a: 0.9, c: 1}, + 650: {a: 0.8, c: 1}, + 700: {a: 0.7, c: 1}, + 750: {a: 0.6, c: 1}, + 800: {a: 0.5, c: 1}, + 850: {a: 0.4, c: 1}, + 900: {a: 0.3, c: 1}, + 950: {a: 0.2, c: 1}, + 1000: {a: 0.15, c: 1}, +}; + +type Theme = 'light' | 'dark'; + +type GeneratePrivateColorsArgs = { + theme: Theme; + colorToken: string; + colorValue: string; + lightBg: string; + darkBg: string; +}; + +export const generatePrivateColors = ({ + theme, + colorToken, + colorValue, + lightBg, + darkBg, +}: GeneratePrivateColorsArgs) => { + const privateColors: Record = {}; + + if (!chroma.valid(colorValue)) { + throw Error('Not valid color for chroma'); + } + + let colorsMapInternal = colorsMap; + + if (colorToken === 'white' || colorToken === 'black') { + colorsMapInternal = themeXd[theme][colorToken].colorsMap; + } + + const pallete = Object.entries(colorsMapInternal).reduce((res, [key, {a, c}]) => { + const solidColor = chroma.mix(colorValue, c > 0 ? darkBg : lightBg, 1 - a, 'rgb').css(); + + const alphaColor = chroma(colorValue).alpha(a).css(); + + res[key] = [solidColor, alphaColor]; + + return res; + }, {} as Record); + + let privateSolidVariablesInternal = privateSolidVariables; + let privateVariablesInternal = privateVariables; + + if (colorToken === 'white' || colorToken === 'black') { + privateSolidVariablesInternal = themeXd[theme][colorToken].privateSolidVariables; + privateVariablesInternal = themeXd[theme][colorToken].privateVariables; + } + + // Set 550 Solid Color + privateColors['550-solid'] = chroma(colorValue).css(); + + // Set 50-1000 Solid Colors, except 550 Solid Color + privateSolidVariablesInternal.forEach((varName) => { + privateColors[`${varName}-solid`] = chroma(pallete[varName][0]).css(); + }); + + // Set 50-500 Colors + privateVariablesInternal.forEach((varName) => { + privateColors[`${varName}`] = chroma(pallete[varName][1]).css(); + }); + + if (theme === 'dark' && colorToken === 'white') { + const updatedColor = chroma(pallete[150][0]).alpha(0.95).css(); + privateColors['opaque-150'] = chroma(updatedColor).css(); + } + + return privateColors; +}; diff --git a/src/components/Themes/lib/themeCreatorContext.ts b/src/components/Themes/lib/themeCreatorContext.ts new file mode 100644 index 000000000000..41cb161d5900 --- /dev/null +++ b/src/components/Themes/lib/themeCreatorContext.ts @@ -0,0 +1,60 @@ +import noop from 'lodash/noop'; +import {createContext} from 'react'; + +import {BrandPreset, DEFAULT_THEME} from './constants'; +import {initThemeCreator} from './themeCreatorUtils'; +import type { + AddColorToThemeParams, + AddFontFamilyTypeParams, + ChangeRadiusPresetInThemeParams, + ChangeUtilityColorInThemeParams, + RenameColorInThemeParams, + UpdateAdvancedTypographySettingsParams, + UpdateColorInThemeParams, + UpdateCustomRadiusPresetInThemeParams, + UpdateFontFamilyParams, + UpdateFontFamilyTypeTitleParams, +} from './themeCreatorUtils'; +import type {ThemeCreatorState} from './types'; + +export const ThemeCreatorContext = createContext( + initThemeCreator(DEFAULT_THEME), +); + +export interface ThemeCreatorMethodsContextType { + addColor: (params?: AddColorToThemeParams) => void; + updateColor: (params: UpdateColorInThemeParams) => void; + removeColor: (title: string) => void; + renameColor: (params: RenameColorInThemeParams) => void; + changeUtilityColor: (params: ChangeUtilityColorInThemeParams) => void; + applyBrandPreset: (preset: BrandPreset) => void; + changeRadiusPreset: (params: ChangeRadiusPresetInThemeParams) => void; + updateCustomRadiusPreset: (params: UpdateCustomRadiusPresetInThemeParams) => void; + updateFontFamily: (params: UpdateFontFamilyParams) => void; + addFontFamilyType: (params: AddFontFamilyTypeParams) => void; + updateFontFamilyTypeTitle: (params: UpdateFontFamilyTypeTitleParams) => void; + removeFontFamilyType: ({fontType}: {fontType: string}) => void; + updateAdvancedTypographySettings: (params: UpdateAdvancedTypographySettingsParams) => void; + updateAdvancedTypography: () => void; + openMainSettings: () => void; + setAdvancedMode: (enabled: boolean) => void; +} + +export const ThemeCreatorMethodsContext = createContext({ + addColor: noop, + updateColor: noop, + removeColor: noop, + renameColor: noop, + changeUtilityColor: noop, + applyBrandPreset: noop, + changeRadiusPreset: noop, + updateCustomRadiusPreset: noop, + updateFontFamily: noop, + addFontFamilyType: noop, + updateFontFamilyTypeTitle: noop, + removeFontFamilyType: noop, + updateAdvancedTypographySettings: noop, + updateAdvancedTypography: noop, + openMainSettings: noop, + setAdvancedMode: noop, +}); diff --git a/src/components/Themes/lib/themeCreatorExport.ts b/src/components/Themes/lib/themeCreatorExport.ts new file mode 100644 index 000000000000..27f3c21be1a3 --- /dev/null +++ b/src/components/Themes/lib/themeCreatorExport.ts @@ -0,0 +1,194 @@ +import {DEFAULT_PALETTE, DEFAULT_THEME} from './constants'; +import { + createBorderRadiusPresetForExport, + createFontImportsForExport, + createPrivateColorCssVariable, + createPrivateColorCssVariableFromToken, + createPrivateColorToken, + createTypographyPresetForExport, + createUtilityColorCssVariable, + isPrivateColorToken, +} from './themeCreatorUtils'; +import type {ColorOption, ThemeCreatorState, ThemeVariant} from './types'; + +const COMMON_VARIABLES_TEMPLATE_NAME = '%COMMON_VARIABLES%'; +const LIGHT_THEME_VARIABLES_TEMPLATE_NAME = '%LIGHT_THEME_VARIABLES%'; +const DARK_THEME_VARIABLES_TEMPLATE_NAME = '%DARK_THEME_VARIABLES%'; +const FONTS_TEMPLATE_NAME = '%IMPORT_FONTS%'; + +const SCSS_TEMPLATE = ` +@use '@gravity-ui/uikit/styles/themes'; + +${FONTS_TEMPLATE_NAME} + +.g-root { + @include themes.g-theme-common; + + ${COMMON_VARIABLES_TEMPLATE_NAME} + + &_theme_light { + @include themes.g-theme-light; + + ${LIGHT_THEME_VARIABLES_TEMPLATE_NAME} + } + + &_theme_dark { + @include themes.g-theme-dark; + + ${DARK_THEME_VARIABLES_TEMPLATE_NAME} + } +} +`.trim(); + +export type ExportFormat = 'scss' | 'json'; + +type ExportThemeParams = { + themeState: ThemeCreatorState; + format?: ExportFormat; + ignoreDefaultValues?: boolean; + forPreview?: boolean; +}; + +const isBackgroundColorChanged = (themeState: ThemeCreatorState) => { + return ( + DEFAULT_THEME.colors.dark['base-background'] !== + themeState.colors.dark['base-background'] || + DEFAULT_THEME.colors.light['base-background'] !== themeState.colors.light['base-background'] + ); +}; + +export function exportTheme({ + themeState, + format = 'scss', + ignoreDefaultValues = true, + forPreview = true, +}: ExportThemeParams) { + if (format === 'json') { + throw new Error('Not implemented'); + } + + const {paletteTokens, palette} = themeState; + const backgroundColorChanged = isBackgroundColorChanged(themeState); + + const prepareThemeVariables = (themeVariant: ThemeVariant) => { + let cssVariables = ''; + const privateColors: Record = {}; + + themeState.tokens.forEach((token) => { + // Dont export colors that are equals to default (except brand color) + // Private colors recalculate when background color changes + const valueEqualsToDefault = + DEFAULT_PALETTE[themeVariant][token] === themeState.palette[themeVariant][token] && + token !== 'brand' && + !backgroundColorChanged; + + if (valueEqualsToDefault && ignoreDefaultValues) { + return; + } + + const needExportColor = + backgroundColorChanged || token === 'brand' || !valueEqualsToDefault; + + if (!needExportColor) { + return; + } + + if (paletteTokens[token]?.privateColors[themeVariant]) { + Object.entries(paletteTokens[token].privateColors[themeVariant]!).forEach( + ([privateColorCode, color]) => { + privateColors[createPrivateColorToken(token, privateColorCode)] = color; + cssVariables += `${createPrivateColorCssVariable( + token, + privateColorCode, + )}: ${color}${forPreview ? ' !important' : ''};\n`; + }, + ); + cssVariables += '\n'; + } + }); + + cssVariables += '\n'; + + cssVariables += `${createUtilityColorCssVariable('base-brand')}: ${ + palette[themeVariant].brand + }${forPreview ? ' !important' : ''};\n`; + + Object.entries(themeState.colors[themeVariant]).forEach( + ([colorName, colorOrPrivateToken]) => { + if ( + ignoreDefaultValues && + DEFAULT_THEME.colors[themeVariant][colorName as ColorOption] === + colorOrPrivateToken + ) { + return; + } + + const color = isPrivateColorToken(colorOrPrivateToken) + ? `var(${createPrivateColorCssVariableFromToken(colorOrPrivateToken)})` + : colorOrPrivateToken; + + cssVariables += `${createUtilityColorCssVariable(colorName)}: ${color}${ + forPreview ? ' !important' : '' + };\n`; + }, + ); + + if (forPreview) { + cssVariables += createBorderRadiusPresetForExport({ + borders: themeState.borders, + forPreview, + ignoreDefaultValues, + }); + + cssVariables += createTypographyPresetForExport({ + typography: themeState.typography, + ignoreDefaultValues, + forPreview, + }); + } + + return cssVariables.trim(); + }; + + const prepareCommonThemeVariables = () => { + const borderRadiusVariabels = createBorderRadiusPresetForExport({ + borders: themeState.borders, + forPreview, + ignoreDefaultValues, + }); + + const typographyVariables = createTypographyPresetForExport({ + typography: themeState.typography, + ignoreDefaultValues, + forPreview, + }); + + return borderRadiusVariabels + '\n' + typographyVariables; + }; + + return { + fontImports: createFontImportsForExport(themeState.typography.baseSetting.fontFamilies), + common: prepareCommonThemeVariables(), + light: prepareThemeVariables('light'), + dark: prepareThemeVariables('dark'), + }; +} + +type ExportThemeForDialogParams = Pick; + +export function exportThemeForDialog({themeState, format = 'scss'}: ExportThemeForDialogParams) { + if (format === 'json') { + return 'not implemented'; + } + + const {common, light, dark, fontImports} = exportTheme({ + themeState, + format, + forPreview: false, + }); + + return SCSS_TEMPLATE.replace(FONTS_TEMPLATE_NAME, fontImports) + .replace(COMMON_VARIABLES_TEMPLATE_NAME, common.replaceAll('\n', '\n'.padEnd(5))) + .replace(LIGHT_THEME_VARIABLES_TEMPLATE_NAME, light.replaceAll('\n', '\n'.padEnd(9))) + .replace(DARK_THEME_VARIABLES_TEMPLATE_NAME, dark.replaceAll('\n', '\n'.padEnd(9))); +} diff --git a/src/components/Themes/lib/themeCreatorImport.ts b/src/components/Themes/lib/themeCreatorImport.ts new file mode 100644 index 000000000000..fb5eeccd3c56 --- /dev/null +++ b/src/components/Themes/lib/themeCreatorImport.ts @@ -0,0 +1 @@ +// TODO implement import logic diff --git a/src/components/Themes/lib/themeCreatorUtils.ts b/src/components/Themes/lib/themeCreatorUtils.ts new file mode 100644 index 000000000000..532b44fb8bf8 --- /dev/null +++ b/src/components/Themes/lib/themeCreatorUtils.ts @@ -0,0 +1,869 @@ +import {TextProps} from 'landing-uikit'; +import capitalize from 'lodash/capitalize'; +import cloneDeep from 'lodash/cloneDeep'; +import kebabCase from 'lodash/kebabCase'; +import lowerCase from 'lodash/lowerCase'; +import {v4 as uuidv4} from 'uuid'; + +import { + BrandPreset, + DEFAULT_NEW_COLOR_TITLE, + DEFAULT_PALETTE_TOKENS, + RADIUS_PRESETS, + THEME_BORDER_RADIUS_VARIABLE_PREFIX, + THEME_COLOR_VARIABLE_PREFIX, +} from './constants'; +import {generatePrivateColors} from './privateColors'; +import type { + BordersOption, + ColorsOptions, + Palette, + PaletteTokens, + PrivateColors, + RadiusValue, + ThemeCreatorState, + ThemeOptions, + ThemeVariant, +} from './types'; +import {CustomFontSelectType, RadiusPresetName, TypographyOptions} from './types'; +import {DefaultFontFamilyType, TextVariants, defaultTypographyPreset} from './typography/constants'; +import { + createFontFamilyVariable, + createFontLinkImport, + createTextFontFamilyVariable, + createTextFontSizeVariable, + createTextFontWeightVariable, + createTextLineHeightVariable, + getCustomFontTypeKey, +} from './typography/utils'; + +function createColorToken(title: string) { + return kebabCase(title); +} + +function createTitleFromToken(token: string) { + return capitalize(lowerCase(token)); +} + +export function createPrivateColorToken(mainColorToken: string, privateColorCode: string) { + return `private.${mainColorToken}.${privateColorCode}`; +} + +export function isPrivateColorToken(privateColorToken?: string) { + if (!privateColorToken) { + return false; + } + + const parts = privateColorToken.split('.'); + + if (parts.length !== 3 || parts[0] !== 'private') { + return false; + } + + return true; +} + +export function parsePrivateColorToken(privateColorToken: string) { + const parts = privateColorToken.split('.'); + + if (parts.length !== 3 || parts[0] !== 'private') { + return undefined; + } + + return { + mainColorToken: parts[1], + privateColorCode: parts[2], + }; +} + +export function createPrivateColorCssVariable(mainColorToken: string, privateColorCode: string) { + return `${THEME_COLOR_VARIABLE_PREFIX}-private-${mainColorToken}-${privateColorCode}`; +} + +export function createPrivateColorCssVariableFromToken(privateColorToken: string) { + const result = parsePrivateColorToken(privateColorToken); + + if (result) { + return createPrivateColorCssVariable(result.mainColorToken, result.privateColorCode); + } + + return ''; +} + +export function createUtilityColorCssVariable(colorName: string) { + return `${THEME_COLOR_VARIABLE_PREFIX}-${colorName}`; +} + +function isManuallyCreatedToken(token: string) { + return !DEFAULT_PALETTE_TOKENS.has(token); +} + +function createNewColorTitle(currentPaletteTokens: PaletteTokens) { + let i = 0; + + // eslint-disable-next-line no-constant-condition + while (true) { + const title = i === 0 ? DEFAULT_NEW_COLOR_TITLE : `${DEFAULT_NEW_COLOR_TITLE} ${i}`; + const token = createColorToken(title); + + if (!currentPaletteTokens[token]) { + return title; + } + + i++; + } +} + +function createPrivateColors({ + themeVariant, + colorToken, + colorValue, + theme, +}: { + colorToken: string; + colorValue: string; + themeVariant: ThemeVariant; + theme: ThemeOptions; +}): PrivateColors { + return generatePrivateColors({ + theme: themeVariant, + colorToken, + colorValue, + lightBg: + themeVariant === 'light' + ? theme.colors.light['base-background'] + : theme.colors.dark['base-background'], + darkBg: + themeVariant === 'light' + ? theme.colors.dark['base-background'] + : theme.colors.light['base-background'], + }); +} + +function createPalleteTokens(theme: ThemeOptions): PaletteTokens { + const {palette} = theme; + const tokens = Object.keys(palette.light); + + return tokens.reduce( + (acc, token) => ({ + ...acc, + [token]: { + title: createTitleFromToken(token), + privateColors: { + light: palette.light[token] + ? createPrivateColors({ + colorToken: token, + colorValue: palette.light[token], + theme, + themeVariant: 'light', + }) + : undefined, + dark: palette.dark[token] + ? createPrivateColors({ + colorToken: token, + colorValue: palette.dark[token], + theme, + themeVariant: 'dark', + }) + : undefined, + }, + }, + }), + {}, + ); +} + +export type UpdateColorInThemeParams = { + /** The title of the color to update. */ + title: string; + /** The theme variant to update. */ + theme: ThemeVariant; + /** The new value of the color. */ + value: string; +}; + +/** + * Updates a color in the given theme state. + * + * @param {ThemeCreatorState} themeState - The current state of the theme. + * @param {UpdateColorInThemeParams} params - The parameters for the color update. + * @returns {ThemeCreatorState} The updated theme state. + */ +export function updateColorInTheme( + themeState: ThemeCreatorState, + params: UpdateColorInThemeParams, +): ThemeCreatorState { + const newThemeState = {...themeState}; + const token = createColorToken(params.title); + + if (params.theme === 'light') { + if (!newThemeState.palette.light[token]) { + newThemeState.palette.light[token] = ''; + } + + newThemeState.palette.light[token] = params.value; + } + + if (params.theme === 'dark') { + if (!newThemeState.palette.dark[token]) { + newThemeState.palette.dark[token] = ''; + } + + newThemeState.palette.dark[token] = params.value; + } + + const privateColors = createPrivateColors({ + colorToken: token, + colorValue: params.value, + theme: newThemeState, + themeVariant: params.theme, + }); + + newThemeState.paletteTokens[token] = { + ...newThemeState.paletteTokens[token], + title: params.title, + privateColors: { + light: + params.theme === 'light' + ? privateColors + : newThemeState.paletteTokens[token]?.privateColors?.light, + dark: + params.theme === 'dark' + ? privateColors + : newThemeState.paletteTokens[token]?.privateColors?.dark, + }, + }; + + const isNewToken = !themeState.paletteTokens[token]; + if (isNewToken) { + newThemeState.tokens.push(token); + } + + return newThemeState; +} + +export type AddColorToThemeParams = + | { + title?: string; + colors?: Partial>; + } + | undefined; + +/** + * Adds a new color to the given theme state. + * + * @param {ThemeCreatorState} themeState - The current state of the theme. + * @param {AddColorToThemeParams} params - The parameters of the adding color. + * @returns {ThemeCreatorState} The updated theme state with the new color added. + */ +export function addColorToTheme( + themeState: ThemeCreatorState, + params: AddColorToThemeParams, +): ThemeCreatorState { + const newThemeState = {...themeState}; + const title = params?.title ?? createNewColorTitle(themeState.paletteTokens); + const token = createColorToken(title); + + if (!themeState.palette.dark[token]) { + newThemeState.palette.dark = { + ...newThemeState.palette.dark, + [token]: '', + }; + } + + if (!themeState.palette.light[token]) { + newThemeState.palette.light = { + ...newThemeState.palette.light, + [token]: '', + }; + } + + if (params?.colors?.dark) { + newThemeState.palette.dark = { + ...newThemeState.palette.dark, + [token]: params.colors.dark, + }; + } + + if (params?.colors?.light) { + newThemeState.palette.light = { + ...newThemeState.palette.light, + [token]: params.colors.light, + }; + } + + newThemeState.paletteTokens = { + ...newThemeState.paletteTokens, + [token]: { + ...newThemeState.paletteTokens[token], + title, + privateColors: { + light: params?.colors?.light + ? createPrivateColors({ + colorToken: token, + colorValue: params.colors.light, + theme: newThemeState, + themeVariant: 'light', + }) + : undefined, + dark: params?.colors?.dark + ? createPrivateColors({ + colorToken: token, + colorValue: params.colors.dark, + theme: newThemeState, + themeVariant: 'dark', + }) + : undefined, + }, + isCustom: true, + }, + }; + + newThemeState.tokens = [...newThemeState.tokens, token]; + + return newThemeState; +} + +export function removeColorFromTheme( + themeState: ThemeCreatorState, + colorTitle: string, +): ThemeCreatorState { + const newThemeState = {...themeState}; + const token = createColorToken(colorTitle); + + delete newThemeState.palette.dark[token]; + delete newThemeState.palette.light[token]; + delete newThemeState.paletteTokens[token]; + + newThemeState.tokens = newThemeState.tokens.filter((t) => t !== token); + + return newThemeState; +} + +export type RenameColorInThemeParams = { + oldTitle: string; + newTitle: string; +}; + +export function renameColorInTheme( + themeState: ThemeCreatorState, + {oldTitle, newTitle}: RenameColorInThemeParams, +): ThemeCreatorState { + const newThemeState = {...themeState}; + const oldToken = createColorToken(oldTitle); + const newToken = createColorToken(newTitle); + + if (newThemeState.paletteTokens[oldToken]) { + newThemeState.paletteTokens[newToken] = { + ...newThemeState.paletteTokens[oldToken], + title: newTitle, + }; + newThemeState.palette.dark[newToken] = newThemeState.palette.dark[oldToken]; + newThemeState.palette.light[newToken] = newThemeState.palette.light[oldToken]; + } + + newThemeState.tokens = newThemeState.tokens.map((token) => + token === oldToken ? newToken : token, + ); + + delete newThemeState.palette.dark[oldToken]; + delete newThemeState.palette.light[oldToken]; + delete newThemeState.paletteTokens[oldToken]; + + return newThemeState; +} + +export type ThemeColorOption = { + token: string; + title: string; + color: string; + privateColors: { + token: string; + title: string; + color: string; + }[]; +}; + +/** + * Generates theme color options from the given palette tokens and theme variant. + * + * @param {Object} params - The parameters for generating theme color options. + * @param {PaletteTokens} params.paletteTokens - The palette tokens to generate options from. + * @param {ThemeVariant} params.themeVariant - The theme variant to filter private colors (light, dark). + * @returns {ThemeColorOption[]} The generated theme color options. + */ +export function getThemeColorOptions({ + themeState, + themeVariant, +}: { + themeState: ThemeCreatorState; + themeVariant: ThemeVariant; +}) { + const {tokens, paletteTokens, palette} = themeState; + + return tokens.reduce((acc, token) => { + if (paletteTokens[token]?.privateColors[themeVariant]) { + return [ + ...acc, + { + token, + color: palette[themeVariant][token], + title: paletteTokens[token].title, + privateColors: Object.entries( + paletteTokens[token].privateColors[themeVariant]!, + ).map(([privateColorCode, color]) => ({ + token: createPrivateColorToken(token, privateColorCode), + title: createPrivateColorCssVariable(token, privateColorCode), + color, + })), + }, + ]; + } + + return acc; + }, []); +} + +export type ChangeUtilityColorInThemeParams = { + themeVariant: ThemeVariant; + name: keyof ColorsOptions; + value: string; +}; + +export function changeUtilityColorInTheme( + themeState: ThemeCreatorState, + {themeVariant, name, value}: ChangeUtilityColorInThemeParams, +): ThemeCreatorState { + const newState = {...themeState}; + newState.colors[themeVariant][name] = value; + + if (name === 'base-background') { + newState.paletteTokens = createPalleteTokens(newState); + } + + return newState; +} + +export function applyBrandPresetToTheme( + themeState: ThemeCreatorState, + {brandColor, colors}: BrandPreset, +): ThemeCreatorState { + let newState = {...themeState}; + + (['light', 'dark'] as const).forEach((theme) => { + newState = updateColorInTheme(newState, { + theme, + title: 'brand', + value: brandColor, + }); + }); + + newState.colors.light = {...colors.light}; + newState.colors.dark = {...colors.dark}; + + return newState; +} + +export function getThemePalette(theme: ThemeCreatorState): Palette { + return theme.tokens.map((token) => { + return { + title: theme.paletteTokens[token]?.title || '', + colors: { + light: theme.palette.light[token], + dark: theme.palette.dark[token], + }, + isCustom: isManuallyCreatedToken(token), + }; + }); +} + +export function initThemeCreator(inputTheme: ThemeOptions): ThemeCreatorState { + const theme = cloneDeep(inputTheme); + const paletteTokens = createPalleteTokens(theme); + + return { + ...theme, + paletteTokens, + tokens: Object.keys(paletteTokens), + showMainSettings: false, + advancedModeEnabled: false, + changesExist: false, + }; +} + +export type ChangeRadiusPresetInThemeParams = { + radiusPresetName: RadiusPresetName; +}; + +export function changeRadiusPresetInTheme( + themeState: ThemeCreatorState, + {radiusPresetName}: ChangeRadiusPresetInThemeParams, +): ThemeCreatorState { + const newBorderValue = { + preset: radiusPresetName, + values: {...RADIUS_PRESETS[radiusPresetName]}, + }; + + return {...themeState, borders: newBorderValue}; +} + +export type UpdateCustomRadiusPresetInThemeParams = {radiusValue: Partial}; + +export function updateCustomRadiusPresetInTheme( + themeState: ThemeCreatorState, + {radiusValue}: UpdateCustomRadiusPresetInThemeParams, +): ThemeCreatorState { + const previousRadiusValues = themeState.borders.values; + const newCustomPresetValues = { + preset: RadiusPresetName.Custom, + values: {...previousRadiusValues, ...radiusValue}, + }; + + return {...themeState, borders: newCustomPresetValues}; +} + +function createBorderRadiusCssVariable(radiusSize: string) { + return `${THEME_BORDER_RADIUS_VARIABLE_PREFIX}-${radiusSize}`; +} + +/** + * Generates ready-to-use in css string with borders variables + * @returns string + */ +export function createBorderRadiusPresetForExport({ + borders, + forPreview, + ignoreDefaultValues, +}: { + borders: BordersOption; + ignoreDefaultValues: boolean; + forPreview: boolean; +}) { + // Don't export radius preset that are equals to default + if (ignoreDefaultValues && borders.preset === RadiusPresetName.Regular) { + return ''; + } + let cssString = ''; + Object.entries(borders.values).forEach(([radiusName, radiusValue]) => { + if (radiusValue) { + cssString += `${createBorderRadiusCssVariable(radiusName)}: ${radiusValue}px${ + forPreview ? ' !important' : '' + };\n`; + } + }); + return cssString; +} + +export type UpdateFontFamilyParams = { + fontType: DefaultFontFamilyType | string; + fontWebsite?: string; + isCustom?: boolean; + customType?: string; + value?: { + title: string; + key: string; + link: string; + alternatives: string[]; + }; +}; + +export function updateFontFamilyInTheme( + themeState: ThemeCreatorState, + {fontType, value, isCustom, fontWebsite, customType}: UpdateFontFamilyParams, +): ThemeCreatorState { + const previousFontFamilySettings = themeState.typography.baseSetting.fontFamilies; + + const newFontFamilySettings = { + ...previousFontFamilySettings, + [fontType]: { + ...previousFontFamilySettings[fontType], + ...(value || {}), + isCustom, + customType: customType || previousFontFamilySettings[fontType].customType, + fontWebsite, + }, + }; + + return { + ...themeState, + typography: { + ...themeState.typography, + baseSetting: { + ...themeState.typography.baseSetting, + fontFamilies: newFontFamilySettings, + }, + }, + }; +} + +export type AddFontFamilyTypeParams = { + title: string; +}; + +export function addFontFamilyTypeInTheme( + themeState: ThemeCreatorState, + {title}: AddFontFamilyTypeParams, +): ThemeCreatorState { + const {customFontFamilyType} = themeState.typography.baseSetting; + const newFontType = `custom-font-type-${uuidv4()}`; + + const newCustomFontFamily = [ + ...customFontFamilyType, + { + value: newFontType, + content: title, + }, + ]; + + return { + ...themeState, + typography: { + ...themeState.typography, + baseSetting: { + ...themeState.typography.baseSetting, + fontFamilies: { + ...themeState.typography.baseSetting.fontFamilies, + [newFontType]: { + isCustom: true, + customType: CustomFontSelectType.GoogleFonts, + title: '', + key: '', + link: '', + alternatives: [], + }, + }, + customFontFamilyType: newCustomFontFamily, + }, + }, + }; +} + +export type UpdateFontFamilyTypeTitleParams = { + title: string; + familyType: string; +}; + +export function updateFontFamilyTypeTitleInTheme( + themeState: ThemeCreatorState, + {title, familyType}: UpdateFontFamilyTypeTitleParams, +): ThemeCreatorState { + const {customFontFamilyType} = themeState.typography.baseSetting; + + const newCustomFontFamily = customFontFamilyType.map((fontFamilyType) => { + return fontFamilyType.value === familyType + ? { + content: title, + value: familyType, + } + : fontFamilyType; + }); + + return { + ...themeState, + typography: { + ...themeState.typography, + baseSetting: { + ...themeState.typography.baseSetting, + customFontFamilyType: newCustomFontFamily, + }, + }, + }; +} + +export function removeFontFamilyTypeFromTheme( + themeState: ThemeCreatorState, + {fontType}: {fontType: string}, +): ThemeCreatorState { + const {customFontFamilyType, fontFamilies} = themeState.typography.baseSetting; + + const {[fontType]: _, ...restFontFamilies} = fontFamilies; + + const newCustomFontFamilyType = customFontFamilyType.filter( + (fontFamily) => fontFamily.value !== fontType, + ); + + const newAdvanced = cloneDeep(themeState.typography.advanced); + + // Reset selected font to default + Object.entries(newAdvanced).forEach(([textVariant, settings]) => { + if (settings.selectedFontFamilyType === fontType) { + newAdvanced[textVariant as TextVariants].selectedFontFamilyType = + defaultTypographyPreset.advanced[ + textVariant as TextVariants + ].selectedFontFamilyType; + } + }); + + return { + ...themeState, + typography: { + ...themeState.typography, + advanced: newAdvanced, + baseSetting: { + ...themeState.typography.baseSetting, + fontFamilies: restFontFamilies, + customFontFamilyType: newCustomFontFamilyType, + }, + }, + }; +} + +export type UpdateAdvancedTypographySettingsParams = { + key: TextVariants; + fontWeight?: number; + selectedFontFamilyType?: string; + sizeKey?: Exclude; + fontSize?: number; + lineHeight?: number; +}; + +export function updateAdvancedTypographySettingsInTheme( + themeState: ThemeCreatorState, + { + key, + fontSize, + selectedFontFamilyType, + sizeKey, + fontWeight, + lineHeight, + }: UpdateAdvancedTypographySettingsParams, +): ThemeCreatorState { + const previousTypographyAdvancedSettings = themeState.typography.advanced; + + const newSizes = sizeKey + ? { + [sizeKey]: { + ...previousTypographyAdvancedSettings[key].sizes[sizeKey], + fontSize: + fontSize ?? previousTypographyAdvancedSettings[key].sizes[sizeKey]?.fontSize, + lineHeight: + lineHeight ?? + previousTypographyAdvancedSettings[key].sizes[sizeKey]?.lineHeight, + }, + } + : {}; + + const newTypographyAdvancedSettings = { + ...previousTypographyAdvancedSettings, + [key]: { + ...previousTypographyAdvancedSettings[key], + fontWeight: fontWeight ?? previousTypographyAdvancedSettings[key].fontWeight, + selectedFontFamilyType: + selectedFontFamilyType ?? + previousTypographyAdvancedSettings[key].selectedFontFamilyType, + sizes: { + ...previousTypographyAdvancedSettings[key].sizes, + ...newSizes, + }, + }, + }; + + return { + ...themeState, + typography: { + ...themeState.typography, + advanced: { + ...newTypographyAdvancedSettings, + }, + }, + }; +} + +export const updateAdvancedTypographyInTheme = ( + themeState: ThemeCreatorState, +): ThemeCreatorState => { + return { + ...themeState, + typography: { + ...themeState.typography, + isAdvancedActive: !themeState.typography.isAdvancedActive, + }, + }; +}; + +export const createFontImportsForExport = ( + fontFamily: TypographyOptions['baseSetting']['fontFamilies'], +) => { + let cssString = ''; + + Object.entries(fontFamily).forEach(([, value]) => { + cssString += `${createFontLinkImport(value.link)}\n`; + }); + + return cssString; +}; + +export const createTypographyPresetForExport = ({ + typography, + forPreview, +}: { + typography: TypographyOptions; + ignoreDefaultValues: boolean; + forPreview: boolean; +}) => { + const {baseSetting, advanced} = typography; + let cssString = ''; + + Object.entries(baseSetting.fontFamilies).forEach(([key, value]) => { + const customFontKey = getCustomFontTypeKey(key, baseSetting.customFontFamilyType); + + cssString += `${createFontFamilyVariable( + customFontKey ? kebabCase(customFontKey) : key, + value.title, + value.alternatives, + forPreview, + )}\n`; + }); + + Object.entries(advanced).forEach(([key, data]) => { + const defaultAdvancedSetting = defaultTypographyPreset.advanced[key as TextVariants]; + + if (defaultAdvancedSetting.selectedFontFamilyType !== data.selectedFontFamilyType) { + const customFontTypeKey = getCustomFontTypeKey( + data.selectedFontFamilyType, + baseSetting.customFontFamilyType, + ); + + cssString += `${createTextFontFamilyVariable( + key as TextVariants, + customFontTypeKey ? kebabCase(customFontTypeKey) : data.selectedFontFamilyType, + forPreview, + )}\n`; + } + if (defaultAdvancedSetting.fontWeight !== data.fontWeight) { + cssString += `${createTextFontWeightVariable( + key as TextVariants, + data.fontWeight, + forPreview, + )}\n`; + cssString += '\n'; + } + + Object.entries(data.sizes).forEach(([sizeKey, sizeData]) => { + if ( + defaultAdvancedSetting.sizes[sizeKey as Exclude] + ?.fontSize !== sizeData.fontSize + ) { + cssString += `${createTextFontSizeVariable( + sizeKey as TextProps['variant'], + sizeData.fontSize, + forPreview, + )}\n`; + } + + if ( + defaultAdvancedSetting.sizes[sizeKey as Exclude] + ?.lineHeight !== sizeData.lineHeight + ) { + cssString += `${createTextLineHeightVariable( + sizeKey as TextProps['variant'], + sizeData.lineHeight, + forPreview, + )}\n`; + cssString += '\n'; + } + }); + }); + + return cssString; +}; diff --git a/src/components/Themes/lib/types.ts b/src/components/Themes/lib/types.ts new file mode 100644 index 000000000000..8a7cc1662b43 --- /dev/null +++ b/src/components/Themes/lib/types.ts @@ -0,0 +1,130 @@ +import {TextProps} from 'landing-uikit'; + +import {DefaultFontFamilyType, TextVariants} from './typography/constants'; + +export type ThemeVariant = 'light' | 'dark'; + +export type PaletteOptions = { + brand: string; + [key: string]: string; +}; + +export type ColorsOptions = { + 'base-background': string; + 'base-brand-hover': string; + 'base-selection': string; + 'base-selection-hover': string; + 'line-brand': string; + 'text-brand': string; + 'text-brand-heavy': string; + 'text-brand-contrast': string; + 'text-link': string; + 'text-link-hover': string; + 'text-link-visited': string; + 'text-link-visited-hover': string; +}; + +export type ColorOption = keyof ColorsOptions; + +export type RadiusSizeName = 'xs' | 's' | 'm' | 'l' | 'xl'; + +export enum RadiusPresetName { + Regular = 'radius_regular', + Circled = 'radius_circled', + Squared = 'radius_squared', + Custom = 'radius_custom', +} + +export type RadiusValue = Record; + +export type BordersOption = { + preset: RadiusPresetName; + values: RadiusValue; +}; + +export enum CustomFontSelectType { + GoogleFonts = 'google-fonts', + Manual = 'manual', +} + +export type TypographyOptions = { + baseSetting: { + defaultFontFamilyType: { + value: DefaultFontFamilyType; + content: string; + }[]; + customFontFamilyType: { + value: string; + content: string; + }[]; + fontFamilies: Record< + string, + { + title: string; + key: string; + link: string; + alternatives: string[]; + isCustom?: boolean; + customType?: string; + fontWebsite?: string; + } + >; + }; + isAdvancedActive: boolean; + advanced: Record< + TextVariants, + { + title: string; + fontWeight: number; + selectedFontFamilyType: DefaultFontFamilyType; + sizes: Partial< + Record< + Exclude, + { + title: string; + fontSize: number; + lineHeight: number; + } + > + >; + } + >; +}; + +export interface ThemeOptions { + /** Values of solid colors, from which private colors are calculated */ + palette: Record; + /** Utility colors that used in components (background, link, brand-text, etc.) */ + colors: Record; + borders: BordersOption; + typography: TypographyOptions; +} + +export type PrivateColors = Record; + +type PaletteToken = { + /** Title that will using in UI */ + title: string; + /** Is color manually created */ + isCustom?: boolean; + /** Auto-generated private colors for each theme variant */ + privateColors: Record; +}; + +export type PaletteTokens = Record; + +export interface ThemeCreatorState extends ThemeOptions { + /** Mapping color tokens to their information (title and private colors) */ + paletteTokens: PaletteTokens; + /** All available palette tokens in theme */ + tokens: string[]; + showMainSettings: boolean; + advancedModeEnabled: boolean; + changesExist: boolean; +} + +export type Palette = { + title: string; + isCustom?: boolean; + colors: Record; +}[]; diff --git a/src/components/Themes/lib/typography/constants.ts b/src/components/Themes/lib/typography/constants.ts new file mode 100644 index 000000000000..0a7dc8f7b7c5 --- /dev/null +++ b/src/components/Themes/lib/typography/constants.ts @@ -0,0 +1,214 @@ +import {CustomFontSelectType, TypographyOptions} from '../types'; + +export const THEME_FONT_FAMILY_PREFIX = '--g-font-family'; +export const THEME_TEXT_PREFIX = '--g-text'; + +export enum DefaultFontFamilyType { + Sans = 'sans', + Monospace = 'monospace', +} + +export enum TextVariants { + Body = 'body', + Caption = 'caption', + Header = 'header', + Subheader = 'subheader', + Display = 'display', + Code = 'code', +} + +export const FONT_WEIGHTS = [100, 200, 300, 400, 500, 600, 700, 800, 900]; + +export const GOOGLE_FONTS_DOWNLOAD_HOST = 'https://fonts.googleapis.com/css2'; +export const GOOGLE_FONTS_FONT_PREVIEW_HOST = 'https://fonts.google.com/specimen/'; + +export const DEFAULT_FONTS: Record = { + sans: ["'Helvetica Neue'", "'Helvetica'", "'Arial'", 'sans-serif'], + monospace: [ + "'Menlo'", + "'Monaco'", + "'Consolas'", + "'Ubuntu Mono'", + "'Liberation Mono'", + "'DejaVu Sans Mono'", + "'Courier New'", + "'Courier'", + 'monospace', + ], +}; + +export const defaultTypographyPreset: TypographyOptions = { + baseSetting: { + customFontFamilyType: [], + defaultFontFamilyType: [ + {value: DefaultFontFamilyType.Sans, content: 'Sans Font Family'}, + {value: DefaultFontFamilyType.Monospace, content: 'Monospace Font Family'}, + ], + fontFamilies: { + [DefaultFontFamilyType.Sans]: { + title: 'Inter', + key: 'inter', + link: 'https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap', + customType: CustomFontSelectType.GoogleFonts, + alternatives: DEFAULT_FONTS[DefaultFontFamilyType.Sans], + }, + [DefaultFontFamilyType.Monospace]: { + title: 'Roboto Mono', + key: 'roboto_mono', + link: 'https://fonts.googleapis.com/css2?family=Roboto+Mono:ital,wght@0,100..700;1,100..700&display=swap', + customType: CustomFontSelectType.GoogleFonts, + alternatives: DEFAULT_FONTS[DefaultFontFamilyType.Monospace], + }, + }, + }, + isAdvancedActive: false, + advanced: { + [TextVariants.Body]: { + title: 'Body Text', + fontWeight: 400, + selectedFontFamilyType: DefaultFontFamilyType.Sans, + sizes: { + 'body-short': { + title: 'Body 1 Short', + fontSize: 13, + lineHeight: 16, + }, + 'body-1': { + title: 'Body 1', + fontSize: 13, + lineHeight: 18, + }, + 'body-2': { + title: 'Body 2', + fontSize: 15, + lineHeight: 20, + }, + 'body-3': { + title: 'Body 3', + fontSize: 17, + lineHeight: 24, + }, + }, + }, + [TextVariants.Caption]: { + title: 'Caption', + fontWeight: 400, + selectedFontFamilyType: DefaultFontFamilyType.Sans, + sizes: { + 'caption-1': { + title: 'Caption 1', + fontSize: 9, + lineHeight: 12, + }, + 'caption-2': { + title: 'Caption 2', + fontSize: 11, + lineHeight: 16, + }, + }, + }, + [TextVariants.Header]: { + title: 'Header', + fontWeight: 600, + selectedFontFamilyType: DefaultFontFamilyType.Sans, + sizes: { + 'header-1': { + title: 'Header 1', + fontSize: 20, + lineHeight: 24, + }, + 'header-2': { + title: 'Header 2', + fontSize: 24, + lineHeight: 28, + }, + }, + }, + [TextVariants.Subheader]: { + title: 'Subheader', + fontWeight: 600, + selectedFontFamilyType: DefaultFontFamilyType.Sans, + sizes: { + 'subheader-1': { + title: 'Subheader 1', + fontSize: 13, + lineHeight: 18, + }, + 'subheader-2': { + title: 'Subheader 2', + fontSize: 15, + lineHeight: 20, + }, + 'subheader-3': { + title: 'Subheader 3', + fontSize: 17, + lineHeight: 24, + }, + }, + }, + [TextVariants.Display]: { + title: 'Display', + fontWeight: 600, + selectedFontFamilyType: DefaultFontFamilyType.Sans, + sizes: { + 'display-1': { + title: 'Display 1', + fontSize: 28, + lineHeight: 36, + }, + 'display-2': { + title: 'Display 2', + fontSize: 32, + lineHeight: 40, + }, + 'display-3': { + title: 'Display 3', + fontSize: 40, + lineHeight: 48, + }, + 'display-4': { + title: 'Display 4', + fontSize: 48, + lineHeight: 52, + }, + }, + }, + [TextVariants.Code]: { + title: 'Code', + fontWeight: 600, + selectedFontFamilyType: DefaultFontFamilyType.Monospace, + sizes: { + 'code-1': { + title: 'Code 1', + fontSize: 12, + lineHeight: 18, + }, + 'code-inline-1': { + title: 'Code Inline 1', + fontSize: 12, + lineHeight: 14, + }, + 'code-2': { + title: 'Code 2', + fontSize: 14, + lineHeight: 20, + }, + 'code-inline-2': { + title: 'Code Inline 2', + fontSize: 14, + lineHeight: 16, + }, + 'code-3': { + title: 'Code 3', + fontSize: 16, + lineHeight: 24, + }, + 'code-inline-3': { + title: 'Code Inline 3', + fontSize: 16, + lineHeight: 20, + }, + }, + }, + }, +}; diff --git a/src/components/Themes/lib/typography/utils.ts b/src/components/Themes/lib/typography/utils.ts new file mode 100644 index 000000000000..bd06d3075252 --- /dev/null +++ b/src/components/Themes/lib/typography/utils.ts @@ -0,0 +1,80 @@ +import {TextProps} from 'landing-uikit'; + +import {TypographyOptions} from '../types'; + +import { + GOOGLE_FONTS_DOWNLOAD_HOST, + THEME_FONT_FAMILY_PREFIX, + THEME_TEXT_PREFIX, + TextVariants, +} from './constants'; + +export const createFontLinkImport = (fontLink: string) => { + return `@import url('${fontLink}');`; +}; + +export const createFontFamilyVariable = ( + fontFamilyType: string, + value: string, + alternatives: string[], + forPreview: boolean, +) => { + return `${THEME_FONT_FAMILY_PREFIX}-${fontFamilyType}: '${value}'${ + alternatives.length ? `, ${alternatives.join(', ')}` : '' + }${forPreview ? '!important' : ''};`; +}; + +export const createTextFontWeightVariable = ( + textVariant: TextVariants, + value: number, + forPreview: boolean, +) => { + return `${THEME_TEXT_PREFIX}-${textVariant}-font-weight: ${value}${ + forPreview ? '!important' : '' + };`; +}; + +export const createTextFontFamilyVariable = ( + textVariant: TextVariants, + value: string, + forPreview: boolean, +) => { + return `${THEME_TEXT_PREFIX}-${textVariant}-font-family: var(${THEME_FONT_FAMILY_PREFIX}-${value})${ + forPreview ? '!important' : '' + };`; +}; + +export const createTextFontSizeVariable = ( + variant: TextProps['variant'], + value: number, + forPreview: boolean, +) => { + return `${THEME_TEXT_PREFIX}-${variant}-font-size: ${value}px${ + forPreview ? '!important' : '' + };`; +}; + +export const createTextLineHeightVariable = ( + variant: TextProps['variant'], + value: number, + forPreview: boolean, +) => { + return `${THEME_TEXT_PREFIX}-${variant}-line-height: ${value}px${ + forPreview ? '!important' : '' + };`; +}; + +export const generateGoogleFontDownloadLink = (fontName?: string) => { + if (!fontName) { + return ''; + } + + return `${GOOGLE_FONTS_DOWNLOAD_HOST}?family=${fontName}&display=swap`; +}; + +export const getCustomFontTypeKey = ( + key: string, + customFontFamilyType: TypographyOptions['baseSetting']['customFontFamilyType'], +) => { + return customFontFamilyType.find((setting) => setting.value === key)?.content.toLowerCase(); +}; diff --git a/src/components/Themes/ui/BasicPalette/AddColorButton.scss b/src/components/Themes/ui/BasicPalette/AddColorButton.scss new file mode 100644 index 000000000000..f9dd80f30b3c --- /dev/null +++ b/src/components/Themes/ui/BasicPalette/AddColorButton.scss @@ -0,0 +1,14 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}theme-palette-add-color-button'; + +#{$block} { + --g-button-border-radius: var(--g-spacing-2); + margin-top: var(--g-spacing-4); + width: min-content; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + width: 100%; + } +} diff --git a/src/components/Themes/ui/BasicPalette/AddColorButton.tsx b/src/components/Themes/ui/BasicPalette/AddColorButton.tsx new file mode 100644 index 000000000000..d85752b78388 --- /dev/null +++ b/src/components/Themes/ui/BasicPalette/AddColorButton.tsx @@ -0,0 +1,24 @@ +import {Plus} from 'landing-icons'; +import {Button, Icon} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {block} from '../../../../utils'; + +import './AddColorButton.scss'; + +const b = block('theme-palette-add-color-button'); + +interface AddColorButtonProps { + onClick: () => void; +} + +export const AddColorButton: React.FC = ({onClick}) => { + const {t} = useTranslation('themes'); + + return ( + + ); +}; diff --git a/src/components/Themes/ui/BasicPalette/BasicPalette.tsx b/src/components/Themes/ui/BasicPalette/BasicPalette.tsx new file mode 100644 index 000000000000..6b2f793bfb9f --- /dev/null +++ b/src/components/Themes/ui/BasicPalette/BasicPalette.tsx @@ -0,0 +1,61 @@ +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {useThemeCreatorMethods, useThemePalette} from '../../hooks'; +import {ThemeVariant} from '../../lib/types'; +import {ColorPickerInput} from '../ColorPickerInput/ColorPickerInput'; +import {ThemableSettings} from '../ThemableSettings/ThemableSettings'; +import {ThemableRow} from '../ThemableSettings/types'; +import {ThemeSection} from '../ThemeSection'; + +import {AddColorButton} from './AddColorButton'; +import {PaletteColorEditor} from './PaletteColorEditor'; + +const hiddenColors = new Set(['white', 'black', 'brand']); + +export const BasicPalette = () => { + const {t} = useTranslation('themes'); + + const {addColor, removeColor, updateColor, renameColor} = useThemeCreatorMethods(); + const origPalette = useThemePalette(); + + const palette = React.useMemo( + () => origPalette.filter(({title}) => !hiddenColors.has(title.toLowerCase())), + [origPalette], + ); + + const rows = React.useMemo( + () => + palette.map((paletteColorData) => ({ + id: paletteColorData.title, + title: paletteColorData.title, + renderTitle: () => ( + + ), + render: (currentTheme: ThemeVariant) => ( + + updateColor({theme: currentTheme, title: paletteColorData.title, value}) + } + /> + ), + })), + [palette, removeColor, renameColor], + ); + + return ( + + } + /> + + ); +}; diff --git a/src/components/Themes/ui/BasicPalette/PaletteColorEditor.scss b/src/components/Themes/ui/BasicPalette/PaletteColorEditor.scss new file mode 100644 index 000000000000..0673e5d65ba8 --- /dev/null +++ b/src/components/Themes/ui/BasicPalette/PaletteColorEditor.scss @@ -0,0 +1,56 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}theme-palette-color-editor'; + +#{$block} { + display: flex; + gap: var(--g-spacing-2); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + flex-direction: column-reverse; + } + + &__default-title { + padding: var(--g-spacing-2) 0; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding: 0; + } + } + + & &__input { + padding-inline-start: 9px; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + padding-inline-start: 3px; + } + } + + &__input-title { + display: none; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + display: block; + padding-left: var(--g-spacing-2); + padding-top: 1px; + } + } + + &__header { + display: flex; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + justify-content: space-between; + align-items: center; + } + } + + &__title { + display: none; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + display: block; + } + } +} diff --git a/src/components/Themes/ui/BasicPalette/PaletteColorEditor.tsx b/src/components/Themes/ui/BasicPalette/PaletteColorEditor.tsx new file mode 100644 index 000000000000..aed0838ee2ca --- /dev/null +++ b/src/components/Themes/ui/BasicPalette/PaletteColorEditor.tsx @@ -0,0 +1,83 @@ +import {TrashBin} from 'landing-icons'; +import {Button, Icon, Text, TextInput} from 'landing-uikit'; +import debounce from 'lodash/debounce'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {Palette} from '../../lib/types'; + +import './PaletteColorEditor.scss'; + +const b = block('theme-palette-color-editor'); + +interface PaletteColorEditorProps { + paletteColorData: Palette[0]; + onUpdateTitle: (params: {oldTitle: string; newTitle: string}) => void; + onDelete: (title: string) => void; +} + +export const PaletteColorEditor: React.FC = ({ + onDelete, + onUpdateTitle, + paletteColorData, +}) => { + const {title, isCustom} = paletteColorData; + + const [localTitle, setLocalTitle] = React.useState(title); + + React.useEffect(() => { + setLocalTitle(title); + }, [title]); + + const handleDelete = React.useCallback(() => onDelete(title), [onDelete, title]); + + const updateTitle = React.useCallback( + (newTitle: string) => onUpdateTitle({oldTitle: title, newTitle}), + [title, onUpdateTitle], + ); + + const debouncedUpdateTitle = React.useMemo(() => debounce(updateTitle, 500), [updateTitle]); + + const handleUpdateTitle = React.useCallback( + (newTitle: string) => { + setLocalTitle(newTitle); + debouncedUpdateTitle(newTitle); + }, + [debouncedUpdateTitle], + ); + + if (!isCustom) { + return ( +
+ {title} +
+ ); + } + + return ( +
+ + Name: + + } + /> +
+ + New color + + +
+
+ ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/BorderCard/BorderCard.tsx b/src/components/Themes/ui/BorderRadiusTab/BorderCard/BorderCard.tsx new file mode 100644 index 000000000000..f26562d7f1c9 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/BorderCard/BorderCard.tsx @@ -0,0 +1,32 @@ +import {useTranslation} from 'next-i18next'; +import React, {useCallback} from 'react'; +import {SelectableCard} from 'src/components/SelectableCard/SelectableCard'; +import {RADIUS_PRESETS} from 'src/components/Themes/lib/constants'; +import {RadiusPresetName} from 'src/components/Themes/lib/types'; + +export type BorderCardProps = { + preset: RadiusPresetName; + selected: boolean; + onClick: (preset: RadiusPresetName) => void; +}; + +export const BorderCard = ({selected, preset, onClick}: BorderCardProps) => { + const {t} = useTranslation('themes'); + + const handleClick = useCallback(() => { + onClick(preset); + }, [preset]); + + const displayName = t(preset); + const borderRadiusStyle = {borderRadius: RADIUS_PRESETS[preset]?.m + 'px'}; + + return ( + + ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/BorderPresets/BorderPresets.tsx b/src/components/Themes/ui/BorderRadiusTab/BorderPresets/BorderPresets.tsx new file mode 100644 index 000000000000..5af16520186a --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/BorderPresets/BorderPresets.tsx @@ -0,0 +1,49 @@ +import {Col, Row} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {useCallback} from 'react'; +import {ChangeRadiusPresetInThemeParams} from 'src/components/Themes/lib/themeCreatorUtils'; +import {RadiusPresetName} from 'src/components/Themes/lib/types'; + +import {ThemeSection} from '../../ThemeSection'; +import {BorderCard, BorderCardProps} from '../BorderCard/BorderCard'; + +const ColCard = (props: BorderCardProps) => ( + + + +); + +const PRESETS_ORDER = [ + RadiusPresetName.Regular, + RadiusPresetName.Circled, + RadiusPresetName.Squared, + RadiusPresetName.Custom, +]; + +export type BorderPresetsProps = { + selectedPreset: RadiusPresetName; + onClick: (preset: ChangeRadiusPresetInThemeParams) => void; +}; + +export const BorderPresets = ({selectedPreset, onClick}: BorderPresetsProps) => { + const {t} = useTranslation('themes'); + + const handleClick = useCallback((preset: RadiusPresetName) => { + onClick({radiusPresetName: preset}); + }, []); + + return ( + + + {PRESETS_ORDER.map((preset) => ( + + ))} + + + ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.scss b/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.scss new file mode 100644 index 000000000000..d67246ae836c --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.scss @@ -0,0 +1,15 @@ +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '../../../../variables.scss'; + +$block: '.#{variables.$ns}border-radius-tab'; + +#{$block} { + @include themes.g-theme-common; //restore default uikit styles for components + + gap: calc(var(--g-spacing-base) * 24); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + gap: calc(var(--g-spacing-base) * 12); + } +} diff --git a/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.tsx b/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.tsx new file mode 100644 index 000000000000..d4e32d9610a0 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/BorderRadiusTab.tsx @@ -0,0 +1,34 @@ +import {Flex} from 'landing-uikit'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {useThemeCreator, useThemeCreatorMethods} from '../../hooks'; +import {RadiusPresetName} from '../../lib/types'; +import {ExportThemeSection} from '../ExportThemeSection/ExportThemeSection'; + +import {BorderPresets} from './BorderPresets/BorderPresets'; +import './BorderRadiusTab.scss'; +import {ComponentPreview} from './ComponentPreview/ComponentPreview'; +import {CustomRadius} from './CustomRadius/CustomRadius'; + +const b = block('border-radius-tab'); + +export const BorderRadiusTab = () => { + const themeState = useThemeCreator(); + + const {changeRadiusPreset, updateCustomRadiusPreset} = useThemeCreatorMethods(); + + const preset = themeState.borders.preset; + const values = themeState.borders.values; + + return ( + + + {preset === RadiusPresetName.Custom && ( + + )} + + + + ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/ComponentPreview/ComponentPreview.tsx b/src/components/Themes/ui/BorderRadiusTab/ComponentPreview/ComponentPreview.tsx new file mode 100644 index 000000000000..430191079f49 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/ComponentPreview/ComponentPreview.tsx @@ -0,0 +1,23 @@ +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {useThemeCreator} from '../../../hooks'; +import {exportTheme} from '../../../lib/themeCreatorExport'; +import {ThemeSection} from '../../ThemeSection'; +import {Showcase} from '../Showcase/Showcase'; + +export const ComponentPreview = () => { + const {t} = useTranslation('themes'); + const themeState = useThemeCreator(); + + const themeStyles = React.useMemo( + () => exportTheme({themeState, ignoreDefaultValues: false}), + [themeState], + ); + + return ( + + + + ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.scss b/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.scss new file mode 100644 index 000000000000..ac2e41b4dbf3 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.scss @@ -0,0 +1,28 @@ +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '../../../../../variables.scss'; +@use '../../../../../mixins.scss' as baseMixins; + +$root: '.g-root'; +$block: '.#{variables.$ns}custom-radius'; + +// Workaround for missing theme class in ThemeProvider +$workaroundBlockDarkTheme: &#{$block}_theme_dark; + +#{$block} { + &__px { + margin-inline: 8px; + } + + &__radius-input-row { + align-items: center; + input::-webkit-outer-spin-button, + input::-webkit-inner-spin-button { + appearance: none; + margin: 0; + } + input[type='number'] { + appearance: textfield; + } + } +} diff --git a/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.tsx b/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.tsx new file mode 100644 index 000000000000..3f530187ffbb --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/CustomRadius/CustomRadius.tsx @@ -0,0 +1,74 @@ +import {Col, Flex, Row, Text, TextInput} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {useCallback, useMemo} from 'react'; +import {UpdateCustomRadiusPresetInThemeParams} from 'src/components/Themes/lib/themeCreatorUtils'; +import {RadiusSizeName, RadiusValue} from 'src/components/Themes/lib/types'; + +import {block} from '../../../../../utils'; +import {ThemeSection} from '../../ThemeSection'; + +import './CustomRadius.scss'; + +const b = block('custom-radius'); + +type RadiusInputProps = { + radiusSizeName: RadiusSizeName; + onUpdate: (param: UpdateCustomRadiusPresetInThemeParams) => void; + value?: string; +}; + +const RadiusInputRow = ({radiusSizeName, onUpdate, value}: RadiusInputProps) => { + const {t} = useTranslation('themes'); + + const text = useMemo(() => t('radius') + ` ${radiusSizeName.toUpperCase()}`, [radiusSizeName]); + + const handleUpdate = useCallback( + (newValue: string) => { + onUpdate({radiusValue: {[radiusSizeName]: newValue}}); + }, + [radiusSizeName], + ); + + return ( + + + {text} + + + + px + + } + /> + + + ); +}; + +type CustomRadiusProps = { + values: RadiusValue; + onUpdate: (param: UpdateCustomRadiusPresetInThemeParams) => void; +}; + +export const CustomRadius = ({onUpdate, values}: CustomRadiusProps) => { + const {t} = useTranslation('themes'); + + return ( + + + + + + + + + + ); +}; diff --git a/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.scss b/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.scss new file mode 100644 index 000000000000..cc7e82206699 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.scss @@ -0,0 +1,27 @@ +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '../../../../../variables.scss'; +@use '../../../../../mixins.scss' as baseMixins; + +$root: '.g-root'; +$block: '.#{variables.$ns}border-radius-showcase'; + +#{$block} { + padding: 40px; + border-radius: 24px; + + &__column-transform { + @media (max-width: (map-get(pcVariables.$gridBreakpoints, 'md') - 1)) { + flex-direction: column; + width: 100%; + } + } + + &__text-input-block { + flex-grow: 1; + @media (max-width: (map-get(pcVariables.$gridBreakpoints, 'lg') - 1)) { + flex-direction: column; + width: 100%; + } + } +} diff --git a/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.tsx b/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.tsx new file mode 100644 index 000000000000..419414e8f898 --- /dev/null +++ b/src/components/Themes/ui/BorderRadiusTab/Showcase/Showcase.tsx @@ -0,0 +1,127 @@ +import {PencilToLine} from 'landing-icons'; +import { + Button, + Flex, + FlexProps, + Label, + RadioButton, + TextInput, + Theme, + ThemeProvider, +} from 'landing-uikit'; +import type {ButtonProps} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React, {useMemo} from 'react'; + +import {block} from '../../../../../utils'; + +import './Showcase.scss'; + +const b = block('border-radius-showcase'); + +export type ShowcaseProps = { + color?: string; + theme: Theme; + style?: string; +}; + +type ShowcaseBlockProps = FlexProps & { + text: string; +}; + +const BlockWrapper = (props: FlexProps) => ( + + {props.children} + +); +const LabelBlock = (props: ShowcaseBlockProps) => ( + + + + + +); + +const getIconSize = (size: ButtonProps['size']) => { + switch (size) { + case 'xs': + return 12; + case 'xl': + return 20; + default: + return 16; + } +}; + +const ShowcaseButton = ({size, children}: Pick) => { + const iconSize = getIconSize(size); + return ( + + ); +}; + +const ButtonBlock = (props: ShowcaseBlockProps) => ( + + {props.text} + {props.text} + {props.text} + {props.text} + {props.text} + +); + +const RadioButtonBlock = (props: ShowcaseBlockProps) => { + const radioButtonOptions = useMemo( + () => [ + {value: '1', content: props.text}, + {value: '2', content: props.text}, + ], + [], + ); + return ( + + + + + + + ); +}; +const TextInputBlock = (props: ShowcaseBlockProps) => ( + + + + + + +); + +const borderRadiusShowcaseCn = b(); + +export const Showcase: React.FC = ({color, theme, style}) => { + const {t} = useTranslation('themes'); + + return ( + + {style ? : null} + + + + + + + + + + + ); +}; diff --git a/src/components/Themes/ui/BrandColors/BrandColors.scss b/src/components/Themes/ui/BrandColors/BrandColors.scss new file mode 100644 index 000000000000..e3b7f14e2139 --- /dev/null +++ b/src/components/Themes/ui/BrandColors/BrandColors.scss @@ -0,0 +1,65 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}brand-colors'; + +#{$block} { + gap: 32px; + + &__brand-color-picker { + display: flex; + gap: 2px; + overflow: auto; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + margin: 0 -24px; + padding: 0 24px; + } + } + + &__color { + display: flex; + align-items: center; + justify-content: center; + border: 2px solid transparent; + border-radius: 12px; + padding: 6px; + cursor: pointer; + + &_custom { + --color-value: conic-gradient( + from 180deg at 50% 50%, + #fa00ff -47.18deg, + #ffd028 46.82deg, + #00e6bd 138.38deg, + #6932de 223.7deg, + #fa00ff 312.82deg, + #ffd028 406.82deg + ); + + gap: 8px; + padding-right: 18px; + border-color: rgba(255, 255, 255, 0.15); + } + + &_selected { + border-color: var(--color-value); + + &#{$block}__color_custom { + border-color: rgba(255, 197, 108, 1); + } + } + + &-inner { + background: var(--color-value); + border-radius: 5px; + height: 32px; + width: 32px; + } + } + + &__switch-button { + --g-button-border-radius: 8px; + width: min-content; + } +} diff --git a/src/components/Themes/ui/BrandColors/BrandColors.tsx b/src/components/Themes/ui/BrandColors/BrandColors.tsx new file mode 100644 index 000000000000..e857956124dc --- /dev/null +++ b/src/components/Themes/ui/BrandColors/BrandColors.tsx @@ -0,0 +1,104 @@ +import {Sliders} from 'landing-icons'; +import {Button, Flex, Icon, Text} from 'landing-uikit'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {useThemeCreatorMethods, useThemePaletteColor} from '../../hooks'; +import {BRAND_COLORS_PRESETS} from '../../lib/constants'; +import {ThemeSection} from '../ThemeSection'; + +import './BrandColors.scss'; + +const b = block('brand-colors'); + +interface BrandColorsProps { + showThemeEditButton?: boolean; + onEditThemeClick: () => void; + onSelectCustomColor: () => void; +} + +export const BrandColors: React.FC = ({ + showThemeEditButton, + onEditThemeClick, + onSelectCustomColor, +}) => { + const [customModeEnabled, setCustomMode] = React.useState(false); + + const [lightBrandColor] = useThemePaletteColor({ + token: 'brand', + theme: 'light', + }); + const [darkBrandColor] = useThemePaletteColor({ + token: 'brand', + theme: 'dark', + }); + + const {applyBrandPreset} = useThemeCreatorMethods(); + + const activeColorIndex = React.useMemo(() => { + return BRAND_COLORS_PRESETS.findIndex( + (value) => value.brandColor === lightBrandColor && value.brandColor === darkBrandColor, + ); + }, [lightBrandColor, darkBrandColor]); + + const setBrandPreset = React.useCallback( + (index: number) => { + setCustomMode(false); + + if (activeColorIndex === index) { + return; + } + + applyBrandPreset(BRAND_COLORS_PRESETS[index]); + }, + [activeColorIndex, applyBrandPreset], + ); + + const handleSelectCustomColor = React.useCallback(() => { + setCustomMode(true); + onSelectCustomColor(); + }, [onSelectCustomColor]); + + return ( + + +
+ {BRAND_COLORS_PRESETS.map((value, index) => ( +
setBrandPreset(index)} + > +
+
+ ))} +
+
+ Custom +
+
+ + {showThemeEditButton && ( + + )} + + ); +}; diff --git a/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.scss b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.scss new file mode 100644 index 000000000000..bce7eb6580e7 --- /dev/null +++ b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.scss @@ -0,0 +1,34 @@ +@use '../../../../variables.scss'; + +$block: '.#{variables.$ns}color-picker'; + +#{$block} { + --g-border-radius-xl: 8px; + flex-grow: 1; + position: relative; + + &__text-input { + z-index: 1; + } + + &__preview { + margin-inline-start: var(--g-spacing-2); + margin-inline-end: var(--g-spacing-1); + + &_with-border { + border: 1px solid var(--g-color-line-generic); + } + } + + &__input { + width: 35px; + opacity: 0; + padding: 0; + margin: 0; + border: 0; + position: absolute; + bottom: 0; + right: 0; + z-index: 0; + } +} diff --git a/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx new file mode 100644 index 000000000000..ee69d733e22f --- /dev/null +++ b/src/components/Themes/ui/ColorPickerInput/ColorPickerInput.tsx @@ -0,0 +1,139 @@ +import {Palette} from 'landing-icons'; +import {Button, Flex, Icon, TextInput, TextInputProps} from 'landing-uikit'; +import debounce from 'lodash/debounce'; +import {useTranslation} from 'next-i18next'; +import React, {ChangeEventHandler, useCallback, useEffect, useRef, useState} from 'react'; + +import {block} from '../../../../utils'; +import {ColorPreview} from '../ColorPreview/ColorPreview'; + +import './ColorPickerInput.scss'; +import {NativeColorPicker} from './NativeColorPicker'; +import {getValidColor, isValidColor} from './utils'; + +const b = block('color-picker'); + +export interface ColorPickerInputProps { + defaultValue: string; + name?: string; + value?: string; + onChange: (color: string) => void; + errorMessage?: string; + size?: TextInputProps['size']; + withBorderInPreview?: boolean; +} + +export const ColorPickerInput = ({ + name, + value, + onChange: onChangeExternal, + defaultValue, + errorMessage, + size = 'l', + withBorderInPreview, +}: ColorPickerInputProps) => { + const {t} = useTranslation('themes'); + + const debouncedExternalChange = React.useMemo( + () => debounce(onChangeExternal, 200), + [onChangeExternal], + ); + + const [color, setColor] = useState(() => { + const validColor = getValidColor(defaultValue); + + return validColor ?? ''; + }); + + const [inputValue, setInputValue] = useState(value ?? defaultValue); + const [validationError, setValidationError] = useState(); + + const colorInputRef = useRef(null); + + const validateAndChangeExternal = React.useCallback( + (newValue: string, formatValueToHex = false) => { + if (!isValidColor(newValue)) { + setValidationError('invalid'); + return; + } + + setValidationError(undefined); + + let formattedValue = newValue; + + if (formatValueToHex) { + const validColor = getValidColor(newValue); + if (validColor !== undefined) { + formattedValue = validColor; + } + } + + setInputValue(formattedValue); + setColor(formattedValue); + debouncedExternalChange(formattedValue); + }, + [debouncedExternalChange], + ); + + const onChange: ChangeEventHandler = useCallback((event) => { + const newValue = event.target.value; + setInputValue(newValue); + setValidationError(undefined); + }, []); + + const onNativeInputChange: ChangeEventHandler = useCallback( + (e) => { + const newValue = e.target.value.toUpperCase(); + setInputValue(newValue); + validateAndChangeExternal(newValue, true); + }, + [validateAndChangeExternal], + ); + + const onBlur = useCallback(() => { + validateAndChangeExternal(inputValue); + }, [inputValue, validateAndChangeExternal]); + + useEffect(() => { + // Dont validate if not initial value + if (!value && !defaultValue) { + return; + } + + validateAndChangeExternal(value ?? defaultValue); + }, [value, defaultValue]); + + return ( + + + } + endContent={ + + } + onBlur={onBlur} + /> + + + ); +}; diff --git a/src/components/Themes/ui/ColorPickerInput/NativeColorPicker.tsx b/src/components/Themes/ui/ColorPickerInput/NativeColorPicker.tsx new file mode 100644 index 000000000000..d38b529d5008 --- /dev/null +++ b/src/components/Themes/ui/ColorPickerInput/NativeColorPicker.tsx @@ -0,0 +1,35 @@ +import React, {ChangeEventHandler, forwardRef} from 'react'; + +import {block} from '../../../../utils'; + +import './ColorPickerInput.scss'; +import {getValidColor} from './utils'; + +export interface NativeColorPickerProps { + value: string; + onChange: ChangeEventHandler; +} + +const b = block('color-picker__input'); + +export const NativeColorPicker = forwardRef( + ({value, onChange}, ref) => { + const normalizedValue = React.useMemo(() => { + try { + return getValidColor(value); + } catch (_err) { + return value; + } + }, [value]); + + return ( + + ); + }, +); diff --git a/src/components/Themes/ui/ColorPickerInput/utils.ts b/src/components/Themes/ui/ColorPickerInput/utils.ts new file mode 100644 index 000000000000..c2fa475d8f17 --- /dev/null +++ b/src/components/Themes/ui/ColorPickerInput/utils.ts @@ -0,0 +1,45 @@ +import chroma from 'chroma-js'; + +export const hexRegexp = /^#[a-fA-F0-9]{6}$/; +export const rgbRegexp = /^rgb\((\d{1,3}, ?){2}(\d{1,3})\)$/; +export const rgbaRegexp = /^rgba\((\d{1,3}, ?){3}((0(,|\.)[0-9]{1,2})|1)\)$/; + +const numberRegexp = /\b\d+\b/g; + +export const parseRgbStringToHex = (rgbString: string) => { + let hexColor = '#'; + rgbString.match(new RegExp(numberRegexp, 'g'))?.forEach((val) => { + const hex = Number(val).toString(16); + + hexColor += hex?.length === 1 ? `0${hex}` : hex; + }); + + return hexColor; +}; + +export const isValidColor = (textColor: string) => { + try { + chroma(textColor); + return true; + } catch (_err) { + return false; + } +}; + +export const getValidColor = (textColor: string) => { + const testColor = textColor.replaceAll(' ', ''); + + if ( + !testColor || + new RegExp(hexRegexp, 'g').test(testColor) || + new RegExp(rgbaRegexp, 'g').test(testColor) + ) { + return textColor; + } + + if (new RegExp(rgbRegexp, 'g').test(testColor)) { + return chroma(testColor).hex(); + } + + return undefined; +}; diff --git a/src/components/Themes/ui/ColorPreview/ColorPreview.scss b/src/components/Themes/ui/ColorPreview/ColorPreview.scss new file mode 100644 index 000000000000..3ef56f7f9baf --- /dev/null +++ b/src/components/Themes/ui/ColorPreview/ColorPreview.scss @@ -0,0 +1,35 @@ +@use '../../../../variables.scss'; + +$block: '.#{variables.$ns}color-preview'; + +#{$block} { + --chess: rgb(235, 235, 235); + --surface: rgb(255, 255, 255); + --opacity-pattern: repeating-conic-gradient(var(--chess) 0% 25%, var(--surface) 0% 50%) 50% / + 8px 8px; + + width: 16px; + height: 16px; + border-radius: var(--g-border-radius-xs); + overflow: hidden; + position: relative; + + &__color { + position: relative; + width: 100%; + height: 100%; + } + + &_with-opacity { + &::before { + content: ''; + display: block; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + background: var(--opacity-pattern); + } + } +} diff --git a/src/components/Themes/ui/ColorPreview/ColorPreview.tsx b/src/components/Themes/ui/ColorPreview/ColorPreview.tsx new file mode 100644 index 000000000000..235b8c69100e --- /dev/null +++ b/src/components/Themes/ui/ColorPreview/ColorPreview.tsx @@ -0,0 +1,22 @@ +import React from 'react'; + +import {block} from '../../../../utils'; + +import './ColorPreview.scss'; + +export interface ColorPreviewProps { + color?: string; + className?: string; +} + +const b = block('color-preview'); + +const isColorWithOpacity = (color?: string) => !color || color?.startsWith('rgba'); + +export const ColorPreview = ({color, className}: ColorPreviewProps) => { + return ( +
+
+
+ ); +}; diff --git a/src/components/Themes/ui/ColorsTab/ColorsTab.scss b/src/components/Themes/ui/ColorsTab/ColorsTab.scss new file mode 100644 index 000000000000..a2061ec559c4 --- /dev/null +++ b/src/components/Themes/ui/ColorsTab/ColorsTab.scss @@ -0,0 +1,12 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}colors-tab'; + +#{$block} { + gap: calc(var(--g-spacing-base) * 24); + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'sm')) { + gap: calc(var(--g-spacing-base) * 12); + } +} diff --git a/src/components/Themes/ui/ColorsTab/ColorsTab.tsx b/src/components/Themes/ui/ColorsTab/ColorsTab.tsx new file mode 100644 index 000000000000..afaaa2e83a4e --- /dev/null +++ b/src/components/Themes/ui/ColorsTab/ColorsTab.tsx @@ -0,0 +1,116 @@ +import {Flex} from 'landing-uikit'; +import {Trans, useTranslation} from 'next-i18next'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {useThemeCreator, useThemeCreatorMethods} from '../../hooks'; +import {BasicPalette} from '../BasicPalette/BasicPalette'; +import {BrandColors} from '../BrandColors/BrandColors'; +import {ComponentPreview} from '../ComponentPreview/ComponentPreview'; +import {ExportThemeSection} from '../ExportThemeSection/ExportThemeSection'; +import {MainSettings} from '../MainSettings/MainSettings'; +import {EditableColorOption, PrivateColorsSettings} from '../PrivateColorsSettings'; + +import './ColorsTab.scss'; + +const b = block('colors-tab'); + +const ADVANCED_COLORS_OPTIONS: EditableColorOption[] = [ + { + title: 'Hovered Brand Color', + name: 'base-brand-hover', + }, + { + title: 'Brand Text', + name: 'text-brand', + }, + { + title: 'Higher Contrast Brand Text', + name: 'text-brand-heavy', + }, + { + title: 'Brand Line Color', + name: 'line-brand', + }, + { + title: 'Selection Background', + name: 'base-selection', + }, + { + title: 'Hovered Selection Background', + name: 'base-selection-hover', + }, +]; + +const ADDITIONAL_COLORS_OPTIONS: EditableColorOption[] = [ + { + title: 'Link', + name: 'text-link', + }, + { + title: 'Hovered Link', + name: 'text-link-hover', + }, + { + title: 'Visited Link', + name: 'text-link-visited', + }, + { + title: 'Hovered Visited Link', + name: 'text-link-visited-hover', + }, +]; + +export const ColorsTab = () => { + const {t} = useTranslation('themes'); + + const {advancedModeEnabled, showMainSettings} = useThemeCreator(); + const {setAdvancedMode, openMainSettings} = useThemeCreatorMethods(); + + const toggleAdvancedMode = React.useCallback( + () => setAdvancedMode(!advancedModeEnabled), + [setAdvancedMode, advancedModeEnabled], + ); + + const handleSelectCustomColor = React.useCallback(() => { + openMainSettings(); + setAdvancedMode(true); + }, [openMainSettings, setAdvancedMode]); + + return ( + + + {showMainSettings && ( + + )} + {advancedModeEnabled && ( + + + +
+ + } + options={ADVANCED_COLORS_OPTIONS} + /> + +
+ )} + + +
+ ); +}; diff --git a/src/components/Themes/ui/ComponentPreview/ComponentPreview.tsx b/src/components/Themes/ui/ComponentPreview/ComponentPreview.tsx new file mode 100644 index 000000000000..093427eda4ac --- /dev/null +++ b/src/components/Themes/ui/ComponentPreview/ComponentPreview.tsx @@ -0,0 +1,37 @@ +import {Flex} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import dynamic from 'next/dynamic'; +import React from 'react'; + +import {useThemeCreator} from '../../hooks'; +import {exportTheme} from '../../lib/themeCreatorExport'; +import {ThemeSection} from '../ThemeSection'; + +const Showcase = dynamic( + () => + import('../../../../blocks/Examples/components/Showcase/Showcase').then( + (res) => res.Showcase, + ), + { + ssr: false, + }, +); + +export const ComponentPreview = () => { + const {t} = useTranslation('themes'); + const themeState = useThemeCreator(); + + const themeStyles = React.useMemo( + () => exportTheme({themeState, ignoreDefaultValues: false}), + [themeState], + ); + + return ( + + + + + + + ); +}; diff --git a/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.scss b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.scss new file mode 100644 index 000000000000..616630036482 --- /dev/null +++ b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.scss @@ -0,0 +1,11 @@ +@use '../../../../variables.scss'; + +$block: '.#{variables.$ns}export-theme-section'; + +#{$block} { + --g-button-border-radius: 8px; + + &__export-button { + width: min-content; + } +} diff --git a/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx new file mode 100644 index 000000000000..170a01ebdec7 --- /dev/null +++ b/src/components/Themes/ui/ExportThemeSection/ExportThemeSection.tsx @@ -0,0 +1,27 @@ +import {ArrowUpFromSquare} from 'landing-icons'; +import {Button, Icon} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {ThemeExportDialog} from '../ThemeExportDialog/ThemeExportDialog'; +import {ThemeSection} from '../ThemeSection'; + +import './ExportThemeSection.scss'; + +const b = block('export-theme-section'); + +export const ExportThemeSection = () => { + const {t} = useTranslation('themes'); + const [isDialogVisible, toggleDialog] = React.useReducer((isOpen) => !isOpen, false); + + return ( + + + + + ); +}; diff --git a/src/components/Themes/ui/MainSettings/MainSettings.scss b/src/components/Themes/ui/MainSettings/MainSettings.scss new file mode 100644 index 000000000000..1acbadbdd644 --- /dev/null +++ b/src/components/Themes/ui/MainSettings/MainSettings.scss @@ -0,0 +1,28 @@ +@use '../../../../variables.scss'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; + +$block: '.#{variables.$ns}main-settings'; + +#{$block} { + --g-button-border-radius: 8px; + --g-text-input-border-radius: 8px; + + &__switch-button { + margin-top: var(--g-spacing-3); + width: min-content; + } + + &__text-card { + width: 50%; + } + + &__text-contrast-title { + height: 80px; + display: flex; + align-items: center; + + @media (max-width: map-get(pcVariables.$gridBreakpoints, 'md')) { + height: auto; + } + } +} diff --git a/src/components/Themes/ui/MainSettings/MainSettings.tsx b/src/components/Themes/ui/MainSettings/MainSettings.tsx new file mode 100644 index 000000000000..a18e7a093d53 --- /dev/null +++ b/src/components/Themes/ui/MainSettings/MainSettings.tsx @@ -0,0 +1,152 @@ +import {Sliders} from 'landing-icons'; +import {Button, Flex, Icon, Text} from 'landing-uikit'; +import {useTranslation} from 'next-i18next'; +import React from 'react'; + +import {block} from '../../../../utils'; +import {SelectableCard} from '../../../SelectableCard/SelectableCard'; +import {useThemePaletteColor, useThemeUtilityColor} from '../../hooks'; +import {TEXT_CONTRAST_COLORS} from '../../lib/constants'; +import type {ColorsOptions, ThemeVariant} from '../../lib/types'; +import {ColorPickerInput} from '../ColorPickerInput/ColorPickerInput'; +import {ThemableSettings} from '../ThemableSettings/ThemableSettings'; +import {ThemableRow} from '../ThemableSettings/types'; +import {ThemeSection} from '../ThemeSection'; + +import './MainSettings.scss'; + +const b = block('main-settings'); + +const BASE_CARD_BUTTON_STYLES = { + borderRadius: '8px', + padding: '10px 16px', + height: 'auto', + width: 'auto', +}; + +interface ThemeUtilityColorEditorProps { + name: keyof ColorsOptions; + theme: ThemeVariant; +} + +const ThemeUtilityColorEditor: React.FC = ({name, theme}) => { + const [color, setColor] = useThemeUtilityColor({ + name, + theme, + }); + + return ( + + ); +}; + +const BrandColorEditor: React.FC<{theme: ThemeVariant}> = ({theme}) => { + const [brandColor, setBrandColor] = useThemePaletteColor({token: 'brand', theme}); + + return ( + + ); +}; + +const TextContrastColorEditor: React.FC<{theme: ThemeVariant}> = ({theme}) => { + const [brandTextColor, setBrandTextColor] = useThemeUtilityColor({ + name: 'text-brand-contrast', + theme, + }); + + const [brandColor] = useThemePaletteColor({token: 'brand', theme}); + + return ( + + setBrandTextColor(TEXT_CONTRAST_COLORS[theme].black)} + textProps={{ + style: { + ...BASE_CARD_BUTTON_STYLES, + color: TEXT_CONTRAST_COLORS[theme].black, + backgroundColor: brandColor, + }, + }} + /> + setBrandTextColor(TEXT_CONTRAST_COLORS[theme].white)} + textProps={{ + style: { + ...BASE_CARD_BUTTON_STYLES, + color: TEXT_CONTRAST_COLORS[theme].white, + backgroundColor: brandColor, + }, + }} + /> + + ); +}; + +interface MainSettingsProps { + advancedModeEnabled: boolean; + toggleAdvancedMode: () => void; +} + +export const MainSettings: React.FC = ({ + advancedModeEnabled, + toggleAdvancedMode, +}) => { + const {t} = useTranslation('themes'); + + const rows = React.useMemo(() => { + return [ + { + id: 'base-background', + title: t('page_background'), + render: (theme) => , + }, + { + id: 'brand', + title: t('brand_color'), + render: (theme) => , + }, + { + id: 'text-brand-contrast', + title: 'Text on Brand', + render: (theme) => , + renderTitle: () => ( +
+ Text on Brand +
+ ), + }, + ]; + }, [t]); + + return ( + + + + {advancedModeEnabled ? t('hide_advanced_settings') : t('advanced_settings')} + + } + /> + + ); +}; diff --git a/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.scss b/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.scss new file mode 100644 index 000000000000..bce0faaed4e5 --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.scss @@ -0,0 +1,26 @@ +@use '../../../../../variables'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; + +$block: '.#{variables.$ns}cards-preview'; + +#{$block} { + width: 100%; + height: 100%; + overflow: auto; + + &__card { + width: 295px; + height: 430px; + padding: var(--g-spacing-1) var(--g-spacing-1) 0; + + &__content { + padding: var(--g-spacing-5) var(--g-spacing-4); + height: 100%; + + &__footer { + margin-block-start: auto; + } + } + } +} diff --git a/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.tsx b/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.tsx new file mode 100644 index 000000000000..049b146692f4 --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/CardsPreview/CardsPreview.tsx @@ -0,0 +1,59 @@ +import {Card, Flex, Text, User} from 'landing-uikit'; +import React from 'react'; + +import avatar1Asset from '../../../../../assets/avatar-1.png'; +import {block} from '../../../../../utils'; +import {cardData} from '../constants'; + +import './CardsPreview.scss'; + +const b = block('cards-preview'); + +const PreviewCard = ({ + imgSrc, + title, + text, + date, + user, +}: { + imgSrc: string; + title: string; + text: string; + date: string; + user: string; +}) => { + return ( + + + {user} + + + {title} + {text} + + + {date} + + + + + + ); +}; + +export const CardsPreview = ({justify}: {justify: string}) => { + return ( + + Cards + + {cardData.map((card, index) => ( + + ))} + + + ); +}; diff --git a/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.scss b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.scss new file mode 100644 index 000000000000..6f59ea1c54b1 --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.scss @@ -0,0 +1,18 @@ +@use '../../../../../variables'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; + +$block: '.#{variables.$ns}dashboards-preview'; + +#{$block} { + overflow-y: auto; + + &__card { + flex: 1; + padding: var(--g-spacing-5); + } + + &__dashboard-wrapper { + height: 230px; + } +} diff --git a/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx new file mode 100644 index 000000000000..10d420d6ccac --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/DashboardsPreview/DashboardPreview.tsx @@ -0,0 +1,80 @@ +import ChartKit, {settings} from '@gravity-ui/chartkit'; +import {D3Plugin} from '@gravity-ui/chartkit/d3'; +import {Card, Col, Container, Flex, Row, Text} from 'landing-uikit'; +import React, {PropsWithChildren} from 'react'; + +import {block} from '../../../../../utils'; +import { + areaDashboardData, + barXDashboardData, + dotsDashboardData, + linesDashboardData, + pieDashboardData, +} from '../constants'; + +import './DashboardPreview.scss'; + +interface StyleCardProps extends PropsWithChildren {} + +settings.set({plugins: [D3Plugin]}); + +const b = block('dashboards-preview'); + +const StyledCard = ({children}: StyleCardProps) => { + return ( + + {children} + + ); +}; + +export const DashboardPreview = ({justify}: {justify: string}) => { + return ( + + Dashboard + + + + About + + + A dashboard is a visual representation of key performance indicators + (KPIs) that helps businesses monitor and analyze their performance in + real time. It typically includes graphs, charts, and tables that + summarize data from multiple sources, such as financial reports, + customer surveys, and operational metrics. Dashboards allow businesses + to quickly identify trends and opportunities for improvement, making + them a valuable tool for decision-making and strategy development. + + + + + + {[barXDashboardData, linesDashboardData, areaDashboardData].map( + (data, index) => ( + + +
+ +
+
+ + ), + )} +
+ + {[pieDashboardData, dotsDashboardData].map((data, index) => ( + + +
+ +
+
+ + ))} +
+
+
+
+ ); +}; diff --git a/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.scss b/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.scss new file mode 100644 index 000000000000..203467e4b858 --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.scss @@ -0,0 +1,13 @@ +@use '../../../../../variables'; +@use '~@gravity-ui/page-constructor/styles/variables.scss' as pcVariables; +@use '~@gravity-ui/uikit/styles/themes/_index.scss' as themes; + +$block: '.#{variables.$ns}form-preview'; + +#{$block} { + overflow: auto; + + &__wrapper { + width: 600px; + } +} diff --git a/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.tsx b/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.tsx new file mode 100644 index 000000000000..6fc8e375de08 --- /dev/null +++ b/src/components/Themes/ui/PreviewTab/FormPreview/FormPreview.tsx @@ -0,0 +1,82 @@ +import {FormRow} from '@gravity-ui/components'; +import {ArrowLeft} from 'landing-icons'; +import {Button, Flex, Icon, Select, Text, TextArea} from 'landing-uikit'; +import React from 'react'; + +import {block} from '../../../../../utils'; +import {labels, projects, users} from '../constants'; + +import './FormPreview.scss'; + +const b = block('form-preview'); + +export const FormPreview = ({justify}: {justify: string}) => { + return ( + + + User edit + + + ({ + value: pr, + content: pr, + }))} + disablePortal={true} + /> + or + + + + +

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 literal 0 HcmV?d00001 diff --git a/src/assets/preview-card-2.png b/src/assets/preview-card-2.png new file mode 100644 index 0000000000000000000000000000000000000000..af28b8db6267f98c2af2a46bd4d593b16756f4e1 GIT binary patch literal 91862 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%0D>Dr>q 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 N002ovPDHLkV1k&KtRDaX literal 0 HcmV?d00001 diff --git a/src/assets/preview-card-3.png b/src/assets/preview-card-3.png new file mode 100644 index 0000000000000000000000000000000000000000..b5a33662064d699fc5acb8e27d9368425e03b3bd GIT binary patch literal 89858 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%0DL+b4A>6~ zt|XYjHN7}&c#n}__}{wquCbSOppm8r*$yt;q~b6Y$IU4cx}ZA(g|^%!M(BmAd}EV2 zNrY4$-@DD8Snbq=&=Mz=kTGM2iush9)GMgA*9E%!?8y4AyOgIj2ON+x&>dLDfrF_= z%c2l@b>{(o);@>4M=?8O`#aDcQ=znbfix@?&N z;ndGXK`h2YpM&f~ztv#d8-^I6Y_3 z<^+Ym<$p-?)R+%Xe1gKKY=giI0a-keRZa6Zp@lF;L>xF0q&QKHKQt2FV-cshluGVVKr3qCh?My9o7JyT4-?oN2d5GV-Ut`7Y4lPdfuV;&N(q({ z$)AwkfW^fcJZY!IEE@+0?ivPcpM#7tt{EB6Qpt*?5&Ga~7#^xbWR@BB#kJ^WGNxYr znC`d3onv~3)L~}Aq|X9v3%#rt9~4V_js?E5vZ`Qlm5mkA_pGOQ@SV>;lg81$)D@rV zl%eEk6ahFPNWJ44sKN-E2ea5#rxwG~wsaFAU0$sy0zEZHfi38~Y^^^e)%r-&s;Opq z;5G+bSYkK^+aO1luB}bzCYY0F_djK9IXkyttY=Nf-+%Z}J%gTHx&E@E>X9^b@xxU| z8ONi?k60)Qy7qN7cv$p{OG~ywU22pf+hX9WX@rP@Yw$kE2hz!lt$%yUUPwK;`}s%e z2}QD}12C^%R97>05OK$APt+rspI=m*DB|CUf!7yRRN=M(b z*cm{%dUbH40Y;;!4vQHWT2td`e`20Wv8Hx}4@qa4b>eVdP)@1$`!h5KFEo&l;;f8M zD;74Tz;MN>>{;O~)C4qvEyw)ztHZEVjBy%$+ z6^omJG&A`c!u;=(+)xCoO?yVDgVd9 zHlH5%USaMmI(b!AUt293+y5p#yYIw>Z7|gSawHgPl;T<=ahb1zp%l+e5;;YR46VvP zbzUqh@O^)B$AI>~D`H4NKDDRQ_QOsflH-~KCxZ(B8d=z+Ibc|aTB?q&O^C;Rv9<0z zsxS{V@vu1zb$-=Qu*4`e^@z}TbGU98C1j=gPC)@3Xx21?iEK7S)1t5d;JedF)gb-EWy+C+HgVEW!MH(|kS!ys_>b1c`hJ-8_{WQ{<;iQx?&#Xi%e)Hz5tig)m z)-^TzF<#cx*)#Qm)-`O|k)wkhzERBb`WodY*iIw1Sp-uSlRxOSWP7tgqktmSc5|0u z)Bc`XSWV|n>LPw}?@L+G5bl+mugUo2tQDE@P!Ky%w}xw$3@mr8bU*8MeImQVh$AsTA3yK>xIc zZOhBEG@j4~0_O?g$l>838wt$K&GFv|E%3Vu#h9k1Cae}LGvkBz1t?4HnK~R-_k3S5rT>0?UEcrB_hoKr zh0W8J)RkNK;5{8wP3!BX1@Mg&{ra<~q_ z8pj%Aiw+)bNXIe-Y{X9Lc*AWcupi}C1Y_;R#ObexrwNrq6)v}-#k)h9g1lH zGoaR=ErL*z-t!C>JUna^)Wr`#KzUM{s7ZIH7%eDOiWF3ckdq@>Z!lXK|yQV!;Sk+KS%Nt%Wo4qrAkh4 zD;sWRTS@LDH0n6Kz2vCtqQ=v7e6#qYU~2&Y@ryniN;u#h5GvJOo06^?w2m5fNPL8v zsYG@9u3|Ok&aG0XC}ZDvlhz2lfh%ArF^P#|+Fz0@}u83 zA|9nbBQqp+$k_e3YC96;0-q?ztn8v_Y^=_3xNf}R!S9P9n19%N1tbo74+z*AH#{>^ zM$QGM1uO_&M-+|mwMk$eUK|)H*jMnI@P8;@eDMX>VeD$CTJG>*cnD7s*TrtbRYn&( z+nc7}lR2r{z`}S+%d*+$fPk|*5&8Oa8va#XLx*~GiWC-%Nn10;b;Ww4@fursqhUi^ zLo*BKoW4)s!~@~5JiPNOxqtf?6bb8f8)Wcy9bW^?Wyo5BQ7}k41lnwYgw9j2o>D2{ zb?f!4Y1s`dblTh5qUV7O6B^dtyZxyGSm)Ry?Bn13LcaUGAINJ8K#wbS z1U-?-$!i){BISF?lK*@6@5|=KGxdPRc~j_^ac*UqfEntLN@{RE`{mziDtZUXSy3SkXSc3VhY08OL|Y&?4? zvAVtI&R>y1JZ9L2jD~UrSqNv)@PJ@E3{RV~DK)<6;iHGLvbxNFL)8G`4H(hzLgC$^ zbOz%D`H`q*En@BE;kk-U3|BggHzTg-+D4S6fQ2cYb^lfwqYZ-l&RI#*sNWa z3)f%Quh%rno|L+JXDE+=htt7&04MF}kZ%9(_!B+IsM+7!s9TF~u@rvh4qCA~y{uqhaw4KTG>U2kz9Qaw%cVIeojE`W&q7NnUop@3 z2~D%edsYysV;{DtL<$L_0<6`hP26ILa6y6J%(Xo>}4qf>R=rB>$I6iD^ zjoQW%=C8^6Nf1x+`m)r;&Vjg6l!TuJ-WN!|*y9i$n*cV2#GDRMiRz{k>X4{+s?pQQ zL7RNHUb96In>d`CaPpH%6SWU@8QmIa$}CmmGtdhuM`lgwRwMR9BfUY30#wcb8om<8 zIms!G9Z?FIpn+9B6Yv7ig${?%2riYmaUnf=e0<347W~JRy{iXzzL2}0eI#+xqT3m2*f6IU6DZ$M z@0*;S;sjz6U=GIBO+@Ms>E-oDcXc7BEU`#jMW%1M<_}_PDVy|ch1>OY}_6^SmHZ(5^e?=i6+SkHA05cR`$Ns@SzdwEUSgu~b zA!{p_)a$9yzz3mM==1%ZyttIZ8i<*Md8ZKQIGv!`{?2#g!qrzbJ6nX`uunIP+Sf}0b4*+2%ZRwr1m$kAonnKE$@ZVcUQ z35snZ-5}sMRgulq6t;$PNPw^=4A&O~`C2bb7jYX88t28PBVLU+LcVq@L=#-TiHR98F}l>EfG{IQg!gS|m_~`3AmARvJt6eQ`{VcM ztZ}Ss63cgQdy8aPNVlS`H1+}Z0~1J&?1}4*GtFcqJ!1}oxm#xTz%n@rWE{}n92p&) z7m!Vituk5|W|>8$&Pm@iLwxZiJS8|peK39d6=q`wgO2sSLhr9`Cdayoa6xcCU%h#Q z{kVSdw|`0Q&QJdA&k0_^5T-gI?lYFAQasf&|7*e z&SYt3S{^-pre4k>T|D$8gXIO%51=)6N)U*15w3yL1U^E)<&gOxPf8h67(!sq1vajR zSOCqFv&Pd|Xq;+hyyy)UWj7twJ@aHke_T4p$BBJsBc~`%JS-M0LUdnU-`L7^bwmv; z^oSna{ajwYc1wmrrv?8f3v!x$;DpFL#)1WeLjkPp-+lCvhHd94VFBaX(T$7nIT!>c zn6J15>hC7esg=FhOEkVH7)Ce)1%X!Ugoc+3%*;y>vlZ{=7=AL`uN-UlgRkStT&)s5 zr#!hJ=Wo6tufO@W%r2di^_@N0+&NOLeVm!t!^66I$&-35;2_l))}#7AP%n5)e_vHx zrE#=Nxe-5hz*SHH4RDrfnKPydj__(g!_<_)$sw=S!O(0DnR@(g#A=Q*ql-Q5y~opI zo1PMX_Jmmr^DMl<7t0_bYY^xM2T2yraotHM>tfy+=QJ_;09|vZ+s*o} zAj(_m2;mYGArBBMa-7F>oLagkP^CUQyUflMR25+4AY3C|^|)y$A>?0jG!leakRBfN z={144IiZL9{&t7^_CODO;8cJsI&Fh$xCRp!j)Myq_aUsMhNhnqW3jG-nU&AOkkFXG zWR%G1Nwb)Jpe%`M$AOhGm~5g+W~MBuAb+8o&`N{JiI58ej76Fdv`#b&waYRJ7_dv1 zF32-Y|NY``{w+__ANrS&`iLgRWm>;BAAPCMeZX`d^o-$tkE^$Ycy?=R zgOh`HAJ|AB0*>oFf=fhQWwdKnKXGDG!#mB~G>%hxS^d<=YKF+`$)qlMTa8-a!UDLf zCCb32;`Mn$$7Y_WPmtWm`Y#yc#MJyPj7qIIH8^c#MCAD>By*cq?1aE%FK8xWcmK#- z>M*6JH!)V06E)hOfA%~1!4LmTH{X;L67=HxPM9FbP`ZPpLp7rN8pdMr-@bQOwsyAV z```OM@4c;|6XZ`|h^kbbjLC1}g426?^yslJ(rNOrxISW`DF42`2PpjLn!);>Wc1#A zE!*kxgW`R2Yy#JGQRi`7y_zd;z9(;d`-k){KfQg2r96_(Zs^CG&GrVz;NtoP)+e` zZs^b{RtD+FHH!@SI_XeAEH9GHvRtMWp+3A1mL9ntUO40t0$Jg;bz@D*;=rnBqj4>i`Gt5g6WzMUJa?HZ!f+?J*4%V+Eo&AIYFq;+}BeDEAk= z=|M*~WP8Bw2faaq9sy1WW|0!~kqQwZvqu+PHGsn;rh%0SPztVMDRZ%~x%UzbToxxa z&E&)?f=`YU8U&=dF?;|B5nOjWMu5WNIHw`llgDlO=vO~ipn6x{c;|h&{_<-wqi!9@ zgU1SrZ$7=RC;k`28DN`yfTuzbnrDYa;q|3)LZY5(3OYLNjP0C3A&AxW?5Tl8Iv*`(S?w;V7ntKB zNi#W(`DEsy1X6fX0p|!D5NnIbI7GXe8U>>%avd=t{7wf*Gm8)I-BH(h1wN$|OCYVA z0~Y9joGkJ3ANn4TA3u^ukDth%dY?C6xvAN$DK5;GdJPD-Wk%31j3nm2d)L zY^HSK;XTo21t(wTGKAuA4T~ZRV5>QcwlO@gkEaebA`BM@!B-iV^DkYOTkm~G>T^r- zH-Gnca;zBNj9w=?C`3+Uc~`TiH4V!V{-Rq6FcGlm5xzl>8?^uV#q%69;5h)3PmT`= zP>*S*5UKnL1=)cmX1cyX$tVNg!eP{DNE2%YDvDvx4q=CX6cr4;x8w00KTh;&V%xAe zK3FhR%(nsbD8I$K!jq(6Njk_ zzXm#wP{PbmxC*b&g}!8f_d&BbBGm#-Bmg(``r^FNz*dqY_=<~mpv{HxhT6r9hVDp8 zAVYeLDCGFSJUK8@^>g}^mhlGL%kiSo6U4QHgfay5;2g$bn%}OMI(|hp%mEjFiK)rH z)s6&Z^GvW&(2*uGG7$^T@EL(q?Wc;qx#URY0SGRun~abPt!)MhR!KS`nYx4LFI-|T z^=FUo=+|xeg}R$-=hxIaFX$pako$M<5yL_Eg@vV60>|Jgf!RvQ3;kp)z}d+$X{xaT zjXVqMtn3ao#z&}yrhn&_7d12XQ#sjt$|BfSXxcPn$YxCD(PKe24aI&a6M<+vdUcTl z1RM3Rjmfp z8N%X&ssN-*x_a7treWx{SKpMG+9Ef0WK~d#jZ|#Gh~ygrf5&Ur(HdL7pf-8^+RMyp zHd~gSzMz>iJkT2rWVJEW_@Jm%Ut2||5A=A_`|Kf>hn}|{5}(y3}xrfUz7QlUf1l&oP7GxZ)9iv8LPXg8Kn!o-*ZhC5f)>o z=n22CAvh=<$K{gKtJXCzH%qUU9*!PNkcGiQhv3`&d-th!P_0i=)$g3n;q?5X9O_!? zwol~ggS)yOO61s>!X`=~ym#pp15X#6`tU2~{-lX31Qp9nsnMLAs4C`pM9-L+Gql9f z@vkZd#dSd#1M)7&9u5e70Nlq~m|j?wXAd9fYardyG;o*zdYt>cz>I*IQDGto43l(9 zmiVevOLDMxC{t>LswJ?L+d3|KXl7^$)uBTGy(*M*SS?!0Bn5MS*w^@*?qSq&P3S>z z_x^2W>y{T+H2Y;(AWDmfca^N;EV)-s1{anHdomtm9b5m2PX!wfB6IGMPgLM54vZ(# zZg$9w#n3}2y{4x>P;I1U(XN=i(gQ0#OC1k^^+}|KTTv)vSqG2+RU?7ZuGbkD@oP|3 zj|ilzMKvfpJlVF_k7RG_fmOn)ApoJRgr@d7X|TQshZHGSi>=qESqw-`03X1F9ILyH z@DC>`j0LhASd8`Ys;nzuySx2FJv{SP64&p`?N-BLg2-Ka$OeN*<6=X`3}WrJm`)vTV*`g)mrZEAj&{Ycn6 zu0s#6qsFSLzWcU@xjj7rLrKM##rk@4UpAVDggNKPep?L9h>-wbUpX)D|LBip_3G<# z=k}NC2|pnT53~SaCs91$!H1Bztp)`ePoYbL16xF!Bp8bW-NXmG>s-fR!Z(hOT&Izg z8-G?as-;q>-t@K{9ygfj1Gx_c&;X~;UA)Z0tF4$(KQu)`XdRt4Izt_xGo?1LwSa}X zZns@3Atdx_%-c~90e#qOx|Yy;4q4S`z=Lm)4XhgkzW2K%$xh8I=seF!?+C7mvFoF- znh$NBZHvugM?DpdfPPLXs*qxVai5x+vA@B~3M_=e`a3PbxnT(4M)LXSfn|INY*HL9(7oyNeGEthp%3n?=l}3jN9*EtlW9+MsO+hm zYwdt5jMGtj0zS`<#^NkrVBBhD9oz)!I!9!4R`j_OG!%Wk?g^csg{5VAc<(k-=NMRI zzfhBs#c?id{_M#!-9)}op71{C?YTu{-2xJ(@{`opy7->oB9r42e4kl8kx_DB`o@Vf zC{EirNk{Zxviy7C)5)P_goHr1!-Xt8WK9AAz3IQp(4P*C2~2Vs08|~r)*%GG?#i`S zUY9<@OJj%o-c6Pw4y2fsf#HD?CF-%jOor?NE&$o9F5GVQNXz$q#@o?ZyA}vO25ka0p+22U~QK8ynf&0Zq3DK z7L{$9FvhsV#MT~Y9w@6po0z&9r-9;v&mKSET8SXX(ruf0b%(=QhNp;YF~j90ZUZZT zW#*I(4nopdu#T-eNXSF{ob=k!IT!n_Hl-fg`HON#GhQI@2CPI4NXEtC49^CK z1EpUw!+KiHwi;H`rE2TJh0mze(0VDAarF+nx@UHF_vBh)$)nhp?Qoq1Y>WWNgXL71 z@|0p8dT{TuLcuz-C`PJI$hwB}6ZJ~2A+)%>Eb9-y(6yS74&qfB2!EuZ2dbQ$V?LlR zP)!1t5;n3IO;2n<7l}wr;|_>>FrA0m6jYZ7#s-EF0{gN;*H2hf#!aaw5G5>G2iT+4 z9Sn40&@Kl(hCql5#yJ498n^H5?O7cTuU}6%&2CI;He*t=Kxkq=j`qpW4ubotS(t;J zEjdxQ5UpZL34^6T$1bIFE%j!)rR2h;OOOp)>8g^LVd@PKhOMyz#gz$t}pAznXwdwW|w zk0r}?sMm-P0PnZ1q0n3{kUcd%I?xij+>qUG=ng7>rv;@zZdAvPW(LXnrk8a?T)gq7 z-1^`Tr7IPZOQ+Z;s!EIon-Q1}J7oqY4T_*GWz&P6%6Jt|^ijUhFSR4?WU znI2ZMJBf$R@h(&J+z?KW3hOi`->0kI^P(=;nrx^Co~yaN?jC0w$g4Y&(=4rBnW*d z`sRGtnh6O`CyCjK$N^P2{N@#F#TWyhik(u$g$oxn8d>Loj?8i}kOF_pXI%}Kidlyu z9#{(fa~Sg(SHQY60%*ftW;^`{c8uV8>JO&nz19pGqZFY zP9MWU^%T;RHga+mCAx#6r}Vsmd1A5i*!UQ40Me-dNio1U#Q;14eQzGCVd*rDbD{$| zIW@2DWtE-<@Sp=VOfAKVVn>P#Qe%`33k|L1i&YyNPoqyA=zymbl>-63>vb+_HtPPt zwr=9KZ8)Flkms{HlF4(w&s-dwPqtgs*sfSS$abx3Dij?z#wsQVmAINAL}QWOZ$rb2 zJD>epmNaA;*L!6JF>yBovaRgJKAI#kr>6u!9wij){)&#WteTE^G6QRhr~(O)w@wx` zGGOP=pXcx40W~(aG$dZvarQ2?ZZb=QS|}+&9!mPH7z92;?UYl+lmfw zRGpD&&3eEXj#XlLeE$wb!b*`XrpUn$L?==UgK`Ed05i{04h+Z(OEoG0_OpmYy$AQc zWSooBC(2=?JD#-fv4i);bqEa0Fl#IOP-d(yHpgwwuTF=pvVHhTJIdDspwYO?o>W1(n-s zsGzC`PYL6O6B(&?8fF?mw&=8iOs-V}r190&!>g(3e6(5u+ZZf)c()GX>a?Lb zJ>Ql{7<$8rlWd7OU%;nIYGiSsK{WseE)p6j{|++K0mqgYBt~7C(aazFH9$8V5*FP) z_eQhRWu4-r0_fyv>4AxZnAa4U&UZuS4!ozS*#-8hLyhC?{F2NsEX##UFOjT?+X{oB z<~1{JVhtFOsDNh$L%*TfL3p5_efEih&D&gmSa0Bu-MM{R4bOyS33cpG)DVIvB_l1T zqf)*8q0YlC23Dz~S7WmWLzO;eZ34H71CtiWPa=CJG^*zY(;xc&Xn8}hkuYg z>?WDNa-koM9)WA8g+oTMEm*j#sA@;=py^qwq#fws&rZ+F%JO-0sRza@;*F~H9@A61 zHlx^vdJjR_X!dOdjh{WbPs4-SsMr}-FQ*_96bNI+@~&z~(5F17Q1dp3)%Yx(myZ4d zr}M$ywl4Mq2@-Rc&2YODUJUp0T@%Eegv6elT%`<`vv`OfuZ6dTx~_$#6*Uz4{%qSL z?7xlhpwCm%HUzSM9rdSI&Rt;khJED4LT0|VGkkDD!C>A&`d+UGOjUr`n;YwLpr`4S z0@sJ?%5%X%R87|dTH}t_$E+cv4jQ~6%-#LZe=SFw59n>gmf|CBmU(t{kmg{sd96eI z3r4(D*F$0Lx?H&Vj=cV@AIRj~vYwlb}CYivT(p^nKl6=tYi$1#Gj} zmFx%3g9#jn?;l0(kC#jJ;dPjY9?rv6*a6%(t0WKAXtYg!bkMcZiY(1l6>*O}X2vSi z(Z-r=cPwiRZWAO{r!_i2ntn#tJ3bd43Emsj2{eKPZz>B)x_{l$#_5e0LF1=zE&ZIe_y%jS=`!z-3qTJr^}R2kioe6LWu}2_F>s zCItHXZpQ&`E%zT94!&Ne1uciafP9{e4NMo19=u*3wcUA)La zL<|kdfXRh5nNh=3Rkw2E**eLF&mP=XeCCiKF@)x0*G-f>pw#Xw415WIJF$@=QzJkw zlN!~PwF`P`O%k{RM*=!Bje{L7Uf(A>2z=40xE}AJs}l-xLYl{g+;BPq*3ltLGyoz4jKoHs zoSNWiIl(R$H7;5d_98PfaH3MUHyD3%Y}D0%@cD10bFjgzTabFJCv;iTOnhGjhOh|D zNnNmt?O4Ze>GCVGcJo`B*?L2k*IuGW3nPPaofbQ^HZ`;;F#&hk% z7~={(W2}od!!i~|>Q%6dESpfq6u?7+OkgbtnJp!5`rgFGfL}uE8{mh*4!Y3Ub9@7B8sN&E- zR~OWX0UHclxdiqi4he*g#~L0%#BWRwBXH~jLLyd-4cT9m7+t^dGWDI-H#R7#lDUWm zGPo)g6FQ=@nJ)OUOWP%xZQNv#<(q~Uo0BsjzJM(U z&w&MsUJ#zy7y}Ny-c05+kA1^iW_2(jN#8PQ18bWLml-u;eMl$(wA5=pY@AT|{M?1h za{0z9>h&zj#N4X%6g1y>wjouVr0rwbczlms7=(m|Z3#Cs?jvwICWe5C<7R|BQBd){ zdhQ%S>$Qt7@f`-40lGLHk98u#Y~U#G!;_E`UM>^dOp;+;kWt|s7RL|EyaPx>LERud zEd~rLCgk-u-Xg^TW5K>hC}f4M5WGrwKcp~psbRgaa*nlZ)L%(W{uPD{40crXqoZs@ z&dG#nVS~$4DbWKOq^Ubt5`u;o&R^iA0{F!IvOWl4yKeA}hqo1Pdd5xTd`6N44c|-c z^mg8H=2aXqyJZdMbZ)-?lYc6gUwv05W>=&GfE4v&$W-avA`C$nl_Mku05+pRJuruM z+iId%5|J1#qbD$2cZ@@;)!^q@2U*kB1{Y?0az;X^{87oW#4yF<8wq<$S=g1hFN*ai zzSZ!MYLJ&dxJ_D2wU2&@_j)ac;NeOy8-HhVrb1j1T%f)lGDsf4^T9~PQ9OhP-Fyrn zFt6hd+CZ80b`gyO);&fVeYa@La6l^-$_^JU2?TE#3WQMdJUTY75!u0OH*T;Xnph3? zs*!SN1igAEFd15M`F*3Rp{r=45qup*Wg47j;T zcnckHif|0Ta=FSHm&{c@hi-#P?yedr&0BT#Nc4|V3jxgK&A2#ISHpt$ZFP(!iSXb^ zHy8SC;VRHyx`8^K&XG)&2l7}k3b@mdBZs#Di%yR%v_4e>S2zjdMoCLltD_)R|J_FA zui_t9uUx0N`f;N}p3j1&q#K7jnq_%L0}#0SCdtYD#e}bUQ%pS_xf7m@yf!BK`3A zM6(gQ+`L#cbv+fy6=B$sknzk+iT=Hgign%C=hh4>Ydc_(nIip6R5hRMKGm$^rb$+a zmj!j69DN-#KF}pX&;rAa7Q9HQzyF7SDodAcN>lgu?%n~zIm`*>7K;|i2=KJvU5Am$ zv>;6Fl6w^7sc3{*B))=YHRy3ONtn@)Al8!~8*p-JmVBU)p_s|uBD*zU z*-h8hugmC&V=U+M8HBkZD7lt5458E0*pD|x#^*9j!W$qPnSf+Ic&8>&qsFJ*qTwM9 z>N2}Vamk!F&X|CPaiB&S4IXfv@LZW-Kq5x(59`b-v= zmSuJIoLs$jgJXe15l#lkv@kO8sNnUWN&pAbCm(+*(^J#V@#vB|fF=;oTgO~2Ew9j+ zLGK;e=EGz4swSq)(7U~by`Q*JEUxW(z4D>n*DbI1#*F|=oOlr<+w?6o4pd7DAP~|H zaNPldA|$}YLpR3+v=W{af{hE$1~nuUjV`e@FWmYv2gA4wp%c6Eq(++>DWoqQ5szFW z>o7pBhFH2A#-dyq6H`~~NF@Y!A>!a~X^I#dF4Y)*Qp4))2cOB&{uZ+bPWhLo5K^6J zcHcoe9h8y4aOnWYF7%=xJY4#|X_oBn@9W<)b^*Wu*Q&9!G`n`9*aY6YsM{N|D7L}{ zz)}rE=#58V0yDXR_4pZKdW&C4D}amMYC&i%kjpn;mxGgrY(0KRIRk7)Tra;{0Y!kFy*)1Y)RFNJ5+e0a&8WDwa$A+aV3l&55r`T>v@x%OCU2~y_eUbv80UEYh`B`9?6Z2 zwXF_qG27e+VIErmG~UB?0~wlUue3OeHu>k_|(&eZ|ExyT8{u@i@0_M!sQ zIM_ib#vwp_P@jt@fowacNsfybFKcqA&dw$~dYAwPnNWj;u|`qsm`fnQ$is_{)JhR> z_K2~y#c;-esqHjB$-LGtPEp`{&}9bb1%uROvpiQpExyDerN;xK1CBc4Y{*VvVPjyh zVJx#X#EGO}gv|PQ0rVhnruuT*T=#B1^F$o z^gO%EZu2JaT z+jaRWZN0ys&w4wgq5~HmP#}y63U`=M*${_MnM#D;`raSP^*7#^&BLa&dZ{cgE|Mu- zij32O6Ld_k378Iuq&V53_y;cl8p7BFXjX?)A3DLvKsD6(w>9kc-8pff)HSn1oJqgR zj)sA-KXba>@C={aze@uIc^81&?Bkvk+UPi5PUi3`4=@j_*Pkzx9cH}D*TG*Sm+>>f zIx{}>2w+TsZDOtA%Y}EWi^`K9R^BlfbZv|i1ES-=3}T4;s!!=*SfcTP@+UqOxEHDf zfQ5kzG^>C!upt`plEEqfui>S9{K+S>pz{DMjRryuA-pC?YTy9{16(_coAq@k`Wnmw z*3#_i zv1#%7fx+yanQLkJ%u@K7VM1Pp(aV^cnw!ovlT}UdypK! z^Z6y<3|P3pEqGdoLRG+lD-Ds*`iGAxI12_aSk~+us)IYfFvm@^z4?rpm?+5d1!*mz zO9m=t2F9CmfKkj5<6C1mD><<+)D`K%9MOxg>Uk_mfS|{%zP$JC?`Z5kC6AwO5IE#X z6#^Hs>>}O(-6jB%qN~TjVS}Oc)Wjsy*B2C&$A*5UDQpyF!dn5Sr=g1ppKZy9m_6En zEBHhNfJ3YgsN(@+gV#GTQMd3wjbop>M1koMm0aggNU&5i#6fd{F$Fi@`kvhQ)(FqgN3!239UFVid?{B8J@DEfFr{bq03=)iuF=R0U{0rS7BOHcKG|) zI12X0)!nU;Km`)hxEdZuSvlBOrs+mie(BA z_PzYd8?v-|UOmZ*+`W5;=}>r@Fc$C-5E8?CfUs5;*EEf~NHB19ZB4FUzfOY#w)c#l zS_mnQ(W|S~rqM7(zcP6>INc`onyXHb99b2r1c-G)V5qBZGyE18#YDXO|%jyVoM))$KBL zK&BG_HjD?b7#JhqlmO9Viq1_^cM083&=VYE2XGZ-HRk0tI8N}I4%v}KKLgoLba2tb zCvru_Oba{DeaO`^GNhNP82UD&-i}C7D z3LKw}rw`@Py)R{VYh89Wo>Jl%a~J)?|LK4J;c=^T3#rJ}wR1e>af2Ww;nal3f>Q+I z&?sn&)Z58Q<1)E;UhjTPCg&F{V*un`H~-G=0mA|xW}z66Ek{xd+dSrn!Ug>agEq|G&mR(lI@VObFQxE?ubhSr;d^9 z)&6rz0gXq%atD(KNeHx+m>H^B%b3`@rs_&&b$5^s+;h!%Q|ds()%FPaCmD+(8?Ymt>8;h_u zP2S9no3F{MZ@j7a%|%^sW3FXRpCrRW^+KD?6K*n|_F}1PUlxJVks((lrN_!H7wB-x zL_(~gonm3VOufKWg36b!-jwUFye0Fim*xDGSLCG|Z^-r6-j-`Gza>djVdl_^h)rL{ zI@Jz%dg1^=){S8znn%`ZW~k8~x>_N)i3hL_a#?g75i;VM;X%T)r03(*AQ2`r+Y_5I zCRpf@<{%#kZHe^@xDmoegxiCGsqPU3PCdKdh2Ao(ca$@XjyF8T?}a}Me-1+@k7|V6 zB(V%><`NaDqh|Q9%`1*rjaY19HU5TV5HKwq>h*cK`ts}2b2JZtzGikXe!!zm~0@nlIC}C0VF6U-UD;$)_8%3KlO^b^3iX9 zp-Gob*;bFbtRXk54BGnDIo?wvw4>h-NCFO$9yxZ=fA+um-+nl|uzU+Caag&P$ zt&L&G5HjJ0K$EYi1x5G*CTHeCEw7F1>IzJ(z`38fTmf+d=Lt9iWc9F?a>i49Mk#W_ z=7XMPK8)BDv5J?vws=l#r#Xpcq0eAs;wgFLsf3QFk+}?3YMvn#@KBrwlAmq@xa&AE z4;An%ahE3iTrQZv7}F*(VYC6JZ|TXHvK)+Ktfx?{p$O>lkj%t{BJJ%nFV?cx#t0`; zO;5SCm#)gJ8lac1y{z5=n#!3bFp3{56Ekw_y&q_L{$06v`3f^U2uJsHL&LbDd%?*` zlZOC42b&TV;wZL6Iu)B4xQ}m>Y#gQ3x_RiLd;It@GoKiHD2m}eQN#<@ZB0FpQhh=_ zqGe6_D;}_Vf&Iq71_y9IaGnLlw18(M17-nX)Zlf|P*CW8T(%W|A|9j9IX-SMJb)+k zL_eRpX!?7E{l@z-*$*&rq4^Du$hzJ}Y?R1D3Y$tjEpU0@Irl)CLvjHj40&Y(>NaI= zzKigqbCu=yeH81zJohJXWL}2dX*w(b_MWx`c}V9EC~v?rhx0+BdSXVs%dr`mTfQhO z8gh;6oWb)wI&Kk!2GEPKff_@fr6NaMhae;(Bu1@RyJxyX7(Z~|ppE|U!F>(W>nvpf zF366&uBjj-X=bOVcz%Pj!6bvu=@*~f({Qlfj=f{`YZc zRQw|M2%0ePu+SguQ1PX-XEgr6xy>}Bp$925mlbiml7Xd*1G7w$Mj%Bl%KW*PWLDF{ zEa}kG1Uwh=Ox&UmT?)Rb8*Et@oB9oESQg}xrvGoed{e`*HF^2fTe5iWk{Y3Lxp4Wa z8vME%rVcY5Ae=$o5{4Eb7VZJ%2K|9mQDeg%ptFZAV&6kNc8P|_Nv**BM;bn2IZdD; zwYlA>|3b(E5ER)a=rUCqo<@$XZKW{~^+HpCcC*R%XJbakmbb=xDLFcr|4GVT#5DLv zhlk9zK+_2>f5a{f<9zSfb&yCL7DyFFq~+Uf7L4Kn(fp&MLwY?(cA&hb**qe~QGrGc z=o>zJm70R*a~@0}|4xrllNHo{P_viS5TO=jLk-Wf2WoiK=w#i7 z9P9U!<0CaJN0dH5&5s&CHAv7-uCPuiE;&7##E4`dx1oAAORPW@XnqjpXfVT!yyze^ zPb4o>5E+uYTt*4ZW7EBH;gx%i?`wof#ouw#43dE>jEI+p&mc?% zT_44C8qE`vxYTz57+s1@91b^*(5jSY&X^#zmLeW7;{-$76t=?i)5N->u*jEE zDfT;dP;nBWn16&@6(mITvq3RH7=lm>hCK>Q76jA^aNN*WJQm44ACKP*h2MroeJraD8T3&R@Dlx=T+t^`RP> z@v5nX;-JO&fjy1x9vC|#N@`f71`5~11z?r48k*PNA_0Mo&E40={c03p81XzZYC zsRl!@p39Ez`^Sp!tf;+s^6-KFsv$e;59LI&%IGH2?=;y=l(=hVhg&;Ei&dRkb*C_Cw=naHfms+}D zK2DQaThdddP3}yrH*cxN0j*`sG@^L}rdIE|D!7YcUvftv^Kr11_M2pfc+V#gS1)DN z!5wu8E2OKNMMsr-=;CW}8X~DvQ_FH*lUry=U6xADV@e&N%#>&%tCn;r)5vv}aPhNv zmbNjCE!+y7b+jc%LRDmGStFx4yejnXt8ude_!Z4oj7`t8ZVQ_dr5~(C13r`)1|bfx z#P#m%?#s;Vf~>7wloJgfc8-qau+foyO|9dU0u%b#vki)ZV~pr^pgbitMF9ZK$Sgs! zV$6kE%yzl{PGfGvTAL*Edf-tY+=PdM*CFEp3;P@4PesW@**UQwc%P>)d9VH%{8w^V+o`nO9 zo7FO4ARMAU6+CHpd{`qSPO9O?Mg+7E9cbVoN#AguffJecvK!X(YL7Y z<&|@4tOlfYps(S*`(LUp*pV5i?uhl62TDGqR8x zuyTx)8X{?G)wAI8{PCassr<`-`CrR}M~~PYfUQ}wp2qZb3Z{eKGp3m>b_T6iXn0Tr zxPP!Jv-8W=##UoIY*pY07<&lSM-}rl5O$R+F{McpNKo8V-6@C?T*mI^wt=Jqj|#Mjv3trR=;Ymjxj@?zmLW{xY?#3j-cSn?h_U#rmtr zDwg*pg2ZLJ!Pm3S3c_r982t6W`Tw%N{q)KuIXLO7+kMEt*J>q(H@pW5kG0u{%XlnC zBE<&9!h&~GCUz5;@EXFFO2riji>Vxn@NXs8bs_I91#g30EiF6K0tvO#p}Yk!xYu5P zLp`mg8m1CGF0f{;NrBL_g13z8ZFU+mJ8Ly$I0SGiFD)<0?94Q?c)ieC#YF6!+2cY6 zp0l{J%C&o-n+3)&(_H~T83mz`$~`&UXC`h(Ph)fd$?F!$w+hHT0W%soYkJP!WN@B> ze4~7w;mKd~+`|h=m@&g#J3)<{>y`So;k+&DofSG}wXIw7>+l>f#8KWFDt3xPWqeky zzVa$FUuZ}5_`xGRh~R-d)%8=7`85r{k)_gi0&LRO=V1JgcehC`nV+o7olkyAhXdKn zOyQPUL^@N`(r}c7`dFErQV^veVj%@WJ(>f}W@$VnThAUTj-zAV(&UBWX~2OI+5+3` zyFzQqkuai6@9HPHaEWGx zjLpUR0J%(AE)*t)Be6yWqUwqT!6lEK9!Zu)Ic+_29!21?U5Pk8him$V_bHbHv8E@E z^4{w@?@R|4TobTV!G%Jg)-PQysysl={{Rs7`tn2c)4WfM6!YFIq}lMsOK>pk}fM6yYME_{HKGn!a< zvi_J#l<0`jYNh-vh<@Ro`>dS`Igb#9tAXIA9$u9iz}Dp5f$?_GRFHz`G1Kw5Z(ux~#t{uP!h@2lwuZNy zbX|)a@#*nlvg-E|P$;10{vbV!B z8{k3qJw$Jdo-oOu9 zDArfh8U!S+EGnKrzawNA04nMerg4*~qv`bs)-G%O4tE$O4LGS9Ez>(`X?)jh?Mnjf zoDBRANRVVQwRT=JF*BNS+tzcps`!Vgq$Aq*jB6qX-`I3iAjEzoFJJs z@r!v%48VQTja*fCx)oaKD-1140}io~GJC$sk>E2j@>=#b9>~A>7ymc;{y+S4S(;hW z=gnvc+M@>ussO-2(CJz81TYfuI7R#`P6Nk0GK4iSKowWLjx}H`htLR^z{eOesL^Zo z9S)VUzZ>4~MBR9{QyCwlw+m4#c*AiyWJSJo4KR&ek^tcra3f47jM2USp|U@DvLwsW z{IIL4?>(C*H}iQ2_Xv+EGcwaNvofo?hOVxv?q*2?O-8Sp!WFP2H(YZ?@=w5yTZ(W& za0Lhj0zd%iLZhp?DzkEm9Ab{}@OiL#ev_)={JwLpnnh$Js^BS}?qP2Bo<7xk&pqcm z-}%1JKC^QFn|h95Lvj!u4t1a85pVZxnUauu3{4}N3YRWjOj|EdE!TVwao{xt`6DMJC&PH4n)o@qP&q7c!~wro?|YzE-BjlBjV0i`95ElE4jR^-*bJ& z(fRR=U^L4q0<3DuP5qdwvV&w|7r_AToMj`(1*5QtpB?)OE2#OU^>ljSvb6wFK(4>v zmo$Aqwn?P|&ecvz*RD3e_{eaY%||CHvuM{dzsL6ir!b_7xn63WL*cg5DP$4Ei0|Wahjaa*I z@h)GzqXXv9vO3mH&)#PUerRR2ff5E1Te;P)q`P*D0hyRdP2@B&DcVh@~!+Vksi06dAcOGd>#CBQHyupn*U z8P}zz6PX-`=!t+hk-I@2=0!>Hc;{Jq|7U-fKKj)!l}686>C>O_v>u+7%;E~yOv(ag zw69xXd@gw~)X0ao;gt>b-SCaTL-uj1;Zp;vZE>H7VLUQW(%QNw*yAFG)hd78-z6)w zQqJxje;-@MOoqy}A6gK}s(zgO+@m5&Yga08TTk&ag8IZBS zR$A}`OoZ_z(5^Ce+BFxD&*e};{EDC9`lVmZpd$gz8pV01z%VGE@3T)n67@yG^Nb<& zW~H==XGUMP<5hZuu=~5#=5Ry$2!{Ey9ZV-hZWPGvnE zA7f5t7t0iLJ$1#wj#EJx0|(J;O)MHtogh`A;+C@+(3$+yq|j&4nb8UY6sM;)W!H)g z)w;?j%X>W!04;MzF*4!{#GMYtwqY(^zacjFp`=TDY6CMq(hGt51=`_kT6<8mad}_x z2wIoz)Oiv(gU|_Jam$I5YX}LCY7nlkQ~#{ue6VdT=q(s9+Ot1Fl8`NEBx*Gj)};Hz zn(k#>EF?%Ox9~AkNA1uT+gp}OUlrz}fSihupLHL5X(Nrj<3*Oi$uA{9I#vWmaHpv= zwOOP9!vuo``>bsAHd7Jowb0LzRkHp37Z1L$^nXcIe0;$W1yit)Bf~_eG9@c~8$`<# zRG1~R!wy`ri4G#&J}C_LD`ik*Lj)#Bhu}5bGfF$~2%rPXvwld2$kMl&XpF~sEtQ_# zf@O7Uh6x?++xu_7kUAmrZ_PLcJKOBs;>JI9-0M82N4b`Xrx^yw=743UfOP-!=h9`{ zsq79vNT7X8lQdup$}Vi@pnZ&%8o@OSX?^FiFHvR`jbL}FmU2D0+yn|IQ(HKPcS z9QST3Lpc!~iLw{qoBc4S1a=$zeX5RCE2Nv$%-O!vbnEu*MA-^mUviK3K?zjzD5sUu zDfKy#(XO{KWg_S&n3Tg;%FN>ybF9pZro8%L!6 zr8_*dL64`b8rUgW1VvrJY-V1I9xWP7;uv7$#NV)N20{A6lZoU5`hA~-2biCkoe6P# z>y%h_Gdy0B7x?UwbrY;?J=xn#`&&=tEjALVaRRs_4L zb7K@>-QfTU*AokzfZ4A88JSDy9Z77Q`$auIGqHuVoJuPTfA+J#Pe1&_IcvKvYva&G z8&6ytCk2pCw?~`~I$xA`WIN@eI5s?AhU2}vI*6D&%ahZIWLQs! z*OWzFGT?X1fL{c!C^^YYC^hK1HNwa|qjHOBAGts}gpERwf-^K8+3QaV$ABmi*OtXk z@(!bu0k^HgSHx?PiO*WrErUGEfCzMy*ZtWU1*M~d1FaXX32x7z@J2%u8^-xuWtZh- zv&BZl#TmDQ3XYkAP6VK6%YHTO>5fW)tz@mXM$wz5TPcmG(~%y9)D=q)SZ!qClsYrW z&xqB2DAJzrA1fRA3{&e6QbrO$8SmNMc`0Cecek(3@C^$_u!%X=sRE`kB81Gv3fkdSiV=vcn%I<1qph)MBZ8qQNU zj>Sl%N-fN>*sGJHp=;*)6FZxiNe&eAI@0&4zsf2NR&SM^Q;XnTI0Mv$oubDj8>g&}7a&&fh$s&c4BJoN{pR=5{wLG)HpKOV*UT?03Xgg1)z@5$xItlX z;-20;$If|r67f?BErxGL>~p-R0Nw?H;&h@LWx-L%2;?6`SF3>e1Yf& zrY^5l3cg8<>3+Ik*Td;@xUQ;r=~iQ02^gQE6G;BFxd=C2E?%&g4qS@(tYs$2kDiYx6-9+H>CeB83q7$ zu&mQ#FZ(d1v*&!ce<Eec+wj;@Mf@uw{3rMpgXF`kwa46ir|Cvnx#Ll(%BeN$s9w6ml?|WpQQyj4fAaxzn z=VUp_Eqxr=?{!Urx^7~AtmrzhU{d0AO&z;yqg!>>VsE?e<@>6vaTA9|4nm09gEvkk z8Qh9_O^}u~x3rKkD(qPRdaf4v0gka29M%o|Ju*ya$GT5fZrxFUX0+uHT^_p^tG0G7 zTl*XV`JurHXm@W|zySLK?8p0l-%2O4DGmopuG5o4wb1LSlUkAH;Lx~n{c8H?gWsfj z2#2b&eSe~i$sK4i6Flg7qUp7o51pHz(OQzF)u9C*>w%rEOa91;;N8(Gl9+m*K2txRRFCl7LqFgo(?&&d$!4Db+VCVRb0o!Gs|kmPe?gSu2~7OyP`IETYI?xU&`a9v$ z=LP1MM;DmM;)&4xn3V*BXD?(0>lUcU+_=Zg@R6keDucgJ5~au}Xw{P4jBA&3ZRTd9 zfzYIljSC*UB&*RA&7bc992Y%9Tq7$b>@%NgD08ZXO)wN5R8KVCAt#iWh3d(gW~}!u ztVHQ0&+d__B@6Y_y67;c92hlhTxUNrUw4#mJbSm$&d)Szu@v(VDgM)2U4jj;t*Hic z!uB{ExF7uNZ05RQ+&B$_t?jc>-4oYmRxNg{Z>*HJSH&p;{+6;63!-GJUp#%7Zolyj zbu#G=-hS<_GL*7x<;Qj9%Jp>V>U9g+K6|*hIOp0_a&VnGRw>!qJ?%{yGnPKFu7e6q zW?NJEgE4%{tkzI#aqI~K!Llu4f8-fE*G6Zyj^~KjJlsGM8J-!LkfaL87LF_;E-C$U zoe{cKFP=S3Ys(9kf*m-gr59#_;#edBuZ&U1*ZcHTQ4>-j;8hdd6%EV*?9poFX9M5K zEzC9;!&PQ4r*qFT`8dIu?MN9N%T{E($aO<{a_X%-m55^v&%t*Q;3eJPR{A4lQAKyJ z?S?=FxJEXmmS>*p0jDVgwBxm4J5Q#O9w%Wt0O)LermH9Ro>N^hsWcufLIcv({F%fOWbxR6stqpoIJZ>HCS*`&jaxSWA~q2%IH0 z8BV3r?U~jp&$sQf>Qtm`nV(g+h>WPr%xggTa4_(R{8E9(%WLQBfFB8KLKw{M19~%J zOKvD39gDI|(JvaMmOMU07ciNfe%19#D2Y?wNF&++sK{ z#dGJOuir3ELogq;f`mFm=x6sRS2&=70;WzAArJr+lp*f|*NWqY9DM6{RAo82v{KmT0C+YrYAFBa0 zTQXMCsA@SqnaEI)gQtpelr_GvRH?&-$eu;`bY#zALdl+Ool{_cZHySH7vhG9c_5j! zqTL&+4!s}$$N!MN^WE<&?K(NNcB!52D}zP-qhv4Sl4&RI_OXV-w7Be{9awvnasyho zcq|A};c;X)g))ZURhy^6og%8zDoN|F<4H~{vz3JFV4p5E*r7l~N z9j+~kWBc%^@<~6I(uMI2(bj8$nN`-=X}vDxYxr;@vk8c-pcugqPDwL6qhL8YKGF%H z&O~fB!jpY$yMF_9SRj6lM5Jn^0>~-5e4+B|VE9z!QD69hwVK3U*7X$LavcQsh}R#< z(KSgaZW6-q;6BsSeOLc4Jkl1y;7}GJ7$(T+zI~G>Cvt* zg(LgD1aqAd4{+Op0xkc?h81vf?d1Uk*eT^Zd(S!Ro{R-HkJMG8d-e9Wza3)-wJ;)F zF=4{Lc=kkdTPMf+%2*}1U%Rsh*biCZSU8PS8juWOQ*7A#t<3e(*0aZUPfkSE^Vavk z@vO+ewO)d4jIIztY<2yD#t^1q*Mme!t+Lo>&+2gS$XU8C?w%AO=whPYIAd7|=22WP zWi;87Obx{*t9=%VfC{IM(z?H3&5X75%ALFE?wfC=M^9g*{`}LlZ$C>$-jh(@k_d#D z_uY8)P2B@{2@tI0tLq!a9|K`1)rq$)eboZ@y+{t0; zb}3vFz#oYUWF%@&bX9osXV0G7&7Pz?ufFOw$jJrQaf+l3PYRaKl}>Fcf9s*-F2Q;J zME<)ECS)>?3ocVOx!z8md+`#ih*qahr28BRe1keRvt&yrlPDQ{JYrHt7mQ4SxCnW! za0yS;3E?)CvZHaKd1k}djF_JRP?E}uOqW6+&4S01ho4w0^svx0sLet98J7hq5f0{bA~o`II??pLTmbCP>DU2$f&*>X zNvV1uEw5j;OyPnUugqt;0C+esv_9F-;-<}fytkDOx1MSKsaLO9`MB!5t;X$Vz=(L} ztCA?Gf+6iq1Sa6cK9-Z^R3c;OJr~JkSy^1nWTA-1LS45_pQ2;3Z)NDBcu*U9-Y6m{ zI}TlC0&ri-iNh|dW%L4S$6!!e#uPe0ZE%k)u=?1Kt3CRl=t!Ir%0vb#74X0ndvgkI zG!W!L9t`(32$XCfb-Ys1H93;z<7x$=MJt^U+JnK)L0N^xRNb8FkgSTb+h`n=4V%om zstNHfJ3Qu=*OXDB*L<|U8{+P50NtLkOC%q$ean(gEe@=#UQN@v_4JeX@25+4A8%TK zA#3Gu;zlqs@!fB|lV0vo3LU3vc2W0_ZsTt0!g}nS`(J#KE^n-*Pd@xjnyqS?9-P|i z;7v9=H|r*hc7TjSJm2M#9UviVnkciitS1@)uE6NvyDLYy+9&sbj2sAu`{N1)rz-KZ z@7%%_3+p<4{F`4|Ah~OccvjI5z>-v+G^y3Nz(_rNcmYKHp`~u${MNT6=Kb@Z|5OiK zK&VGW#E8GGviK>vV<(6&ju#I|(gP zUbWu`%x9gZGXp?>uV(5qWYg9M-Ppu%FDhG{w6{F)G%nnYP7e#K^7LLOgTNMRzuM`m zVMkls$95VWEv{;@vl+-7QFY`K&sxcY_VHk0Ssg4%nArDGdJX!sYTr){Lve?sQe`ct z4p>nU4zN9Oa4ZPp*JW+iMvL1sBU0r4{BpW*=|;M7^Nv*MhR7i>@)5Q}8jhut1D0bz zEhdNiThHwo57W`!RGC^smvk~w7JI?)JcftSC`?4-;boL&!LS3l7c-*^O>Pb3IFpPeSQx|Rwl43Thl5L@#});VxMbwZ(D(r4$QP3 zcUiax3)fik?qQ)IMd<)FgMD#ubeuAuo^?(uT%!WQPrRcl3Q0a7ZM|>+qP+uI6ggsW zwcVXP(I}WU-=pna=WeVWW(H-nv#V*>O3zt@(hRhH)t>7&zIP+7S@UONneW7)jZfeE zvDPZCxj4!&u0qz+3{QN5-98@)0wWYppFZib&BfV%di42cItYORdZqKQXdduPyv+8` zF%fh!umE@=efZI*KB5w)4W0@Vv8|(z3g6S)-+m_Dm|y<< z@6+%7;h&}BaU*~*O-_Vk^u#Bya_nf&75MDo|H&W!k#u_g{zreSlZ*h?D!NWn>M)y1 z9GxO))}d_NX^A+V5?!n!1uy5!r6Qj`>T{<;CwLunbpLtpCp2{vL@#gK66N`CQq8dh zkQT%?<^cdyf;nl3kfG7Ynv^2i1}>@@l`4?x*hDTUpXAV}*M@_WBDE}?Oa(WH;6q1e z-@1M;9^Kaoe);+hDZ%X?*yrVaxIaZtb6;dMY%;Q>$2VEIxCCwp=vNn7wshO#XvK`kD$&IA94THh#aY_1v?jf!>RdY0OF@gu=zWg&I$8l z7QVqQCZbJD4f~i=Cy#P*JZ_cI5vXT^UZN0EhW=BGRd~myRZCh#%Q#5oeXfC8U&mxs zM|Pd7OH0Ze;M|;MN!r#$*VHXT6wSWpaNKB}VNawo*`EJ_VR-Q9S~>JKD#Q1Njmp`@ zjcXEwTe6H=L5qyS*4eLr`BTkpk;NkZKCn{m2$_ts6f=2#q0)M14IkU3Z&|>>ot6$F zi)qiWvJ*QfCw4D-4PyJ=1ul!uP|EF-P!q5UhuJRXk7KP*$$)nK3Wz z{k}7-aV%+N1AUx44ROAl@FBQuBdeKTTGYaNB2U?yFFKeW#V$E8pb$9 z7npMSma-dw|GkJ+!`HZ`qtS^nD1wh9CLlbvO;?(U8x%xJf&iydwy;%~q^`S`X^mKx zG<!6QdkRFARQpEa zZqS)ouM)IbxYU&! zeTGc4KUQ+#u!?03B{lwFGTb9T*@l6o%po*9I#edY{h*D0>*fu0n$Y^00oNIxS?Ll$ z_?f9Z+h)?1E%3cf1BfrI#0Oxq3EX7Aa8g-}+j*gT~ zIbUh4@(O?-<2)Gc>J-&rF?~(Zd*{f@S(x;v#|Is;QS)rA^JxI3IWsd3sd7t{lO~w* zKGH)F2AgW7|6Rn0&_GxZ_@ZVH%Odc*)CtAOvDJbR&tc922{U!Qexs6WXLnx#OU(ld z*sH4>hEr8($-0!t&Mq3j{OTL;qz@lF5x7p}@xU5BS1gb|yI*U4%&CJmo1Q*@nXX^I zrS&XfeS1IjkQgBuge^3BO2^xlX+C{qnd7#!$BRkZVKk|94eKobB4^>`Om{D#M%p8z zNv&*~c6lqa2A4h-g#e5Tz7om~g=g&2on{U!c}bk%u-@U$wx#RC^!dl{r&nHkBYpda zf2<8dd+*~9K2$x3BmvsXSfMg`jD!IXMHAP9esr(=giy;;q`AHiVN%OC(=YkF7s2t# zp5_@FIxC@Cr9jL#GWX9h|n1aJv|?q^uU{cdeX} zL&VZX+9w?*FNE(SO(5?cvB7BTPZ}S2uLa1pX%z-6lm`vG)=GU{w)Ie_Z3_Kg5i5IH zw}=stWy|tb)!I}m|MbXlp~^Q8pB-T`GM^m-Cy|oiqY0YmR_(* zkY1=LAafeZ0X^x+xz1BhyrZFxu70r8C4v^&DqSBD0V#UR6o!*$YJeIcvEO6)hzHq~ z3GB`@BC;Ux9wq<=1Caq|7iK~Lo?69SJ|-ASqWVXP+{WP>hbfzxEM#Z%Sz5hx-I@i* zT7NTkf397DmO0!@o`FI1g}puKIfP(M3sEa2q1=ktiGqO0fRQk09H>3s zwl_Sq(`G;Y^soQ>^!7LIDP@|O>81UbPt(+}0kl`=mR8cnwQK49Pd>2+u+nvC<_z3| z{{tVPmE4Sra8FvTMQtfsS~ zZegQw2s#-9T9m^R0i>rK_sm!q zk-rNgq03_ng0e*&n97NuRXHOpj&z;pFk=}MWU{r5bqi(_b)T3~(+CCXj_L%KmeL=K z%fWmT2TMEg&JzcQY>A6T6Z!%QOUJ>c`#U=6s~H!b<8Z+DX`0+o6Mh}(K3NC9ivtfd z&5Uo<(^GG8&jp99lc`0r#IUIos2b8@sx^W^CcSL!?V$x8@QYcy;dEM_y?7!!UV_Cj zstGWsrJJ490V~stTJ)k%O#L}9_as*eGFdW7%Pu(xxP}Tvz!}8tX2Porkhtw=7+j+; zw#ET_DHM?5&CRB)K!`kW+4iMzQ%`-0z6}97*8NDfQm1MA>HRc3+)n$?KG!-$b(7au zHrlvK0sG}>=V|)vH$(gU*Dd?Jkbd)vpQR-$Q_Fgo9zA2j;cgZ>0Sr z>(uT(O1BJzo>{W;-SDCP7f;jS=Hqnu{E3F0v9tc(5C2dYV9_f)m=}JCvv;&-z&r^s zqZ7wIDN9jF?9Frs1I>fO2M;YkUX?n<)-&s>4qkMS2gBtl8Z_QOaR&C`a4HUZ8L>ct z3T>jkY*kP7Ko0hg^pFO#MSA?;^E5u*_d&+G)ye+w;eB-o5Sn5kRmuDMeG#~ZK4X&3 z6!+bUvpt9Lq=2G}jt@}Xe2A2P?Q9 zj&=U6 z@)EArj8Sc;*{%icuH=37*3$?$MnY7()bHXgXXf0w!E^bjS0Nx%Td2&SF7b7VS z^#e3l_L-kQeQZI@vV)mr2j#(2tgXDrj8+MO(ECr@?H(R`t-T$rEn zPSmOMzrb6-aAb9Ja;lO9&JA-!WAR-4I$19(R@(QmAFa2POyIO-bkJJKVSa%vt1-l+dmdu6` zm>}>G*qQ3ivLO1CwG+Wfm;s$uX-6f|)+u9Yqt}-89G$vkY!M?hBM!1GA}p_tNh)~X`ggwf2kN?v zhllCCpZ&;g!l8qHOyb(Zp;lxJfg7!E0YocXx9YrPKdp}484KIf(d4H~k>wMb zOaW58p1B1b))S>z4lYGxK6KzD3{Og}VCz%(rQ|Z4?bk1%2(Wfqxc14g z^UkhRw)oH|3jz#gCNyr;E|rnqP$wwZM;XAR6DWH+>Bb^Y)m^$hu-CvK9abuXm6xsz z#17^2&I|@!nThp`IxtKG6R@DW8@Q*e5%w!1Dt6NG8(^5zeIWjdeKtBmr9HjMEmUR} zmend(i7?w2(bG!-FCFJqiWS=YxJW|RC(yKo8^MXxNT-DH1h18>ox7_|3TWIb?U`GN zcx3l+G~P}d$d}r^fAR9U?hi9EUzbiS#07j(UM1u~EQT zX2@naFt~0=zEatn2=twX)UMX6eQkW|7TL<)QC*n297tWcB4(1Vk8Z9TQa>Y18A)*6t?;GPAtU;q5a=}-UUpBj8}C4IX2NaIFQ3Jt6^ zH+abAp?e@d%bXl|FHGv2_SxS2#y8W)pFh@NfrDB*SkO8U&;o85(tbeGVT}| z8DQiQEpYfsMVv-@R6eFq+Rx%*P#d0c#jXWy?tMF8z(%&Wwq#YKOxJ?j>ILLs4}>9{ zj89@tu2Jc=ymD0;&GV<9`_Ln%1D7wRxl5PzJS3A^`+Y47=f}w1KpCNRZ00<3>s2$# z9KgL)D#eg7*boDXGstZWPxM^C7L_$k{kasu^(sPGUhH~(&RS%6%4-4`*&2rkK@^t0 z22`VL%MKjaN`Y~`c>df4)eKaXxd2iwNMP7AII&=V?X|la%6(};ndKpn7qx`2qUHcp zYrC0*8DN-YsxdK5qW6^U!4Bke<=QLhq~<_dNUIxHtmAZ5jQZ!+b%Ndf+H3Eq8-;}K zi^uoVu>r}5d$lo*KRR`4z}|~T>2%MamB0Vn^v*l)q%S`Dl^tNULmaa`CjHqqz5mnyIsNLVe`BY@T$(q4gTYAp`jss>%*nP5^kVVC zLzuIRB-K`zYZ7DkG68e|%Rf}qfJL}>@-X|olnv;d8&E_^<@}z`=L!%^nlaO0pgL$M z^f!5s^QrDO7FiQ*_rmpJgFD2=U~wa@KoEH2tv5uX+r`qOaB!{&XAH0AzVPpj;J_NRo^ zn4trwQQ+F>O)|;x-v&9?Z`3YUfTTl>lRPITLa$F|-V^ z63GWTNvYLmuL3s&Pa!~{oIs~e!K2N}2oqmSnFpp9_O&@aMMP^>{Hw9Frd(D7ZDZyT z$(ZYj>vK~k^F9Q7GB2kp{GYyUq6OOyastn0FSvCplozjVpg$x2$j{Y^W#<|UR-M*8>*Yxq2Ws(tZ$ zzyD9ts=W^w?G79>d%l}?KyUyJ?66(4`+mH?rM1OjjI0JKkDEI?+RwYsPoyrutQ8v! z)zXuZ-3v?3_l{1}wM#2$e*K~jt;bIur{^y>)5Fg{O|Rd5L-U>n0j4kRf0iB?L<8Q* zH4tQ~cBUeC6c#L9 z3nWwxP@A_Fe68fs+v}wBq_|D)3`Loujad|(v}s_;9g(nVtB$=~N#LtIM`|iVMK0LO zQM7T|6~RE2GGlVnz1$wH0uyrl#IqPcVp9A%IUh&DR27rBhdPPi8K}i50jJtYVFJ6) zEKBMTVPbL9$>^)C?XAKpK+Z|+-4{;Do^*1&LsACEiT3cgZj?1#v{N6ZEf0dvMQ}sy zkFFD(nH76bb?Dowlq*BFweoo>$)g_$e6E+2>-xaB2_XwlLpCK;Pby zBSaN8)I2dp7MNXA7m_t%!H}*MT%yyE+9+yY8QepS6L6?-o%X%(WoQBrbYL|@Ss-YG zgYXO>IEuWe;mfJYDmt0HP#ie_t5Zn`wmKjuB?R|`f!5K)*DnWUJ$CElGH36xp4Fja z?yx_QupFH#*-`U+!T0Q$tY5w+@AKsgtHSNpF1n-3jM{UCOCj7RX_Z&`s-;}Em+XEz-a5oY7}c?yi|Y!zZtAtO6A;&s4;tX-w#hM zXcsf-(kpkl22khY zI;8s@6WatMFc~Qfpe5aSut#UQm>DQ=Go)HeEN!Z1GLqho`@pZtpyFj0q`O zKv+44Otb1>@O5&7BV>Zfw93lvO&P>L5W`Wx2azqwpRM$P<&O8Gtk_Ab3;>gX9NBv8 z_wW`K4dXBN`p z`jzx@e`J~OK^oX~>~C#anQR&0Y%g6vOl?@FSKs-*)%K_Yv{H+pD~B~T!>jo3;gf!F z;+;Q@CD94CTLep-!1(!tCwACf5>H9@*#4x7S+EXUHMeZ#-pw>`&lYFd7h8MjTi>~t zKL7ZGG(@d}&LEvq)=TLvq_&u<+(tJ`_+dC7vs1TUJd<+dOpsGGl4IAI5bSk$`ZWUJPPChHiTcX9RzI?}Q!oNQEk29TMa zncaL|2RFM%SkqWl2mTM zI90a-*;Q-H!j8sl4gSvBrE4mY#!YOZ4S?e+(k80N?$59JBs~6U!h22BHSft8% z)zOq_`-X$SB{@W16Aa2S7UVT4jadN4yITU!^|{J?2!yHt3kHyq&XH}*Su3w5nklm& zNGqPnc2aXdNZWuX)t=ISPJc2M-aF6iLDMIA!wx?_8i}x{)->t8rl(KUA!(!o?goEk zM@{R%d!Dxv=wJ9jgm4($%b6Hwp(7^EYf(3X&(pSHzSl-D@>RmK1goU1D=PO~Q|6(J zH|(gJx;rta;T%df0OrZYENm@-d#qTdGqFfGzqBSTaENuK0PRYLod$hNCv_4qC85z4 z+I+o!>zgtd{n?E~2M%kAah!wWbaCTy+TDMdwx8U0jh=zsx86#6Vjbs8H(s;**rYiI zy{)rJ8NE0^qcy)`0pp>SNH3o}OtbbL=rz+68d4HAKG?Zr0gBQs74zxMcfOPEfA||a zV2(AThx+KMWzvEYZS61=j7%^A=k;%VOYns~FyUiV1w6Oo6H2Yd{qCo(cSVx|b~^V| zPGcIss%`)6Da$2K?lnCFIAQQk_tN3ht@M+fM``Wa?eyAP-%5Y<7ysJQZ|@HL-QWEO zrJ{{tL~sKxVJ=dz$*ZOuzSKkXgYbCfwz0=v}awo#;Ab&V%q} z@g))OqUf+4Z|{5UPXHlXnX}JEoes;HQ=T#aH$<8tNP$HPORZFh&t5^@<=+ z>LleP78fYmqO}K^PD)eh`oupkXDcHd%z0s5!bSpXu#U|L@EDSubs?5;--!*T~ zRJ<(wv%q#>olE-EgJo*!aPIJq7ta$)2J2eRp zR@2hls(i_6aJTK}>GNNYE%<$=GEfI9B6=1C35Ik9uUs;K96p(qYWwzc2-h7Ac@FdH z=+0Xfdtg7exp$Pl_1*6a4%mFLotpllR1Z0@Fl>Z9jrR3))6q+1K6!qeK*p=@F6C0ekC+Nk~2qI4~2O`SL1%4O3|CjQ=y zI6gxyVh4;l|2yGz&Pfu#zsRX>j}>;FX?remm%|E7!koKN*{t8ZEXfp z=?GCuQKCM7{=~5`15~fyyrqL-`{fJqE*MHw)>Ao1A2&gK6yar!%e%si*JQX|$Fg1j z@o=it9F9~eX_ZoXE_BquF&NXhVCg>P6?`Eu6lEENb+9rdKBF-{uxEEZ|cM_F|$QFzyyA%jhUxwR2E+V<>F@;S%0E0tR>wlq{M*^1T~ zPAM?Rob@#EHAtZYyXTCoEUc}kCCfT#7VH{62iQzU3glUu;H3vmI&YMk8cenS=I|&( z7pELlYU1o~@2JH-E4!#^5M}*6SwH;jf`PP+wW-0)YU`k4gMI1BjWm7sOs|1+$-zEz zVU|_aRk~pR_Ra78P~{*FDJ!;a5QVEP2>kMAKeA5P17U15P?-H&GZ^Km;Xs?ahJjiW zVR>OLU9qOb(uHejWP9gVzx;({S!>pWebx;-z;55UBb}g=;Y6kcl>P9T2G-skS&4XL zCH>3IEm@=!6K>vqD=mNH+v($9{!|XKm`>0g zmsl?1rBol`q$*nPZKejbIkE9gm|KypvzXo6E01G%c_WZGekgl!O>0kS<@H1-gRBSb z*Z{FJFwVeUDQ61Tb`d_%`hX*Ktv*-lM8F(ma=}uEhgKz97w?KSQ=cGLyOf$7*V5%> zpXsv2Ny-fSnuU-Flho={%Q9iL>XfJRWB(4|NeP1OkXWJiJ{PS#URiaPIkbB^Xbi!! zF}JM6ySKfqlLhOYckX>(0qVu0&(fn$f0K^3pQ;<7Ql>pCT1BB}t}Vb%9RNL-hV9KP zs-+Cem}?dkGj%=aF@E3#OUflS0`pms?eJ{)yxdEe=2cJ=z}zG>7QvmMRuyf?>=sfI zKqXO}964jSjEDTxFsAEyr%g7)($I18sRBpq2SUi1c{vsJe4Ao{wVo*z=QHTME{hm} zWN@VJ%ZjlWw+jkc7+a&1jxQd6A%FB) zc!s%AqiOe2+%fJ8p#Pv($eWCf4m10^zyHUHL7>;)eA|HcOX3W<&6VLj*KQd0bSw;r zuGfhL=5_np$g;dkSFWaATN5M~Tn9GG(PLJ+?Dv2G~`zJ^HlF|9>!(XQdpM5ByyMEzaXtJB#y~A|#wKvoE{@_mx z%d+)qW&DvHV$oG9DSc*)d7<%N0J-)Y~IP0mPpaMA@7byVq)P2HWtDIJc@ zjK{7eBt^`0#uf85RXDr8?J9UbXqw23@{CbRL7hk)@zF6%cZ!|0`;N^Gy5J>h0=7<8 zEHlNLxDLB*N>7M>{hm95$nBy^asgIG8~V=Y3JHy*|TyQ76HDp@ka(CHL6dis*k7Qn$_-OuG7f@ zTd)9GF;Cog+-txnzl1P1UaA#kmkPIMXO=ce9b)VX9EI~!+Mu+{-yq!0WQmg;IIL@z z_oPcVt$n6T@wsvzC0~ez7`BoFRnSWU0JT}_Xmc>pONre%lt^c6#*5Z_>k0eq~wDb4jI?5zyNx zZ@9N?j1-&n z3@oM2ghMAmb}3TMo&#e`L6PvI%rnC#hEe5-b?PRW*wfH$oJhml4=|b;n%1WkpB(qu zwi1L6Ayff125e34S^N9&#p6^?Plfe~Vh|V;xaf6jNAq_{f5b2+<2=f&qx-5!1G;~9 zh+VZ(>7DQXAlMZ%dV3>hx2N+urT|sJ%D@KKui_yZl=#a{U|+p@P!0~)~{RfO88jDzAb=@)?Z>u^4{!WtYynaFIqf zk-qm7NMbZ3rQjKr3O=0lZBYM3Ge`J)>iWAn(I~4h%EQ;pI#pZ;$p@lhEb`S07p)e* zl&)C)etbICOcKEjcJbXi*VFLuW%}?JKT7}q|MLHn0C7N$zkc!FFSQ9SUc8k4_CNlO zWlEcYb+zfr^;_u&mg-Inhz8Gl`0;y&;oVn@T_sl;*ain|+-s5edf}f|xMb_h{EA8p zq-DW>P|u^y-HZVj2jWRFFiO6P@*-K=p=EZM3V;>W%Iqd8o#ZMSDt&ZHWXCcY356km z@I5jXY8$oAW&MebZ8wTC^3)@T|v{koU&-@yD!)@3WX z?mvH|?7`bLfwh&6dBPmVsr1<1gA5J)NWpF5Hq?|^U_}7${QNE&Qro*$5-d@_b z><8FmEb{81f&_)mgZrObv%r8}GEwgD$nm>MgVdg7*6`4dcGLEAmue-zK`H4K9+E|( zRaMb-gJMj|9aW?`G`FbN(@2y3JgjG$AOPmipFMG^iY$*(^RAUa_q_Y$r#id=F67aJ z2cp_DwY_2h*yW2CtYLGI4iB~^e9ia(Vpj85BM*;-l~_bdH{bY1y8G?#rcK}_QKs9r1jGuXfZMsUMnqjARfTD z7t`!$7Aqjz{|&^Fy=>X#1uJPc#Mz)L_Vmdkv79%SXVZK!OuzV>|G~h!AKA5y^*(p( zJ}+-vO7DO0zAX+XeJxq~{fB?@=hop{N)IfPeelsQ)ANTPr=#7MVl`JGHQKg;j})GP za!>L&iLyB>vvFG>Ffx@sQK!yQdP*O(ZTO6(+sLr_*sP@MP2;{`Bod5Ops|d(poHU< zCAlY72BRfL7ny>)f=qNsHMwSLn#hi8D?_(JS~b>vkV5kz&}GPtHzj(#s#`DK?P_AK zFvc#xS?nJeg#lL?S@{U|N3fvWnz4J>v)^xj>$~Z|unIa}ht@HrRjxy&ZM#iZY8^G5 zY$$(6a)s9(PhDhP+F4Hw_%-BaWpP0b26@c2F}Fyj)jDQL`B}8SSGfO+7!yd+;-Z2# zKQk}m!OFo~`*|<_pkFk0h^^}y35dAE&d<-LXHTD~?TrHs^MZ6f2{Z-4VduG~?oqcy zVz-IxJwpq8E{P1L0OSiltYxzu`&g32jca)|Vy}<9+-}?@hQkFQ`oP{}+k#Lv==I*U zPjb&+)d4}om&)Kx(8a>xV0Rl}b0@uOi1+17*Q|BBC+01s#LD7)I(YFUHK#*i6PK>N zlCD~fx4*Tm&BNwof!2Zb=)qu~rgm|*9jWB!+(ufQWjJzIN!dv%&N84#yS*)Y##hO| ziYUW8t8sirPN4RCHi&TU%ay!bJNL6G%nVZwW?fe#1rNx}#LNj2!A1uH8EMK^XC>V<+Zezh229C%wBSP>zV9mTPv}a=6h-0%8~bf^0#UK zsV&^evA6SWa2-loHvHAx=n;;g2rvHB95-skgf8N$4y!-N7Sc!Ps)k{7m=z`S z^Y)-rc1-#F{OVA<^w~jY9TPyLUfG+G54uD&>@)rA|HHc?RZcM6Gl2Bk?bp-7h0BQ$ zIcKE_fd-(~ol8C7A`(ZiTsABe>VxZ=JC|po^3Tc)I~-2-w$tXbN18XB%6M}k@LqI* zI0!IgAh_JTaZOf1!?!lKqi|{}+ae$U6Ok39i$)hhGSW5ORUBpPt zA}v$fp!X9?$p_#bh;pr5vKIZKZGbN#we!e631j=LYzQ$8udpIcUvQCL)$7vZx(h^Q zh>}N^6DeSjim3RC4kt)O zW;=VERf~Zv0-F|$?J(IR3xIuGxn3{X9;FEbx+`*?oOi&{HXd_Qn=hV;+}THrYk5%^ z&1dhwmxi`Ln7Ps^VyEHyt=H1;{qT>|kN*D0BHqng_VgG3{9mQTwM(+fx&Og?>B%R* zFp%+)+%7anRODL}Cx2{M+4KrT_6*OGdX-(JI)!$s*RZDdt&BRBK8s3Qs1}stD%twt zQ1LwZtW2;IAW=I|$r|z{bim+zxQSxpz&xEnw6~`Y?EA23t1MM+CCOb|^K<#`_wE^X z@VGlBv?)T~B4ayc-WbW(T|edt6`CxoTwGogtNmm&4Qpc0TnH8)fBKoaMhLi9)?n$) zuW6!uW^pB5Fraj4c~xAiZ@%*_mA&Zoym-E;EQk!{)+@Jk9cW+A&Ce@ypI|^@JGWRp+(v5hZ@M4LhVNlrhg?9yg(0^?#!kzfP9FrsUKJz!DN@^{CZf-f>jWX?LS9k)1JYDWv-VEXLqoWy zlrtqM)@foERzR~M@z{hMP#?2s2smk?6m%AmYFc~DEy+QFg*z{OTQUQ*XtY6!zVIB~ zbbh{>p0S*>mv(Y7q>iVN+R)%V`-(e@rVxnohe~IF;n+b?y?LMtKpJjzioI;2CvJw; zbue=F6y=uh23H^~V)D5O?vk#xEYtx)llcT!Qu}wryBC&MRq{QuZUv{fPgD;rNNlF9 zN2e+Q!A@@6xM^Q|o}PX2iM2=pWJkg#;7_&1yaCF;X8`ld^z!-Rv}C965C8Cw)8hKo z^x)wm1DAiDp5FhJ0?*_)Tw}}7JPMpm&IItaQX3hF^IvR9N%{ekM;6xj_*iv6xKkkt z0+o(ssi(F`7p;Xp8j37P2al8YBA_tS%LMtx#l{H2%%q`)C}A{$XzhY)EAr@s^cbhkNPRTJ^LFl}6izEXsm);;dnD zARKI@W@Le~Y^WQlZ&BaRC0S2%OJVQ^|Dtf#X&D05b(BUOaGhLLKaX|@Psp5>Hbm^n zyySc2n!%m*vN|Tyl-2mp%YS6dK&J@X)_d+kFYp=B`_spr%W=IhIm#w4mBn_<|KRwu%J+C+E>ksf^bv$Xg06AKu-djAaUJ7?oeD?7)~qG`L$KF|`F zi1^LoCv}%9;WTHD&I)(H*E0+71Q#6}%Y{@vT(r;IJajvaXFd||2O?b^lnZGywe`6m zk-C82G2Qc~jPyST93|*Mxp4cWegqvq0CKa!=@e!9v%mNk>EW{%maUMgXkVXM_qylGhuS;hip^N*dQl8#A&pJl87q|W3{`%q zW9Y-YjIpd=xFEe9H{xt#*3h$Qd7d#=bhw|kUcS`zKvrC_(*N-2*gAAWl}UK;HH8E8 z$^ugnWYZY@hEG(uQ!$4N<&@l6PF=yX5+mJb8{vJ`vMQRmiJ=BikG*?b=ZOX~?m_Qe z`;U8U!uA{(=P7N~ZRSkilfb$HP=I-58)>bbcy^jBtzVXi)X2cA#(sktIet^<=1`)j zlxzLw%6Lzif|q?d8(O7O@I8C+YCz1FP2dbP|?YuSHEYRhwhhM=E5l$z^ZaTnTaQD!RvXzK32w3g@$%_nsJ1AiWdzXc zx5Fhw^7u|sICqR@hCpu1Ciksz!Ed+rcF{QQA=x#Cm%Y+;nR!8)1`tJecea%Xz!|%F z>y}}RJHjGS!z`ui)A+t?aucfXc|~w7gAQm~faQwIC8l!Eh4!Pn%=(^$=il1Wf_Q+M z18V}Lk66Oczb^y`BFTT4(kc_O?KQ}_M}8cccp5_&g~&0*+XI=uI2{9%*2+1 zJBFQ#Bs?dYLNqfiKH^yulR@nDJt0ziKo~*;XTV%vaMggtp)qovZP0!yq}(a`m=QO(s8z?iQ2q$0elTp zrZQT=!HEh2rX~~!ZVZpA>{>{7-*_jz^2S?oB4COh$GMYYDP;zyGdErsV_A{;cXN7{##f@vy+gY*z12%WV?&(i{ z^f#8R_EkQ;^7>mM+&!`^i3}<8*;y9^4AvsLIla(tg5$%C752^y3Dec2lcn4 z_2!V+x7Tupyl1E>CJQnwK}W2P%#Kp9R)*yAFznIJ&yVXjRQp}~`aPX{rFSs!`)&j8 zX@c=89t=OAz5w8HsnfVs@Uq*}TS!-Kz9}7$Z3ChAw>OolLncC9zlhlve^VC=cN``n zVQ4q26caHqn5&HkJX{gju=r-vVY_H4G5ixqgC3v)=?S2?3NS2tySoK*48rPRm44l{ z{w-yup4VL0WcsC)y=`;pl_FRM5FOkj0)jleY6k`7IUZ7-GFZbS3f_}_46!e6tKWn?AG@!pP38^$wq?*Ovxw7U1lf1Yl=`7Mz>0VrQSd!8PC z`m1#RSAUldo_%WR?vVqQn!77w%)o1`+=fnV#zlIf0>I5O03^*Wucym5-cIlSAOG|8 zz2Eu*BT4_=o zp|LESXB=Q_bhL7NyluZW_y}uMOFOz+oMS;AMQ~nStJ;kQMB@OTs2!`|SKWG0B3nn7 z2p{^seMYdcOZM3=SO8*tV&4u0y0H@O$Bt%cRYRK9>_WPD<+@nF*f&dzF}IR-Q%lvyB)A64oV2Ih>%hCRJI9eZ%++t0kV+#B>}iXU%E-FR<5>N;75rB*=Fr$&*WyU^y7OWb@KNIm`oW)tO@V|TM?Xso%@Q5DSL#bxg1v1&KNlW$+7B5^& zm#*JUo7>ORj3}t~S?Do3w7u*wZ>)qx{O$#MHWmkJ8z~1;ma;>?)N` zOLPmb^6Btwgo6MUEozUGwMVn6{jD;g$mKw22;*LXsv9Tig8e4ou|S_bd8`15n3w46 z2&dcY?!SC)foET|dqO*$E7-AUHKR6g>Bf!J_KS3MI!>EUpQo1(KS`hc{6AW$^|^)! zy`;hzabQ2s3FHh^K{n3D3~rK7@00N$Om*k(+vz(${3C0dFYEKa|5rb^PRUc1F{>A@ zq|5f+7cbvPH?LkvfBw(^6YFGtl(wIKYF(U(q%i2Xp@V}k6=X!Zcyiom9p%+xolH8s z?R=o=f=%E!S$akDv}geZA(cQvIkU5~BbCTr-18>xY114!klSi!b@pe zC+k+`9V?rQGA;rt?{WW&hjx2MBKY;>;Z|vCU0E2D0#hGn5>Lsn)_JseEZZw)SHu-t z*|6s}hrLfp=4gNXfiCv{u}Kg>0aADreZ;ffTdqI zO@~Dls!|3n6B2BG0x$R_2?NjF%Qrvtsy6mvk{wprwTwmhLh4~M^%<&u8v&sWZzEgA zY;0^=EG zqLJZE(-C4})_Fs>c;{hy_StXJ!rHZT{l=^5d*68{-F^L=Y3u2u03|1KI9*t<7O(|7 zx?XNmGbdSwd3&8lpKdw8+K+$0^cyU#6|*q%dV9!x_s0rzdeUfbb%k31A)E zbF`99Y)vsi?xJ)(>2FSLO)Ohb+1)=#S5~hGL@vrX4LA-gTUbT0(Vp##tz8Lfy>jQZ zw0m%>DRzne*YXVV4$#o)0Rp$t#fGt6&gq%T$1d2`eBLWpFQP8k&Pas4>ki^H$UIUFS3wf!WJrNJ-@Ngvg7OEI#w#ZoK?Yi5TnL{R40f;dQySJy- zJc43@y>h0Us6vv(_&`}W0mz4|8{uz@vsK#NJkY@*-dy9|OrN=PJgzrbSk;Lm6hF0^ zIU>s-6A_qL;yK=E!d2xA6{!8&fR?2Fo*wVmMV_iPcwn1EiFL+h zkxDD48}F3mHIia-phdr4xhEEYs#>t^^GW{S{YNxjnzK)adTiBeVAMVq3w7? zbO32pss`rtlIN4V6=?iq%!XJ{(1VnQtOVCb$KYt^nUz{wQm#XGK=Q$FqTGr9FU}p)mWIb|i zu;0~8dh>ffNPqS(|1y2{@%!n$zxsE|Uf>nA6F1|VOx;ds#SRLx*U@MpV)0EY@hL^iVK2rUre`hnQ~#>#5CV8FiCCLL1= zkxc}e%0J9rd)t8Ng+(xnzHgR^`%-OKyPd`a)-g*uJexCCd}adMri4TG#r^x~zz(oW z>&sfx-1B;NH64zc)W38moo+u({rWWRJbT~(GK5DNZO*7#*s|<#Si6)9jPlwJ`P$aZ zf@M^D`zP*tf`6I?nc>9N^^pBKl6KQzu2B=nuBCxVZ+jAA&r=fl5hC}gu9 z$B-RMFHs%sziXT9UdBPxt|PVNzaiz0fO(E~vhd?X#)LMvW#kAtMv2tex82*(;r)R(y$4;W=!KaBpg6@8)#{HYeuOQ#UJhCYu7G| zueEJh6+|-UIfa0~bf_mG95xc2fXs+4PPVkkfhCgy^RL|5Is5l8jMP+r=`6Iul?yIe z5Fz-eV^q0-oXTz_ZRwC!jt>nXD-wupO}=vXEd%}WK%ZAO3n(i7jNKcaBd0c&Mx5C5 z_V>QDz^#N?S{9R-eV{V1th(zI=7-q*=}@Ij=e=gvNv8+Uxn8Fom@ zxG|XB!nau8=t+m#qE>>$`z-Tca8=Cd)U}3YtQ-W-fk%e+j>N|hZ%3-tG9EYH6sbsS z5#cv@Ws=S#OT$vAiZvGUBXtPtr^dzm@r|Q=@9R0Wfjd>wsbW+})=gE_Inhen8H|fL zQM)ESXBDGLUEqn6)v({*yY|8F$?z_)5WxnabeEk;t1z(>{g67((sY0+hQ-iWX*A_J zOfC`Ot#IaL{B%E3M@tjRjmuL~o2Nj>ooe5z7A?x$p*l;ug$q@FvP`5D*mlIRSq$pz z-^qYT9~Yx@rFu9@pPcR~vWH%7>IjN$R~}Is!Tuz$Nky;5YUXTMv{IQi>aI82xa1iZ z0vaOqY+lz{>2=ImFf@!1!7w0k;ek#Y9q!9yc%<=%CZs!?vOH_))1XNGbiwenH@^Kt zz0Zp$52cF>F#i|-{C}6`R@T%aerE0VAOH1VNll>7V`c zf0aJ?@cs1bU;M}x*`9{XigDv0d}=yeEzi>-!NACcW_dUjXOQ*4Fz}IxYi)5hpyET9 z({8YnDQFjutJ8V??%!2%Wnvv=4Fj)rSaIw13b!@RYhzh~A~bzk53t;0O3&%kM;*vC z83CEG(hRrVB08$v+zXZ|@Ofr!tvWyHPyvs?Lsx4)*t=ZM%ChSp*CBP=XpplX!1z>~ zHfKN(XSr7#U`WtRL*JZhTSB(N0@{HEWmv$aGW3atjf=*4XnYR#3~Qi~CRR@>3}hIP z8hOoPW=;(l9xtvK$hlw|010srvwD<_G%~b}0<@NFY*}gKV#$IOS<)aZ#FZs7*)FPp zQwg%6rSI7?0{K8Pzu>r~<|hm1Zc(b8x|iDN;ekZcxIR8t8Kw1||f=Vi5a5r<#3x}Foi4c7`6xv#snIl9FPK4lpJ zIFF}#s~n6;K2ni+^h%#c(y4+m8Vi~hv()LTjyp3Rd)6bCC?vXi8l5(u%TZ^5fmVAs zWC5*}VGsZ(8d*3M-CQAu>yiF%&*eXe*M{Z1`RyO1Yp=eoOyY}AK1kD(gY?~d-$_6F z#V<9*eEXG~>A(B0{(oub=@+_wISG_G^GdQdCP>d)>-dlU*n$d$B(r^7nB_>>3YB(bGhiY%B@=N&iiui z*qvAJrq|zm%Y)MLsvr*Ddv|wVT%abh#C2;rz`Uny8CW1f^XT-*d0u@O%x(CD+4`o0 z94va*3jJnzb+HHS5Th+lV598cxO7Q-m+Khf85Z;a1#DrEa|$@{4*D zpNT+j4{$l%&bG_GpxY?ff@)p|9X~8?(KY6}u&B9l^A&ZiB#f291%nO2=}cW6g6wTk zrL0BG^>Ff$>2T8oL{o;eE(8TuMc|OQShVtU@bS4D7fd5f9*>4+1V>uleQyhkmJovH z%*&-9-N6K{+B(2+mss!x?a~h<-#1@&24?au&I9X)S&H!3Sw)dpG^*pZ`UA z@9+LPePCU$3ca3SoO_V2ljkz6K-YC^FWaXW0D^NRxav*%w%*WuJ71plz&CMp6FK#R+ocp>1|v zUJ|_a{n#w=Tq$LksiG{GWJ*vL*mNqfa9OqMV69Plef;sqD*yR5I#&l6HJqF}3*Oc$ zP$Hnea8Ecm33uH?HDCz(w6sUEoA%D6xJ0%-DWj=4_<7d(?!KEI?rp!6^5My0o>o5) zs~I6Ppb32ABuW=deb%FN&2>F9s!}uzZP#|`@-=Dl(7l>)sFFqXeBO`s!JkEFH}Q2! zRstmug8c2Kc~;NYK$D$oigZT#;5pAO&cAE_ey_=kKUDjag0XQ32+CT{#HO0oXRgru zA%+oLG<+Ju2eBx1Oa|*;!=($Ln|DG48Cp;uaO67v- zO1qJTMz&TP7qQid31FZ$dl0 z7gxpmSeWajo#&6zvoAhX%Kg0`{1ego|J{H4UmIq#ld$d+O4g(piE)iQOP|z=U0S=O z=D_aO3k`ZAI>l!{ul*c3#;m+k&S^rP^NI&@_E{DdZ5mSDnSPZBf@FS!l`MH z&JHm$Br$e199gGWe_eU<)j)K^Bpy{yQnzjsOb3i0)K{a% z9X`m6e3E~lKe>;YC&Xw5y4U!9@eEn}Ko$W0GN_D6fVd+T7zVmt)~-Vu-bqyE1|&d9 zO@|Lq-!MB4H(YLEA@5oSv}2tuf)AewtsqKkGDYYK+&hO1T6YpfWX$dvgRwvt6XBRX z0VpzLlw57;h6~&Wu2s^xM|;ZTHHX+tJH=9$;7C4S7}Wbhf6I(yia_p0ca6wYwes0U;zQdYph6AK_aRt~^Molz~nD1uc{&Z@0i_2-qfp=FEM zwxF=mGrM7cc1&cateTioC+My$th+~UcE|}QFD{tTfYDkgp_3!`(n>*#OhQ8YjSDS# za0}F_4H`gSU_+Z3y71fFN<`J?+WiCp_)pK<-@ zDrYN|2X#tQa4R?vRpxz>$$s_MdEmM0gcZL2>b8ycZWZG{u2kvx zl=FO4LP#pN^^9XW?XU%LhIp-hUxs*OJ4c6yTDQz#9iAMEZ4S?i4a)mD_`IOci+ly8 z6e9`3onmbkG1up6lx1gp$t~h__`STmq^w|ZeqLFl);GZzEhM`Zz+zsTl1KxiF!n16 zgLJk!(!DC2G^+pvo7-NGtcL?ZuEAkHMBu5>)UCo6w@JG854oRoqS3zd8r8uBNHY#G%`mID#FxYzR_ z8U~Zq%B8FCTD$vRFK(d50kR%R=3G=UNSLJyD3NSqFoefc?>Io%BIboe*VcHwcRN7z ztDaNd+b;BEfv^-G(&u4@vfk|nUeJqEE=BP2OrmKr7o^aC*Wt}AU#LOl6z>`V>s_nu zH*7;~$m@D;VOd=`O&YgWW*LsbN?~)&Xl|^LcNU-`cnlHU2M%2#^87Gk-XxRIdzLIk za)Ud4Huxoj8P_;zTvk-PogjEg^)QzjZP=J;gXoNq~WKAeXIdA+JW)>$!8W6 zPgSq)S^NIe4?awf?|-HSLJ^oxUxTpyt}OEQGMYbqrP=((=PgNJCw0DA{@F^ud;v90 zO23Ua|IS~o2pQ>m&I(gL1pI!Lp#qqd3Ul{T!A@;--vDGxd>_F4l9iPN9)MWNtg`Yh z93vCk+ZL3s-*6cWRr<99-zwppuHpLNWvAem;=PNEGo=*fkUeEYfY!4iFT(ZU<%YTf zSp+`|0gw!dER4gCb(fjw{=#P&A!QM3a&>i0Vq)H-Dl|eNL9y9^GHM`$UUlZ9rS6)Q zSeLHeunc%judiY5)~&uL0;OHLmeP>nS6+WkP9xq>Ny=i1&d7k(%6l*Xa(ZmtZYvu( zh-AAo4F)@;&(?L6*vIVc{JUDXa_wD9L+|$VOz*lz}48X2gM*P4}3K7)U)b&V4*v}smOy6rqjBX zZxI?MSsz#~9ief;0`vPfiThW1JwcZbfO3#i=^C=M-P(z)vWlQx298k2+?s+`a?Pl0w?t=$t`6CZN_9IxeFA@8 zxETYMIE;V=(NfP~_R8|2A55XBIGxr(|7fEWM4hwl-~4vvS}f%>nkqcLO{(LB3@%u|L=+m{7j`*4wsLkJaK=m)iCdhbK)S(NdkAHnkDyNFZlsG{=H*B6Qm+?5EIW zMxPkX6FNe;Tf#e`E@k3YCmbO@I{xbXQ-2Vcy$Vn$^qw)$dFSJ~y0Y+;>o}0c`iBbBD zOqp$cv?^WCrfOF*>(O}}Hs=7vT7nXbKmMj-KLP@ak7vGDM@ z;-D&|)ie<4)C8+h=1H|@Ao*Clw3e3gX{)du7d5Lt%(&~D;_j|veUT*J+Zv}VX zGM`u99n8+$)2Y-p9T%q##lP&Ip2>Gp@dbJk6(UuGR18a6y2y4B1*9nfQ?t&9oQ{J# z^gya$wa5P9$w z`5zU^$~2kI$wJ$*U)l}dNn7?%(VgbuU%q@vf1YZ_Wun$9ZDAGOSU0N_sKls<*DXW^T#Djm=q z$)3moPi#zz+FGm69;BcD=&#fJ@BKvM5#UK^D{WkVRc@09dz0(k>}=T(7`0!+|0IdnH<4MyTJSz%tf}O?e{)2m78|cV1NoX=s~wd39AC zC>(Bc>B`~4W{y6j&pWnlcRd&rxE)l}Wy2gw>>mwow*DM5=PYYetEDboqml0~%b51| z5A<`FE?(5(fX5sxuU;7)#E`lmK+*DUC$%s)o{y&M$1YWKdg5{y;`4-?3t6A45yLx| ztgA^WNU%9P*j2(Hk$>DM*soL9>dAUN1Vg&O?0?oZYn462+F=bG8-55oAL|^jK$%C_ zUY)lLa@i^k26cya8INCXCq9v8HKm7i;p)44hx_+3Vp0q*f(Z z4d5-ruSM(bu!UiP@&O4<48O7A@Xv;TwPxkUoKA==XG%-Ir}AohYdh`jZl~wZp2kTv zR&8I!Yz_-TI#{))qyi2|DajK>x34m$up~1_2vF_OATdx_0 zv1u1f$MHacbtJ#?BRf2NfN@+C9NYmG>UEjE*Y@RtnG6}Li4&FMl;v7Ku9|2l~)Yva| z_=shEMrC=-gWY4yJ{!5IrfcFvDZHljkqPg7=>Zf@oSSlU>;^2OH(a_ZU?$+zfyZgnW!_3k zp$1q6h}}jO;K7I+&4R(iaFy1uJ&^sqeOGs@eL9*8zjX6sM~4wM#eB z(WtiH6GEPzt2t`A@-G2#h^!Qf%?wfH^fUC0t60EwAp0u0~aO;kDS`dvbYXgnDf>i zJ`qrP#$OV9mBk~oM%Ng|B|)X>*cYn@>*m~;L=p2p{$FiQO(K8j{+iNnkqf^Pi4=Uw zD5G+T>TE@(e;F zaY3mu5YV2YZCpu{iXb39*t8Dzzkg6^_~Z=4em#Et$hwfv(wb#dlB|txmjl_3r_I}1 zol(XfxCpIuvfmodtS8dVZZ#8EM9JVJN-#cQij2E(xWbjQza!gA$qd80mdT=b%)I5D zH1$3+zm#5k^^P=>DBq3`_oU5bZL(CK9$1&`SXgZ>)54KlNmH=8p#{k6&YlV5O|YgV zLu_l9(rQ+2sI#4|`b6u_vC=AjOKKSY*xJ>b?^eCy9yKFTo6}5WI&H#1w+5o~9t)@P z7P3HNqWxGr3PjP>Ez5+v{){$zGo40;;5BHrFKIg!3qya;j`}>Ejf_keg8PtlTX&Mc}6sdAPHg_BNlT8P+B1RzcLAa|u+^iK4^GA;Kty ztr40i5F^F6nz}phne9_wHp%M-Yw+BUR8AcUuO#3o=!}lN6bz@{s&oK4%cPQ_31e;C zXmWmjPHUJ+g(f(0tSvgml(%%wNGhh`!8TFmeIiZp-tyAC>bE0OXb4i)O*v({8xmZd zqN~u;jdwXt*UV`fkEs2D%L<%YRDFV6^t=LZV;^`#*~{$1>8 zpA(@3z;~R}XU#xRKICINNlpRrCSJm9Txm3DIj0YgdfvRsz8Wwz!O>XO*Gdawm7NZU z$k`w5yLzF0#uIr}4^@(s_PL;?55o3_+P@(P0Tj1G4;U=?pw27xjDg(PGU^zTWe7JS z>uG%Ay_@Fl0#D^eeW7t%Pp9D}<*y`t6k$RGeKyCi?D^2$gS&Awj1=F?7|K>UgO{&f z)b)UE5zt7RT`py+K|)gUNl1n0wnL#Woe4}f%JZ7D`{f*vCOQ-$x2i5h8HR8pr#IAf zWXNYhqZ^5#9QsO96WIE1{W{B9e63_B3L!Qvpstf#vmUh?BH5pVVTB7O$td zHa2@?rUN^z0pc%TyOth3duE5!Y`XsH+i7S4XyeMY82q*D2yG{OKFqMOMkM7L&kgNu z2#T2tH&mRS5F~N8#Fj{o@~{Z~orzsazr(mBq5Ox(mtI zu2{2R>xtn|yHEYTGfvcUIG0)rR{R9!)AMnfzE25oU=J(<-agvt=rStrEB`kd3(Nru zL$qs0_)k5D+NEIfAxI}{G71xhfj@WFG$sa8g@oVM3t=#O7Q-+e)OgX<)hV>z8)teK zaUrs~1}|kc2b5m3O#Lc`@uot?C$h=#9fNkR$aI6AXEw=48iv?B^;)T$9qjFiu?b5O zwYw??AjpY%}FA*ofqZEn5Lu-@I*UP+tVJ8A!Tn0B5%OvhWB zE~;%eeQ9kaRaQ?z4euKkai zvd9bAt@dccbo`*pV4U?l33=IYz!Zx(2wT+pq~`>tu3erwZk=pLVrHn0lTr5w_drOo>+k9by*w={?GwnB#+L9eKe3 ztz5W}%CQT`FIdZ)b>@Sar2_xlAc9Jrq}{`&N(XYmTmJ#tk50xO$SWU@AX}HNQRNuW#10V#eer6i zi>y*O@2?2VGLcX2kH$zxO%{xmI5;B#9;l$61Rp6$PR4C~TpEWAhQkcANRkUOu7TWF z#%f?l5s_@Go&*y<3hlCuf$}6>9|bohFTKIL_J;Sgu~MXpVvoXuSXFA))@>I!B;3w} zMbn2(EgZmwlcr;5GGjn55g~An6k5G8kXi(Ao!g{E1fopPa?M)r{^&+!-5mRV7X7xJ z=qSZqyLvgzR1V$|EGYdT*ir8ek+8JWotY!fJp7_DYI|m#pd-j-L)YUG<9O<1I^bPp zDrnb&r)XTDa2ug!8UpeWT=1C+08(P`(TY{aV>*eMC?7-UgvR1@@5LBM2S`q*u}ETZ zR6g8C_605jhDI5Qyh1aXW-8)8>H3$U#W z*yeGXo&d`rjg~H@E4>*_HkVyXSuzm%oZ~LC{IB6RMXt1Rmh?4c*KhrIbj|XdTqdc0 zDT6+DkfkEOcK+=+k)|#9Ucc#?OI%z zlZ-|YnQdQ#lWt$kD8@|8b5W+URy3?R8bv8RqY(>!Q>JJRP$mOTT=fj8(Yze@9|)rt z;#_2RbVZN19;KiE&0nPnMhxR4zg;mwK)ao+8KyA+GbIko;n>#41;eVGWj_{{Sq8u+ z%^iD=0Kq*DSV~59xekTdqUke+r=vLFWu}Os-B9S+KsK2&p9RSc%I~o-qG0bQ=lbQO zgFR3w+Zj2J2>h400QX1(q4tkUD=S)f2Tb-hS;n#zXU92PPO2)cB;w{{es+9RrA4cc znSN#dWNaUXdb4j?5+o+9SLJq7x(fyDBfV})9S`FSNb?WK1{_pAV5-iMpq9e3GI@Pl z7GyvfAT)wvuiU;(&nMl#e_y8%mbatHp#lge*xKrfXzq+B42S(_srSYB!WE&d2u};$RCm}^+Fzb+sPkZG4z5m$^q|wI znspfx$d6!G;zTuB%Ce9(3N39vRVE4)avA8mGUQFmc$iTdh7IvVlhR3nXY2-T!te;N z*;lMP2rBP})G=H<%^eC-yKxgj^h&Mk^mRJSUkW7cSN`p5f>hVdia?`7 zE(J!!@NO}QW__ICoSw=u$}=gJ9GKb^<2lYJ(~KWOkhV52T)9pvq}KpvL4<92Wkp~u z_Z*`{z-GsHb1UC5ENSfo210Nl7?B0#DRxPb1}mC*sv_Flw5=txf+(B3<}J&z^~*zI zt(LNqsr2XbooDIU=O3n{&Btk`Iq?ic^EM9FlJ%$&Fu*x=tU!2bCCDr`+(?&(L~6d} zP0YAyVx19(u^(d7ULm1088<3h4>QB^oH1wX*^jih>nlTKCzV zX@^H?!8J}g6gxRGnlcVp7tD4y)~wy!*`0)wV;1LcL{+al%Mq}p5|+6AF8V%arb+Gj zdFi|GnuxHoSQt|&Q{7=4ZRw!?%{zBG08u{ZnK0V8ml&T(fS`ofCeiK=&WU}18M;?o zPrnzz-n)2tQxoWBWC_I%K$+Sf+%m#_ZgpGRj$Ti44@Y zH$d_6$rm4`%?BT+pZ)v)F14q7;&MgpBANq55V}N6mS4Yh$2wI9c32$i-?Q0eU)ozE z*;PCHyHp1h0X51>_)f}>7zJv^VQJ)Qp?Y>5J>r~gc=9AcI_b50&wF|10)cq=wfO+6 z-ElUT!}1ObrkqAz8n>;g3{Z1P4Tyy?u}+{sD#O{Wy-sgO7g01W6qRB+7|J&spTRCo*q;BlYGZLcyme3T*x7of zOyBQ`l%j&Vue= z>A|yUQ`d3QAYGivBcpyM5-tPVJ;h_%Fd3!$0O8L4k)zQVFl^`MuqVmj9 zGy~=0MfLm2oWMv=nN@^5YWI3Z?=h=2QG{Yd8;S`B+b`0S&p%4{fAh2Sn;-pqYbfl9 z{HJHB*kc(>TNwy_O%_#1!AenJXIr=r;I<~y3!HKnq@xWkrj;xa_*pB>SH#hwLden= z9BA$;GI524bavm%?s+DsbA-TO84aY=_@P~P6J{~e(&V5NSX|@5Cz}c6&ZGtX>Rnr) z_dMh9Xyv>Ef4W=1HOpf?#?kG&d?% zi8YRi@}Am+bIRVvVZBl}p51u>idr`YBR%^q&u(mVW^%?Oj3I(*5jaVT`@}8h8nXTi zry@ZIz6Mju0GKl&%0%ho1E{9~0y_KLPyRxDqBY5gwi2fz7^rlN>z+JG;Q>(wrzP0;D7G@Mq_x7TIpb$}%>aa{j4|-w%JsH9f=j*pW%5 z@yv97duFVzXuuk|^{>gcaXm?yT*y~h^qOP`FQ`X)2x=|c_dv_8YC8p*aJC?w#3ayC zN%;+phUyTJRltAXN|vk(vu-IZIx;7gx^mLW;|EKX;Pm9f%^9In)t6<6n6;9;zPjLWJH2m5n|(oxH>L+wMKW2 z_G)q&i1F#E@Ep2tnHgSmU4yeZChpyW-BXbp$*f3s$38U=S4n{PMKqxC=x7i3P5<#n@hW=lXU6U>((9nK^g*%+q2x=ey+e3(nYQT)c0AkeQU1h z5GwNXBN|k?2NFCH9b}}=6b1mwkj}N_yJWIBlkzJ9{PzIDAs1x9be45y^G7eW+AcHB zYKAGDIn%16jbDQV;wQN))r#N1OAH%#7_FPSdvR&qU>P!T!SI|BK(Ly(h&+i825&}6 za3@v@)VmV*+PHX88o9?BjBEsybr;^A!DC|BMw{9(Q}+wYDg(=g=;LpWM^sz*Ni>ne z1X)cZE(;!56K+ibC^?mHmd<=zSWfElp|@#azk3VzT-vl~Wemi^5mN)hBQ0>HqFT!i zetUU!CW78k`=jOtl!pXKwgzT3Zzt;vL3!e80dy&5)MoeYo$QeHVoj%@s4ii2)6VvC z5#5|hSLHG`En9I6;stxg=~G3OD?nDi!NLW z4p9nS9WSvYz!n3qStPEz7w0mIQr2Sdc>K1Vzv9IuM-+cZkJ-z>-9jewSsq$QQWNebj= zmF$`NU@mu65M=^t?IqS3SI?i3)5{tBp(bfTI!`frX{yel&L9I#9egIEI*G06O z%C4hR;Y`kfphW1Ej=$Wzc{6?biT(U(axp1Lg|!fAo#d1)ML~&X8*)RaM#6O?o!dB)@Mt{^_1d;pCZ~Bf zM9)|h)ll6wu3uBo_8IpX^B8+6l}U1`nMR80%7)zvC>$N;(MbcP=Q5%$xL><(7S|SL zi)Ht$lKW#bD5!uGSd^~4ak+!Yg7SuGqU{fGIto5eijz~NBrIyKyKzugLyk>f;3CG8 zMSCtNwCQ&Sn6Cz#^O(t(z8(wy>~-Sb0;9{46m9%Z!^++Fc$NoM1Fj6g;%MTf&!r3N zsjg-nBME*KPO>wanJUyN0_^9x1LDsIbD!>_tNOWavF7{w9;Do9)cIz4BUYg|RfIr1 z$5emdSuvmC)Nq&Gt>@{(_kNo8HlLDrJNHWWc97ODUa`P)H@))Kca`y=^tox!0>1B) z;{)MY8KpER zMfSSq*EU^%k{Dib?l~5r?ZkR+wGWH#fjPkC+BJ2!L?AbM%{Kh!U))!X$by~e`H54+ z03;Vlt+}u`XJuFsVqmR+-}!mhn%UdiQKx6o>g{XSZp)N!*Sp^JfKkJ5K;P9< z*PP3Y2v=1&8Ne<@c$V zX2iuq3X&3)Z(_-{8eQ?gTm-n@NV;Uq0#D9v=KaQ_6Q2uXqy#-;Wok*p)OI?J(k|A= zSAs{I@}mCjAoSIMls7{cnA&`$Nf~%MZMC^deZ3Cbp`LeTXlMim!+KD*-S(9+BN?%< zwy11)W`0)6m)yM5laVm8o&@V^4I-nQaELas{rAq!L0YlHlPLgAbW0$8>ZQNb0H?Ya zJsCyXJz#`I^1O2rt}nvP0|F>z^5&z@(-*(`X*$_`p;8|;ffL4I?E7E;#_tQ8>O(eM zSxL`7`6NC3{L?hT7O6ze6$-(!1i$8IDh&{yN`}>{mD1<(yyS}Jj9o9%s#CggmJl3F zXdHP})R*X3J~ZlB>)xT$K@%lcajwDQ&n2wG8y8ti(UzBd%K2v%`=^b%JU?2O7mId! z84t?|YPH7vCsXH%Jbn7qWf$y+N#!E>RToJmiPX!O2^$y^e_38l5{c(@AXqUKZ9fMO zh(JsS%mU=tRqB&V(xtzoEKcYDQ&$|3H*>Jj)Av=zXqpHAcs!sRTgXEXW%r->}Ie7^Y;Cl8J)8^_qr-ZH+y4hP;u1L&2 zq(ag0&2UuXMu+v(y|LY+J|sb!HaaI&cT#a*^QeflvEv@9qtSS&J?IU>6~ayB+8|Q) zs(Bxdl@?B9RDlg;LS|}n)QQhtoGs#i=vOD1k-l8QWk9!xa;rFtYAFs^&mLp><8#Fv z)C|ghG6FbG7iarv_ZZEnQmi3#$XBtru>%o5I?AwPBvu%)uu>hj53+YUUML|Fa2QJF zUJOD8<&tI1&z?Qj1#l2w-f&Ct4GWA1n=d4MK<%c+0_gJGjL44QM);x*^Fr6?U6ETg@=SIefopi&#Sr+^cj=RgU|~2cGly7hNNu4LkLmEr01brY{Gb z{I9*Do$loars&=JuwfoPWKC7Jj`7~|PEXHuT-5=poup(p!#g`YDef;WEXmC5;P61% z05xc@9JqBaL#QKUGENoL_V*6cmFu_Co!hUahmXFHI1%F!c$iP^t}rw@H@~D5`_yV& z%9qrP!cfoWl+-duVztQrl7`eb%xTj2}|iL_!SlQ?l2rxe5k)bopZuP-f*07G-_-lj||Xu?*-XYeM5mCeq( z0|QyFh-_h+#|C3M--Xu3q5I@Ul9K-@Yail_dmwYk2yk8blzzLs`nvn_<$uco=(m5h z5zx*X4HlV+o_tfO^GD;v*5cA&-quf<9z48n2hL2oaOt|bK6ADXu3y>kti(WccrcWa z{JkFAYmG)~VvyB8w?OgW>;z6qCEYP(h;g{%AEiPX&Sm7I%-5=>tqWL3osdUo~m$XB10-G9-_3dX0 zahXG{#b*Ty{OAfrHJhgM^fxB0HY?SXFKud4M<%Ekya8^0-TzPqV;|_^M~x z*^|wOTbh5w^KF08E2i~-)mFv-wR^yYpSX&KOw(4q&YhE}+OrZ09LRmklcYh#DX~mx zX4Vb!_V*9d+U2XM7>*4-tU=W`rfY_30rm?8rWw@hO z`kbXU)#2W@0eXv);XqpRmDk=(&lqfd`P4gq>MYso+4V22ZKy4dzxw2OUxM&t4AVjs zz^*TKJ^*D(K_=myWj<|WKdA#X2t;H&eW}OIcVO=6j&2nu8?U8hT0FJ3;ds_16+?OrdhTu{515jO?~PppN@0ItiG`9N)9$l}Y46#iG_vRJq|er8 zo9t&#p3JM8)r9-R!NXd!f^;RDv6pD~?cU8YjcJEDO_AY&GqAxe3q0D_P}#gD7vB31 zKDV~`k+8=??Qr)NBU3$Mq$qg@6}3;bzNhZ7)=EULjIJzfXcyU=#Pbj)+Ga7owi7tZ z_q%I!1U@Ler}FIJ$g^u1Cr&Z;(y2)n=hX&&2koLwzo^F3=8Jx>_|GgIUL~tR&N0QH zoZhoC=;4-8m)1j7&wG!b!4_L~Ir`?=!Z|1ESBo z2<>_#7;B5#3sz>VtgWlmWAeU`PBLx@dm77U_!HGc0v4i0^A{{ItZYcb2VRG3>iWd4 zk3~#FPr24&5J^g%uSz5?aG+_N+P7c1rOyX2PTgM3EUGM9SXtMEF~mj%AB5hy-V}VG z^xNH>Tx#XtU)?uZ)rt`1oL7nW=P|lLL+#Rvl-N@+KCqr{=$HeVqK?iz59) zJfM#ElQ%5aluXj#rBig(wy-+fgEK8FXtZX{5wS?$8CFP2Blz;~&_+=%R z-WUzXDw7X(x6|I%)AacV@1;kd{wgh6e|TVr=aGG_vS6?}XZOYc;0i~QQwz-E&WzNN znl~(wxk60?U=oR-9L(dflU%h&R7n_~2l?^tTj|oZn^Na|_TpjM-g+S~ugNLKfdq^b zm021zE_vT%nPW^_9H)*QsX6m#O|ntu6jgp4lC&b()B=l@LZr1mftR#rvZ*9?mHGX24~ zp$h_vFNSg34f_?r^oz z?9^B@(2Z&2B1#7UU^Hj*FdMiFN{YSNrL=V6Qo3$!Nkp;cc5Likf z%B|7{>Ok^RiVwOl@6+RyiyIf#wD~YV?9Z>HIV%HcuaXKM?z~VS>-XJJqdjZ2{1$-v z)s59{$a5Pg2YWI(@1-Fu6DlKyMat*EK_3i_UEqQiyFSL`$+SGEPLbfC2dgV<2W=4@-JUJNuPi8tMu5q zpL;JKSeCM>dB35R{|xtXFUHctnK-DM+~q{pF@>*HZE5F#oLvX1l@>J6qk^$KDJ;Xa zb@ket?`W{~laJq*9PV`JHq%Uw_j@z|hRUMK{=EG>rhc>T$bzIWBNJo)-7B-$e&5CF z`))EQ!leBZ1K88aX$*pp6Azx^D8#{ZeMsm3U{1EM+L+t9zjBy141T z7#@!Qzbg3mj)wo!^2UY#r>&X)`v`#8uJnS{uUz=90bR7{ba92Z*&ylp+gI8kjm+3w zhgRcRWEDjJu@kbIwhHOcq=lJcAxQT|fvHOC20qKrTLiI`7OloE2MexgTshNpzFkg3 zJ4yKd@r3!OB^eWSLj-J+@0;72iZH?sO4!LpuxK1z?_;l4!lrHd;NwTTw_*+cuflH%*W zrmRJ^cd5*C)=n#eP!&=P{K^~}va+5$;>m*Q6zird=c+Gd8o{Ya>9@aD`ywfN>D&lP ztBg+Wo3^OoP~p)|wlh`heWG%L&nU)vIKqDEObpCXpk~>8nZf>*Y_K?23Z4%n`Lo0; zo-0YiD(BpNJHwRn*ZgzUK}h8uz&M^NHKa8I#o)%Y6)^F zt4&U7y<*wTE3e*F@HrYz(yh`5H8&0aWB?ikh9v9ZR->3|S?i^jPftZ~rL#2^4a7bxcI0SKOYJa^N;Nug{8=?3JJ#XIqNE^2 zrW^yH#kt^7v}ez*JlBP6QVvLGu)^0J!1n*Ym>VqqKTgwL>V#WHC#V0@%+ksO+eP;b zoL!~!gw2em(F+%G*N_4?c2O8ckd zbUJQSfV}5ci8$G>h||Gc3s{U8uSu(?%gJ+1pTTCU+~7u<1cOM zv$Et2ElFQWkNv;Pb5f*j90-*H9@xOLm9OY#OA+zq3l|n|oo1j$L>M|2zxyNQ#rCD^ zE7F%|w{md$x>D@xFrMF;>Exd;yv@v^C6!3zFyK9f6A3B=*t?8RPUYlL6w|c7yOlou z}We5`ftKI)$Fx+S+?c`jRv z?&*EyUgy93R$%ep`5-y_`nm5ZivMD6X8ND+?G5+%T6O+~Cnrb0=&fA*uk9P(8(ILe zhq$`3x;Bf}$lB+Ox9i@+;}~ zYj26zwqtcP3VfHX{k~+SQz3J|C`aI3^h?#M;5`7u1Qb;A$&l7BUrvX1jmWDukwU7x z(86#TPR&zU7KC3>zSRUwN;Dpj+S)~{5`%w~G(v9>!SJ#=Tf>9hbh`6WC!uu4lD9Y2 z4QssvmHq)duRK@w?@^xWpSg?#N(_<4BQA$A_;Lqx70Oa$Z%}>_$9H@R44$lXh zubt~k=^y<2*JqJF7wE*lv5VtL*0&ckUqvvw8*e%kQ~8#qFwtW@92_2Ltm2SvlpUfA z3yZR0LgYjM`BqrJfB%4`r08RP}TFLRJhPRU|P^x&}dX9OWMVWCaypHT?xYtT_< z9LW98rnVpKz3lgat+zs6?L3$Hbou(-^wvAyO{*6#8eGw)m8IEq-^#SD7luJm?v9;K zLP9VnVZAl6;i1E1ttQu-^3Jd8^_0;J_28Pz)vx = ({color, theme}) => { +export const Showcase: React.FC = ({color, theme, style}) => { const [activeTab, setActiveTab] = React.useState(tabs[0].id); const [tableSelectedIds, setTableSelectedIds] = React.useState(['1']); @@ -67,6 +68,9 @@ export const Showcase: React.FC = ({color, theme}) => { return ( + {style ? ( + + ) : null}