diff --git a/packages/core/src/Bundle.ts b/packages/core/src/Bundle.ts index 4ab5a92e..dabc6a08 100644 --- a/packages/core/src/Bundle.ts +++ b/packages/core/src/Bundle.ts @@ -17,6 +17,9 @@ export type Bundle = { spaces: Map traits: Map> theorems: Map + lean?: { + properties: { id: string; module: string }[] + } version: Version } @@ -26,6 +29,16 @@ export const serializedSchema = z.object({ theorems: z.array(theoremSchema), traits: z.array(traitSchema(z.string())), version: z.object({ ref: z.string(), sha: z.string() }), + lean: z + .object({ + properties: z.array( + z.object({ + id: z.string(), + module: z.string(), + }), + ), + }) + .optional(), }) export type Serialized = z.infer @@ -41,14 +54,16 @@ export function serialize(bundle: Bundle): Serialized { } export function deserialize(data: unknown): Bundle { - const serialized = serializedSchema.parse(data) + const { properties, spaces, theorems, traits, version, lean } = + serializedSchema.parse(data) return { - properties: indexBy(serialized.properties, p => p.uid), - spaces: indexBy(serialized.spaces, s => s.uid), - theorems: indexBy(serialized.theorems, t => t.uid), - traits: indexBy(serialized.traits, traitId), - version: serialized.version, + properties: indexBy(properties, p => p.uid), + spaces: indexBy(spaces, s => s.uid), + theorems: indexBy(theorems, t => t.uid), + traits: indexBy(traits, traitId), + lean, + version, } } diff --git a/packages/core/src/Property.ts b/packages/core/src/Property.ts index e06fd96f..17158ea3 100644 --- a/packages/core/src/Property.ts +++ b/packages/core/src/Property.ts @@ -5,6 +5,7 @@ export const propertySchema = z.intersection( z.object({ name: z.string(), aliases: z.array(z.string()), + mathlib: z.string().optional(), }), recordSchema, ) diff --git a/packages/viewer/package.json b/packages/viewer/package.json index 741bb3b0..09b0ebf2 100644 --- a/packages/viewer/package.json +++ b/packages/viewer/package.json @@ -20,12 +20,14 @@ "@pi-base/core": "workspace:*", "@sentry/browser": "^7.75.1", "bootstrap": "^4.6.2", + "d3": "^7.8.5", "debug": "^4.3.4", "fromnow": "^3.0.1", "fuse.js": "^6.6.2", "hast-to-hyperscript": "^10.0.3", "hyperscript": "^2.0.2", "jquery": "1.12.4", + "katex": "^0.16.9", "rehype-katex": "^6.0.3", "remark-rehype": "^10.1.0", "unified": "^10.1.2", @@ -37,6 +39,7 @@ "@sveltejs/kit": "^1.27.1", "@sveltejs/vite-plugin-svelte": "^2.4.6", "@tsconfig/svelte": "^3.0.0", + "@types/d3": "^7.4.3", "@types/debug": "^4.1.10", "@types/hyperscript": "0.0.6", "@types/katex": "^0.16.5", diff --git a/packages/viewer/public/global.css b/packages/viewer/public/global.css index baeba608..25d0258a 100644 --- a/packages/viewer/public/global.css +++ b/packages/viewer/public/global.css @@ -46,3 +46,14 @@ .description { margin-bottom: 1rem; } + +.links line { + stroke: #999; + stroke-opacity: 0.6; +} + +.nodes circle { + stroke: #fff; + stroke-width: 1.5px; +} + \ No newline at end of file diff --git a/packages/viewer/src/app.html b/packages/viewer/src/app.html index 1d198b01..9e0af5d5 100644 --- a/packages/viewer/src/app.html +++ b/packages/viewer/src/app.html @@ -4,25 +4,25 @@ - π-Base + π-Base - - - - - - - - - - + + + + + + + + + + - - + + %sveltekit.head% diff --git a/packages/viewer/src/components/Properties/Show.svelte b/packages/viewer/src/components/Properties/Show.svelte index 52462f62..1c7fd3c3 100644 --- a/packages/viewer/src/components/Properties/Show.svelte +++ b/packages/viewer/src/components/Properties/Show.svelte @@ -1,14 +1,28 @@ @@ -21,6 +35,16 @@ </h1> <section class="description"> + {#if property?.lean} + <p> + <Icons.Robot /> + <a href={leanUrl(property.lean)} target="_blank"> + <code>{property.lean.id}</code> + in + <code>{property.lean.module}</code> + </a> + </p> + {/if} <Typeset body={property.description} /> </section> diff --git a/packages/viewer/src/components/Shared/Cite.svelte b/packages/viewer/src/components/Shared/Cite.svelte index 73fa29da..ffabc5c3 100644 --- a/packages/viewer/src/components/Shared/Cite.svelte +++ b/packages/viewer/src/components/Shared/Cite.svelte @@ -13,7 +13,7 @@ <div class="text-center p-2"> <small> Cite as: - <span class="text-muted"> + <span class="citation text-muted"> The pi-Base Community. {#if title} <cite>{title}.</cite> @@ -32,3 +32,13 @@ <CopyButton text={markdown}>Markdown Link</CopyButton> </small> </div> + +<style> + .p-2 { + overflow: hidden; + } + + .p-2:hover { + overflow: visible; + } +</style> diff --git a/packages/viewer/src/components/Theorems/Table.svelte b/packages/viewer/src/components/Theorems/Table.svelte index 7e6e5e02..c4262b78 100644 --- a/packages/viewer/src/components/Theorems/Table.svelte +++ b/packages/viewer/src/components/Theorems/Table.svelte @@ -1,11 +1,14 @@ <script lang="ts"> - import type { Theorem } from '@/models' + import type { Property, Theorem } from '@/models' import { Formula, Link } from '../Shared' + import type { Readable } from 'svelte/store' export let theorems: Theorem[] = [] + export let small = false + export let selected: Readable<Theorem | Property> | undefined = undefined </script> -<table class="table"> +<table class="table" class:table-sm={small}> <thead> <tr> <th>Id</th> @@ -15,7 +18,7 @@ </thead> <tbody> {#each theorems as theorem (theorem.id)} - <tr> + <tr class:table-warning={$selected === theorem}> <td> <Link.Theorem {theorem} /> </td> diff --git a/packages/viewer/src/components/Traits/Graph.svelte b/packages/viewer/src/components/Traits/Graph.svelte new file mode 100644 index 00000000..8b05665a --- /dev/null +++ b/packages/viewer/src/components/Traits/Graph.svelte @@ -0,0 +1,202 @@ +<script lang="ts"> + import { onMount } from 'svelte' + import * as d3 from 'd3' + import type { Property, Theorem } from '@/models' + import type { Writable } from 'svelte/store' + + import { + type Node, + type Link, + type Graph, + drawLinkWithMidpoint, + renderLatex, + pin, + } from './graph' + + export let selected: Writable<Property | Theorem> + export let graph: Graph + + let el: SVGSVGElement + + const width = 600 + const height = 600 + + // Assumptions will be snapped to x = -bound, while the derived trait + // will be located at x = +bound + const bound = 200 + + // Maximum width of node label text + const textWidth = 500 + + $: pin(graph, bound) + + onMount(() => { + const color = d3.scaleOrdinal(d3.schemeTableau10) + + const simulation = d3 + .forceSimulation(graph.nodes) + // Space out properties + .force( + 'charge', + d3.forceManyBody<Node>().strength(d => -100 * (d.pinned ? 10 : 3)), + ) + // Keep linked properties close together + .force( + 'link', + d3.forceLink<Node, Link>(graph.links).id(d => d.property.id.toString()), + ) + + // Setup the SVG palette and primary shape types + const svg = d3 + .select(el) + .attr('width', width) + .attr('height', height) + .attr('viewBox', [-width / 2, -height / 2, width, height]) + .attr('style', 'max-width: 100%; width: 100%; height: 100%;') + + // Labeling property nodes is tricky, for a few reasons: + // + // While we'd _like_ labels to be middle-anchored text nodes, if we want + // them to contain katex-rendered math, we need to attach foreignObjects to + // hold HTML nodes. + // + // Because we can't middle-anchor those nodes, we kludge around it by + // providing the foreignObjects with a generous bounding box and + // text-aligning inside them. + // + // We _don't_ want these bounding boxes to intercept clicks or mouseovers on + // the graph, so we have to keep them first in SVG document order. + const text = svg + .append('g') + .attr('class', 'labels') + .selectAll('foreignObject') + .data(graph.nodes) + .enter() + .append('foreignObject') + .attr( + 'requiredFeatures', + 'http://www.w3.org/TR/SVG11/feature#Extensibility', + ) + .attr('width', `${textWidth}px`) + .attr('height', '2em') + + text + .append('xhtml:div') + .html(d => (d.degree > 2 || d.pinned ? renderLatex(d.property.name) : '')) + .style('width', '100%') + .style('text-align', 'center') + + // Draw edges connecting properties which are related by a theorem + const link = svg + .append('g') + .attr('stroke', '#777') + .attr('stroke-opacity', 0.6) + .selectAll('path') + .data(graph.links) + .join('path') + .attr('stroke-width', 2) + .attr('marker-mid', 'url(#arrowhead)') + + link.append('title').text(d => d.theorem.name) + + // Draw nodes for each property + const node = svg + .append('g') + .selectAll('circle') + .data(graph.nodes) + .enter() + .append('circle') + .attr('stroke', '#888') + .attr('stroke-width', d => (d.pinned ? 3 : 1.5)) + .attr('r', d => { + if (d.pinned) { + return 10 + } else if (d.degree > 2) { + return 8 + } else { + return 5 + } + }) + .attr('fill', d => (d.pinned || d.degree > 2 ? color('1') : color('2'))) + + node.append('title').text(d => d.property.name) + + // Run the simulation and update elements + simulation.on('tick', () => { + link.attr('d', drawLinkWithMidpoint) + + node.attr('cx', ({ x }) => x ?? null).attr('cy', ({ y }) => y ?? null) + + // Position labels just under their corresponding nodes, and shifted so + // that centered internal text will appear middle-anchored + text + .attr('x', ({ x }) => (x ? x - textWidth / 2 : null)) + .attr('y', ({ y }) => (y ? y + 8 : null)) + }) + + // Allow hover-over + node.on('mouseover', function () { + const datum = d3.select(this).datum() as { property: Property } + if (datum.property) { + $selected = datum.property + } + }) + + link.on('mouseover', function () { + const datum = d3.select(this).datum() as Link + if (datum.theorem) { + $selected = datum.theorem + } + }) + + // Allow dragging non-pinned nodes + + type DragEvent = d3.D3DragEvent<HTMLElement, unknown, Node> + + node.call( + d3 + .drag<any, Node, unknown>() + .on('start', dragstarted) + .on('drag', dragged) + .on('end', dragended), + ) + + function dragstarted({ active, subject }: DragEvent) { + if (!active) { + simulation.alphaTarget(0.3).restart() + } + + subject.fx = subject.pinned?.x || subject.x + subject.fy = subject.pinned?.y || subject.y + } + + function dragged({ subject, x, y }: DragEvent) { + subject.fx = subject.pinned?.x || x + subject.fy = subject.pinned?.y || y + } + + function dragended({ active, subject }: DragEvent) { + if (!active) { + simulation.alphaTarget(0) + } + + subject.fx = subject.pinned?.x + subject.fy = subject.pinned?.y + } + }) +</script> + +<svg xmlns="http://www.w3.org/2000/svg" bind:this={el}> + <defs> + <marker + id="arrowhead" + markerWidth="3" + markerHeight="3" + refX="0" + refY="1.5" + orient="auto" + > + <polygon points="0,0 3,1.5 0,3" fill="#888" /> + </marker> + </defs> +</svg> diff --git a/packages/viewer/src/components/Traits/Proof.svelte b/packages/viewer/src/components/Traits/Proof.svelte index 1a0f1b33..e41d8577 100644 --- a/packages/viewer/src/components/Traits/Proof.svelte +++ b/packages/viewer/src/components/Traits/Proof.svelte @@ -1,19 +1,32 @@ <script lang="ts"> - import { Link } from '../Shared' + import { writable } from 'svelte/store' + import { Icons, Link } from '../Shared' import { Table as Theorems } from '../Theorems' + import Graph from './Graph.svelte' import Value from './Value.svelte' import type { Property, Space, Theorem, Trait } from '@/models' + import { toGraph } from './graph' export let space: Space + export let property: Property export let theorems: Theorem[] export let traits: [Property, Trait][] + + const selected = writable<Property | Theorem>() + + $: graph = toGraph(property, traits, theorems) </script> +<Icons.Robot /> + Automatically deduced from the following: + <div class="row"> - <div class="col"> - <h5>Properties</h5> - <table class="table"> + <div class="col-6"> + <Graph {graph} {selected} /> + </div> + <div class="col-6"> + <table class="table table-sm"> <thead> <tr> <th>Property</th> @@ -22,7 +35,7 @@ Automatically deduced from the following: </thead> <tbody> {#each traits as [property, trait] (property.id)} - <tr> + <tr class:table-warning={$selected === property}> <td> <Link.Property {property} /> </td> @@ -35,9 +48,7 @@ Automatically deduced from the following: {/each} </tbody> </table> - </div> - <div class="col"> - <h5>Theorems</h5> - <Theorems {theorems} /> + + <Theorems {theorems} small={true} {selected} /> </div> </div> diff --git a/packages/viewer/src/components/Traits/Show.svelte b/packages/viewer/src/components/Traits/Show.svelte index ad82d57a..d3a26747 100644 --- a/packages/viewer/src/components/Traits/Show.svelte +++ b/packages/viewer/src/components/Traits/Show.svelte @@ -1,60 +1,36 @@ <script lang="ts"> - import { get } from 'svelte/store' - import { - Loading, - Link, - NotFound, - References, - Title, - Typeset, - } from '../Shared' - import context from '@/context' import Proof from './Proof.svelte' - import { Robot } from '../Shared/Icons' + import { Link, References, Title, Typeset } from '../Shared' + import type { + Proof as ProofData, + Property, + Ref, + Space, + Trait, + } from '@/models' - export let spaceId: string - export let propertyId: string - - const { spaces, properties, theorems, traits, load, checked } = context() - - const loading = load( - traits, - ts => - ts.lookup({ - spaceId, - propertyId, - spaces: get(spaces), - properties: get(properties), - theorems: get(theorems), - }), - checked(spaceId), - ) + export let space: Space + export let property: Property + export let trait: Trait + export let proof: ProofData | undefined + export let meta: { description: string; refs: Ref[] } | undefined </script> -{#await loading} - <Loading /> -{:then { property, space, trait, proof, meta }} - <Title title={`${space.name}: ${property.name}`} /> +<Title title={`${space.name}: ${property.name}`} /> - <h1> - {#if proof} - <Robot /> - {/if} - <Link.Space {space} /> - is - {trait.value ? '' : 'not'} - <Link.Property {property} /> - </h1> +<h1> + <Link.Space {space} /> + is + {trait.value ? '' : 'not'} + <Link.Property {property} /> +</h1> - {#if proof} - <Proof {space} {...proof} /> - {:else if meta} - <section class="description"> - <Typeset body={meta.description} /> - </section> - <h3>References</h3> - <References references={meta.refs} /> - {/if} -{:catch} - <NotFound>Could not find space {spaceId} / property {propertyId}</NotFound> -{/await} +{#if proof} + <Proof {space} {property} {...proof} /> +{:else if meta} + <section class="description"> + <Typeset body={meta.description} /> + </section> + <h3>References</h3> + <References references={meta.refs} /> +{/if} diff --git a/packages/viewer/src/components/Traits/graph.ts b/packages/viewer/src/components/Traits/graph.ts new file mode 100644 index 00000000..4bf29376 --- /dev/null +++ b/packages/viewer/src/components/Traits/graph.ts @@ -0,0 +1,89 @@ +import * as katex from 'katex' +import { formula } from '@pi-base/core' +import type { Property, Theorem, Trait } from '@/models' + +export type Node = d3.SimulationNodeDatum & { + property: Property + degree: number + trait?: Trait + kind?: 'assumed' | 'deduced' + pinned?: { x?: number; y?: number } +} + +export type Link = d3.SimulationLinkDatum<Node> & { theorem: Theorem } + +export type Graph = { nodes: Node[]; links: Link[] } + +// Build graph +// - one node per property +// - theorems correspond to edges linking "when" and "then" (note that theorems +// with compound formulas may correspond to multiple edges) +export function toGraph( + property: Property, + traits: [Property, Trait][], + theorems: Theorem[], +): Graph { + const nodes: Record<string, Node> = {} + const links = [] + + for (const theorem of theorems) { + for (const a of formula.properties(theorem.when)) { + nodes[a.id] ||= { property: a, degree: 0 } + nodes[a.id].degree++ + + for (const c of formula.properties(theorem.then)) { + nodes[c.id] ||= { property: c, degree: 0 } + nodes[c.id].degree++ + + links.push({ + source: a.id.toString(), + target: c.id.toString(), + theorem, + }) + } + } + } + + nodes[property.id].kind = 'deduced' + + for (const [property, trait] of traits) { + nodes[property.id] ||= { property, degree: 0 } + nodes[property.id] = { ...nodes[property.id], kind: 'assumed', trait } + } + + return { nodes: Object.values(nodes), links } +} + +export function pin(graph: Graph, bound: number) { + for (const n of graph.nodes) { + if (n.kind === 'deduced') { + n.fx = bound + n.fy = 1 + n.pinned = { x: bound, y: 1 } + } else if (n.kind === 'assumed') { + n.fx = -1 * bound + n.pinned = { x: -1 * bound } + } + } +} + +// Adding a vertex at the midpoint allows using marker-mid to +// draw a shape there. +export function drawLinkWithMidpoint({ source, target }: Link) { + const { x: x1 = 0, y: y1 = 0 } = source as Node + const { x: x2 = 0, y: y2 = 0 } = target as Node + const mx = (x1 + x2) / 2 + const my = (y1 + y2) / 2 + return `M${x1},${y1}L${mx},${my}L${x2},${y2}` +} + +// Render a string with embedded $-math +// +// This isn't as robust as full typesetting, but should be +// suitable for rendering space or property names +export function renderLatex(s: string) { + return s.replaceAll(/\$[^$]+\$/g, p => { + // FIXME: katex's import typing appears to be wrong + return (katex as any).default.renderToString(p.replaceAll('$', '')) + }) +} diff --git a/packages/viewer/src/constants.ts b/packages/viewer/src/constants.ts index e46dfeb4..43049b41 100644 --- a/packages/viewer/src/constants.ts +++ b/packages/viewer/src/constants.ts @@ -1,6 +1,6 @@ import { bundle } from '@pi-base/core' -export const mainBranch = 'main' +export const mainBranch = 'jcd/mathlib' // 'main' export const contributingUrl = `https://github.com/pi-base/data/blob/${mainBranch}/CONTRIBUTING.md` export const defaultHost = bundle.defaultHost diff --git a/packages/viewer/src/gateway.ts b/packages/viewer/src/gateway.ts index 2e2d7db1..238e1a97 100644 --- a/packages/viewer/src/gateway.ts +++ b/packages/viewer/src/gateway.ts @@ -31,11 +31,18 @@ export function sync( trace({ event: 'remote_fetch_started', host, branch }) const result = await pb.bundle.fetch({ host, branch, etag, fetch }) + const propIdx: Record<string, string> = {} + if (result?.bundle.lean?.properties) { + for (const { id, module } of result.bundle.lean.properties) { + propIdx[id] = module + } + } + if (result) { trace({ event: 'remote_fetch_complete', result }) return { spaces: transform(space, result.bundle.spaces), - properties: transform(property, result.bundle.properties), + properties: transform(property(propIdx), result.bundle.properties), traits: transform(trait, result.bundle.traits), theorems: transform(theorem, result.bundle.theorems), etag: result.etag, @@ -47,19 +54,28 @@ export function sync( } } -function property({ - uid, - name, - aliases, - description, - refs, -}: pb.Property): Property { - return { - id: Id.toInt(uid), +function property(propertyIdx: Record<string, string>) { + return function ({ + uid, name, aliases, description, refs, + mathlib, + }: pb.Property): Property { + return { + id: Id.toInt(uid), + name, + aliases, + description, + refs, + lean: mathlib + ? { + id: mathlib, + module: propertyIdx[mathlib], + } + : undefined, + } } } diff --git a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte index 5a6f6cea..a097c6ef 100644 --- a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte +++ b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.svelte @@ -1,6 +1,15 @@ <script lang="ts"> - import { page } from '$app/stores' import { Show } from '@/components/Traits' + + import type { PageData } from './$types' + + export let data: PageData </script> -<Show spaceId={$page.params.id} propertyId={$page.params.propertyId} /> +<Show + space={data.space} + property={data.property} + trait={data.trait} + proof={data.proof} + meta={data.meta} +/> diff --git a/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts new file mode 100644 index 00000000..c21a294e --- /dev/null +++ b/packages/viewer/src/routes/(app)/spaces/[id]/properties/[propertyId]/+page.ts @@ -0,0 +1,22 @@ +import type { PageLoad } from './$types' +import { get } from 'svelte/store' + +export const load: PageLoad = async ({ + params: { id: spaceId, propertyId }, + parent, +}) => { + const { spaces, properties, theorems, traits, load, checked } = await parent() + + return load( + traits, + ts => + ts.lookup({ + spaceId, + propertyId, + spaces: get(spaces), + properties: get(properties), + theorems: get(theorems), + }), + checked(spaceId), + ) +} diff --git a/packages/viewer/src/types/index.ts b/packages/viewer/src/types/index.ts index b41724f0..1acf4429 100644 --- a/packages/viewer/src/types/index.ts +++ b/packages/viewer/src/types/index.ts @@ -9,6 +9,10 @@ export type Property = { aliases: string[] description: string refs: Ref[] + lean?: { + id: string + module: string + } } export type Space = { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3996532a..698aa682 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -159,6 +159,9 @@ importers: bootstrap: specifier: ^4.6.2 version: 4.6.2(jquery@1.12.4)(popper.js@1.16.1) + d3: + specifier: ^7.8.5 + version: 7.8.5 debug: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) @@ -177,6 +180,9 @@ importers: jquery: specifier: 1.12.4 version: 1.12.4 + katex: + specifier: ^0.16.9 + version: 0.16.9 rehype-katex: specifier: ^6.0.3 version: 6.0.3 @@ -205,6 +211,9 @@ importers: '@tsconfig/svelte': specifier: ^3.0.0 version: 3.0.0 + '@types/d3': + specifier: ^7.4.3 + version: 7.4.3 '@types/debug': specifier: ^4.1.10 version: 4.1.10 @@ -1134,6 +1143,185 @@ packages: '@types/node': 20.1.1 dev: true + /@types/d3-array@3.2.1: + resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==} + dev: true + + /@types/d3-axis@3.0.6: + resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-brush@3.0.6: + resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-chord@3.0.6: + resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==} + dev: true + + /@types/d3-color@3.1.3: + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + dev: true + + /@types/d3-contour@3.0.6: + resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/geojson': 7946.0.13 + dev: true + + /@types/d3-delaunay@6.0.4: + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + dev: true + + /@types/d3-dispatch@3.0.6: + resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==} + dev: true + + /@types/d3-drag@3.0.7: + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-dsv@3.0.7: + resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==} + dev: true + + /@types/d3-ease@3.0.2: + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + dev: true + + /@types/d3-fetch@3.0.7: + resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==} + dependencies: + '@types/d3-dsv': 3.0.7 + dev: true + + /@types/d3-force@3.0.9: + resolution: {integrity: sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA==} + dev: true + + /@types/d3-format@3.0.4: + resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==} + dev: true + + /@types/d3-geo@3.0.8: + resolution: {integrity: sha512-eDivwKKB4ELHw93QNxigleCxZczcyrFgtKyHK5HoCQoeUD0i5feT8i5tH6RxXvt5hPPhpruvKWDSwvfsW448zQ==} + dependencies: + '@types/geojson': 7946.0.13 + dev: true + + /@types/d3-hierarchy@3.1.6: + resolution: {integrity: sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw==} + dev: true + + /@types/d3-interpolate@3.0.4: + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + dependencies: + '@types/d3-color': 3.1.3 + dev: true + + /@types/d3-path@3.0.2: + resolution: {integrity: sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA==} + dev: true + + /@types/d3-polygon@3.0.2: + resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==} + dev: true + + /@types/d3-quadtree@3.0.5: + resolution: {integrity: sha512-Cb1f3jyNBnvMMkf4KBZ7IgAQVWd9yzBwYcrxGqg3aPCUgWELAS+nyeB7r76aqu1e3+CGDjhk4BrWaFBekMwigg==} + dev: true + + /@types/d3-random@3.0.3: + resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==} + dev: true + + /@types/d3-scale-chromatic@3.0.2: + resolution: {integrity: sha512-kpKNZMDT3OAX6b5ct5nS/mv6LULagnUy4DmS6yyNjclje1qVe7vbjPwY3q1TGz6+Wr2IUkgFatCzqYUl54fHag==} + dev: true + + /@types/d3-scale@4.0.8: + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + dependencies: + '@types/d3-time': 3.0.3 + dev: true + + /@types/d3-selection@3.0.10: + resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==} + dev: true + + /@types/d3-shape@3.1.5: + resolution: {integrity: sha512-dfEWpZJ1Pdg8meLlICX1M3WBIpxnaH2eQV2eY43Y5ysRJOTAV9f3/R++lgJKFstfrEOE2zdJ0sv5qwr2Bkic6Q==} + dependencies: + '@types/d3-path': 3.0.2 + dev: true + + /@types/d3-time-format@4.0.3: + resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==} + dev: true + + /@types/d3-time@3.0.3: + resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==} + dev: true + + /@types/d3-timer@3.0.2: + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + dev: true + + /@types/d3-transition@3.0.8: + resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==} + dependencies: + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3-zoom@3.0.8: + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.10 + dev: true + + /@types/d3@7.4.3: + resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==} + dependencies: + '@types/d3-array': 3.2.1 + '@types/d3-axis': 3.0.6 + '@types/d3-brush': 3.0.6 + '@types/d3-chord': 3.0.6 + '@types/d3-color': 3.1.3 + '@types/d3-contour': 3.0.6 + '@types/d3-delaunay': 6.0.4 + '@types/d3-dispatch': 3.0.6 + '@types/d3-drag': 3.0.7 + '@types/d3-dsv': 3.0.7 + '@types/d3-ease': 3.0.2 + '@types/d3-fetch': 3.0.7 + '@types/d3-force': 3.0.9 + '@types/d3-format': 3.0.4 + '@types/d3-geo': 3.0.8 + '@types/d3-hierarchy': 3.1.6 + '@types/d3-interpolate': 3.0.4 + '@types/d3-path': 3.0.2 + '@types/d3-polygon': 3.0.2 + '@types/d3-quadtree': 3.0.5 + '@types/d3-random': 3.0.3 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.0.2 + '@types/d3-selection': 3.0.10 + '@types/d3-shape': 3.1.5 + '@types/d3-time': 3.0.3 + '@types/d3-time-format': 4.0.3 + '@types/d3-timer': 3.0.2 + '@types/d3-transition': 3.0.8 + '@types/d3-zoom': 3.0.8 + dev: true + /@types/debug@4.1.10: resolution: {integrity: sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA==} dependencies: @@ -1163,6 +1351,10 @@ packages: '@types/serve-static': 1.15.1 dev: true + /@types/geojson@7946.0.13: + resolution: {integrity: sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==} + dev: true + /@types/glob@8.1.0: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: @@ -1900,6 +2092,11 @@ packages: resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} engines: {node: '>= 6'} + /commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + dev: false + /commander@8.3.0: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} @@ -2058,6 +2255,254 @@ packages: yauzl: 2.10.0 dev: true + /d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + dependencies: + internmap: 2.0.3 + dev: false + + /d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + dev: false + + /d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + dev: false + + /d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + dependencies: + delaunator: 5.0.0 + dev: false + + /d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + dev: false + + /d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + dev: false + + /d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + dev: false + + /d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + dev: false + + /d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + dependencies: + d3-dsv: 3.0.1 + dev: false + + /d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + dev: false + + /d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + dev: false + + /d3-geo@3.1.0: + resolution: {integrity: sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + dev: false + + /d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + dev: false + + /d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + dev: false + + /d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + dev: false + + /d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + dev: false + + /d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + dev: false + + /d3-scale-chromatic@3.0.0: + resolution: {integrity: sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==} + engines: {node: '>=12'} + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + dev: false + + /d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + dev: false + + /d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + dev: false + + /d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + dependencies: + d3-path: 3.1.0 + dev: false + + /d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + dependencies: + d3-time: 3.1.0 + dev: false + + /d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + dev: false + + /d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + dev: false + + /d3-transition@3.0.1(d3-selection@3.0.0): + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + dev: false + + /d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + dev: false + + /d3@7.8.5: + resolution: {integrity: sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==} + engines: {node: '>=12'} + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.0 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.0.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + dev: false + /dashdash@1.14.1: resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} engines: {node: '>=0.10'} @@ -2157,6 +2602,12 @@ packages: engines: {node: '>=10'} dev: true + /delaunator@5.0.0: + resolution: {integrity: sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==} + dependencies: + robust-predicates: 3.0.2 + dev: false + /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} @@ -3257,8 +3708,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: safer-buffer: 2.1.2 - dev: true - optional: true /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -3334,6 +3783,11 @@ packages: resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} dev: false + /internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + dev: false + /ip@2.0.0: resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} dev: true @@ -3566,8 +4020,8 @@ packages: verror: 1.10.0 dev: true - /katex@0.16.7: - resolution: {integrity: sha512-Xk9C6oGKRwJTfqfIbtr0Kes9OSv6IFsuhFGc7tW4urlpMJtuh+7YhzU6YEG9n8gmWKcMAFzkp7nr+r69kV0zrA==} + /katex@0.16.9: + resolution: {integrity: sha512-fsSYjWS0EEOwvy81j3vRA8TEAhQhKiqO+FQaKWp0m39qwOzHVBgAUBIXWj1pB+O2W3fIpNa6Y9KSKCVbfPhyAQ==} hasBin: true dependencies: commander: 8.3.0 @@ -3866,7 +4320,7 @@ packages: resolution: {integrity: sha512-WH+fJkveMvM3ZN+deb/jT3UW623x8xO9ycfJNDC+UQXX+V72RO6hT9KqxA7c8XFwozAFJ7tufOeG+x/CVSXHUw==} dependencies: '@types/katex': 0.16.5 - katex: 0.16.7 + katex: 0.16.9 micromark-factory-space: 1.0.0 micromark-util-character: 1.1.0 micromark-util-symbol: 1.0.1 @@ -4879,7 +5333,7 @@ packages: '@types/katex': 0.14.0 hast-util-from-html-isomorphic: 1.0.0 hast-util-to-text: 3.1.2 - katex: 0.16.7 + katex: 0.16.9 unist-util-visit: 4.1.2 dev: false @@ -5032,6 +5486,10 @@ packages: glob: 10.3.10 dev: true + /robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + dev: false + /rollup@2.79.1: resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} engines: {node: '>=10.0.0'} @@ -5054,6 +5512,10 @@ packages: queue-microtask: 1.2.3 dev: true + /rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + dev: false + /rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} dependencies: @@ -5072,7 +5534,6 @@ packages: /safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true /sander@0.5.1: resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}