UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 46 kB
{"version":3,"file":"CanvasTextGenerator.mjs","sources":["../../../../src/scene/text/canvas/CanvasTextGenerator.ts"],"sourcesContent":["import { Color } from '../../../color/Color';\nimport { Rectangle } from '../../../maths/shapes/Rectangle';\nimport { type CanvasAndContext, CanvasPool } from '../../../rendering/renderers/shared/texture/CanvasPool';\nimport { getCanvasBoundingBox } from '../../../utils/canvas/getCanvasBoundingBox';\nimport { type TextStyle } from '../TextStyle';\nimport { CanvasTextMetrics } from './CanvasTextMetrics';\nimport { fontStringFromTextStyle } from './utils/fontStringFromTextStyle';\nimport { getCanvasFillStyle } from './utils/getCanvasFillStyle';\n\n/**\n * Temporary rectangle for getting the bounding box of the text.\n * @internal\n */\nconst tempRect = new Rectangle();\n\nfunction countSpaces(text: string): number\n{\n let count = 0;\n\n for (let i = 0; i < text.length; i++)\n {\n if (text.charCodeAt(i) === 32) count++;\n }\n\n return count;\n}\n\n/**\n * Utility for generating and managing canvas-based text rendering.\n *\n * This class is responsible for rendering text to canvas elements based on provided styles,\n * measuring the resulting text dimensions, and managing the lifecycle of canvas resources.\n *\n * CanvasTextGenerator supports:\n * - Text rendering with various styles (fill, stroke, gradient, etc.)\n * - Drop shadows and letter spacing\n * - Automatic trimming of transparent pixels\n * - Canvas resource pooling\n *\n * As a singleton, it's accessed via the exported `CanvasTextGenerator` constant.\n * @example\n * ```typescript\n * // Basic usage - render text to a canvas\n * import { CanvasTextGenerator } from 'pixi.js';\n * import { TextStyle } from 'pixi.js';\n *\n * // Create a text style\n * const style = new TextStyle({\n * fontFamily: 'Arial',\n * fontSize: 24,\n * fill: 0xff1010,\n * align: 'center',\n * });\n *\n * // Get a canvas with the text rendered to it\n * const { canvasAndContext, frame } = CanvasTextGenerator.getCanvasAndContext({\n * text: 'Hello Pixi!',\n * style,\n * resolution: 1\n * });\n *\n * @internal\n */\nclass CanvasTextGeneratorClass\n{\n /**\n * Creates a canvas with the specified text rendered to it.\n *\n * Generates a canvas of appropriate size, renders the text with the provided style,\n * and returns both the canvas/context and a Rectangle representing the text bounds.\n *\n * When trim is enabled in the style, the frame will represent the bounds of the\n * non-transparent pixels, which can be smaller than the full canvas.\n * @param options - The options for generating the text canvas\n * @param options.text - The text to render\n * @param options.style - The style to apply to the text\n * @param options.resolution - The resolution of the canvas (defaults to 1)\n * @param options.padding\n * @returns An object containing the canvas/context and the frame (bounds) of the text\n */\n public getCanvasAndContext(options: {text: string, style: TextStyle, resolution?: number, padding?: number})\n {\n const { text, style, resolution = 1 } = options;\n\n const padding = (style as TextStyle)._getFinalPadding();\n\n // create a canvas with the word hello on it\n const measured = CanvasTextMetrics.measureText(text || ' ', style);\n\n const width = Math.ceil(Math.ceil((Math.max(1, measured.width) + (padding * 2))) * resolution);\n const height = Math.ceil(Math.ceil((Math.max(1, measured.height) + (padding * 2))) * resolution);\n\n const canvasAndContext = CanvasPool.getOptimalCanvasAndContext(width, height);\n\n this._renderTextToCanvas(style, padding, resolution, canvasAndContext, measured);\n\n const frame = style.trim\n ? getCanvasBoundingBox({ canvas: canvasAndContext.canvas, width, height, resolution: 1, output: tempRect })\n : tempRect.set(0, 0, width, height);\n\n return {\n canvasAndContext,\n frame\n };\n }\n\n /**\n * Returns a canvas and context to the pool.\n *\n * This should be called when you're done with the canvas to allow reuse\n * and prevent memory leaks.\n * @param canvasAndContext - The canvas and context to return to the pool\n */\n public returnCanvasAndContext(canvasAndContext: CanvasAndContext): void\n {\n CanvasPool.returnCanvasAndContext(canvasAndContext);\n }\n\n /**\n * Renders text to its canvas, and updates its texture.\n * @param style - The style of the text\n * @param padding - The padding of the text\n * @param resolution - The resolution of the text\n * @param canvasAndContext - The canvas and context to render the text to\n * @param measured - Pre-measured text metrics to avoid duplicate measurement\n */\n private _renderTextToCanvas(\n style: TextStyle,\n padding: number,\n resolution: number,\n canvasAndContext: CanvasAndContext,\n measured: CanvasTextMetrics\n ): void\n {\n // Check if we have tagged text data\n if (measured.runsByLine && measured.runsByLine.length > 0)\n {\n this._renderTaggedTextToCanvas(measured, style, padding, resolution, canvasAndContext);\n\n return;\n }\n\n const { canvas, context } = canvasAndContext as { canvas: HTMLCanvasElement, context: CanvasRenderingContext2D };\n\n const font = fontStringFromTextStyle(style);\n\n const lines = measured.lines;\n const lineHeight = measured.lineHeight;\n const lineWidths = measured.lineWidths;\n const maxLineWidth = measured.maxLineWidth;\n const fontProperties = measured.fontProperties;\n\n const height = canvas.height;\n\n context.resetTransform();\n context.scale(resolution, resolution);\n context.textBaseline = style.textBaseline;\n\n // set stroke styles..\n\n if (style._stroke?.width)\n {\n const strokeStyle = style._stroke;\n\n context.lineWidth = strokeStyle.width;\n\n context.miterLimit = strokeStyle.miterLimit;\n context.lineJoin = strokeStyle.join;\n context.lineCap = strokeStyle.cap;\n }\n\n // return;\n context.font = font;\n\n let linePositionX: number;\n let linePositionY: number;\n\n // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text\n const passesCount = style.dropShadow ? 2 : 1;\n\n // For v4, we drew text at the colours of the drop shadow underneath the normal text. This gave the correct zIndex,\n // but features such as alpha and shadowblur did not look right at all, since we were using actual text as a shadow.\n //\n // For v5.0.0, we moved over to just use the canvas API for drop shadows, which made them look much nicer and more\n // visually please, but now because the stroke is drawn and then the fill, drop shadows would appear on both the fill\n // and the stroke; and fill drop shadows would appear over the top of the stroke.\n //\n // For v5.1.1, the new route is to revert to v4 style of drawing text first to get the drop shadows underneath normal\n // text, but instead drawing text in the correct location, we'll draw it off screen (-paddingY), and then adjust the\n // drop shadow so only that appears on screen (+paddingY). Now we'll have the correct draw order of the shadow\n // beneath the text, whilst also having the proper text shadow styling.\n // Calculate alignment width - use the larger of wordWrapWidth and maxLineWidth\n // when wrapping, so lines wider than wordWrapWidth still center correctly\n const alignWidth = style.wordWrap ? Math.max(style.wordWrapWidth, maxLineWidth) : maxLineWidth;\n const strokeWidth = style._stroke?.width ?? 0;\n const halfStroke = strokeWidth / 2;\n\n let linePositionYShift = (lineHeight - fontProperties.fontSize) / 2;\n\n if (lineHeight - fontProperties.fontSize < 0)\n {\n linePositionYShift = 0;\n }\n\n for (let i = 0; i < passesCount; ++i)\n {\n const isShadowPass = style.dropShadow && i === 0;\n // we only want the drop shadow, so put text way off-screen\n const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (padding * 2)) : 0;\n const dsOffsetShadow = dsOffsetText * resolution;\n\n if (isShadowPass)\n {\n this._setupDropShadow(context, style, resolution, dsOffsetShadow);\n }\n else\n {\n // When gradient bounds are set (e.g., from SplitText), use them for gradient calculation\n const gradientBounds = style._gradientBounds;\n const gradientOffset = style._gradientOffset;\n\n if (gradientBounds)\n {\n const gradientMetrics = {\n width: gradientBounds.width,\n height: gradientBounds.height,\n lineHeight: gradientBounds.height,\n lines: measured.lines,\n } as CanvasTextMetrics;\n\n this._setFillAndStrokeStyles(\n context, style, gradientMetrics, padding, halfStroke,\n gradientOffset?.x ?? 0, gradientOffset?.y ?? 0\n );\n }\n else if (gradientOffset)\n {\n this._setFillAndStrokeStyles(\n context, style, measured, padding, halfStroke,\n gradientOffset.x, gradientOffset.y\n );\n }\n else\n {\n this._setFillAndStrokeStyles(context, style, measured, padding, halfStroke);\n }\n\n context.shadowColor = 'rgba(0,0,0,0)';\n }\n\n // draw lines line by line\n for (let j = 0; j < lines.length; j++)\n {\n linePositionX = halfStroke;\n linePositionY = (halfStroke + (j * lineHeight)) + fontProperties.ascent + linePositionYShift;\n\n linePositionX += this._getAlignmentOffset(lineWidths[j], alignWidth, style.align);\n\n let wordSpacing = 0;\n\n if (style.align === 'justify' && style.wordWrap && j < lines.length - 1)\n {\n const spaces = countSpaces(lines[j]);\n\n if (spaces > 0)\n {\n wordSpacing = (alignWidth - lineWidths[j]) / spaces;\n }\n }\n\n if (style._stroke?.width)\n {\n this._drawLetterSpacing(\n lines[j],\n style,\n canvasAndContext,\n linePositionX + padding,\n linePositionY + padding - dsOffsetText,\n true,\n wordSpacing\n );\n }\n\n if (style._fill !== undefined)\n {\n this._drawLetterSpacing(\n lines[j],\n style,\n canvasAndContext,\n linePositionX + padding,\n linePositionY + padding - dsOffsetText,\n false,\n wordSpacing\n );\n }\n }\n }\n }\n\n /**\n * Renders tagged text (with per-run styles) to canvas.\n * @param measured - The measured text metrics containing runsByLine\n * @param style - The base text style\n * @param padding - The padding of the text\n * @param resolution - The resolution of the text\n * @param canvasAndContext - The canvas and context to render to\n */\n private _renderTaggedTextToCanvas(\n measured: CanvasTextMetrics,\n style: TextStyle,\n padding: number,\n resolution: number,\n canvasAndContext: CanvasAndContext\n ): void\n {\n const { canvas, context } = canvasAndContext;\n const { runsByLine, lineWidths, maxLineWidth, lineAscents, lineHeights, hasDropShadow } = measured;\n\n const height = canvas.height;\n\n context.resetTransform();\n context.scale(resolution, resolution);\n context.textBaseline = style.textBaseline;\n\n // require 2 passes if a shadow; the first to draw the drop shadow, the second to draw the text\n const passesCount = hasDropShadow ? 2 : 1;\n\n // Calculate alignment width - use the larger of wordWrapWidth and maxLineWidth\n // when wrapping, so lines wider than wordWrapWidth still center correctly\n const alignWidth = style.wordWrap ? Math.max(style.wordWrapWidth, maxLineWidth) : maxLineWidth;\n let maxStrokeWidth = style._stroke?.width ?? 0;\n\n for (const lineRuns of runsByLine)\n {\n for (const run of lineRuns)\n {\n const w = run.style._stroke?.width ?? 0;\n\n if (w > maxStrokeWidth) maxStrokeWidth = w;\n }\n }\n const halfStroke = maxStrokeWidth / 2;\n\n // Pre-calculate run widths and font strings to avoid redundant computation per pass\n const runDataByLine: Array<Array<{ width: number; font: string }>> = [];\n\n for (let lineIndex = 0; lineIndex < runsByLine.length; lineIndex++)\n {\n const lineRuns = runsByLine[lineIndex];\n const runData: Array<{ width: number; font: string }> = [];\n\n for (const run of lineRuns)\n {\n const font = fontStringFromTextStyle(run.style);\n\n context.font = font;\n runData.push({\n width: CanvasTextMetrics._measureText(run.text, run.style.letterSpacing, context),\n font,\n });\n }\n runDataByLine.push(runData);\n }\n\n for (let pass = 0; pass < passesCount; ++pass)\n {\n const isShadowPass = hasDropShadow && pass === 0;\n const dsOffsetText = isShadowPass ? Math.ceil(Math.max(1, height) + (padding * 2)) : 0;\n const dsOffsetShadow = dsOffsetText * resolution;\n\n if (!isShadowPass)\n {\n context.shadowColor = 'rgba(0,0,0,0)';\n }\n\n let currentY = halfStroke;\n\n // Draw lines\n for (let lineIndex = 0; lineIndex < runsByLine.length; lineIndex++)\n {\n const lineRuns = runsByLine[lineIndex];\n const lineWidth = lineWidths[lineIndex];\n const lineAscent = lineAscents[lineIndex];\n const currentLineHeight = lineHeights[lineIndex];\n const lineRunData = runDataByLine[lineIndex];\n\n // Calculate line X position based on alignment\n let linePositionX = halfStroke;\n\n linePositionX += this._getAlignmentOffset(lineWidth, alignWidth, style.align);\n\n let wordSpacing = 0;\n\n if (style.align === 'justify' && style.wordWrap && lineIndex < runsByLine.length - 1)\n {\n let totalSpaces = 0;\n\n for (const run of lineRuns)\n {\n totalSpaces += countSpaces(run.text);\n }\n\n if (totalSpaces > 0)\n {\n wordSpacing = (alignWidth - lineWidth) / totalSpaces;\n }\n }\n\n // Calculate Y position - use line ascent for proper baseline\n const linePositionY = currentY + lineAscent;\n\n // Track X position for runs\n let runX = linePositionX + padding;\n\n // First pass: draw strokes for all runs\n for (let runIndex = 0; runIndex < lineRuns.length; runIndex++)\n {\n const run = lineRuns[runIndex];\n const { width: runWidth, font: runFont } = lineRunData[runIndex];\n\n context.font = runFont;\n context.textBaseline = run.style.textBaseline;\n\n // Set stroke style for this run\n if (run.style._stroke?.width)\n {\n const runStroke = run.style._stroke;\n\n // Always set stroke properties (both passes need correct lineWidth)\n context.lineWidth = runStroke.width;\n context.miterLimit = runStroke.miterLimit;\n context.lineJoin = runStroke.join;\n context.lineCap = runStroke.cap;\n\n if (isShadowPass)\n {\n // Set up drop shadow for this specific run\n if (run.style.dropShadow)\n {\n this._setupDropShadow(\n context as CanvasRenderingContext2D,\n run.style,\n resolution,\n dsOffsetShadow\n );\n }\n else\n {\n // No shadow for this run, skip drawing\n const spacesSkipped = countSpaces(run.text);\n\n runX += runWidth + (spacesSkipped * wordSpacing);\n continue;\n }\n }\n else\n {\n // Create per-run metrics for gradient calculation\n // Use run's font metrics for height to match non-tagged text behavior\n const runFontProps = CanvasTextMetrics.measureFont(runFont);\n const runHeight = run.style.lineHeight || runFontProps.fontSize;\n\n const runMetrics = {\n width: runWidth,\n height: runHeight,\n lineHeight: runHeight,\n lines: [run.text],\n } as CanvasTextMetrics;\n\n // Pass position offsets so gradient aligns with where the run is drawn\n // Subtract padding from runX because runX already includes padding,\n // but regular text rendering has gradient at origin with text at +padding\n context.strokeStyle = getCanvasFillStyle(\n runStroke, context, runMetrics, padding * 2, runX - padding, currentY\n );\n }\n\n this._drawLetterSpacing(\n run.text,\n run.style,\n canvasAndContext,\n runX,\n linePositionY + padding - dsOffsetText,\n true,\n wordSpacing\n );\n }\n\n const spacesInRun = countSpaces(run.text);\n\n runX += runWidth + (spacesInRun * wordSpacing);\n }\n\n // Reset X position for fill pass\n runX = linePositionX + padding;\n\n // Second pass: draw fills for all runs\n for (let runIndex = 0; runIndex < lineRuns.length; runIndex++)\n {\n const run = lineRuns[runIndex];\n const { width: runWidth, font: runFont } = lineRunData[runIndex];\n\n context.font = runFont;\n context.textBaseline = run.style.textBaseline;\n\n // Set fill style for this run if not shadow pass\n if (run.style._fill !== undefined)\n {\n if (isShadowPass)\n {\n // Set up drop shadow for this specific run\n if (run.style.dropShadow)\n {\n this._setupDropShadow(\n context as CanvasRenderingContext2D,\n run.style,\n resolution,\n dsOffsetShadow\n );\n }\n else\n {\n // No shadow for this run, skip drawing\n const spacesSkipped = countSpaces(run.text);\n\n runX += runWidth + (spacesSkipped * wordSpacing);\n continue;\n }\n }\n else\n {\n // Create per-run metrics for gradient calculation\n // Use run's font metrics for height to match non-tagged text behavior\n const runFontProps = CanvasTextMetrics.measureFont(runFont);\n const runHeight = run.style.lineHeight || runFontProps.fontSize;\n\n const runMetrics = {\n width: runWidth,\n height: runHeight,\n lineHeight: runHeight,\n lines: [run.text],\n } as CanvasTextMetrics;\n\n // Pass position offsets so gradient aligns with where the run is drawn\n // Subtract padding from runX because runX already includes padding,\n // but regular text rendering has gradient at origin with text at +padding\n context.fillStyle = getCanvasFillStyle(\n run.style._fill, context, runMetrics, padding * 2, runX - padding, currentY\n );\n }\n\n this._drawLetterSpacing(\n run.text,\n run.style,\n canvasAndContext,\n runX,\n linePositionY + padding - dsOffsetText,\n false,\n wordSpacing\n );\n }\n\n const spacesInFillRun = countSpaces(run.text);\n\n runX += runWidth + (spacesInFillRun * wordSpacing);\n }\n\n currentY += currentLineHeight;\n }\n }\n }\n\n /**\n * Sets fill and stroke styles on the canvas context for text rendering.\n * @param context - The canvas context\n * @param style - The text style\n * @param metrics - The text metrics for gradient calculation\n * @param padding - The padding value\n * @param halfStroke - Half the stroke width\n * @param offsetX - X offset for gradient positioning\n * @param offsetY - Y offset for gradient positioning\n */\n private _setFillAndStrokeStyles(\n context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n style: TextStyle,\n metrics: CanvasTextMetrics,\n padding: number,\n halfStroke: number,\n offsetX: number = 0,\n offsetY: number = 0\n ): void\n {\n context.fillStyle = style._fill\n ? getCanvasFillStyle(style._fill, context, metrics, padding * 2, offsetX, offsetY)\n : null;\n\n if (style._stroke?.width)\n {\n const strokePadding = halfStroke + (padding * 2);\n\n context.strokeStyle = getCanvasFillStyle(\n style._stroke, context, metrics, strokePadding, offsetX, offsetY\n );\n }\n }\n\n /**\n * Sets up the canvas context for drop shadow rendering.\n * @param context - The canvas context\n * @param style - The text style containing drop shadow options\n * @param resolution - The resolution multiplier\n * @param dsOffsetShadow - The shadow Y offset\n */\n private _setupDropShadow(\n context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D,\n style: TextStyle,\n resolution: number,\n dsOffsetShadow: number\n ): void\n {\n // On Safari, text with gradient and drop shadows together do not position correctly\n // if the scale of the canvas is not 1: https://bugs.webkit.org/show_bug.cgi?id=197689\n // Therefore we'll set the styles to be a plain black whilst generating this drop shadow\n context.fillStyle = 'black';\n context.strokeStyle = 'black';\n\n const shadowOptions = style.dropShadow;\n const dropShadowColor = shadowOptions.color;\n const dropShadowAlpha = shadowOptions.alpha;\n\n context.shadowColor = Color.shared\n .setValue(dropShadowColor)\n .setAlpha(dropShadowAlpha)\n .toRgbaString();\n\n const dropShadowBlur = shadowOptions.blur * resolution;\n const dropShadowDistance = shadowOptions.distance * resolution;\n\n context.shadowBlur = dropShadowBlur;\n context.shadowOffsetX = Math.cos(shadowOptions.angle) * dropShadowDistance;\n context.shadowOffsetY = (Math.sin(shadowOptions.angle) * dropShadowDistance) + dsOffsetShadow;\n }\n\n /**\n * Calculates the X offset for text alignment.\n * @param lineWidth - The width of the current line\n * @param alignWidth - The width to align against (maxLineWidth or wordWrapWidth)\n * @param align - The text alignment\n * @returns The X offset for this line\n */\n private _getAlignmentOffset(lineWidth: number, alignWidth: number, align: string): number\n {\n if (align === 'right')\n {\n return alignWidth - lineWidth;\n }\n else if (align === 'center')\n {\n return (alignWidth - lineWidth) / 2;\n }\n\n return 0;\n }\n\n /**\n * Render the text with letter-spacing.\n *\n * This method handles rendering text with the correct letter spacing, using either:\n * 1. Native letter spacing if supported by the browser\n * 2. Manual letter spacing calculation if not natively supported\n *\n * For manual letter spacing, it calculates the position of each character\n * based on its width and the desired spacing.\n * @param text - The text to draw\n * @param style - The text style to apply\n * @param canvasAndContext - The canvas and context to draw to\n * @param x - Horizontal position to draw the text\n * @param y - Vertical position to draw the text\n * @param isStroke - Whether to render the stroke (true) or fill (false)\n * @param wordSpacing - Extra spacing to add between words (for justify alignment)\n * @private\n */\n private _drawLetterSpacing(\n text: string,\n style: TextStyle,\n canvasAndContext: CanvasAndContext,\n x: number, y: number,\n isStroke = false,\n wordSpacing = 0\n ): void\n {\n const { context } = canvasAndContext;\n\n // letterSpacing of 0 means normal\n const letterSpacing = style.letterSpacing;\n\n let useExperimentalLetterSpacing = false;\n\n if (CanvasTextMetrics.experimentalLetterSpacingSupported)\n {\n if (CanvasTextMetrics.experimentalLetterSpacing)\n {\n context.letterSpacing = `${letterSpacing}px`;\n context.textLetterSpacing = `${letterSpacing}px`;\n useExperimentalLetterSpacing = true;\n }\n else\n {\n context.letterSpacing = '0px';\n context.textLetterSpacing = '0px';\n }\n }\n\n if ((letterSpacing === 0 || useExperimentalLetterSpacing) && wordSpacing === 0)\n {\n if (isStroke)\n {\n context.strokeText(text, x, y);\n }\n else\n {\n context.fillText(text, x, y);\n }\n\n return;\n }\n\n if (wordSpacing !== 0 && (letterSpacing === 0 || useExperimentalLetterSpacing))\n {\n const words = text.split(' ');\n let currentPosition = x;\n const spaceWidth = context.measureText(' ').width;\n\n for (let i = 0; i < words.length; i++)\n {\n if (isStroke)\n {\n context.strokeText(words[i], currentPosition, y);\n }\n else\n {\n context.fillText(words[i], currentPosition, y);\n }\n\n currentPosition += context.measureText(words[i]).width + spaceWidth + wordSpacing;\n }\n\n return;\n }\n\n let currentPosition = x;\n\n const stringArray = CanvasTextMetrics.graphemeSegmenter(text);\n let previousWidth = context.measureText(text).width;\n let currentWidth = 0;\n\n for (let i = 0; i < stringArray.length; ++i)\n {\n const currentChar = stringArray[i];\n\n if (isStroke)\n {\n context.strokeText(currentChar, currentPosition, y);\n }\n else\n {\n context.fillText(currentChar, currentPosition, y);\n }\n let textStr = '';\n\n for (let j = i + 1; j < stringArray.length; ++j)\n {\n textStr += stringArray[j];\n }\n currentWidth = context.measureText(textStr).width;\n currentPosition += previousWidth - currentWidth + letterSpacing;\n if (currentChar === ' ') currentPosition += wordSpacing;\n previousWidth = currentWidth;\n }\n }\n}\n\n/** @internal */\nexport const CanvasTextGenerator = new CanvasTextGeneratorClass();\n"],"names":["currentPosition"],"mappings":"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"}