mirror of
				https://github.com/bspeice/speice.io
				synced 2025-11-03 18:10:32 -05:00 
			
		
		
		
	Code for 2D camera system
This commit is contained in:
		@ -27,6 +27,8 @@ If the chaos game encounters the same pixel twice, nothing changes.
 | 
				
			|||||||
To demonstrate how much work is wasted, we'll count each time the chaos game
 | 
					To demonstrate how much work is wasted, we'll count each time the chaos game
 | 
				
			||||||
visits a pixel while iterating. This gives us a kind of image "histogram":
 | 
					visits a pixel while iterating. This gives us a kind of image "histogram":
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import CodeBlock from "@theme/CodeBlock";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import chaosGameHistogramSource from "!!raw-loader!./chaosGameHistogram"
 | 
					import chaosGameHistogramSource from "!!raw-loader!./chaosGameHistogram"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<CodeBlock language="typescript">{chaosGameHistogramSource}</CodeBlock>
 | 
					<CodeBlock language="typescript">{chaosGameHistogramSource}</CodeBlock>
 | 
				
			||||||
@ -35,8 +37,6 @@ When the chaos game finishes, we find the pixel encountered most often.
 | 
				
			|||||||
Finally, we "paint" the image by setting each pixel's alpha (transparency) value
 | 
					Finally, we "paint" the image by setting each pixel's alpha (transparency) value
 | 
				
			||||||
