From 8b8efa93f7c7fefbf999e342b4e305545f53cd85 Mon Sep 17 00:00:00 2001 From: Daniele Guido Date: Fri, 8 Mar 2024 12:17:23 +0100 Subject: [PATCH] add data JSON --- .gitignore | 2 + gatsby-browser.js | 44 +++++++++++---- gatsby-node.js | 28 ++++++++-- package.json | 4 ++ src/collections/basic-datavis.mdx | 10 ++++ src/collections/enter-impresso.mdx | 1 + .../notebooks-we-are-testing-right-now.mdx | 11 ++++ src/components/AuthorCard.jsx | 10 ++++ src/components/CollectionCard.css | 11 +++- src/components/CollectionCard.js | 30 ++++++----- src/components/Layout.js | 5 +- src/components/Modals.js | 2 +- src/components/NotebookCard.css | 9 ++++ src/components/NotebookCard.js | 53 +++++++++++++++++++ src/components/PrefetchData.js | 40 ++++++++++++++ .../introduction-to-topic-modeling.mdx | 5 ++ src/notebooks/setup.mdx | 16 ++++-- .../time-distribution-of-a-search.mdx | 52 ++++++++++++++++++ src/pages/index.jsx | 45 +++++----------- src/store.js | 25 +++++++++ src/styles/style.css | 10 +++- static/data/authors.json | 16 ------ static/data/collections.json | 20 ------- static/data/notebooks.json | 28 ---------- yarn.lock | 20 +++++++ 25 files changed, 365 insertions(+), 132 deletions(-) create mode 100644 src/collections/basic-datavis.mdx create mode 100644 src/collections/notebooks-we-are-testing-right-now.mdx create mode 100644 src/components/AuthorCard.jsx create mode 100644 src/components/NotebookCard.css create mode 100644 src/components/NotebookCard.js create mode 100644 src/components/PrefetchData.js create mode 100644 src/notebooks/introduction-to-topic-modeling.mdx create mode 100644 src/notebooks/time-distribution-of-a-search.mdx delete mode 100644 static/data/authors.json delete mode 100644 static/data/collections.json delete mode 100644 static/data/notebooks.json diff --git a/.gitignore b/.gitignore index 9fe0a4c..fcc2b10 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ node_modules/ .cache/ public .DS_Store +static/data/ +!static/data/.gitkeep diff --git a/gatsby-browser.js b/gatsby-browser.js index e80a729..d4a550f 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -5,37 +5,61 @@ import 'bootstrap/dist/css/bootstrap.min.css' import './src/styles/style.css' import Modals from './src/components/Modals' import { AvailableModalsViews, useBrowserStore } from './src/store' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import PrefetchData from './src/components/PrefetchData' // Logs when the client route changes export function onRouteUpdate({ location, prevLocation }) { console.log('[Layout] render') console.log('[gatsby-browser]@onRouteUpdate new pathname', location) + let view = null + let viewId = null // update zustand with search params, if any if (location.search) { const params = new URLSearchParams(location.search) - const view = params.get('view') - if (AvailableModalsViews.includes(view)) { - console.log('[gatsby-browser]@onRouteUpdate view:', view) - useBrowserStore.setState({ view }) + const paramView = params.get('view') + const paramViewId = params.get('viewId') + + if (AvailableModalsViews.includes(paramView)) { + console.log('[gatsby-browser]@onRouteUpdate view:', paramView) + view = String(paramView) } else { console.log( '[gatsby-browser]@onRouteUpdate view not recognized, close everything:', - view + paramView + ) + } + + // test view id against a regex (lowercase letters and numbers, only trailing slash) + if (paramViewId && /^[a-z0-9]+$/.test(paramViewId)) { + console.log('[gatsby-browser]@onRouteUpdate viewId:', paramViewId) + viewId = String(paramViewId) + } else { + console.log( + '[gatsby-browser]@onRouteUpdate viewId not recognized, close everything:', + paramViewId ) - useBrowserStore.setState({ view: null }) } - } else { - useBrowserStore.setState({ view: null }) } + + // always update store with view and viewId + useBrowserStore.setState({ + view, + viewId, + }) } +// Create a client +const queryClient = new QueryClient() + // Wraps every page in a component export function wrapRootElement({ element, props }) { console.log('[gatsby-browser]@wrapRootElement') return ( - <> + + {element} - + ) } diff --git a/gatsby-node.js b/gatsby-node.js index d51359d..ece330c 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -10,6 +10,9 @@ exports.createPages = async function ({ actions, graphql }) { const authorsMap = {} const notebooksMap = {} const collectionsMap = {} + if (!fs.existsSync('./static/data/notebooks')) { + fs.mkdirSync('./static/data/notebooks') + } const { data: authors } = await graphql(` query { @@ -48,10 +51,13 @@ exports.createPages = async function ({ actions, graphql }) { accessTime childMdx { excerpt + body + tableOfContents frontmatter { title binderUrl authors + tags } } } @@ -59,7 +65,6 @@ exports.createPages = async function ({ actions, graphql }) { } `) console.log('createPages: n. notebooks: ', notebooks.allFile.nodes.length) - notebooks.allFile.nodes.forEach((node) => { notebooksMap[node.name] = { name: node.name, @@ -67,6 +72,7 @@ exports.createPages = async function ({ actions, graphql }) { birthTime: node.birthTime, accessTime: node.accessTime, title: node.childMdx.frontmatter.title, + tags: node.childMdx.frontmatter.tags || [], excerpt: node.childMdx.excerpt, binderUrl: node.childMdx.frontmatter.binderUrl, authors: node.childMdx.frontmatter.authors || [], @@ -83,6 +89,19 @@ exports.createPages = async function ({ actions, graphql }) { } }) + fs.writeFileSync( + `./static/data/notebooks/${node.name}.json`, + JSON.stringify( + { + ...notebooksMap[node.name], + body: node.childMdx.body, + tableOfContents: node.childMdx.tableOfContents, + }, + null, + 2 + ) + ) + actions.createPage({ path: `/notebook/${node.name}`, component: require.resolve(`./src/templates/Notebook.js`), @@ -102,6 +121,7 @@ exports.createPages = async function ({ actions, graphql }) { frontmatter { title notebooks + tags } } } @@ -117,6 +137,7 @@ exports.createPages = async function ({ actions, graphql }) { title: node.childMdx.frontmatter.title, excerpt: node.childMdx.excerpt, notebooks: node.childMdx.frontmatter.notebooks, + tags: node.childMdx.frontmatter.tags || [], contributors: [], } node.childMdx.frontmatter.notebooks.forEach((notebook) => { @@ -149,12 +170,13 @@ exports.createPages = async function ({ actions, graphql }) { return acc }, {}) ) - collectionsMap[node.name].contributors.forEach((contributor) => { + collectionsMap[node.name].contributors.forEach(([k, contributor]) => { if (authorsMap[contributor.name]) { authorsMap[contributor.name].collections.push(node.name) } else { console.error( - `Contributor ${contributor.name} not found in authorsMap, skipping collection ${node.name}` + `Contributor ${contributor.name} not found in authorsMap, skipping collection ${node.name}`, + collectionsMap[node.name].contributors ) } }) diff --git a/package.json b/package.json index c662f9f..ffb0ec0 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@tanstack/react-query": "^5.25.0", "axios": "^1.6.7", "bootstrap": "^5.3.2", + "boring-avatars": "^1.10.1", "debug": "^4.3.4", "gatsby": "^5.13.2", "gatsby-plugin-manifest": "^5.13.1", @@ -27,6 +28,9 @@ "gatsby-plugin-mdx-source-name": "^1.0.1", "gatsby-plugin-sitemap": "^6.13.1", "gatsby-source-filesystem": "^5.13.1", + "iconoir-react": "^7.5.0", + "luxon": "^3.4.4", + "marked": "^12.0.1", "react": "^18.2.0", "react-bootstrap": "^2.10.0", "react-dom": "^18.2.0", diff --git a/src/collections/basic-datavis.mdx b/src/collections/basic-datavis.mdx new file mode 100644 index 0000000..a62fa31 --- /dev/null +++ b/src/collections/basic-datavis.mdx @@ -0,0 +1,10 @@ +--- +title: 'Basic Datavisualisation' + +notebooks: + - time-distribution-of-a-search +authors: + - impresso-team +--- + +Three easy steps to enter the _impresso_ way of doing research. diff --git a/src/collections/enter-impresso.mdx b/src/collections/enter-impresso.mdx index 8cfa828..5532f1e 100644 --- a/src/collections/enter-impresso.mdx +++ b/src/collections/enter-impresso.mdx @@ -3,6 +3,7 @@ title: 'Enter *impresso*' tags: - highlight notebooks: + - setup - team-starter-pack authors: - impresso-team diff --git a/src/collections/notebooks-we-are-testing-right-now.mdx b/src/collections/notebooks-we-are-testing-right-now.mdx new file mode 100644 index 0000000..f622180 --- /dev/null +++ b/src/collections/notebooks-we-are-testing-right-now.mdx @@ -0,0 +1,11 @@ +--- +title: Notebooks we are testing right now +notebooks: + - introduction-to-topic-modeling + - time-distribution-of-a-search + - team-starter-pack +tags: + - testing + - notebooks + - topic-modeling +--- diff --git a/src/components/AuthorCard.jsx b/src/components/AuthorCard.jsx new file mode 100644 index 0000000..f3d1e03 --- /dev/null +++ b/src/components/AuthorCard.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import { useDataStore } from '../store' + +const AuthorCard = ({ name }) => { + const getAuthorByName = useDataStore((state) => state.getAuthorByName) + const author = getAuthorByName(name) + return {author.fullName || name} +} + +export default AuthorCard diff --git a/src/components/CollectionCard.css b/src/components/CollectionCard.css index 2f1d231..8164234 100644 --- a/src/components/CollectionCard.css +++ b/src/components/CollectionCard.css @@ -1,4 +1,11 @@ .CollectionCard { - border-radius: 5px; - box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1); + border-radius: var(--impresso-border-radius-lg); + + box-shadow: var(--shadow-lg); +} + +.CollectionCard ol { + padding: 0; + margin: 0; + list-style: none; } diff --git a/src/components/CollectionCard.js b/src/components/CollectionCard.js index 1a8ab76..03e6d06 100644 --- a/src/components/CollectionCard.js +++ b/src/components/CollectionCard.js @@ -1,20 +1,24 @@ import React from 'react' import './CollectionCard.css' -import { graphql, useStaticQuery } from 'gatsby' +import { useDataStore } from '../store' +import NotebookCard from './NotebookCard' -const CollectionCard = ({ - frontmatter = {}, - name = '', - notebooks = [], - excerpt = '', -}) => { +const CollectionCard = ({ name }) => { + const getCollectionByName = useDataStore((state) => state.getCollectionByName) + const collection = getCollectionByName(name) return ( -
-
-

