diff --git a/packages/components/README.md b/packages/components/README.md
index f49ee21ef..cf0ba97ee 100644
--- a/packages/components/README.md
+++ b/packages/components/README.md
@@ -254,6 +254,33 @@ const theme = createTheme(appTheme)
```
+To apply custom colors that align with your branding while maintaining the SDS design configurations, use the `makeSdsSemanticAppTheme`. Provide it with a Colors object that follows the SDS model.
+
+```tsx
+import { ThemeProvider as EmotionThemeProvider } from "@emotion/react";
+import { makeSdsSemanticAppTheme, makeThemeOptions, type Colors } from "@czi-sds/components";
+import { StyledEngineProvider, ThemeProvider } from "@mui/material/styles";
+import createTheme from "@mui/material/styles/createTheme";
+
+const CustomColors: Colors = {
+ ...
+}
+
+const customColorAppTheme = makeSdsSemanticAppTheme(CustomColors);
+
+const appTheme = makeThemeOptions(customColorAppTheme)
+
+const theme = createTheme(appTheme)
+
+
+
+
+
+
+
+
+```
+
💡 CZGE example available [here](https://github.com/chanzuckerberg/czgenepi/blob/trunk/src/frontend/src/common/styles/theme.ts).
💡 Material UI docs for custom theming available [here](https://mui.com/material-ui/customization/theming/).
diff --git a/packages/components/src/core/styles/common/SDSAppTheme.ts b/packages/components/src/core/styles/common/SDSAppTheme.ts
index 76382543a..9d9c88cd7 100644
--- a/packages/components/src/core/styles/common/SDSAppTheme.ts
+++ b/packages/components/src/core/styles/common/SDSAppTheme.ts
@@ -466,130 +466,77 @@ const sharedAppTheme: Omit = {
},
};
-export const SDSLightAppTheme: AppTheme = {
+/**
+ * Create a SDS App Theme with custom colors that follows the SDS color model.
+ */
+export const makeSdsSemanticAppTheme = (colors: Colors): AppTheme => ({
...sharedAppTheme,
- colors: SDSLightThemeColors,
-};
-
-// (mlila) whenever our theme uses colors, we need to make sure we allow consuming
-// applications to override those colors using their own custom theme.
-// By defining borders using SDSAppTheme.colors instead of defaultThemeColors,
-// we allow other apps to specify their colors once, and have them apply
-// throughout the application, such as in borders, etc without having to manually
-// override every theme property that makes use of colors.
-
-SDSLightAppTheme.borders = {
- accent: {
- default: `1px solid ${SDSLightAppTheme.colors.blue[500]}`,
- focused: `1px solid ${SDSLightAppTheme.colors.blue[500]}`,
- hover: `1px solid ${SDSLightAppTheme.colors.blue[600]}`,
- open: `1px solid ${SDSLightAppTheme.colors.blue[500]}`,
- pressed: `1px solid ${SDSLightAppTheme.colors.blue[700]}`,
- selected: `1px solid ${SDSLightAppTheme.colors.blue[500]}`,
- },
- base: {
- default: `1px solid ${SDSLightAppTheme.colors.gray[500]}`,
- disabled: `1px solid ${SDSLightAppTheme.colors.gray[300]}`,
- divider: `1px solid ${SDSLightAppTheme.colors.gray[200]}`,
- hover: `1px solid ${SDSLightAppTheme.colors.gray[900]}`,
- pressed: `1px solid ${SDSLightAppTheme.colors.gray[900]}`,
- table: `1px solid ${SDSLightAppTheme.colors.gray[300]}`,
- },
- beta: {
- default: `1px solid ${SDSLightAppTheme.colors.purple[600]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.purple[600]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.purple[600]}`,
- },
- info: {
- default: `1px solid ${SDSLightAppTheme.colors.blue[600]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.blue[600]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.blue[600]}`,
- },
- link: {
- dashed: `1px dashed`,
- solid: `1px solid`,
- },
- negative: {
- default: `1px solid ${SDSLightAppTheme.colors.red[600]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.red[600]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.red[600]}`,
- },
- neutral: {
- default: `1px solid ${SDSLightAppTheme.colors.gray[500]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.gray[500]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.gray[500]}`,
- },
- none: "none",
- notice: {
- default: `1px solid ${SDSLightAppTheme.colors.yellow[600]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.yellow[600]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.yellow[600]}`,
- },
- positive: {
- default: `1px solid ${SDSLightAppTheme.colors.green[600]}`,
- extraThick: `4px solid ${SDSLightAppTheme.colors.green[600]}`,
- thick: `2px solid ${SDSLightAppTheme.colors.green[600]}`,
+ // (mlila) whenever our theme uses colors, we need to make sure we allow consuming
+ // applications to override those colors using their own custom theme.
+ // By defining borders using SDSAppTheme.colors instead of defaultThemeColors,
+ // we allow other apps to specify their colors once, and have them apply
+ // throughout the application, such as in borders, etc without having to manually
+ // override every theme property that makes use of colors.
+ borders: {
+ accent: {
+ default: `1px solid ${colors.blue[500]}`,
+ focused: `1px solid ${colors.blue[500]}`,
+ hover: `1px solid ${colors.blue[600]}`,
+ open: `1px solid ${colors.blue[500]}`,
+ pressed: `1px solid ${colors.blue[700]}`,
+ selected: `1px solid ${colors.blue[500]}`,
+ },
+ base: {
+ default: `1px solid ${colors.gray[500]}`,
+ disabled: `1px solid ${colors.gray[300]}`,
+ divider: `1px solid ${colors.gray[200]}`,
+ hover: `1px solid ${colors.gray[900]}`,
+ pressed: `1px solid ${colors.gray[900]}`,
+ table: `1px solid ${colors.gray[300]}`,
+ },
+ beta: {
+ default: `1px solid ${colors.purple[600]}`,
+ extraThick: `4px solid ${colors.purple[600]}`,
+ thick: `2px solid ${colors.purple[600]}`,
+ },
+ info: {
+ default: `1px solid ${colors.blue[600]}`,
+ extraThick: `4px solid ${colors.blue[600]}`,
+ thick: `2px solid ${colors.blue[600]}`,
+ },
+ link: {
+ dashed: `1px dashed`,
+ solid: `1px solid`,
+ },
+ negative: {
+ default: `1px solid ${colors.red[600]}`,
+ extraThick: `4px solid ${colors.red[600]}`,
+ thick: `2px solid ${colors.red[600]}`,
+ },
+ neutral: {
+ default: `1px solid ${colors.gray[500]}`,
+ extraThick: `4px solid ${colors.gray[500]}`,
+ thick: `2px solid ${colors.gray[500]}`,
+ },
+ none: "none",
+ notice: {
+ default: `1px solid ${colors.yellow[600]}`,
+ extraThick: `4px solid ${colors.yellow[600]}`,
+ thick: `2px solid ${colors.yellow[600]}`,
+ },
+ positive: {
+ default: `1px solid ${colors.green[600]}`,
+ extraThick: `4px solid ${colors.green[600]}`,
+ thick: `2px solid ${colors.green[600]}`,
+ },
},
-};
+ colors,
+});
-export const SDSDarkAppTheme: AppTheme = {
- ...sharedAppTheme,
- colors: SDSDarkThemeColors,
-};
-
-SDSDarkAppTheme.borders = {
- accent: {
- default: `1px solid ${SDSDarkAppTheme.colors.blue[500]}`,
- focused: `1px solid ${SDSDarkAppTheme.colors.blue[500]}`,
- hover: `1px solid ${SDSDarkAppTheme.colors.blue[600]}`,
- open: `1px solid ${SDSDarkAppTheme.colors.blue[500]}`,
- pressed: `1px solid ${SDSDarkAppTheme.colors.blue[700]}`,
- selected: `1px solid ${SDSDarkAppTheme.colors.blue[500]}`,
- },
- base: {
- default: `1px solid ${SDSDarkAppTheme.colors.gray[500]}`,
- disabled: `1px solid ${SDSDarkAppTheme.colors.gray[300]}`,
- divider: `1px solid ${SDSDarkAppTheme.colors.gray[200]}`,
- hover: `1px solid ${SDSDarkAppTheme.colors.gray[900]}`,
- pressed: `1px solid ${SDSDarkAppTheme.colors.gray[900]}`,
- table: `1px solid ${SDSDarkAppTheme.colors.gray[300]}`,
- },
- beta: {
- default: `1px solid ${SDSDarkAppTheme.colors.purple[600]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.purple[600]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.purple[600]}`,
- },
- info: {
- default: `1px solid ${SDSDarkAppTheme.colors.blue[600]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.blue[600]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.blue[600]}`,
- },
- link: {
- dashed: `1px dashed`,
- solid: `1px solid`,
- },
- negative: {
- default: `1px solid ${SDSDarkAppTheme.colors.red[600]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.red[600]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.red[600]}`,
- },
- neutral: {
- default: `1px solid ${SDSDarkAppTheme.colors.gray[500]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.gray[500]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.gray[500]}`,
- },
- none: "none",
- notice: {
- default: `1px solid ${SDSDarkAppTheme.colors.yellow[600]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.yellow[600]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.yellow[600]}`,
- },
- positive: {
- default: `1px solid ${SDSDarkAppTheme.colors.green[600]}`,
- extraThick: `4px solid ${SDSDarkAppTheme.colors.green[600]}`,
- thick: `2px solid ${SDSDarkAppTheme.colors.green[600]}`,
- },
-};
+export const SDSLightAppTheme: AppTheme =
+ makeSdsSemanticAppTheme(SDSLightThemeColors);
+export const SDSDarkAppTheme: AppTheme =
+ makeSdsSemanticAppTheme(SDSDarkThemeColors);
/**
* Helper function to select the appropriate theme settings.
diff --git a/yarn.lock b/yarn.lock
index c58bce4b5..408f5fa5a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -301,18 +301,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.7":
- version: 7.25.7
- resolution: "@babel/parser@npm:7.25.7"
- dependencies:
- "@babel/types": "npm:^7.25.7"
- bin:
- parser: ./bin/babel-parser.js
- checksum: 10c0/b771469bb6b636c18a8d642b9df3c73913c3860a979591e1a29a98659efd38b81d3e393047b5251fe382d4c82c681c12da9ce91c98d69316d2604d155a214bcf
- languageName: node
- linkType: hard
-
-"@babel/parser@npm:^7.25.8":
+"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.23.9, @babel/parser@npm:^7.25.7, @babel/parser@npm:^7.25.8":
version: 7.25.8
resolution: "@babel/parser@npm:7.25.8"
dependencies:
@@ -1410,18 +1399,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.22.5, @babel/types@npm:^7.25.7, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4":
- version: 7.25.7
- resolution: "@babel/types@npm:7.25.7"
- dependencies:
- "@babel/helper-string-parser": "npm:^7.25.7"
- "@babel/helper-validator-identifier": "npm:^7.25.7"
- to-fast-properties: "npm:^2.0.0"
- checksum: 10c0/e03e1e2e08600fa1e8eb90632ac9c253dd748176c8d670d85f85b0dc83a0573b26ae748a1cbcb81f401903a3d95f43c3f4f8d516a5ed779929db27de56289633
- languageName: node
- linkType: hard
-
-"@babel/types@npm:^7.25.8":
+"@babel/types@npm:^7.0.0, @babel/types@npm:^7.18.9, @babel/types@npm:^7.20.7, @babel/types@npm:^7.21.3, @babel/types@npm:^7.22.5, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.3.3, @babel/types@npm:^7.4.4":
version: 7.25.8
resolution: "@babel/types@npm:7.25.8"
dependencies:
@@ -5190,7 +5168,7 @@ __metadata:
languageName: node
linkType: hard
-"@testing-library/jest-dom@npm:6.5.0, @testing-library/jest-dom@npm:^6.1.5":
+"@testing-library/jest-dom@npm:6.5.0":
version: 6.5.0
resolution: "@testing-library/jest-dom@npm:6.5.0"
dependencies:
@@ -5205,6 +5183,21 @@ __metadata:
languageName: node
linkType: hard
+"@testing-library/jest-dom@npm:^6.1.5":
+ version: 6.6.2
+ resolution: "@testing-library/jest-dom@npm:6.6.2"
+ dependencies:
+ "@adobe/css-tools": "npm:^4.4.0"
+ aria-query: "npm:^5.0.0"
+ chalk: "npm:^3.0.0"
+ css.escape: "npm:^1.5.1"
+ dom-accessibility-api: "npm:^0.6.3"
+ lodash: "npm:^4.17.21"
+ redent: "npm:^3.0.0"
+ checksum: 10c0/1c51390f97063ce8b06a7267534aac0d6ac9b1f27042a0ae43ca52d886b32c9d2b0ff85e62e7cfeb7e1f089ef03c4d75fda4f2b7b1f08afb4bdb09a5d56566d9
+ languageName: node
+ linkType: hard
+
"@testing-library/react@npm:^14.1.2":
version: 14.3.1
resolution: "@testing-library/react@npm:14.3.1"
@@ -5666,11 +5659,11 @@ __metadata:
linkType: hard
"@types/node@npm:*, @types/node@npm:^22.0.0":
- version: 22.7.4
- resolution: "@types/node@npm:22.7.4"
+ version: 22.7.6
+ resolution: "@types/node@npm:22.7.6"
dependencies:
undici-types: "npm:~6.19.2"
- checksum: 10c0/c22bf54515c78ff3170142c1e718b90e2a0003419dc2d55f79c9c9362edd590a6ab1450deb09ff6e1b32d1b4698da407930b16285e8be3a009ea6cd2695cac01
+ checksum: 10c0/d4406a63afce981c363fb1d1954aaf1759ad2d487c0833ebf667565ea4e45ff217d6fab4b5343badbdeccdf9d2e4a0841d633e0c929ceabcb33c288663dd0c73
languageName: node
linkType: hard
@@ -6498,16 +6491,7 @@ __metadata:
languageName: node
linkType: hard
-"acorn@npm:^8.1.0, acorn@npm:^8.12.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
- version: 8.12.1
- resolution: "acorn@npm:8.12.1"
- bin:
- acorn: bin/acorn
- checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386
- languageName: node
- linkType: hard
-
-"acorn@npm:^8.11.0":
+"acorn@npm:^8.1.0, acorn@npm:^8.11.0, acorn@npm:^8.12.1, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0":
version: 8.13.0
resolution: "acorn@npm:8.13.0"
bin:
@@ -7044,9 +7028,9 @@ __metadata:
linkType: hard
"axe-core@npm:^4.10.0, axe-core@npm:^4.2.0, axe-core@npm:^4.8.4":
- version: 4.10.0
- resolution: "axe-core@npm:4.10.0"
- checksum: 10c0/732c171d48caaace5e784895c4dacb8ca6155e9d98045138ebe3952f78457dd05b92c57d05b41ce2a570aff87dbd0471e8398d2c0f6ebe79617b746c8f658998
+ version: 4.10.1
+ resolution: "axe-core@npm:4.10.1"
+ checksum: 10c0/53d865efb7284fd69bc95ced1a1709fd603ea07f06e272da06942e7cfeca1c823e09bde28f57178e3a1a4c9a089fe4b5d274c871e3e6522a3b1bffec8eaa7dd8
languageName: node
linkType: hard
@@ -7762,8 +7746,8 @@ __metadata:
linkType: hard
"chromatic@npm:^11.4.0":
- version: 11.12.5
- resolution: "chromatic@npm:11.12.5"
+ version: 11.12.6
+ resolution: "chromatic@npm:11.12.6"
peerDependencies:
"@chromatic-com/cypress": ^0.*.* || ^1.0.0
"@chromatic-com/playwright": ^0.*.* || ^1.0.0
@@ -7776,7 +7760,7 @@ __metadata:
chroma: dist/bin.js
chromatic: dist/bin.js
chromatic-cli: dist/bin.js
- checksum: 10c0/4a083e4b12ebd0e1f04f944fef66c8345d0895e4c42e253cc4726328b13207553d860fbd5955804fbea806ae06a58d88f8ef845e6c90ce8ce2bc62f5660a3c8e
+ checksum: 10c0/7d161c52bc239ac6e8380f9a64533dd3792819d8f103d0083a805d5c9ece0844787eedd45c19c41e69d0ef0a3756051fa3e5c1f2fc9630d60f2ada4d5452e929
languageName: node
linkType: hard
@@ -9521,9 +9505,9 @@ __metadata:
linkType: hard
"electron-to-chromium@npm:^1.5.28":
- version: 1.5.39
- resolution: "electron-to-chromium@npm:1.5.39"
- checksum: 10c0/36364f9c68a7d20c54b020fe81cabf3e6022b7feb91f63695dd1039612cac031cc98bbcc0c3ba957f1876dde89853ba48407c590a4227fd13616a028ac1a0944
+ version: 1.5.41
+ resolution: "electron-to-chromium@npm:1.5.41"
+ checksum: 10c0/97b82383963029e6ed0bd7a71eb527f640c8cf658c9e43c776b0257b3c65e366590ac54135683a21e4474a156b8be78717d6e94d3c1def84b69f92bf48f2390f
languageName: node
linkType: hard
@@ -11202,13 +11186,6 @@ __metadata:
languageName: node
linkType: hard
-"get-func-name@npm:^2.0.1":
- version: 2.0.2
- resolution: "get-func-name@npm:2.0.2"
- checksum: 10c0/89830fd07623fa73429a711b9daecdb304386d237c71268007f788f113505ef1d4cc2d0b9680e072c5082490aec9df5d7758bf5ac6f1c37062855e8e3dc0b9df
- languageName: node
- linkType: hard
-
"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4":
version: 1.2.4
resolution: "get-intrinsic@npm:1.2.4"
@@ -11966,8 +11943,8 @@ __metadata:
linkType: hard
"html-webpack-plugin@npm:^5.5.0":
- version: 5.6.0
- resolution: "html-webpack-plugin@npm:5.6.0"
+ version: 5.6.2
+ resolution: "html-webpack-plugin@npm:5.6.2"
dependencies:
"@types/html-minifier-terser": "npm:^6.0.0"
html-minifier-terser: "npm:^6.0.2"
@@ -11982,7 +11959,7 @@ __metadata:
optional: true
webpack:
optional: true
- checksum: 10c0/50d1a0f90d512463ea8d798985d91a7ccc9d5e461713dedb240125b2ff0671f58135dd9355f7969af341ff4725e73b2defbc0984cfdce930887a48506d970002
+ checksum: 10c0/4a6e8367d47e9265aaebd30cd83076bb4a1006eda526b7273f06328f68d1ad2d088da29bd10b41e5016352e8dc1f2b63707a36dde26bed438a01c23cd3799844
languageName: node
linkType: hard
@@ -14577,11 +14554,9 @@ __metadata:
linkType: hard
"loupe@npm:^3.1.0, loupe@npm:^3.1.1":
- version: 3.1.1
- resolution: "loupe@npm:3.1.1"
- dependencies:
- get-func-name: "npm:^2.0.1"
- checksum: 10c0/99f88badc47e894016df0c403de846fedfea61154aadabbf776c8428dd59e8d8378007135d385d737de32ae47980af07d22ba7bec5ef7beebd721de9baa0a0af
+ version: 3.1.2
+ resolution: "loupe@npm:3.1.2"
+ checksum: 10c0/b13c02e3ddd6a9d5f8bf84133b3242de556512d824dddeea71cce2dbd6579c8f4d672381c4e742d45cf4423d0701765b4a6e5fbc24701def16bc2b40f8daa96a
languageName: node
linkType: hard
@@ -16513,9 +16488,9 @@ __metadata:
linkType: hard
"picocolors@npm:^1.0.0, picocolors@npm:^1.0.1, picocolors@npm:^1.1.0":
- version: 1.1.0
- resolution: "picocolors@npm:1.1.0"
- checksum: 10c0/86946f6032148801ef09c051c6fb13b5cf942eaf147e30ea79edb91dd32d700934edebe782a1078ff859fb2b816792e97ef4dab03d7f0b804f6b01a0df35e023
+ version: 1.1.1
+ resolution: "picocolors@npm:1.1.1"
+ checksum: 10c0/e2e3e8170ab9d7c7421969adaa7e1b31434f789afb9b3f115f6b96d91945041ac3ceb02e9ec6fe6510ff036bcc0bf91e69a1772edc0b707e12b19c0f2d6bcf58
languageName: node
linkType: hard
@@ -18161,8 +18136,8 @@ __metadata:
linkType: hard
"sass@npm:^1.23.7, sass@npm:^1.70.0":
- version: 1.79.5
- resolution: "sass@npm:1.79.5"
+ version: 1.80.2
+ resolution: "sass@npm:1.80.2"
dependencies:
"@parcel/watcher": "npm:^2.4.1"
chokidar: "npm:^4.0.0"
@@ -18170,7 +18145,7 @@ __metadata:
source-map-js: "npm:>=0.6.2 <2.0.0"
bin:
sass: sass.js
- checksum: 10c0/7331865fd1d0c03e6e180a4fe0e175ac1bf1214f6c77f0d99ad72fbe2ed9ede3fab8a64c0c41471cb8a358a9d11624ec59a49283f9b6070eb99c522b34b814bf
+ checksum: 10c0/0006e2ee7a732abaa96a663167b078b8d53b4d7fe5ce435636a8bca6e8a3b6ebc12308c0725f577a456329ed962436d96cfcdd50a8e733ed4c4e4590f21243c9
languageName: node
linkType: hard
@@ -19445,8 +19420,8 @@ __metadata:
linkType: hard
"terser@npm:^5.10.0, terser@npm:^5.26.0":
- version: 5.35.0
- resolution: "terser@npm:5.35.0"
+ version: 5.36.0
+ resolution: "terser@npm:5.36.0"
dependencies:
"@jridgewell/source-map": "npm:^0.3.3"
acorn: "npm:^8.8.2"
@@ -19454,7 +19429,7 @@ __metadata:
source-map-support: "npm:~0.5.20"
bin:
terser: bin/terser
- checksum: 10c0/c9899d23c2d1548329d5b5717cb0cfaae5cfa26e6c4930daebc7a4dc00658c3ca44c06626777a9d09f03b2b13338921769c0eb56b6ad8560d705a375425129d6
+ checksum: 10c0/f4ed2bead19f64789ddcfb85b7cef78f3942f967b8890c54f57d1e35bc7d547d551c6a4c32210bce6ba45b1c738314bbfac6acbc6c762a45cd171777d0c120d9
languageName: node
linkType: hard