typegpu 0.11.8 → 0.12.0
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.
- package/builtin.d.ts +51 -53
- package/builtin.js +30 -34
- package/common/fullScreenTriangle.d.ts +2 -10
- package/common/fullScreenTriangle.js +20 -28
- package/common/index.d.ts +2 -9
- package/common/index.js +3 -12
- package/common/writeSoA.d.ts +11 -12
- package/common/writeSoA.js +88 -76
- package/core/buffer/buffer.d.ts +79 -62
- package/core/buffer/buffer.js +279 -205
- package/core/buffer/bufferBinding.d.ts +71 -0
- package/core/buffer/bufferBinding.js +154 -0
- package/core/buffer/bufferUsage.d.ts +14 -45
- package/core/buffer/bufferUsage.js +1 -171
- package/core/buffer/laidOutBuffer.d.ts +25 -0
- package/core/buffer/laidOutBuffer.js +55 -0
- package/core/commandEncoder/attachments.d.ts +125 -0
- package/core/commandEncoder/attachments.js +29 -0
- package/core/commandEncoder/commandEncoder.d.ts +53 -0
- package/core/commandEncoder/commandEncoder.js +56 -0
- package/core/commandEncoder/computePass.d.ts +58 -0
- package/core/commandEncoder/computePass.js +63 -0
- package/core/commandEncoder/renderPass.d.ts +121 -0
- package/core/commandEncoder/renderPass.js +196 -0
- package/core/constant/tgpuConstant.d.ts +26 -26
- package/core/constant/tgpuConstant.js +76 -65
- package/core/declare/tgpuDeclare.d.ts +3 -6
- package/core/declare/tgpuDeclare.js +37 -38
- package/core/function/autoIO.d.ts +61 -33
- package/core/function/autoIO.js +68 -73
- package/core/function/comptime.d.ts +11 -13
- package/core/function/comptime.js +60 -52
- package/core/function/createCallableSchema.d.ts +16 -0
- package/core/function/createCallableSchema.js +50 -40
- package/core/function/dualImpl.d.ts +44 -0
- package/core/function/dualImpl.js +71 -50
- package/core/function/entryInputRouter.d.ts +26 -0
- package/core/function/entryInputRouter.js +31 -33
- package/core/function/extractArgs.d.ts +38 -0
- package/core/function/extractArgs.js +202 -200
- package/core/function/fnCore.d.ts +44 -0
- package/core/function/fnCore.js +148 -92
- package/core/function/fnTypes.d.ts +31 -29
- package/core/function/fnTypes.js +1 -0
- package/core/function/ioSchema.d.ts +12 -10
- package/core/function/ioSchema.js +65 -47
- package/core/function/shelllessImpl.d.ts +9 -12
- package/core/function/shelllessImpl.js +18 -20
- package/core/function/templateUtils.d.ts +2 -0
- package/core/function/templateUtils.js +9 -8
- package/core/function/tgpuComputeFn.d.ts +26 -28
- package/core/function/tgpuComputeFn.js +47 -48
- package/core/function/tgpuFn.d.ts +34 -37
- package/core/function/tgpuFn.js +179 -153
- package/core/function/tgpuFragmentFn.d.ts +52 -53
- package/core/function/tgpuFragmentFn.js +63 -56
- package/core/function/tgpuVertexFn.d.ts +36 -39
- package/core/function/tgpuVertexFn.js +56 -53
- package/core/pipeline/computePipeline.d.ts +141 -53
- package/core/pipeline/computePipeline.js +291 -225
- package/core/pipeline/connectAttachmentToShader.d.ts +4 -0
- package/core/pipeline/connectAttachmentToShader.js +25 -22
- package/core/pipeline/connectTargetsToShader.d.ts +3 -0
- package/core/pipeline/connectTargetsToShader.js +29 -27
- package/core/pipeline/drawState.d.ts +52 -0
- package/core/pipeline/drawState.js +225 -0
- package/core/pipeline/limitsOverflow.d.ts +2 -0
- package/core/pipeline/limitsOverflow.js +13 -10
- package/core/pipeline/performanceTracker.d.ts +14 -0
- package/core/pipeline/performanceTracker.js +34 -0
- package/core/pipeline/pipelineUtils.d.ts +18 -0
- package/core/pipeline/pipelineUtils.js +54 -25
- package/core/pipeline/priors.d.ts +1 -0
- package/core/pipeline/priors.js +12 -0
- package/core/pipeline/renderPipeline.d.ts +246 -261
- package/core/pipeline/renderPipeline.js +487 -480
- package/core/pipeline/timeable.d.ts +28 -18
- package/core/pipeline/timeable.js +90 -52
- package/core/pipeline/typeGuards.d.ts +17 -0
- package/core/pipeline/typeGuards.js +52 -22
- package/core/querySet/querySet.d.ts +26 -21
- package/core/querySet/querySet.js +127 -103
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.d.ts +13 -18
- package/core/rawCodeSnippet/tgpuRawCodeSnippet.js +90 -93
- package/core/resolve/externals.d.ts +25 -7
- package/core/resolve/externals.js +79 -62
- package/core/resolve/namespace.d.ts +22 -25
- package/core/resolve/namespace.js +16 -21
- package/core/resolve/resolvableString.d.ts +7 -0
- package/core/resolve/resolvableString.js +13 -0
- package/core/resolve/resolveData.d.ts +10 -0
- package/core/resolve/resolveData.js +162 -121
- package/core/resolve/stitch.d.ts +8 -0
- package/core/resolve/stitch.js +23 -21
- package/core/resolve/tgpuResolve.d.ts +55 -53
- package/core/resolve/tgpuResolve.js +106 -55
- package/core/root/configurableImpl.d.ts +10 -0
- package/core/root/configurableImpl.js +17 -19
- package/core/root/init.d.ts +76 -38
- package/core/root/init.js +346 -454
- package/core/root/rootTypes.d.ts +461 -627
- package/core/root/rootTypes.js +1 -0
- package/core/sampler/sampler.d.ts +50 -31
- package/core/sampler/sampler.js +120 -113
- package/core/simulate/tgpuSimulate.d.ts +9 -12
- package/core/simulate/tgpuSimulate.js +68 -71
- package/core/slot/accessor.d.ts +36 -13
- package/core/slot/accessor.js +138 -91
- package/core/slot/internalSlots.d.ts +2 -0
- package/core/slot/internalSlots.js +1 -6
- package/core/slot/lazy.d.ts +2 -6
- package/core/slot/lazy.js +71 -39
- package/core/slot/slot.d.ts +2 -6
- package/core/slot/slot.js +45 -38
- package/core/slot/slotTypes.d.ts +78 -80
- package/core/slot/slotTypes.js +11 -16
- package/core/texture/externalTexture.d.ts +20 -11
- package/core/texture/externalTexture.js +46 -46
- package/core/texture/texture.d.ts +152 -97
- package/core/texture/texture.js +407 -314
- package/core/texture/textureFormats.d.ts +42 -23
- package/core/texture/textureFormats.js +104 -75
- package/core/texture/textureProps.d.ts +7 -10
- package/core/texture/textureProps.js +1 -0
- package/core/texture/textureUtils.d.ts +8 -0
- package/core/texture/textureUtils.js +185 -179
- package/core/texture/usageExtension.d.ts +21 -18
- package/core/texture/usageExtension.js +13 -17
- package/core/unroll/tgpuUnroll.d.ts +20 -19
- package/core/unroll/tgpuUnroll.js +82 -91
- package/core/valueProxyUtils.d.ts +3 -0
- package/core/valueProxyUtils.js +52 -41
- package/core/variable/tgpuVariable.d.ts +26 -27
- package/core/variable/tgpuVariable.js +93 -96
- package/core/vertexLayout/connectAttributesToShader.d.ts +9 -0
- package/core/vertexLayout/connectAttributesToShader.js +61 -56
- package/core/vertexLayout/vertexAttribute.d.ts +21 -17
- package/core/vertexLayout/vertexAttribute.js +1 -0
- package/core/vertexLayout/vertexLayout.d.ts +24 -18
- package/core/vertexLayout/vertexLayout.js +130 -99
- package/core/whitespaces.d.ts +2 -0
- package/core/whitespaces.js +16 -0
- package/data/alignIO.d.ts +7 -0
- package/data/alignIO.js +13 -13
- package/data/alignmentOf.d.ts +5 -8
- package/data/alignmentOf.js +90 -75
- package/data/array.d.ts +6 -9
- package/data/array.js +48 -40
- package/data/atomic.d.ts +2 -7
- package/data/atomic.js +26 -23
- package/data/attributes.d.ts +19 -21
- package/data/attributes.js +192 -132
- package/data/autoStruct.d.ts +36 -3
- package/data/autoStruct.js +84 -81
- package/data/compiledIO.d.ts +5 -0
- package/data/compiledIO.js +231 -214
- package/data/dataIO.d.ts +13 -11
- package/data/dataIO.js +643 -589
- package/data/dataTypes.d.ts +83 -65
- package/data/dataTypes.js +66 -68
- package/data/deepEqual.d.ts +2 -7
- package/data/deepEqual.js +80 -55
- package/data/disarray.d.ts +6 -10
- package/data/disarray.js +52 -46
- package/data/float16Conversion.d.ts +4 -0
- package/data/float16Conversion.js +7 -0
- package/data/getLongestContiguousPrefix.d.ts +4 -8
- package/data/getLongestContiguousPrefix.js +6 -11
- package/data/index.d.ts +30 -31
- package/data/index.js +39 -172
- package/data/instanceToSchema.d.ts +24 -27
- package/data/instanceToSchema.js +1 -0
- package/data/isContiguous.d.ts +4 -8
- package/data/isContiguous.js +6 -11
- package/data/matrix.d.ts +21 -21
- package/data/matrix.js +513 -505
- package/data/numberOps.d.ts +6 -0
- package/data/numberOps.js +26 -20
- package/data/numeric.d.ts +21 -12
- package/data/numeric.js +287 -192
- package/data/offsetUtils.d.ts +9 -13
- package/data/offsetUtils.js +204 -144
- package/data/offsets.d.ts +8 -0
- package/data/offsets.js +33 -33
- package/data/partialIO.d.ts +13 -8
- package/data/partialIO.js +124 -113
- package/data/ptr.d.ts +12 -12
- package/data/ptr.js +42 -44
- package/data/ref.d.ts +40 -27
- package/data/ref.js +125 -95
- package/data/sampler.d.ts +99 -101
- package/data/sampler.js +17 -21
- package/data/schemaCallWrapper.d.ts +19 -0
- package/data/schemaCallWrapper.js +31 -26
- package/data/schemaMemoryLayout.d.ts +8 -0
- package/data/schemaMemoryLayout.js +213 -185
- package/data/sizeOf.d.ts +4 -8
- package/data/sizeOf.js +6 -11
- package/data/snippet.d.ts +96 -20
- package/data/snippet.js +75 -86
- package/data/struct.d.ts +4 -7
- package/data/struct.js +51 -39
- package/data/texture.d.ts +253 -250
- package/data/texture.js +238 -200
- package/data/unstruct.d.ts +2 -7
- package/data/unstruct.js +43 -37
- package/data/vector.d.ts +33 -21
- package/data/vector.js +234 -221
- package/data/vectorImpl.d.ts +231 -0
- package/data/vectorImpl.js +563 -515
- package/data/vectorOps.d.ts +63 -0
- package/data/vectorOps.js +642 -630
- package/data/vertexFormatData.d.ts +181 -184
- package/data/vertexFormatData.js +104 -106
- package/data/wgslTypes.d.ts +665 -600
- package/data/wgslTypes.js +220 -198
- package/errors.d.ts +50 -24
- package/errors.js +146 -120
- package/execMode.d.ts +16 -0
- package/execMode.js +47 -40
- package/extension.d.ts +13 -8
- package/extension.js +10 -16
- package/getGPUValue.d.ts +1 -0
- package/getGPUValue.js +2 -7
- package/index.d.ts +28 -68
- package/index.js +8 -28
- package/indexNamedExports.d.ts +69 -42
- package/indexNamedExports.js +25 -0
- package/internal.d.ts +16 -0
- package/internal.js +12 -0
- package/mathUtils.d.ts +5 -0
- package/mathUtils.js +7 -11
- package/memo.d.ts +11 -0
- package/memo.js +20 -22
- package/minify.d.ts +5 -0
- package/minify.js +93 -0
- package/nameUtils.d.ts +29 -0
- package/nameUtils.js +428 -398
- package/package.json +9 -3
- package/resolutionCtx.d.ts +162 -22
- package/resolutionCtx.js +911 -624
- package/serial/registry.d.ts +15 -0
- package/serial/registry.js +106 -0
- package/serial/restore.d.ts +49 -0
- package/serial/restore.js +68 -0
- package/serial/schema.d.ts +58 -0
- package/serial/schema.js +209 -0
- package/serial/types.d.ts +5 -0
- package/serial/types.js +1 -0
- package/shared/env.d.ts +9 -0
- package/shared/env.js +9 -12
- package/shared/generators.d.ts +4 -0
- package/shared/generators.js +10 -12
- package/shared/meta.d.ts +29 -14
- package/shared/meta.js +71 -55
- package/shared/normalizeMetadata.d.ts +32 -27
- package/shared/normalizeMetadata.js +23 -36
- package/shared/repr.d.ts +73 -55
- package/shared/repr.js +1 -0
- package/shared/soul.d.ts +17 -0
- package/shared/soul.js +1 -0
- package/shared/stringify.d.ts +2 -0
- package/shared/stringify.js +29 -20
- package/shared/symbols.d.ts +26 -20
- package/shared/symbols.js +79 -79
- package/shared/tseynit.d.ts +2 -0
- package/shared/tseynit.js +160 -75
- package/shared/utilityTypes.d.ts +30 -14
- package/shared/utilityTypes.js +2 -6
- package/shared/vertexFormat.d.ts +41 -43
- package/shared/vertexFormat.js +59 -62
- package/std/array.d.ts +2 -7
- package/std/array.js +18 -23
- package/std/atomic.d.ts +14 -18
- package/std/atomic.js +96 -95
- package/std/bitcast.d.ts +193 -10
- package/std/bitcast.js +309 -39
- package/std/boolean.d.ts +19 -33
- package/std/boolean.js +296 -288
- package/std/copy.d.ts +2 -7
- package/std/copy.js +27 -24
- package/std/derivative.d.ts +11 -15
- package/std/derivative.js +56 -79
- package/std/discard.d.ts +1 -6
- package/std/discard.js +7 -14
- package/std/environment.d.ts +19 -14
- package/std/environment.js +71 -51
- package/std/extensions.d.ts +2 -8
- package/std/extensions.js +10 -11
- package/std/index.d.ts +20 -24
- package/std/index.js +32 -187
- package/std/matrix.d.ts +6 -12
- package/std/matrix.js +60 -69
- package/std/numeric.d.ts +143 -146
- package/std/numeric.js +858 -749
- package/std/operators.d.ts +19 -27
- package/std/operators.js +227 -193
- package/std/packing.d.ts +5 -11
- package/std/packing.js +67 -75
- package/std/range.d.ts +6 -11
- package/std/range.js +48 -36
- package/std/subgroup.d.ts +33 -37
- package/std/subgroup.js +180 -217
- package/std/texture.d.ts +70 -38
- package/std/texture.js +176 -172
- package/taskQueue.d.ts +6 -0
- package/taskQueue.js +30 -0
- package/tgpu.d.ts +16 -0
- package/tgpu.js +17 -44
- package/tgpuBindGroupLayout.d.ts +132 -152
- package/tgpuBindGroupLayout.js +346 -268
- package/tgpuLogger.d.ts +34 -0
- package/tgpuLogger.js +63 -0
- package/tgpuUnstable.d.ts +16 -22
- package/tgpuUnstable.js +13 -35
- package/tgsl/accessIndex.d.ts +2 -0
- package/tgsl/accessIndex.js +76 -33
- package/tgsl/accessProp.d.ts +2 -0
- package/tgsl/accessProp.js +142 -100
- package/tgsl/accessStructProp.d.ts +5 -0
- package/tgsl/accessStructProp.js +18 -0
- package/tgsl/consoleLog/deserializers.d.ts +13 -0
- package/tgsl/consoleLog/deserializers.js +119 -103
- package/tgsl/consoleLog/logGenerator.d.ts +21 -0
- package/tgsl/consoleLog/logGenerator.js +85 -80
- package/tgsl/consoleLog/serializers.d.ts +21 -0
- package/tgsl/consoleLog/serializers.js +119 -100
- package/tgsl/consoleLog/types.d.ts +40 -39
- package/tgsl/consoleLog/types.js +1 -0
- package/tgsl/conversion.d.ts +33 -0
- package/tgsl/conversion.js +272 -193
- package/tgsl/forOfUtils.d.ts +15 -0
- package/tgsl/forOfUtils.js +85 -70
- package/tgsl/generationHelpers.d.ts +22 -39
- package/tgsl/generationHelpers.js +85 -58
- package/tgsl/infixDispatch.d.ts +70 -0
- package/tgsl/infixDispatch.js +48 -46
- package/tgsl/jsPolyfills.d.ts +16 -19
- package/tgsl/jsPolyfills.js +44 -42
- package/tgsl/makeDereferenceable.d.ts +48 -0
- package/tgsl/makeDereferenceable.js +86 -0
- package/tgsl/makeResolvable.d.ts +22 -0
- package/tgsl/makeResolvable.js +33 -0
- package/tgsl/shaderGenerator.d.ts +77 -17
- package/tgsl/shaderGenerator.js +1 -0
- package/tgsl/shellless.d.ts +6 -9
- package/tgsl/shellless.js +73 -43
- package/tgsl/wgslGenerator.d.ts +66 -59
- package/tgsl/wgslGenerator.js +1344 -747
- package/types.d.ts +287 -221
- package/types.js +61 -44
- package/unwrapper.d.ts +31 -26
- package/unwrapper.js +1 -0
- package/wgslExtensions.d.ts +3 -5
- package/wgslExtensions.js +12 -16
- package/_virtual/rolldown_runtime.js +0 -13
- package/core/buffer/bufferShorthand.d.ts +0 -50
- package/core/buffer/bufferShorthand.js +0 -55
- package/core/pipeline/applyPipelineState.js +0 -37
- package/package.js +0 -5
- package/tgsl/shaderGenerator_members.d.ts +0 -33
- package/tgsl/shaderGenerator_members.js +0 -12
package/core/function/fnCore.js
CHANGED
|
@@ -1,101 +1,157 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Void, isWgslData, isWgslStruct } from "../../data/wgslTypes.js";
|
|
3
|
-
import { getFunctionMetadata, getName } from "../../shared/meta.js";
|
|
1
|
+
import { getAttributesString } from "../../data/attributes.js";
|
|
4
2
|
import { undecorate } from "../../data/dataTypes.js";
|
|
5
3
|
import { snip } from "../../data/snippet.js";
|
|
6
|
-
import {
|
|
4
|
+
import { isWgslData, isWgslStruct, Void } from "../../data/wgslTypes.js";
|
|
7
5
|
import { validateIdentifier } from "../../nameUtils.js";
|
|
8
|
-
import {
|
|
6
|
+
import { getFunctionMetadata, getName } from "../../shared/meta.js";
|
|
7
|
+
import { $getNameForward } from "../../shared/symbols.js";
|
|
8
|
+
import { replaceExternalsInWgsl, mergeFunctionExternals, } from "../resolve/externals.js";
|
|
9
|
+
import { ResolvableString } from "../resolve/resolvableString.js";
|
|
9
10
|
import { extractArgs } from "./extractArgs.js";
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
11
|
+
export function createFnCore(implementation, functionType, workgroupSize) {
|
|
12
|
+
/**
|
|
13
|
+
* External application has to be deferred until resolution because
|
|
14
|
+
* some externals can reference the owner function which has not been
|
|
15
|
+
* initialized yet (like when accessing the Output struct of a vertex
|
|
16
|
+
* entry fn).
|
|
17
|
+
*/
|
|
18
|
+
const externals = {};
|
|
19
|
+
const core = {
|
|
20
|
+
// Making the implementation the holder of the name, as long as it's
|
|
21
|
+
// a function (and not a string implementation)
|
|
22
|
+
[$getNameForward]: typeof implementation === 'function' ? implementation : undefined,
|
|
23
|
+
setExternals(key, newExternal) {
|
|
24
|
+
if (key === 'userProvided' && 'userProvided' in externals) {
|
|
25
|
+
throw new Error("Cannot call '$uses' multiple times. If you wish to override dependencies, use slots or accessors instead.");
|
|
26
|
+
}
|
|
27
|
+
externals[key] = newExternal;
|
|
28
|
+
if (externals.userProvided && externals.pluginProvided) {
|
|
29
|
+
throw new Error("Cannot call '$uses' on functions whose metadata was provided by unplugin-typegpu.");
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
resolve(ctx, argTypes, returnType, entryInput) {
|
|
33
|
+
let attributes = '';
|
|
34
|
+
if (functionType === 'compute') {
|
|
35
|
+
attributes = `@compute @workgroup_size(${workgroupSize?.join(', ')}) `;
|
|
36
|
+
}
|
|
37
|
+
else if (functionType === 'vertex') {
|
|
38
|
+
attributes = `@vertex `;
|
|
39
|
+
}
|
|
40
|
+
else if (functionType === 'fragment') {
|
|
41
|
+
attributes = `@fragment `;
|
|
42
|
+
}
|
|
43
|
+
const id = ctx.makeUniqueIdentifier(getName(this), 'global');
|
|
44
|
+
if (typeof implementation === 'string') {
|
|
45
|
+
if (!returnType) {
|
|
46
|
+
throw new Error('Explicit return type is required for string implementation');
|
|
47
|
+
}
|
|
48
|
+
if (entryInput) {
|
|
49
|
+
for (const arg of entryInput.positionalArgs) {
|
|
50
|
+
const result = validateIdentifier(arg.schemaKey);
|
|
51
|
+
if (!result.success) {
|
|
52
|
+
throw new Error(`Invalid argument name "${arg.schemaKey}"${result.error ? `: ${result.error}` : ''}`);
|
|
53
|
+
}
|
|
54
|
+
if (ctx.isIdentifierBanned(arg.schemaKey)) {
|
|
55
|
+
throw new Error(`Invalid argument name "${arg.schemaKey}", the identifier is a reserved keyword.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
this.setExternals('args', {
|
|
59
|
+
in: Object.fromEntries(entryInput.positionalArgs.map((a) => [
|
|
60
|
+
a.schemaKey,
|
|
61
|
+
new ResolvableString(a.schemaKey),
|
|
62
|
+
])),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const replacedImpl = replaceExternalsInWgsl(ctx, mergeFunctionExternals(externals), implementation);
|
|
66
|
+
let header = '';
|
|
67
|
+
let body = '';
|
|
68
|
+
if (functionType !== 'normal' && entryInput) {
|
|
69
|
+
const { dataSchema, positionalArgs } = entryInput;
|
|
70
|
+
const parts = [];
|
|
71
|
+
if (dataSchema && isArgUsedInBody('in', replacedImpl)) {
|
|
72
|
+
parts.push(`in: ${ctx.resolve(dataSchema).value}`);
|
|
73
|
+
}
|
|
74
|
+
for (const a of positionalArgs) {
|
|
75
|
+
const argName = a.schemaKey;
|
|
76
|
+
if (isArgUsedInBody(argName, replacedImpl)) {
|
|
77
|
+
parts.push(`${getAttributesString(a.type)}${argName}: ${ctx.resolve(a.type).value}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const input = `(${parts.join(', ')})`;
|
|
81
|
+
const attributes = isWgslData(returnType) ? getAttributesString(returnType) : '';
|
|
82
|
+
const output = returnType !== Void
|
|
83
|
+
? isWgslStruct(returnType)
|
|
84
|
+
? ` -> ${ctx.resolve(returnType).value} `
|
|
85
|
+
: ` -> ${attributes !== '' ? attributes : '@location(0)'} ${ctx.resolve(returnType).value} `
|
|
86
|
+
: ' ';
|
|
87
|
+
header = `${input}${output}`;
|
|
88
|
+
body = replacedImpl;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const providedArgs = extractArgs(replacedImpl);
|
|
92
|
+
if (providedArgs.args.length !== argTypes.length) {
|
|
93
|
+
throw new Error(`WGSL implementation has ${providedArgs.args.length} arguments, while the shell has ${argTypes.length} arguments.`);
|
|
94
|
+
}
|
|
95
|
+
const input = providedArgs.args
|
|
96
|
+
.map((argInfo, i) => `${argInfo.identifier}: ${checkAndReturnType(ctx, `parameter ${argInfo.identifier}`, argInfo.type, argTypes[i])}`)
|
|
97
|
+
.join(', ');
|
|
98
|
+
const output = returnType === Void
|
|
99
|
+
? ' '
|
|
100
|
+
: ` -> ${checkAndReturnType(ctx, 'return type', providedArgs.ret?.type, returnType)} `;
|
|
101
|
+
header = `(${input})${output}`;
|
|
102
|
+
body = replacedImpl.slice(providedArgs.range.end);
|
|
103
|
+
}
|
|
104
|
+
ctx.addDeclaration(`${attributes}fn ${id}${header}${body}`, id);
|
|
105
|
+
return snip(id, returnType, /* origin */ 'runtime');
|
|
106
|
+
}
|
|
107
|
+
// get data generated by the plugin
|
|
108
|
+
const pluginData = getFunctionMetadata(implementation);
|
|
109
|
+
const pluginExternals = pluginData?.externals();
|
|
110
|
+
if (pluginExternals) {
|
|
111
|
+
this.setExternals('pluginProvided', pluginExternals);
|
|
112
|
+
}
|
|
113
|
+
const ast = pluginData?.ast;
|
|
114
|
+
if (!ast) {
|
|
115
|
+
throw new Error("Missing metadata for tgpu.fn function body (either missing 'use gpu' directive, or misconfigured `unplugin-typegpu`)");
|
|
116
|
+
}
|
|
117
|
+
// If an entrypoint implementation has a second argument, it represents the output schema.
|
|
118
|
+
// We look at the identifier chosen by the user and add it to externals.
|
|
119
|
+
const maybeSecondArg = ast.params[1];
|
|
120
|
+
if (maybeSecondArg && maybeSecondArg.type === 'i' && functionType !== 'normal') {
|
|
121
|
+
this.setExternals('out', {
|
|
122
|
+
// oxlint-disable-next-line typescript/no-non-null-assertion -- entry functions cannot be shellless
|
|
123
|
+
[maybeSecondArg.name]: undecorate(returnType),
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// generate wgsl string
|
|
127
|
+
const { code, returnType: actualReturnType } = ctx.resolveFunction({
|
|
128
|
+
functionType,
|
|
129
|
+
name: id,
|
|
130
|
+
workgroupSize,
|
|
131
|
+
argTypes,
|
|
132
|
+
entryInput,
|
|
133
|
+
params: ast.params,
|
|
134
|
+
returnType,
|
|
135
|
+
body: ast.body,
|
|
136
|
+
externalMap: mergeFunctionExternals(externals),
|
|
137
|
+
});
|
|
138
|
+
ctx.addDeclaration(code, id);
|
|
139
|
+
return snip(id, actualReturnType, /* origin */ 'runtime');
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
return core;
|
|
88
143
|
}
|
|
89
144
|
function isArgUsedInBody(argName, body) {
|
|
90
|
-
|
|
145
|
+
return new RegExp(`\\b${argName}\\b`).test(body);
|
|
91
146
|
}
|
|
92
147
|
function checkAndReturnType(ctx, name, wgslType, jsType) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
148
|
+
const resolvedJsType = ctx.resolve(jsType).value.replace(/\s/g, '');
|
|
149
|
+
if (!wgslType) {
|
|
150
|
+
return resolvedJsType;
|
|
151
|
+
}
|
|
152
|
+
const resolvedWgslType = wgslType.replace(/\s/g, '');
|
|
153
|
+
if (resolvedWgslType !== resolvedJsType) {
|
|
154
|
+
throw new Error(`Type mismatch between TGPU shell and WGSL code string: ${name}, JS type "${resolvedJsType}", WGSL type "${resolvedWgslType}".`);
|
|
155
|
+
}
|
|
156
|
+
return wgslType;
|
|
98
157
|
}
|
|
99
|
-
|
|
100
|
-
//#endregion
|
|
101
|
-
export { createFnCore };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { BuiltinClipDistances } from
|
|
2
|
-
import { AnyAttribute } from
|
|
3
|
-
import { BaseData, Bool, Decorated, F16, F32, I32, U32, Vec2f, Vec2h, Vec2i, Vec2u, Vec3f, Vec3h, Vec3i, Vec3u, Vec4f, Vec4h, Vec4i, Vec4u, Void } from
|
|
4
|
-
import { InferGPU } from
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
type
|
|
10
|
-
|
|
1
|
+
import type { BuiltinClipDistances } from '../../builtin.ts';
|
|
2
|
+
import type { AnyAttribute } from '../../data/attributes.ts';
|
|
3
|
+
import type { BaseData, Bool, Decorated, F16, F32, I32, U32, Vec2f, Vec2h, Vec2i, Vec2u, Vec3f, Vec3h, Vec3i, Vec3u, Vec4f, Vec4h, Vec4i, Vec4u, Void } from '../../data/wgslTypes.ts';
|
|
4
|
+
import type { InferGPU } from '../../shared/repr.ts';
|
|
5
|
+
export type AnyFn = (...args: never[]) => unknown;
|
|
6
|
+
export type InferArgs<T extends unknown[]> = {
|
|
7
|
+
[Idx in keyof T]: InferGPU<T[Idx]>;
|
|
8
|
+
};
|
|
9
|
+
type InheritTupleValues<T, From> = {
|
|
10
|
+
[K in keyof T]: K extends keyof From ? From[K] : never;
|
|
11
|
+
};
|
|
11
12
|
/**
|
|
12
13
|
* Returns a type that has arg and return types of `T`, but argument
|
|
13
14
|
* names of `From`
|
|
@@ -15,28 +16,29 @@ type InheritTupleValues<T, From> = { [K in keyof T]: K extends keyof From ? From
|
|
|
15
16
|
* Wrapped in an object type with `result` prop just so that it's easier
|
|
16
17
|
* to remove InheritArgNames<...> from Intellisense with Prettify<T>['result']
|
|
17
18
|
*/
|
|
18
|
-
type InheritArgNames<T extends AnyFn, From extends AnyFn> = {
|
|
19
|
-
|
|
19
|
+
export type InheritArgNames<T extends AnyFn, From extends AnyFn> = {
|
|
20
|
+
result: (...args: Parameters<((...args: InheritTupleValues<Parameters<From>, Parameters<T>>) => ReturnType<T>) & T>) => ReturnType<T>;
|
|
20
21
|
};
|
|
21
|
-
type InferImplSchema<ImplSchema extends AnyFn> = (...args: InferArgs<Parameters<ImplSchema>>) => InferGPU<ReturnType<ImplSchema>>;
|
|
22
|
-
type Implementation<ImplSchema extends AnyFn = AnyFn> = string | InferImplSchema<ImplSchema>;
|
|
23
|
-
type BaseIOData = Bool | F32 | F16 | I32 | U32 | Vec2f | Vec3f | Vec4f | Vec2h | Vec3h | Vec4h | Vec2i | Vec3i | Vec4i | Vec2u | Vec3u | Vec4u;
|
|
24
|
-
type IOData = BaseIOData | Decorated<BaseIOData, AnyAttribute[]> | BuiltinClipDistances;
|
|
25
|
-
type IORecord<TElementType extends IOData = IOData> = Record<string, TElementType>;
|
|
22
|
+
export type InferImplSchema<ImplSchema extends AnyFn> = (...args: InferArgs<Parameters<ImplSchema>>) => InferGPU<ReturnType<ImplSchema>>;
|
|
23
|
+
export type Implementation<ImplSchema extends AnyFn = AnyFn> = string | InferImplSchema<ImplSchema>;
|
|
24
|
+
export type BaseIOData = Bool | F32 | F16 | I32 | U32 | Vec2f | Vec3f | Vec4f | Vec2h | Vec3h | Vec4h | Vec2i | Vec3i | Vec4i | Vec2u | Vec3u | Vec4u;
|
|
25
|
+
export type IOData = BaseIOData | Decorated<BaseIOData, AnyAttribute[]> | BuiltinClipDistances;
|
|
26
|
+
export type IORecord<TElementType extends IOData = IOData> = Record<string, TElementType>;
|
|
26
27
|
/**
|
|
27
28
|
* Used for I/O definitions of entry functions.
|
|
28
29
|
*/
|
|
29
|
-
type IOLayout<TElementType extends IOData = IOData> = TElementType | IORecord<TElementType> | Void;
|
|
30
|
-
type InferIO<T> = T extends {
|
|
31
|
-
|
|
32
|
-
} ? InferGPU<T> : T extends Record<string, unknown> ? {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
30
|
+
export type IOLayout<TElementType extends IOData = IOData> = TElementType | IORecord<TElementType> | Void;
|
|
31
|
+
export type InferIO<T> = T extends {
|
|
32
|
+
type: string;
|
|
33
|
+
} ? InferGPU<T> : T extends Record<string, unknown> ? {
|
|
34
|
+
[K in keyof T]: InferGPU<T[K]>;
|
|
35
|
+
} : T;
|
|
36
|
+
export interface PositionalArgInfo {
|
|
37
|
+
schemaKey: string;
|
|
38
|
+
type: BaseData;
|
|
36
39
|
}
|
|
37
|
-
interface SeparatedEntryArgs {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
export interface SeparatedEntryArgs {
|
|
41
|
+
dataSchema: BaseData | undefined;
|
|
42
|
+
positionalArgs: PositionalArgInfo[];
|
|
40
43
|
}
|
|
41
|
-
|
|
42
|
-
export { AnyFn, BaseIOData, IOLayout, IORecord, Implementation, InferArgs, InferIO, InferImplSchema, InheritArgNames, SeparatedEntryArgs };
|
|
44
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import { Decorate, HasCustomLocation, IsBuiltin } from
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
type IOLayoutToSchema<T> = T extends BaseData ? HasCustomLocation<T> extends true ? T : Decorate<T, Location<0>> : T extends Record<string, BaseData> ? WgslStruct<WithLocations<T>> : T extends {
|
|
8
|
-
|
|
1
|
+
import { type Decorate, type HasCustomLocation, type IsBuiltin } from '../../data/attributes.ts';
|
|
2
|
+
import { type BaseData, type Location, type WgslStruct } from '../../data/wgslTypes.ts';
|
|
3
|
+
import type { SeparatedEntryArgs } from './fnTypes.ts';
|
|
4
|
+
export type WithLocations<T extends Record<string, BaseData>> = {
|
|
5
|
+
[Key in keyof T]: IsBuiltin<T[Key]> extends true ? T[Key] : HasCustomLocation<T[Key]> extends true ? T[Key] : Decorate<T[Key], Location>;
|
|
6
|
+
};
|
|
7
|
+
export type IOLayoutToSchema<T> = T extends BaseData ? HasCustomLocation<T> extends true ? T : Decorate<T, Location<0>> : T extends Record<string, BaseData> ? WgslStruct<WithLocations<T>> : T extends {
|
|
8
|
+
type: 'void';
|
|
9
9
|
} ? void : never;
|
|
10
|
-
|
|
11
|
-
export
|
|
10
|
+
export declare function withLocations<T extends BaseData>(members: Record<string, T> | undefined, locations?: Record<string, number>): Record<string, BaseData>;
|
|
11
|
+
export declare function separateBuiltins(schema: Record<string, BaseData>, locations?: Record<string, number>): SeparatedEntryArgs;
|
|
12
|
+
export declare function separateAllAsPositional(schema: Record<string, BaseData>): SeparatedEntryArgs;
|
|
13
|
+
export declare function createIoSchema<T extends BaseData | Record<string, BaseData>>(layout: T, locations?: Record<string, number>): IOLayoutToSchema<T>;
|
|
@@ -1,53 +1,71 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { location, } from "../../data/attributes.js";
|
|
2
|
+
import { isBuiltin } from "../../data/attributes.js";
|
|
2
3
|
import { getCustomLocation, isData } from "../../data/dataTypes.js";
|
|
3
|
-
import { isBuiltin, location } from "../../data/attributes.js";
|
|
4
4
|
import { INTERNAL_createStruct } from "../../data/struct.js";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
import { isVoid } from "../../data/wgslTypes.js";
|
|
6
|
+
export function withLocations(members, locations = {}) {
|
|
7
|
+
let nextLocation = 0;
|
|
8
|
+
const usedCustomLocations = new Set();
|
|
9
|
+
return Object.fromEntries(Object.entries(members ?? {})
|
|
10
|
+
.map(([key, member]) => {
|
|
11
|
+
const customLocation = getCustomLocation(member);
|
|
12
|
+
if (customLocation !== undefined) {
|
|
13
|
+
if (usedCustomLocations.has(customLocation)) {
|
|
14
|
+
throw new Error('Duplicate custom location attributes found');
|
|
15
|
+
}
|
|
16
|
+
usedCustomLocations.add(customLocation);
|
|
17
|
+
}
|
|
18
|
+
return [key, member];
|
|
19
|
+
})
|
|
20
|
+
.map(([key, member]) => {
|
|
21
|
+
if (isBuiltin(member)) {
|
|
22
|
+
// skipping builtins
|
|
23
|
+
return [key, member];
|
|
24
|
+
}
|
|
25
|
+
if (getCustomLocation(member) !== undefined) {
|
|
26
|
+
// this member is already marked
|
|
27
|
+
return [key, member];
|
|
28
|
+
}
|
|
29
|
+
if (locations[key]) {
|
|
30
|
+
// location has been determined by a previous procedure
|
|
31
|
+
return [key, location(locations[key], member)];
|
|
32
|
+
}
|
|
33
|
+
while (usedCustomLocations.has(nextLocation)) {
|
|
34
|
+
nextLocation++;
|
|
35
|
+
}
|
|
36
|
+
return [key, location(nextLocation++, member)];
|
|
37
|
+
}));
|
|
24
38
|
}
|
|
25
|
-
function separateBuiltins(schema, locations = {}) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
export function separateBuiltins(schema, locations = {}) {
|
|
40
|
+
const positionalArgs = [];
|
|
41
|
+
const dataFields = {};
|
|
42
|
+
for (const [key, type] of Object.entries(schema)) {
|
|
43
|
+
if (isBuiltin(type)) {
|
|
44
|
+
positionalArgs.push({ schemaKey: key, type });
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
dataFields[key] = type;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const dataSchema = Object.keys(dataFields).length > 0
|
|
51
|
+
? INTERNAL_createStruct(withLocations(dataFields, locations), /* isAbstruct */ false)
|
|
52
|
+
: undefined;
|
|
53
|
+
return { dataSchema, positionalArgs };
|
|
37
54
|
}
|
|
38
|
-
function separateAllAsPositional(schema) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
positionalArgs: Object.entries(withLocs).map(([key, type]) => ({
|
|
43
|
-
schemaKey: key,
|
|
44
|
-
type
|
|
45
|
-
}))
|
|
46
|
-
};
|
|
55
|
+
export function separateAllAsPositional(schema) {
|
|
56
|
+
const withLocs = withLocations(schema);
|
|
57
|
+
const positionalArgs = Object.entries(withLocs).map(([key, type]) => ({ schemaKey: key, type }));
|
|
58
|
+
return { dataSchema: undefined, positionalArgs };
|
|
47
59
|
}
|
|
48
|
-
function createIoSchema(layout, locations = {}) {
|
|
49
|
-
|
|
60
|
+
export function createIoSchema(layout, locations = {}) {
|
|
61
|
+
return (isData(layout)
|
|
62
|
+
? isVoid(layout)
|
|
63
|
+
? layout
|
|
64
|
+
: isBuiltin(layout)
|
|
65
|
+
? layout
|
|
66
|
+
: getCustomLocation(layout) !== undefined
|
|
67
|
+
? layout
|
|
68
|
+
: location(0, layout)
|
|
69
|
+
: INTERNAL_createStruct(withLocations(layout, locations),
|
|
70
|
+
/* isAbstruct */ false));
|
|
50
71
|
}
|
|
51
|
-
|
|
52
|
-
//#endregion
|
|
53
|
-
export { createIoSchema, separateAllAsPositional, separateBuiltins };
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
//#region src/core/function/shelllessImpl.d.ts
|
|
6
|
-
|
|
1
|
+
import type { BaseData } from '../../data/wgslTypes.ts';
|
|
2
|
+
import { $getNameForward } from '../../shared/symbols.ts';
|
|
3
|
+
import type { SelfResolvable } from '../../types.ts';
|
|
7
4
|
/**
|
|
8
5
|
* Shell-less functions are possible because we can infer the signature based solely on the context
|
|
9
6
|
* around the function.
|
|
@@ -20,10 +17,10 @@ import { BaseData } from "../../data/wgslTypes.js";
|
|
|
20
17
|
*
|
|
21
18
|
* TODO: This behavior can be refined by considering the "expected type" of the function call expression.
|
|
22
19
|
*/
|
|
23
|
-
interface ShelllessImpl extends SelfResolvable {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
export interface ShelllessImpl extends SelfResolvable {
|
|
21
|
+
readonly resourceType: 'shellless-impl';
|
|
22
|
+
readonly argTypes: BaseData[];
|
|
23
|
+
readonly [$getNameForward]: unknown;
|
|
27
24
|
}
|
|
28
|
-
|
|
29
|
-
export
|
|
25
|
+
export declare function isShelllessImpl(value: unknown): value is ShelllessImpl;
|
|
26
|
+
export declare function createShelllessImpl(argTypes: BaseData[], implementation: (...args: never[]) => unknown): ShelllessImpl;
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
-
import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
|
|
2
1
|
import { getName } from "../../shared/meta.js";
|
|
2
|
+
import { $getNameForward, $internal, $resolve } from "../../shared/symbols.js";
|
|
3
3
|
import { createFnCore } from "./fnCore.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
4
|
+
export function isShelllessImpl(value) {
|
|
5
|
+
return value?.resourceType === 'shellless-impl';
|
|
6
|
+
}
|
|
7
|
+
export function createShelllessImpl(argTypes, implementation) {
|
|
8
|
+
const core = createFnCore(implementation, 'normal');
|
|
9
|
+
return {
|
|
10
|
+
[$internal]: true,
|
|
11
|
+
[$getNameForward]: core,
|
|
12
|
+
resourceType: 'shellless-impl',
|
|
13
|
+
argTypes,
|
|
14
|
+
[$resolve](ctx) {
|
|
15
|
+
return core.resolve(ctx, argTypes, undefined);
|
|
16
|
+
},
|
|
17
|
+
toString() {
|
|
18
|
+
return `fn*:${getName(core) ?? '<unnamed>'}(${argTypes.map((t) => t.toString()).join(', ')})`;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
-
//#endregion
|
|
23
|
-
export { createShelllessImpl };
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
return isTemplateStringsArray(arg) ? templateLiteralIdentity(arg, ...values) : arg;
|
|
1
|
+
export function stripTemplate(arg, ...values) {
|
|
2
|
+
return isTemplateStringsArray(arg) ? templateLiteralIdentity(arg, ...values) : arg;
|
|
4
3
|
}
|
|
5
4
|
function isTemplateStringsArray(value) {
|
|
6
|
-
|
|
5
|
+
return (Array.isArray(value) &&
|
|
6
|
+
'raw' in value &&
|
|
7
|
+
Array.isArray(value.raw) &&
|
|
8
|
+
value.raw.every((item) => typeof item === 'string'));
|
|
7
9
|
}
|
|
8
10
|
function templateLiteralIdentity(strings, ...values) {
|
|
9
|
-
|
|
11
|
+
return strings
|
|
12
|
+
.slice(1)
|
|
13
|
+
.reduce((acc, elem, index) => `${acc}${values[index]}${elem}`, strings[0]);
|
|
10
14
|
}
|
|
11
|
-
|
|
12
|
-
//#endregion
|
|
13
|
-
export { stripTemplate };
|