to the ratio of times visited divided by the maximum:
 | 
					to the ratio of times visited divided by the maximum:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import CodeBlock from "@theme/CodeBlock";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import paintLinearSource from "!!raw-loader!./paintLinear"
 | 
					import paintLinearSource from "!!raw-loader!./paintLinear"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<CodeBlock language="typescript">{paintLinearSource}</CodeBlock>
 | 
					<CodeBlock language="typescript">{paintLinearSource}</CodeBlock>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										80
									
								
								blog/2024-11-15-playing-with-fire/4-camera/FlameCamera.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								blog/2024-11-15-playing-with-fire/4-camera/FlameCamera.tsx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,80 @@
 | 
				
			|||||||
 | 
					import React, { useContext, useEffect } from "react";
 | 
				
			||||||
 | 
					import * as params from "../src/params";
 | 
				
			||||||
 | 
					import { PainterContext } from "../src/Canvas";
 | 
				
			||||||
 | 
					import {chaosGameCamera, Props as ChaosGameColorProps} from "./chaosGameCamera";
 | 
				
			||||||
 | 
					import styles from "../src/css/styles.module.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Props = {
 | 
				
			||||||
 | 
					  children?: React.ReactElement;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export default function FlameCamera({ children }: Props) {
 | 
				
			||||||
 | 
					  const { width, height, setPainter } = useContext(PainterContext);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Scale chosen so the largest axis is `[-2, 2]` in IFS coordinates,
 | 
				
			||||||
 | 
					  // the smaller axis will be a shorter range to maintain the aspect ratio.
 | 
				
			||||||
 | 
					  const scale = Math.max(width, height) / 4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const [zoom, setZoom] = React.useState(0);
 | 
				
			||||||
 | 
					  const [rotate, setRotate] = React.useState(0);
 | 
				
			||||||
 | 
					  const [offsetX, setOffsetX] = React.useState(0);
 | 
				
			||||||
 | 
					  const [offsetY, setOffsetY] = React.useState(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const resetCamera = () => {
 | 
				
			||||||
 | 
					    setZoom(0);
 | 
				
			||||||
 | 
					    setRotate(0);
 | 
				
			||||||
 | 
					    setOffsetX(0);
 | 
				
			||||||
 | 
					    setOffsetY(0);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const resetButton = <button className={styles.inputReset} onClick={resetCamera}>Reset</button>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(() => {
 | 
				
			||||||
 | 
					    const gameParams: ChaosGameColorProps = {
 | 
				
			||||||
 | 
					      width,
 | 
				
			||||||
 | 
					      height,
 | 
				
			||||||
 | 
					      transforms: params.xforms,
 | 
				
			||||||
 | 
					      final: params.xformFinal,
 | 
				
			||||||
 | 
					      palette: params.palette,
 | 
				
			||||||
 | 
					      colors: [
 | 
				
			||||||
 | 
					        {color: params.xform1Color, colorSpeed: 0.5},
 | 
				
			||||||
 | 
					        {color: params.xform2Color, colorSpeed: 0.5},
 | 
				
			||||||
 | 
					        {color: params.xform3Color, colorSpeed: 0.5}
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      finalColor: { color: params.xformFinalColor, colorSpeed: 0.5 },
 | 
				
			||||||
 | 
					      scale,
 | 
				
			||||||
 | 
					      zoom,
 | 
				
			||||||
 | 
					      rotate: rotate / 180 * Math.PI,
 | 
				
			||||||
 | 
					      offsetX,
 | 
				
			||||||
 | 
					      offsetY
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    setPainter(chaosGameCamera(gameParams));
 | 
				
			||||||
 | 
					  }, [scale, zoom, rotate, offsetX, offsetY]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					      <>
 | 
				
			||||||
 | 
					        <div className={styles.inputGroup} style={{display: "grid", gridTemplateColumns: "1fr 1fr"}}>
 | 
				
			||||||
 | 
					          <p className={styles.inputTitle} style={{gridColumn: "1/-1"}}>Camera {resetButton}</p>
 | 
				
			||||||
 | 
					          <div className={styles.inputElement}>
 | 
				
			||||||
 | 
					            <p>Zoom: {zoom}</p>
 | 
				
			||||||
 | 
					            <input type={"range"} min={-0.5} max={2} step={0.01} value={zoom}
 | 
				
			||||||
 | 
					                   onInput={e => setZoom(Number(e.currentTarget.value))}/>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div className={styles.inputElement}>
 | 
				
			||||||
 | 
					            <p>Rotate (deg): {rotate}</p>
 | 
				
			||||||
 | 
					            <input type={"range"} min={0} max={360} step={1} value={rotate}
 | 
				
			||||||
 | 
					                   onInput={e => setRotate(Number(e.currentTarget.value))}/>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div className={styles.inputElement}>
 | 
				
			||||||
 | 
					            <p>Offset X: {offsetX}</p>
 | 
				
			||||||
 | 
					            <input type={"range"} min={-2} max={2} step={0.01} value={offsetX}
 | 
				
			||||||
 | 
					                   onInput={e => setOffsetX(Number(e.currentTarget.value))}/>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <div className={styles.inputElement}>
 | 
				
			||||||
 | 
					            <p>Offset Y: {offsetY}</p>
 | 
				
			||||||
 | 
					            <input type={"range"} min={-2} max={2} step={0.01} value={offsetY}
 | 
				
			||||||
 | 
					                   onInput={e => setOffsetY(Number(e.currentTarget.value))}/>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        {children}
 | 
				
			||||||
 | 
					      </>
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								blog/2024-11-15-playing-with-fire/4-camera/camera.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								blog/2024-11-15-playing-with-fire/4-camera/camera.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					export function camera(
 | 
				
			||||||
 | 
					    x: number,
 | 
				
			||||||
 | 
					    y: number,
 | 
				
			||||||
 | 
					    width: number,
 | 
				
			||||||
 | 
					    height: number,
 | 
				
			||||||
 | 
					    scale: number,
 | 
				
			||||||
 | 
					    zoom: number,
 | 
				
			||||||
 | 
					    rotate: number,
 | 
				
			||||||
 | 
					    offsetX: number,
 | 
				
			||||||
 | 
					    offsetY: number,
 | 
				
			||||||
 | 
					): [number, number] {
 | 
				
			||||||
 | 
					    const zoomFactor = Math.pow(2, zoom);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Zoom, offset, and rotation are
 | 
				
			||||||
 | 
					    // applied in IFS coordinates
 | 
				
			||||||
 | 
					    [x, y] = [
 | 
				
			||||||
 | 
					        (x - offsetX) * zoomFactor,
 | 
				
			||||||
 | 
					        (y - offsetY) * zoomFactor,
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    [x, y] = [
 | 
				
			||||||
 | 
					        x * Math.cos(rotate) -
 | 
				
			||||||
 | 
					        y * Math.sin(rotate),
 | 
				
			||||||
 | 
					        x * Math.sin(rotate) +
 | 
				
			||||||
 | 
					        y * Math.cos(rotate),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Scale is applied to pixel
 | 
				
			||||||
 | 
					    // coordinates. Shift by half
 | 
				
			||||||
 | 
					    // the image width and height
 | 
				
			||||||
 | 
					    // to compensate for the
 | 
				
			||||||
 | 
					    // IFS coordinates being symmetric
 | 
				
			||||||
 | 
					    // around the origin
 | 
				
			||||||
 | 
					    return [
 | 
				
			||||||
 | 
					        Math.floor(x * scale + width / 2),
 | 
				
			||||||
 | 
					        Math.floor(y * scale + height / 2)
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										139
									
								
								blog/2024-11-15-playing-with-fire/4-camera/chaosGameCamera.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								blog/2024-11-15-playing-with-fire/4-camera/chaosGameCamera.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,139 @@
 | 
				
			|||||||
 | 
					// hidden-start
 | 
				
			||||||
 | 
					import { Props as ChaosGameColorProps } from "../3-log-density/chaosGameColor";
 | 
				
			||||||
 | 
					import { randomBiUnit } from "../src/randomBiUnit";
 | 
				
			||||||
 | 
					import { randomChoice } from "../src/randomChoice";
 | 
				
			||||||
 | 
					import { camera } from "./camera";
 | 
				
			||||||
 | 
					import { histIndex } from "../src/camera";
 | 
				
			||||||
 | 
					import {colorFromPalette} from "../3-log-density/colorFromPalette";
 | 
				
			||||||
 | 
					import {mixColor} from "../3-log-density/mixColor";
 | 
				
			||||||
 | 
					import {paintColor} from "../3-log-density/paintColor";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const quality = 10;
 | 
				
			||||||
 | 
					const step = 100_000;
 | 
				
			||||||
 | 
					// hidden-end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type Props = ChaosGameColorProps & {
 | 
				
			||||||
 | 
					  scale: number;
 | 
				
			||||||
 | 
					  zoom: number,
 | 
				
			||||||
 | 
					  rotate: number;
 | 
				
			||||||
 | 
					  offsetX: number;
 | 
				
			||||||
 | 
					  offsetY: number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function* chaosGameCamera(
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    width,
 | 
				
			||||||
 | 
					    height,
 | 
				
			||||||
 | 
					    transforms,
 | 
				
			||||||
 | 
					    final,
 | 
				
			||||||
 | 
					    palette,
 | 
				
			||||||
 | 
					    colors,
 | 
				
			||||||
 | 
					    finalColor,
 | 
				
			||||||
 | 
					    scale,
 | 
				
			||||||
 | 
					    zoom,
 | 
				
			||||||
 | 
					    rotate,
 | 
				
			||||||
 | 
					    offsetX,
 | 
				
			||||||
 | 
					    offsetY,
 | 
				
			||||||
 | 
					  }: Props
 | 
				
			||||||
 | 
					) {
 | 
				
			||||||
 | 
					  const pixels = width * height;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // highlight-start
 | 
				
			||||||
 | 
					  const imgRed = Array<number>(pixels)
 | 
				
			||||||
 | 
					    .fill(0);
 | 
				
			||||||
 | 
					  const imgGreen = Array<number>(pixels)
 | 
				
			||||||
 | 
					    .fill(0);
 | 
				
			||||||
 | 
					  const imgBlue = Array<number>(pixels)
 | 
				
			||||||
 | 
					    .fill(0);
 | 
				
			||||||
 | 
					  const imgAlpha = Array<number>(pixels)
 | 
				
			||||||
 | 
					    .fill(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const plotColor = (
 | 
				
			||||||
 | 
					    x: number,
 | 
				
			||||||
 | 
					    y: number,
 | 
				
			||||||
 | 
					    c: number
 | 
				
			||||||
 | 
					  ) => {
 | 
				
			||||||
 | 
					    const [pixelX, pixelY] =
 | 
				
			||||||
 | 
					      camera(x, y, width, height, scale, zoom, rotate, offsetX, offsetY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (
 | 
				
			||||||
 | 
					      pixelX < 0 ||
 | 
				
			||||||
 | 
					      pixelX >= width ||
 | 
				
			||||||
 | 
					      pixelY < 0 ||
 | 
				
			||||||
 | 
					      pixelY >= width
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const hIndex =
 | 
				
			||||||
 | 
					      histIndex(pixelX, pixelY, width, 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const [r, g, b] =
 | 
				
			||||||
 | 
					      colorFromPalette(palette, c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    imgRed[hIndex] += r;
 | 
				
			||||||
 | 
					    imgGreen[hIndex] += g;
 | 
				
			||||||
 | 
					    imgBlue[hIndex] += b;
 | 
				
			||||||
 | 
					    imgAlpha[hIndex] += 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // highlight-end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let [x, y] = [
 | 
				
			||||||
 | 
					    randomBiUnit(),
 | 
				
			||||||
 | 
					    randomBiUnit()
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					  let c = Math.random();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const iterations = quality * pixels;
 | 
				
			||||||
 | 
					  for (let i = 0; i < iterations; i++) {
 | 
				
			||||||
 | 
					    const [transformIndex, transform] =
 | 
				
			||||||
 | 
					      randomChoice(transforms);
 | 
				
			||||||
 | 
					    [x, y] = transform(x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // highlight-start
 | 
				
			||||||
 | 
					    const transformColor =
 | 
				
			||||||
 | 
					      colors[transformIndex];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    c = mixColor(
 | 
				
			||||||
 | 
					      c,
 | 
				
			||||||
 | 
					      transformColor.color,
 | 
				
			||||||
 | 
					      transformColor.colorSpeed
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    // highlight-end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const [finalX, finalY] = final(x, y);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // highlight-start
 | 
				
			||||||
 | 
					    const finalC = mixColor(
 | 
				
			||||||
 | 
					      c,
 | 
				
			||||||
 | 
					      finalColor.color,
 | 
				
			||||||
 | 
					      finalColor.colorSpeed
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    // highlight-end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i > 20)
 | 
				
			||||||
 | 
					      plotColor(
 | 
				
			||||||
 | 
					        finalX,
 | 
				
			||||||
 | 
					        finalY,
 | 
				
			||||||
 | 
					        finalC
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (i % step === 0)
 | 
				
			||||||
 | 
					      yield paintColor(
 | 
				
			||||||
 | 
					        width,
 | 
				
			||||||
 | 
					        height,
 | 
				
			||||||
 | 
					        imgRed,
 | 
				
			||||||
 | 
					        imgGreen,
 | 
				
			||||||
 | 
					        imgBlue,
 | 
				
			||||||
 | 
					        imgAlpha
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  yield paintColor(
 | 
				
			||||||
 | 
					    width,
 | 
				
			||||||
 | 
					    height,
 | 
				
			||||||
 | 
					    imgRed,
 | 
				
			||||||
 | 
					    imgGreen,
 | 
				
			||||||
 | 
					    imgBlue,
 | 
				
			||||||
 | 
					    imgAlpha
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								blog/2024-11-15-playing-with-fire/4-camera/index.mdx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								blog/2024-11-15-playing-with-fire/4-camera/index.mdx
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					---
 | 
				
			||||||
 | 
					slug: 2025/03/playing-with-fire-camera
 | 
				
			||||||
 | 
					title: "Playing with fire: The camera"
 | 
				
			||||||
 | 
					date: 2025-03-07 12:00:00
 | 
				
			||||||
 | 
					authors: [bspeice]
 | 
				
			||||||
 | 
					tags: []
 | 
				
			||||||
 | 
					---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- truncate -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import CodeBlock from "@theme/CodeBlock";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import cameraSource from "!!raw-loader!./camera"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<CodeBlock language="typescript">{cameraSource}</CodeBlock>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import {SquareCanvas} from "../src/Canvas";
 | 
				
			||||||
 | 
					import FlameCamera from "./FlameCamera";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<SquareCanvas name={"flame_camera"} width={'95%'} aspectRatio={'4/3'}><FlameCamera /></SquareCanvas>
 | 
				
			||||||
@ -18,6 +18,8 @@ const downloadImage = (name: string) =>
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type CanvasProps = {
 | 
					type CanvasProps = {
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
 | 
					    width?: string;
 | 
				
			||||||
 | 
					    aspectRatio?: string;
 | 
				
			||||||
    style?: any;
 | 
					    style?: any;
 | 
				
			||||||
    children?: React.ReactElement
 | 
					    children?: React.ReactElement
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -105,6 +107,6 @@ export const Canvas: React.FC<CanvasProps> = ({name, style, children}) => {
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const SquareCanvas: React.FC<CanvasProps> = ({name, style, children}) => {
 | 
					export const SquareCanvas: React.FC<CanvasProps> = ({name, width, aspectRatio, style, children}) => {
 | 
				
			||||||
    return <center><Canvas name={name} style={{width: '75%', aspectRatio: '1/1', ...style}} children={children}/></center>
 | 
					    return <center><Canvas name={name} style={{width: width ?? '75%', aspectRatio: aspectRatio ?? '1/1', ...style}} children={children}/></center>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										9
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@ -3035,6 +3035,7 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ==",
 | 
					      "integrity": "sha512-b0fUmaL+JbzDIQaamzpAFpTviiaU4cX3Qz8cuo14+HGBCwa0evEK0UYCBFY3n4cLzL8Op1BueeroUD2LYAIHbQ==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@docusaurus/babel": "3.7.0",
 | 
					        "@docusaurus/babel": "3.7.0",
 | 
				
			||||||
        "@docusaurus/bundler": "3.7.0",
 | 
					        "@docusaurus/bundler": "3.7.0",
 | 
				
			||||||
@ -3109,6 +3110,7 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/faster/-/faster-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/faster/-/faster-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-d+7uyOEs3SBk38i2TL79N6mFaP7J4knc5lPX/W9od+jplXZhnDdl5ZMh2u2Lg7JxGV/l33Bd7h/xwv4mr21zag==",
 | 
					      "integrity": "sha512-d+7uyOEs3SBk38i2TL79N6mFaP7J4knc5lPX/W9od+jplXZhnDdl5ZMh2u2Lg7JxGV/l33Bd7h/xwv4mr21zag==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@docusaurus/types": "3.7.0",
 | 
					        "@docusaurus/types": "3.7.0",
 | 
				
			||||||
        "@rspack/core": "1.2.0-alpha.0",
 | 
					        "@rspack/core": "1.2.0-alpha.0",
 | 
				
			||||||
@ -3362,6 +3364,7 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg==",
 | 
					      "integrity": "sha512-g7WdPqDNaqA60CmBrr0cORTrsOit77hbsTj7xE2l71YhBn79sxdm7WMK7wfhcaafkbpIh7jv5ef5TOpf1Xv9Lg==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@docusaurus/types": "3.7.0",
 | 
					        "@docusaurus/types": "3.7.0",
 | 
				
			||||||
        "@types/history": "^4.7.11",
 | 
					        "@types/history": "^4.7.11",
 | 
				
			||||||
@ -3586,6 +3589,7 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q==",
 | 
					      "integrity": "sha512-nPHj8AxDLAaQXs+O6+BwILFuhiWbjfQWrdw2tifOClQoNfuXDjfjogee6zfx6NGHWqshR23LrcN115DmkHC91Q==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@docusaurus/core": "3.7.0",
 | 
					        "@docusaurus/core": "3.7.0",
 | 
				
			||||||
        "@docusaurus/plugin-content-blog": "3.7.0",
 | 
					        "@docusaurus/plugin-content-blog": "3.7.0",
 | 
				
			||||||
@ -3681,6 +3685,7 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/theme-live-codeblock/-/theme-live-codeblock-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-peLs77sk+TuHjAnhyhT8IH3Qsr/zewpwHg5A4EOe/8K4Lj2T8fhro1/Dj66FS8784wwAoxhy5A9Ux9Rsp8h87w==",
 | 
					      "integrity": "sha512-peLs77sk+TuHjAnhyhT8IH3Qsr/zewpwHg5A4EOe/8K4Lj2T8fhro1/Dj66FS8784wwAoxhy5A9Ux9Rsp8h87w==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@docusaurus/core": "3.7.0",
 | 
					        "@docusaurus/core": "3.7.0",
 | 
				
			||||||
        "@docusaurus/theme-common": "3.7.0",
 | 
					        "@docusaurus/theme-common": "3.7.0",
 | 
				
			||||||
@ -3746,12 +3751,14 @@
 | 
				
			|||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-vRsyj3yUZCjscgfgcFYjIsTcAru/4h4YH2/XAE8Rs7wWdnng98PgWKvP5ovVc4rmRpRg2WChVW0uOy2xHDvDBQ==",
 | 
					      "integrity": "sha512-vRsyj3yUZCjscgfgcFYjIsTcAru/4h4YH2/XAE8Rs7wWdnng98PgWKvP5ovVc4rmRpRg2WChVW0uOy2xHDvDBQ==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true,
 | 
				
			||||||
 | 
					      "license": "MIT"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    "node_modules/@docusaurus/types": {
 | 
					    "node_modules/@docusaurus/types": {
 | 
				
			||||||
      "version": "3.7.0",
 | 
					      "version": "3.7.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.7.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.7.0.tgz",
 | 
				
			||||||
      "integrity": "sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ==",
 | 
					      "integrity": "sha512-kOmZg5RRqJfH31m+6ZpnwVbkqMJrPOG5t0IOl4i/+3ruXyNfWzZ0lVtVrD0u4ONc/0NOsS9sWYaxxWNkH1LdLQ==",
 | 
				
			||||||
 | 
					      "license": "MIT",
 | 
				
			||||||
      "dependencies": {
 | 
					      "dependencies": {
 | 
				
			||||||
        "@mdx-js/mdx": "^3.0.0",
 | 
					        "@mdx-js/mdx": "^3.0.0",
 | 
				
			||||||
        "@types/history": "^4.7.11",
 | 
					        "@types/history": "^4.7.11",
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user