@paper-design/shaders 0.0.51 → 0.0.52

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -64,8 +64,8 @@ export declare const GlassGridShapes: {
64
64
  export declare const GlassDistortionShapes: {
65
65
  readonly prism: 1;
66
66
  readonly lens: 2;
67
- readonly сontour: 3;
68
- readonly сascade: 4;
67
+ readonly contour: 3;
68
+ readonly cascade: 4;
69
69
  readonly facete: 5;
70
70
  };
71
71
  export type GlassDistortionShape = keyof typeof GlassDistortionShapes;
@@ -176,8 +176,8 @@ const GlassGridShapes = {
176
176
  const GlassDistortionShapes = {
177
177
  prism: 1,
178
178
  lens: 2,
179
- \u0441ontour: 3,
180
- \u0441ascade: 4,
179
+ contour: 3,
180
+ cascade: 4,
181
181
  facete: 5
182
182
  };
183
183
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/shaders/fluted-glass.ts"],
4
- "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2 } from '../shader-utils.js';\n\n/**\n * Mimicking glass surface distortion over the image by distorting the texture\n * coordinates within line patterns\n *\n * Uniforms:\n * - u_count, u_angle - number and direction of grid relative to the image\n * - u_shape (float used as integer):\n * ---- 1: uniformly spaced stripes\n * ---- 2: randomly spaced stripes\n * ---- 3: sine wave stripes\n * ---- 4: zigzag stripes\n * ---- 5: wave-based pattern\n * - u_distortion - the power of distortion applied along within each stripe\n * - u_distortionShape (float used as integer):\n * ---- 5 shapes available\n * - u_shift - texture shift in direction opposite to the grid\n * - u_blur - one-directional blur applied over the main distortion\n * - u_highlights - thin color lines along the grid (independent from distortion)\n * - u_marginLeft, u_marginRight, u_marginTop, u_marginBottom - paddings\n * within picture to be shown without any distortion\n *\n */\n\n// language=GLSL\nexport const flutedGlassFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_count;\nuniform float u_angle;\nuniform float u_highlights;\nuniform float u_shape;\nuniform float u_distortion;\nuniform float u_distortionShape;\nuniform float u_shift;\nuniform float u_blur;\nuniform float u_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n\nfloat getUvFrame(vec2 uv) {\n float aax = 2. * fwidth(uv.x);\n float aay = 2. * fwidth(uv.y);\n\n float left = smoothstep(0., aax, uv.x);\n float right = smoothstep(1., 1. - aax, uv.x);\n float bottom = smoothstep(0., aay, uv.y);\n float top = smoothstep(1., 1. - aay, uv.y);\n\n return left * right * bottom * top;\n}\n\nconst int MAX_RADIUS = 50;\n\nvec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {\n if (sigma <= .5) return texture(tex, uv);\n int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));\n\n float twoSigma2 = 2.0 * sigma * sigma;\n float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);\n\n vec4 sum = texture(tex, uv) * gaussianNorm;\n float weightSum = gaussianNorm;\n\n for (int i = 1; i <= MAX_RADIUS; i++) {\n if (i > radius) break;\n\n float x = float(i);\n float w = exp(-(x * x) / twoSigma2) * gaussianNorm;\n\n vec2 offset = dir * texelSize * x;\n vec4 s1 = texture(tex, uv + offset);\n vec4 s2 = texture(tex, uv - offset);\n\n sum += (s1 + s2) * w;\n weightSum += 2.0 * w;\n }\n\n return sum / weightSum;\n}\n\nvoid main() {\n vec2 imageUV = v_imageUV;\n \n vec2 uv = imageUV;\n float frame = getUvFrame(imageUV);\n if (frame < .05) discard;\n\n float gridNumber = u_count * u_imageAspectRatio;\n\n vec2 sw = vec2(.005 * u_distortion) * vec2(1., u_imageAspectRatio);\n float maskOuter =\n smoothstep(u_marginLeft - sw.x, u_marginLeft, imageUV.x + sw.x) *\n smoothstep(u_marginRight - sw.x, u_marginRight, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop - sw.y, u_marginTop, imageUV.y + sw.y) *\n smoothstep(u_marginBottom - sw.y, u_marginBottom, 1.0 - imageUV.y + sw.y);\n float mask =\n smoothstep(u_marginLeft, u_marginLeft + sw.x, imageUV.x + sw.x) *\n smoothstep(u_marginRight, u_marginRight + sw.x, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop, u_marginTop + sw.y, imageUV.y + sw.y) *\n smoothstep(u_marginBottom, u_marginBottom + sw.y, 1.0 - imageUV.y + sw.y);\n float stroke = (1. - mask) * maskOuter;\n\n float patternRotation = u_angle * PI / 180.;\n uv = rotate(uv - vec2(.5), patternRotation);\n uv *= gridNumber;\n \n float curve = 0.;\n if (u_shape > 4.5) {\n // pattern\n curve = .5 + .5 * sin(1.5 * uv.x) * cos(1.5 * uv.y);\n } else if (u_shape > 3.5) {\n // zigzag\n curve = 10. * abs(fract(.1 * uv.y) - .5);\n } else if (u_shape > 2.5) {\n // wave\n curve = 4. * sin(.23 * uv.y);\n } else if (u_shape > 1.5) {\n // lines irregular\n curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);\n } else {\n // lines\n curve = .2 * gridNumber / u_imageAspectRatio;\n }\n\n vec2 uvOrig = uv;\n uv += curve;\n\n vec2 fractUV = fract(uv);\n vec2 floorUV = floor(uv);\n\n vec2 fractOrigUV = fract(uvOrig);\n vec2 floorOrigUV = floor(uvOrig);\n\n float highlights = smoothstep(.85, .95, fractUV.x);\n highlights *= mask;\n\n float xDistortion = 0.;\n if (u_distortionShape == 1.) {\n xDistortion = -pow(1.5 * fractUV.x, 3.) + (.5 + u_shift);\n } else if (u_distortionShape == 2.) {\n xDistortion = 2. * pow(fractUV.x, 2.) - (.5 + u_shift);\n } else if (u_distortionShape == 3.) {\n xDistortion = pow(2. * (fractUV.x - .5), 6.) + .5 - .5 + u_shift;\n } else if (u_distortionShape == 4.) {\n xDistortion = sin((fractUV.x + .25 + u_shift) * TWO_PI);\n xDistortion *= .5;\n } else if (u_distortionShape == 5.) {\n xDistortion += (.5 + u_shift);\n xDistortion -= pow(abs(fractUV.x), .2) * fractUV.x;\n xDistortion *= .33;\n }\n\n xDistortion *= 3. * u_distortion;\n\n uv = (floorOrigUV + fractOrigUV) / gridNumber;\n uv.x += xDistortion / gridNumber;\n uv += pow(stroke, 4.);\n uv.y = mix(uv.y, .0, .4 * u_highlights * highlights);\n \n uv = rotate(uv, -patternRotation) + vec2(.5);\n\n uv = mix(imageUV, uv, mask);\n float blur = mix(0., u_blur, mask);\n \n vec4 color = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);\n\n float opacity = color.a;\n fragColor = vec4(color.rgb, opacity);\n}\n`;\n\nexport interface FlutedGlassUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_count: number;\n u_angle: number;\n u_distortion: number;\n u_shift: number;\n u_blur: number;\n u_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_highlights: number;\n u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];\n u_shape: (typeof GlassGridShapes)[GlassGridShape];\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string | undefined;\n count?: number;\n angle?: number;\n distortion?: number;\n shift?: number;\n blur?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n highlights?: number;\n distortionShape?: GlassDistortionShape;\n shape?: GlassGridShape;\n}\n\nexport const GlassGridShapes = {\n lines: 1,\n linesIrregular: 2,\n wave: 3,\n zigzag: 4,\n pattern: 5,\n} as const;\n\nexport const GlassDistortionShapes = {\n prism: 1,\n lens: 2,\n \u0441ontour: 3,\n \u0441ascade: 4,\n facete: 5,\n} as const;\n\nexport type GlassDistortionShape = keyof typeof GlassDistortionShapes;\nexport type GlassGridShape = keyof typeof GlassGridShapes;\n"],
5
- "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,iBAAiB;AA0B9B,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuB/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuKJ,MAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,MAAM,wBAAwB;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,cAAS;AAAA,EACT,cAAS;AAAA,EACT,QAAQ;AACV;",
4
+ "sourcesContent": ["import type { ShaderMotionParams } from '../shader-mount.js';\nimport { sizingVariablesDeclaration, type ShaderSizingParams, type ShaderSizingUniforms } from '../shader-sizing.js';\nimport { declarePI, rotation2 } from '../shader-utils.js';\n\n/**\n * Mimicking glass surface distortion over the image by distorting the texture\n * coordinates within line patterns\n *\n * Uniforms:\n * - u_count, u_angle - number and direction of grid relative to the image\n * - u_shape (float used as integer):\n * ---- 1: uniformly spaced stripes\n * ---- 2: randomly spaced stripes\n * ---- 3: sine wave stripes\n * ---- 4: zigzag stripes\n * ---- 5: wave-based pattern\n * - u_distortion - the power of distortion applied along within each stripe\n * - u_distortionShape (float used as integer):\n * ---- 5 shapes available\n * - u_shift - texture shift in direction opposite to the grid\n * - u_blur - one-directional blur applied over the main distortion\n * - u_highlights - thin color lines along the grid (independent from distortion)\n * - u_marginLeft, u_marginRight, u_marginTop, u_marginBottom - paddings\n * within picture to be shown without any distortion\n *\n */\n\n// language=GLSL\nexport const flutedGlassFragmentShader: string = `#version 300 es\nprecision mediump float;\n\nuniform float u_time;\nuniform vec2 u_resolution;\nuniform float u_pixelRatio;\n\nuniform sampler2D u_image;\nuniform float u_imageAspectRatio;\n\nuniform float u_count;\nuniform float u_angle;\nuniform float u_highlights;\nuniform float u_shape;\nuniform float u_distortion;\nuniform float u_distortionShape;\nuniform float u_shift;\nuniform float u_blur;\nuniform float u_marginLeft;\nuniform float u_marginRight;\nuniform float u_marginTop;\nuniform float u_marginBottom;\n\n${sizingVariablesDeclaration}\n\nout vec4 fragColor;\n\n${declarePI}\n${rotation2}\n\nfloat getUvFrame(vec2 uv) {\n float aax = 2. * fwidth(uv.x);\n float aay = 2. * fwidth(uv.y);\n\n float left = smoothstep(0., aax, uv.x);\n float right = smoothstep(1., 1. - aax, uv.x);\n float bottom = smoothstep(0., aay, uv.y);\n float top = smoothstep(1., 1. - aay, uv.y);\n\n return left * right * bottom * top;\n}\n\nconst int MAX_RADIUS = 50;\n\nvec4 getBlur(sampler2D tex, vec2 uv, vec2 texelSize, vec2 dir, float sigma) {\n if (sigma <= .5) return texture(tex, uv);\n int radius = int(min(float(MAX_RADIUS), ceil(3.0 * sigma)));\n\n float twoSigma2 = 2.0 * sigma * sigma;\n float gaussianNorm = 1.0 / sqrt(TWO_PI * sigma * sigma);\n\n vec4 sum = texture(tex, uv) * gaussianNorm;\n float weightSum = gaussianNorm;\n\n for (int i = 1; i <= MAX_RADIUS; i++) {\n if (i > radius) break;\n\n float x = float(i);\n float w = exp(-(x * x) / twoSigma2) * gaussianNorm;\n\n vec2 offset = dir * texelSize * x;\n vec4 s1 = texture(tex, uv + offset);\n vec4 s2 = texture(tex, uv - offset);\n\n sum += (s1 + s2) * w;\n weightSum += 2.0 * w;\n }\n\n return sum / weightSum;\n}\n\nvoid main() {\n vec2 imageUV = v_imageUV;\n \n vec2 uv = imageUV;\n float frame = getUvFrame(imageUV);\n if (frame < .05) discard;\n\n float gridNumber = u_count * u_imageAspectRatio;\n\n vec2 sw = vec2(.005 * u_distortion) * vec2(1., u_imageAspectRatio);\n float maskOuter =\n smoothstep(u_marginLeft - sw.x, u_marginLeft, imageUV.x + sw.x) *\n smoothstep(u_marginRight - sw.x, u_marginRight, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop - sw.y, u_marginTop, imageUV.y + sw.y) *\n smoothstep(u_marginBottom - sw.y, u_marginBottom, 1.0 - imageUV.y + sw.y);\n float mask =\n smoothstep(u_marginLeft, u_marginLeft + sw.x, imageUV.x + sw.x) *\n smoothstep(u_marginRight, u_marginRight + sw.x, 1.0 - imageUV.x + sw.x) *\n smoothstep(u_marginTop, u_marginTop + sw.y, imageUV.y + sw.y) *\n smoothstep(u_marginBottom, u_marginBottom + sw.y, 1.0 - imageUV.y + sw.y);\n float stroke = (1. - mask) * maskOuter;\n\n float patternRotation = u_angle * PI / 180.;\n uv = rotate(uv - vec2(.5), patternRotation);\n uv *= gridNumber;\n \n float curve = 0.;\n if (u_shape > 4.5) {\n // pattern\n curve = .5 + .5 * sin(1.5 * uv.x) * cos(1.5 * uv.y);\n } else if (u_shape > 3.5) {\n // zigzag\n curve = 10. * abs(fract(.1 * uv.y) - .5);\n } else if (u_shape > 2.5) {\n // wave\n curve = 4. * sin(.23 * uv.y);\n } else if (u_shape > 1.5) {\n // lines irregular\n curve = .5 + .5 * sin(.5 * uv.x) * sin(1.7 * uv.x);\n } else {\n // lines\n curve = .2 * gridNumber / u_imageAspectRatio;\n }\n\n vec2 uvOrig = uv;\n uv += curve;\n\n vec2 fractUV = fract(uv);\n vec2 floorUV = floor(uv);\n\n vec2 fractOrigUV = fract(uvOrig);\n vec2 floorOrigUV = floor(uvOrig);\n\n float highlights = smoothstep(.85, .95, fractUV.x);\n highlights *= mask;\n\n float xDistortion = 0.;\n if (u_distortionShape == 1.) {\n xDistortion = -pow(1.5 * fractUV.x, 3.) + (.5 + u_shift);\n } else if (u_distortionShape == 2.) {\n xDistortion = 2. * pow(fractUV.x, 2.) - (.5 + u_shift);\n } else if (u_distortionShape == 3.) {\n xDistortion = pow(2. * (fractUV.x - .5), 6.) + .5 - .5 + u_shift;\n } else if (u_distortionShape == 4.) {\n xDistortion = sin((fractUV.x + .25 + u_shift) * TWO_PI);\n xDistortion *= .5;\n } else if (u_distortionShape == 5.) {\n xDistortion += (.5 + u_shift);\n xDistortion -= pow(abs(fractUV.x), .2) * fractUV.x;\n xDistortion *= .33;\n }\n\n xDistortion *= 3. * u_distortion;\n\n uv = (floorOrigUV + fractOrigUV) / gridNumber;\n uv.x += xDistortion / gridNumber;\n uv += pow(stroke, 4.);\n uv.y = mix(uv.y, .0, .4 * u_highlights * highlights);\n \n uv = rotate(uv, -patternRotation) + vec2(.5);\n\n uv = mix(imageUV, uv, mask);\n float blur = mix(0., u_blur, mask);\n \n vec4 color = getBlur(u_image, uv, 1. / u_resolution / u_pixelRatio, vec2(0., 1.), blur);\n\n float opacity = color.a;\n fragColor = vec4(color.rgb, opacity);\n}\n`;\n\nexport interface FlutedGlassUniforms extends ShaderSizingUniforms {\n u_image: HTMLImageElement | string | undefined;\n u_count: number;\n u_angle: number;\n u_distortion: number;\n u_shift: number;\n u_blur: number;\n u_marginLeft: number;\n u_marginRight: number;\n u_marginTop: number;\n u_marginBottom: number;\n u_highlights: number;\n u_distortionShape: (typeof GlassDistortionShapes)[GlassDistortionShape];\n u_shape: (typeof GlassGridShapes)[GlassGridShape];\n u_noiseTexture?: HTMLImageElement;\n}\n\nexport interface FlutedGlassParams extends ShaderSizingParams, ShaderMotionParams {\n image?: HTMLImageElement | string | undefined;\n count?: number;\n angle?: number;\n distortion?: number;\n shift?: number;\n blur?: number;\n marginLeft?: number;\n marginRight?: number;\n marginTop?: number;\n marginBottom?: number;\n highlights?: number;\n distortionShape?: GlassDistortionShape;\n shape?: GlassGridShape;\n}\n\nexport const GlassGridShapes = {\n lines: 1,\n linesIrregular: 2,\n wave: 3,\n zigzag: 4,\n pattern: 5,\n} as const;\n\nexport const GlassDistortionShapes = {\n prism: 1,\n lens: 2,\n contour: 3,\n cascade: 4,\n facete: 5,\n} as const;\n\nexport type GlassDistortionShape = keyof typeof GlassDistortionShapes;\nexport type GlassGridShape = keyof typeof GlassGridShapes;\n"],
5
+ "mappings": ";;;;;AACA,SAAS,kCAAsF;AAC/F,SAAS,WAAW,iBAAiB;AA0B9B,MAAM,4BAAoC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuB/C,0BAA0B;AAAA;AAAA;AAAA;AAAA,EAI1B,SAAS;AAAA,EACT,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuKJ,MAAM,kBAAkB;AAAA,EAC7B,OAAO;AAAA,EACP,gBAAgB;AAAA,EAChB,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AACX;AAEO,MAAM,wBAAwB;AAAA,EACnC,OAAO;AAAA,EACP,MAAM;AAAA,EACN,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paper-design/shaders",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "license": "SEE LICENSE IN https://github.com/paper-design/shaders/blob/main/LICENSE",
5
5
  "type": "module",
6
6
  "sideEffects": false,