{frontmatter.title}

-

{excerpt}

-
-
{JSON.stringify(notebooks, null, 2)}
+
+
+

{collection?.title}

+

{collection?.excerpt}

+
+
    + {collection?.notebooks.map((name, i) => ( +
  1. + +
  2. + ))} +
) } diff --git a/src/components/Layout.js b/src/components/Layout.js index 4714c8f..382d490 100644 --- a/src/components/Layout.js +++ b/src/components/Layout.js @@ -2,8 +2,11 @@ import { Link } from 'gatsby' import React from 'react' import { Col, Container, Row } from 'react-bootstrap' import Header from './Header' +import { useDataStore } from '../store' const Layout = ({ children }) => { + const isDataReady = useDataStore((state) => state.isReady) + console.log('[Layout] render') return ( <> @@ -22,7 +25,7 @@ const Layout = ({ children }) => { - + {isDataReady ? 'ready' : 'loading'} diff --git a/src/components/Modals.js b/src/components/Modals.js index 69e4bc9..44419f7 100644 --- a/src/components/Modals.js +++ b/src/components/Modals.js @@ -5,7 +5,7 @@ import { navigate } from 'gatsby' import ModalLogin from './ModalLogin' import ModalNotebookPreview from './ModalNotebookPreview' -const Modals = ({ debug = true }) => { +const Modals = ({ debug = false }) => { const onCloseHandler = () => { navigate('') } diff --git a/src/components/NotebookCard.css b/src/components/NotebookCard.css new file mode 100644 index 0000000..725ca78 --- /dev/null +++ b/src/components/NotebookCard.css @@ -0,0 +1,9 @@ +.NotebookCard { + border-radius: var(--impresso-border-rqdius-sm); + background: white; +} + +.NotebookCard h3 { + font-size: var(--fs18px); + font-weight: bold; +} diff --git a/src/components/NotebookCard.js b/src/components/NotebookCard.js new file mode 100644 index 0000000..9fe8d2c --- /dev/null +++ b/src/components/NotebookCard.js @@ -0,0 +1,53 @@ +import React from 'react' +import { ModalNotebookPreviewView, useDataStore } from '../store' +import AuthorCard from './AuthorCard' +import { Button } from 'react-bootstrap' +import './NotebookCard.css' +import { navigate } from 'gatsby' +import Avatar from 'boring-avatars' +import { ArrowRight } from 'iconoir-react' + +const AvatarVariants = ['marble', 'beam', 'pixel', 'sunset', 'ring', 'bauhaus'] +const NotebookCard = ({ name }) => { + const getNotebookByName = useDataStore((state) => state.getNotebookByName) + const notebook = getNotebookByName(name) + const navigateToNotebookPage = () => { + navigate(`?view=${ModalNotebookPreviewView}&viewId=${name}`) + } + + return ( +
+
+
+ +
+
+

{notebook?.title}

+
    + {notebook?.authors.map((name) => ( +
  1. + +
  2. + ))} +
+
+
+ +
+
+
+ ) +} +export default NotebookCard diff --git a/src/components/PrefetchData.js b/src/components/PrefetchData.js new file mode 100644 index 0000000..5872f3c --- /dev/null +++ b/src/components/PrefetchData.js @@ -0,0 +1,40 @@ +import { useQuery } from '@tanstack/react-query' +import axios from 'axios' +import { useDataStore } from '../store' + +const PrefetchData = () => { + const [setData, isReady] = useDataStore((state) => [ + state.setData, + state.isReady, + ]) + console.info('[PrefetchData] load data', !isReady) + // this schema updates the store so that e always have the full list of authors and books + useQuery({ + queryKey: ['todoss'], + queryFn: () => + Promise.all( + [ + '/data/authors.json', + '/data/notebooks.json', + '/data/collections.json', + ].map((url) => + axios.get(url).then((res) => { + console.info(`[PrefetchData] ${url}`, res.data) + return res.data + }) + ) + ).then((res) => { + console.info('[PrefetchData] done', res) + + setData({ + authors: res[0], + notebooks: res[1], + collections: res[2], + }) + return true + }), + enabled: !isReady, + }) +} + +export default PrefetchData diff --git a/src/notebooks/introduction-to-topic-modeling.mdx b/src/notebooks/introduction-to-topic-modeling.mdx new file mode 100644 index 0000000..58450dd --- /dev/null +++ b/src/notebooks/introduction-to-topic-modeling.mdx @@ -0,0 +1,5 @@ +--- +title: 'Introduction to topic modeling' +url: https://colab.research.google.com/github/littlecolumns/ds4j-notebooks/blob/master/text-analysis/notebooks/Introduction%20to%20topic%20modeling.ipynb +author: '@littlecolumns' +--- diff --git a/src/notebooks/setup.mdx b/src/notebooks/setup.mdx index 0507507..3412bbf 100644 --- a/src/notebooks/setup.mdx +++ b/src/notebooks/setup.mdx @@ -2,12 +2,18 @@ title: 'Setup' collection: enter-impresso tags: - - r - - rstudio - - binder - - demo + - hello-world binderUrl: https://mybinder.org/v2/gh/binder-examples/r/master?urlpath=rstudio repoUrl: +authors: + - impresso-team --- -# RStudio on Binder +# Enter the Impresso-py + +This is the first notebook in the Enter Impresso series. It is a simple introduction to the series and the tools we will be using. +First things, let's see if we can run some Python code. + +```python +print("Hello, World!") +``` diff --git a/src/notebooks/time-distribution-of-a-search.mdx b/src/notebooks/time-distribution-of-a-search.mdx new file mode 100644 index 0000000..90962b8 --- /dev/null +++ b/src/notebooks/time-distribution-of-a-search.mdx @@ -0,0 +1,52 @@ +--- +title: Draw time Distribution of your search results +excerpt: >- + This code snippet shows how to draw a time distribution of your search results using Python and Matplotlib. +authors: + - daniele-guido +collections: + - enter-impresso +tags: + - matplotlib +--- + +This code snippet shows how to draw a time distribution of your search results using Python and Matplotlib. + +# Python code in Jupyter Notebook + +## Import necessary libraries + +```python +import matplotlib.pyplot as plt +import matplotlib.dates as mdates +from datetime import datetime +``` + +# List of (date, value) pairs + +data = [('2022-01-01', 10), ('2022-02-01', 15), ('2022-03-01', 7), ('2022-04-01', 18)] + +# Separate dates and values + +dates = [datetime.strptime(date, '%Y-%m-%d') for date, _ in data] +values = [value for _, value in data] + +# Create a new figure and an axes + +fig, ax = plt.subplots() + +# Plot the data + +ax.plot(dates, values) + +# Format the x-axis to display dates + +ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d')) + +# Rotate date labels automatically + +fig.autofmt_xdate() + +# Show the plot + +plt.show() diff --git a/src/pages/index.jsx b/src/pages/index.jsx index c9d860a..dfd5cf6 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -2,56 +2,37 @@ import React from 'react' import { Link, graphql } from 'gatsby' import { Col, Container, Row } from 'react-bootstrap' import CollectionCard from '../components/CollectionCard' +import { useDataStore } from '../store' const Index = ({ data }) => { const highlighted = data.highlighted.nodes + const isReady = useDataStore((state) => state.isReady) + return ( - +

Highlights

- {highlighted.length ? ( - highlighted.map((node, i) => ( - + {highlighted.length && isReady ? ( + highlighted.map((node) => ( + )) ) : (

No highlighted collections found.

)} - -
    - {data.notebooks.totalCount} - {data.notebooks.nodes.map((node, i) => ( -
  • - - - {node.childMdx.frontmatter.title} - -
  • - ))} -

Give your media monitoring a boost.

-

Notebooks that we're testing right now

- -
    - {data.collections.totalCount} - {data.collections.nodes.map((node, i) => ( -
  • {node.childMdx.frontmatter.title}
  • - ))} -
+

+ We collected {data.notebooks.totalCount} notebooks so far, + in {data.collections.totalCount} collections developed by{' '} + {data.highlighted.totalCount} authors. +

+
-
- -
{JSON.stringify(data, null, 2)}
-
) } diff --git a/src/store.js b/src/store.js index efc2820..dc09410 100644 --- a/src/store.js +++ b/src/store.js @@ -14,7 +14,32 @@ export const AvailableModalsViews = [ export const useBrowserStore = create((set) => ({ view: null, + viewId: null, setView(view) { set({ view }) }, })) + +export const useDataStore = create((set, get) => ({ + notebooksMap: {}, + authorsMap: {}, + collectionsMap: {}, + getNotebookByName(name) { + return get().notebooksMap[name] + }, + getAuthorByName(name) { + return get().authorsMap[name] + }, + getCollectionByName(name) { + return get().collectionsMap[name] + }, + setData({ notebooks, authors, collections }) { + set({ + notebooksMap: notebooks, + authorsMap: authors, + collectionsMap: collections, + isReady: true, + }) + }, + isReady: false, +})) diff --git a/src/styles/style.css b/src/styles/style.css index ee4b8d8..7cef518 100644 --- a/src/styles/style.css +++ b/src/styles/style.css @@ -4,6 +4,9 @@ --impresso-color-yellow: #ffeb78; --impresso-color-black: #343a40; --impresso-color-black-rgb: 52, 58, 64; + --impresso-border-rqdius-sm: 20px; + --impresso-border-radius-lg: 30px; + --impresso-border-radius-xl: 40px; --bs-font-sans-serif: 'Satoshi-Variable', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; @@ -59,6 +62,11 @@ --spacer-3: 1rem; --spacer-4: 1.5rem; --spacer-5: 3rem; + + /* SHADOWS */ + --shadow-sm: 0 0 0.5rem 0 rgba(0, 0, 0, 0.1); + --shadow: 0 0 1rem 0 rgba(0, 0, 0, 0.1); + --shadow-lg: 0 0 1.5rem 0 rgba(0, 0, 0, 0.1); } html { @@ -122,7 +130,7 @@ b { } /* ... */ h2 { - border-bottom: 1px solid var(--impresso-color-black); + /* border-bottom: 1px solid var(--impresso-color-black); */ padding-bottom: var(--spacer-3); margin-bottom: var(--spacer-3); } diff --git a/static/data/authors.json b/static/data/authors.json deleted file mode 100644 index 9035c27..0000000 --- a/static/data/authors.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "daniele-guido": { - "name": "daniele-guido", - "fullName": "Daniele Guido", - "collections": [], - "notebooks": [] - }, - "impresso-team": { - "name": "impresso-team", - "fullName": "The Impresso Team", - "collections": [], - "notebooks": [ - "team-starter-pack" - ] - } -} \ No newline at end of file diff --git a/static/data/collections.json b/static/data/collections.json deleted file mode 100644 index ca45120..0000000 --- a/static/data/collections.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "enter-impresso": { - "name": "enter-impresso", - "path": "/collection/enter-impresso", - "title": "Enter *impresso*", - "excerpt": "Three easy steps to enter the impresso way of doing research.", - "notebooks": [ - "team-starter-pack" - ], - "contributors": [ - [ - "impresso-team", - { - "name": "impresso-team", - "count": 1 - } - ] - ] - } -} \ No newline at end of file diff --git a/static/data/notebooks.json b/static/data/notebooks.json deleted file mode 100644 index a937823..0000000 --- a/static/data/notebooks.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "setup": { - "name": "setup", - "path": "/notebook/setup", - "birthTime": "2024-02-20T11:22:42.754Z", - "accessTime": "2024-03-01T11:18:39.885Z", - "title": "Setup", - "excerpt": "", - "binderUrl": "https://mybinder.org/v2/gh/binder-examples/r/master?urlpath=rstudio", - "authors": [], - "collections": [] - }, - "team-starter-pack": { - "name": "team-starter-pack", - "path": "/notebook/team-starter-pack", - "birthTime": "2024-02-09T16:55:21.331Z", - "accessTime": "2024-03-07T09:16:28.892Z", - "title": "A demo of RStudio running on Binder", - "excerpt": "All together, right now.", - "binderUrl": "https://mybinder.org/v2/gh/binder-examples/r/master?urlpath=rstudio", - "authors": [ - "impresso-team" - ], - "collections": [ - "enter-impresso" - ] - } -} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index ced6626..9de43bd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3316,6 +3316,11 @@ bootstrap@^5.3.2: resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-5.3.3.tgz#de35e1a765c897ac940021900fcbb831602bac38" integrity sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg== +boring-avatars@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/boring-avatars/-/boring-avatars-1.10.1.tgz#0e40811043cb3412bee38a0b6ca14f85fcdb0d2b" + integrity sha512-WcgHDeLrazCR03CDPEvCchLsUecZAZvs4F6FnMiGlTEjyQQf15Q5TRl4EUaAQ1dacvhPq7lC9EOTWkCojQ6few== + boxen@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" @@ -6351,6 +6356,11 @@ human-signals@^5.0.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-5.0.0.tgz#42665a284f9ae0dade3ba41ebc37eb4b852f3a28" integrity sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ== +iconoir-react@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/iconoir-react/-/iconoir-react-7.5.0.tgz#adc0cd1a772e5a97050a3087242df962fd253ede" + integrity sha512-BreNjTeCquoYCLsvM6YLai/hvVEEAUz661TkXm7Kh/YvfG0tLqdhTsvYnL4yj/owYahqtLctvVwjjEDSWZmfNw== + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -7306,6 +7316,11 @@ lru-queue@^0.1.0: dependencies: es5-ext "~0.10.2" +luxon@^3.4.4: + version "3.4.4" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.4.4.tgz#cf20dc27dc532ba41a169c43fdcc0063601577af" + integrity sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA== + make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" @@ -7330,6 +7345,11 @@ markdown-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== +marked@^12.0.1: + version "12.0.1" + resolved "https://registry.yarnpkg.com/marked/-/marked-12.0.1.tgz#8ab1eb15560c7cbe3b011074845d7ca6c4d392b0" + integrity sha512-Y1/V2yafOcOdWQCX0XpAKXzDakPOpn6U0YLxTJs3cww6VxOzZV1BTOOYWLvH3gX38cq+iLwljHHTnMtlDfg01Q== + mdast-util-definitions@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2"