Reland "Rearrange SkSL pre-include modules to hide things"

This reverts commit 4cb5c5e1728933637ca9b8653ff95f876871dc9b, and fixes
the Chromium issue by declaring sign(x) in sksl_public.sksl.

Original description:

This makes numerous internal and GLSL types or intrinsics hidden from
public (runtime effect) SkSL. In particular:

- Only core numeric types are visible to all program types. GLSL types
  involving images, textures, and sampling are restricted to internal use.
- sk_Caps is no longer visible to runtime effects.
- The set of intrinsics available to runtime effects is now a separate,
  curated list in sksl_public.sksl. It exactly matches the GLSL ES 1.00
  spec order.
- The blend intrinsics are no longer visible, which also fixes a bug.
  These are nice, but we're not going to offer them yet - they involve
  enums, which creates complications.

Bug: skia:10680
Bug: skia:10709
Bug: skia:10913

Cq-Include-Trybots: luci.chromium.try:linux-chromeos-rel,linux-rel
Change-Id: I42deeeccd725a9fe18314d091ce253404e3572e2
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332750
Commit-Queue: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
Auto-Submit: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 26ee20c..b762d9f 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -604,6 +604,7 @@
       "src/sksl/sksl_gpu.sksl",
       "src/sksl/sksl_interp.sksl",
       "src/sksl/sksl_pipeline.sksl",
+      "src/sksl/sksl_public.sksl",
       "src/sksl/sksl_vert.sksl",
     ]
     outputs = [ "$root_out_dir/{{source_file_part}}" ]
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 3ab88a3..ba2dd81 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -9,6 +9,9 @@
 
   * <insert new release notes here>
 
+  * Limit the types and intrinsics supported in SkRuntimeEffect to GLSL ES 1.00
+    https://review.skia.org/332597
+
   * Add AVIF support to SkHeifCodec.
 
   * Add support for creating SkSurfaceCharacterizations directly for use by a
diff --git a/src/sksl/SkSLByteCodeGenerator.cpp b/src/sksl/SkSLByteCodeGenerator.cpp
index f24f0a5..681eda3 100644
--- a/src/sksl/SkSLByteCodeGenerator.cpp
+++ b/src/sksl/SkSLByteCodeGenerator.cpp
@@ -43,9 +43,9 @@
     : INHERITED(program, errors, nullptr)
     , fContext(*context)
     , fOutput(output)
-    // If you're adding new intrinsics here, ensure that they're declared in sksl_interp.inc, so
-    // they're available to "generic" interpreter programs (eg particles).
-    // You can probably copy the declarations from sksl_gpu.inc.
+    // If you're adding new intrinsics here, ensure that they're declared in sksl_interp.sksl or
+    // sksl_public.sksl, so they're available to "generic" interpreter programs (eg particles).
+    // You can probably copy the declarations from sksl_gpu.sksl.
     , fIntrinsics {
         { "abs",       ByteCodeInstruction::kAbs },
         { "atan",      ByteCodeInstruction::kATan },
diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp
index 6a1db1c..27d389a 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -61,6 +61,7 @@
 #include "src/sksl/generated/sksl_gpu.dehydrated.sksl"
 #include "src/sksl/generated/sksl_interp.dehydrated.sksl"
 #include "src/sksl/generated/sksl_pipeline.dehydrated.sksl"
+#include "src/sksl/generated/sksl_public.dehydrated.sksl"
 #include "src/sksl/generated/sksl_vert.dehydrated.sksl"
 
 #define MODULE_DATA(name) MakeModuleData(SKSL_INCLUDE_sksl_##name,\
@@ -89,142 +90,93 @@
 , fContext(std::make_shared<Context>())
 , fErrorCount(0) {
     fRootSymbolTable = std::make_shared<SymbolTable>(this, /*builtin=*/true);
+    fPrivateSymbolTable = std::make_shared<SymbolTable>(fRootSymbolTable, /*builtin=*/true);
     fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), &fInliner, *this);
-#define ADD_TYPE(t) fRootSymbolTable->addWithoutOwnership(fContext->f##t##_Type.get())
-    ADD_TYPE(Void);
-    ADD_TYPE(Float);
-    ADD_TYPE(Float2);
-    ADD_TYPE(Float3);
-    ADD_TYPE(Float4);
-    ADD_TYPE(Half);
-    ADD_TYPE(Half2);
-    ADD_TYPE(Half3);
-    ADD_TYPE(Half4);
-    ADD_TYPE(Int);
-    ADD_TYPE(Int2);
-    ADD_TYPE(Int3);
-    ADD_TYPE(Int4);
-    ADD_TYPE(UInt);
-    ADD_TYPE(UInt2);
-    ADD_TYPE(UInt3);
-    ADD_TYPE(UInt4);
-    ADD_TYPE(Short);
-    ADD_TYPE(Short2);
-    ADD_TYPE(Short3);
-    ADD_TYPE(Short4);
-    ADD_TYPE(UShort);
-    ADD_TYPE(UShort2);
-    ADD_TYPE(UShort3);
-    ADD_TYPE(UShort4);
-    ADD_TYPE(Byte);
-    ADD_TYPE(Byte2);
-    ADD_TYPE(Byte3);
-    ADD_TYPE(Byte4);
-    ADD_TYPE(UByte);
-    ADD_TYPE(UByte2);
-    ADD_TYPE(UByte3);
-    ADD_TYPE(UByte4);
-    ADD_TYPE(Bool);
-    ADD_TYPE(Bool2);
-    ADD_TYPE(Bool3);
-    ADD_TYPE(Bool4);
-    ADD_TYPE(Float2x2);
-    ADD_TYPE(Float2x3);
-    ADD_TYPE(Float2x4);
-    ADD_TYPE(Float3x2);
-    ADD_TYPE(Float3x3);
-    ADD_TYPE(Float3x4);
-    ADD_TYPE(Float4x2);
-    ADD_TYPE(Float4x3);
-    ADD_TYPE(Float4x4);
-    ADD_TYPE(Half2x2);
-    ADD_TYPE(Half2x3);
-    ADD_TYPE(Half2x4);
-    ADD_TYPE(Half3x2);
-    ADD_TYPE(Half3x3);
-    ADD_TYPE(Half3x4);
-    ADD_TYPE(Half4x2);
-    ADD_TYPE(Half4x3);
-    ADD_TYPE(Half4x4);
-    ADD_TYPE(GenType);
-    ADD_TYPE(GenHType);
-    ADD_TYPE(GenIType);
-    ADD_TYPE(GenUType);
-    ADD_TYPE(GenBType);
-    ADD_TYPE(Mat);
-    ADD_TYPE(Vec);
-    ADD_TYPE(GVec);
-    ADD_TYPE(GVec2);
-    ADD_TYPE(GVec3);
-    ADD_TYPE(GVec4);
-    ADD_TYPE(HVec);
-    ADD_TYPE(IVec);
-    ADD_TYPE(UVec);
-    ADD_TYPE(SVec);
-    ADD_TYPE(USVec);
-    ADD_TYPE(ByteVec);
-    ADD_TYPE(UByteVec);
-    ADD_TYPE(BVec);
 
-    ADD_TYPE(Sampler1D);
-    ADD_TYPE(Sampler2D);
-    ADD_TYPE(Sampler3D);
-    ADD_TYPE(SamplerExternalOES);
-    ADD_TYPE(SamplerCube);
-    ADD_TYPE(Sampler2DRect);
-    ADD_TYPE(Sampler1DArray);
-    ADD_TYPE(Sampler2DArray);
-    ADD_TYPE(SamplerCubeArray);
-    ADD_TYPE(SamplerBuffer);
-    ADD_TYPE(Sampler2DMS);
-    ADD_TYPE(Sampler2DMSArray);
+#define TYPE(t) fContext->f##t##_Type.get()
 
-    ADD_TYPE(ISampler2D);
+    const SkSL::Symbol* rootTypes[] = {
+        TYPE(Void),
 
-    ADD_TYPE(Image2D);
-    ADD_TYPE(IImage2D);
+        TYPE( Float), TYPE( Float2), TYPE( Float3), TYPE( Float4),
+        TYPE(  Half), TYPE(  Half2), TYPE(  Half3), TYPE(  Half4),
+        TYPE(   Int), TYPE(   Int2), TYPE(   Int3), TYPE(   Int4),
+        TYPE(  UInt), TYPE(  UInt2), TYPE(  UInt3), TYPE(  UInt4),
+        TYPE( Short), TYPE( Short2), TYPE( Short3), TYPE( Short4),
+        TYPE(UShort), TYPE(UShort2), TYPE(UShort3), TYPE(UShort4),
+        TYPE(  Byte), TYPE(  Byte2), TYPE(  Byte3), TYPE(  Byte4),
+        TYPE( UByte), TYPE( UByte2), TYPE( UByte3), TYPE( UByte4),
+        TYPE(  Bool), TYPE(  Bool2), TYPE(  Bool3), TYPE(  Bool4),
 
-    ADD_TYPE(SubpassInput);
-    ADD_TYPE(SubpassInputMS);
+        TYPE(Float2x2), TYPE(Float2x3), TYPE(Float2x4),
+        TYPE(Float3x2), TYPE(Float3x3), TYPE(Float3x4),
+        TYPE(Float4x2), TYPE(Float4x3), TYPE(Float4x4),
 
-    ADD_TYPE(GSampler1D);
-    ADD_TYPE(GSampler2D);
-    ADD_TYPE(GSampler3D);
-    ADD_TYPE(GSamplerCube);
-    ADD_TYPE(GSampler2DRect);
-    ADD_TYPE(GSampler1DArray);
-    ADD_TYPE(GSampler2DArray);
-    ADD_TYPE(GSamplerCubeArray);
-    ADD_TYPE(GSamplerBuffer);
-    ADD_TYPE(GSampler2DMS);
-    ADD_TYPE(GSampler2DMSArray);
+        TYPE(Half2x2),  TYPE(Half2x3),  TYPE(Half2x4),
+        TYPE(Half3x2),  TYPE(Half3x3),  TYPE(Half3x4),
+        TYPE(Half4x2),  TYPE(Half4x3),  TYPE(Half4x4),
 
-    ADD_TYPE(Sampler1DShadow);
-    ADD_TYPE(Sampler2DShadow);
-    ADD_TYPE(SamplerCubeShadow);
-    ADD_TYPE(Sampler2DRectShadow);
-    ADD_TYPE(Sampler1DArrayShadow);
-    ADD_TYPE(Sampler2DArrayShadow);
-    ADD_TYPE(SamplerCubeArrayShadow);
-    ADD_TYPE(GSampler2DArrayShadow);
-    ADD_TYPE(GSamplerCubeArrayShadow);
-    ADD_TYPE(FragmentProcessor);
-    ADD_TYPE(Sampler);
-    ADD_TYPE(Texture2D);
+        TYPE(GenType), TYPE(GenHType), TYPE(GenIType), TYPE(GenUType), TYPE(GenBType),
+        TYPE(Mat), TYPE(Vec),
+        TYPE(GVec), TYPE(GVec2), TYPE(GVec3), TYPE(GVec4),
+        TYPE(HVec), TYPE(IVec), TYPE(UVec), TYPE(SVec), TYPE(USVec),
+        TYPE(ByteVec), TYPE(UByteVec), TYPE(BVec),
+
+        TYPE(FragmentProcessor),
+    };
+
+    const SkSL::Symbol* privateTypes[] = {
+        TYPE(Sampler1D), TYPE(Sampler2D), TYPE(Sampler3D),
+        TYPE(SamplerExternalOES),
+        TYPE(SamplerCube),
+        TYPE(Sampler2DRect),
+        TYPE(Sampler1DArray), TYPE(Sampler2DArray), TYPE(SamplerCubeArray),
+        TYPE(SamplerBuffer),
+        TYPE(Sampler2DMS), TYPE(Sampler2DMSArray),
+
+        TYPE(ISampler2D),
+        TYPE(Image2D), TYPE(IImage2D),
+        TYPE(SubpassInput), TYPE(SubpassInputMS),
+
+        TYPE(GSampler1D), TYPE(GSampler2D), TYPE(GSampler3D),
+        TYPE(GSamplerCube),
+        TYPE(GSampler2DRect),
+        TYPE(GSampler1DArray), TYPE(GSampler2DArray), TYPE(GSamplerCubeArray),
+        TYPE(GSamplerBuffer),
+        TYPE(GSampler2DMS), TYPE(GSampler2DMSArray),
+
+        TYPE(Sampler1DShadow), TYPE(Sampler2DShadow), TYPE(SamplerCubeShadow),
+        TYPE(Sampler2DRectShadow),
+        TYPE(Sampler1DArrayShadow), TYPE(Sampler2DArrayShadow), TYPE(SamplerCubeArrayShadow),
+
+        TYPE(GSampler2DArrayShadow), TYPE(GSamplerCubeArrayShadow),
+        TYPE(Sampler),
+        TYPE(Texture2D),
+    };
+
+    for (const SkSL::Symbol* type : rootTypes) {
+        fRootSymbolTable->addWithoutOwnership(type);
+    }
+    for (const SkSL::Symbol* type : privateTypes) {
+        fPrivateSymbolTable->addWithoutOwnership(type);
+    }
+
+#undef TYPE
 
     // sk_Caps is "builtin", but all references to it are resolved to Settings, so we don't need to
     // treat it as builtin (ie, no need to clone it into the Program).
-    StringFragment skCapsName("sk_Caps");
-    fRootSymbolTable->add(std::make_unique<Variable>(/*offset=*/-1,
-                                                     fIRGenerator->fModifiers->handle(Modifiers()),
-                                                     skCapsName,
-                                                     fContext->fSkCaps_Type.get(),
-                                                     /*builtin=*/false,
-                                                     Variable::Storage::kGlobal));
+    fPrivateSymbolTable->add(
+            std::make_unique<Variable>(/*offset=*/-1,
+                                       fIRGenerator->fModifiers->handle(Modifiers()),
+                                       "sk_Caps",
+                                       fContext->fSkCaps_Type.get(),
+                                       /*builtin=*/false,
+                                       Variable::Storage::kGlobal));
 
     fRootModule = {fRootSymbolTable, /*fIntrinsics=*/nullptr};
+    fPrivateModule = {fPrivateSymbolTable, /*fIntrinsics=*/nullptr};
 
-    fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fRootModule);
+    fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fPrivateModule);
     fVertexModule = this->parseModule(Program::kVertex_Kind, MODULE_DATA(vert), fGPUModule);
     fFragmentModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(frag), fGPUModule);
 }
@@ -246,10 +198,17 @@
     return fFPModule;
 }
 
+const ParsedModule& Compiler::loadPublicModule() {
+    if (!fPublicModule.fSymbols) {
+        fPublicModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(public), fRootModule);
+    }
+    return fPublicModule;
+}
+
 const ParsedModule& Compiler::loadPipelineModule() {
     if (!fPipelineModule.fSymbols) {
-        fPipelineModule =
-                this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline), fGPUModule);
+        fPipelineModule = this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline),
+                                            this->loadPublicModule());
 
         // Add some aliases to the pipeline module so that it's friendlier, and more like GLSL
         fPipelineModule.fSymbols->addAlias("shader", fContext->fFragmentProcessor_Type.get());
@@ -283,8 +242,8 @@
 
 const ParsedModule& Compiler::loadInterpreterModule() {
     if (!fInterpreterModule.fSymbols) {
-        fInterpreterModule =
-                this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp), fRootModule);
+        fInterpreterModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp),
+                                               this->loadPublicModule());
     }
     return fInterpreterModule;
 }
@@ -305,7 +264,13 @@
                                   ModuleData data,
                                   std::shared_ptr<SymbolTable> base) {
     if (!base) {
-        base = fRootSymbolTable;
+        // NOTE: This is a workaround. The only time 'base' is null is when dehydrating includes.
+        // In that case, skslc doesn't know which module it's preparing, nor what the correct base
+        // module is. We can't use 'Root', because many GPU intrinsics reference private types,
+        // like samplers or textures. Today, 'Private' does contain the union of all known types,
+        // so this is safe. If we ever have types that only exist in 'Public' (for example), this
+        // logic needs to be smarter (by choosing the correct base for the module we're compiling).
+        base = fPrivateSymbolTable;
     }
 
 #if defined(SKSL_STANDALONE)
diff --git a/src/sksl/SkSLCompiler.h b/src/sksl/SkSLCompiler.h
index 8b652df..349ba79 100644
--- a/src/sksl/SkSLCompiler.h
+++ b/src/sksl/SkSLCompiler.h
@@ -228,6 +228,7 @@
 private:
     const ParsedModule& loadFPModule();
     const ParsedModule& loadGeometryModule();
+    const ParsedModule& loadPublicModule();
     const ParsedModule& loadInterpreterModule();
     const ParsedModule& loadPipelineModule();
 
@@ -271,15 +272,20 @@
     const ShaderCapsClass* fCaps = nullptr;
 
     std::shared_ptr<SymbolTable> fRootSymbolTable;
+    std::shared_ptr<SymbolTable> fPrivateSymbolTable;
 
-    ParsedModule fRootModule;
-    ParsedModule fGPUModule;
-    ParsedModule fInterpreterModule;
-    ParsedModule fVertexModule;
-    ParsedModule fFragmentModule;
-    ParsedModule fGeometryModule;
-    ParsedModule fPipelineModule;
-    ParsedModule fFPModule;
+    ParsedModule fRootModule;         // Core types
+
+    ParsedModule fPrivateModule;      // [Root] + Internal types
+    ParsedModule fGPUModule;          // [Private] + GPU intrinsics, helper functions
+    ParsedModule fVertexModule;       // [GPU] + Vertex stage decls
+    ParsedModule fFragmentModule;     // [GPU] + Fragment stage decls
+    ParsedModule fGeometryModule;     // [GPU] + Geometry stage decls
+    ParsedModule fFPModule;           // [GPU] + FP features
+
+    ParsedModule fPublicModule;       // [Root] + Public features
+    ParsedModule fInterpreterModule;  // [Public] + Interpreter-only decls
+    ParsedModule fPipelineModule;     // [Public] + Runtime effect decls
 
     // holds ModifiersPools belonging to the core includes for lifetime purposes
     std::vector<std::unique_ptr<ModifiersPool>> fModifiers;
diff --git a/src/sksl/generated/sksl_interp.dehydrated.sksl b/src/sksl/generated/sksl_interp.dehydrated.sksl
index bfb10f3..d528733 100644
--- a/src/sksl/generated/sksl_interp.dehydrated.sksl
+++ b/src/sksl/generated/sksl_interp.dehydrated.sksl
@@ -1,1319 +1,293 @@
-static uint8_t SKSL_INCLUDE_sksl_interp[] = {143,1,
-8,121,95,111,118,101,114,95,120,
-8,36,103,101,110,84,121,112,101,
-4,97,116,97,110,
-9,36,103,101,110,72,84,121,112,101,
-1,121,
-3,99,111,115,
+static uint8_t SKSL_INCLUDE_sksl_interp[] = {166,0,
 1,120,
-3,100,111,116,
-5,102,108,111,97,116,
-4,104,97,108,102,
-5,102,114,97,99,116,
-1,109,
-8,102,108,111,97,116,50,120,50,
-7,105,110,118,101,114,115,101,
-8,102,108,111,97,116,51,120,51,
-8,102,108,111,97,116,52,120,52,
-7,104,97,108,102,50,120,50,
-7,104,97,108,102,51,120,51,
-7,104,97,108,102,52,120,52,
-6,108,101,110,103,116,104,
-9,110,111,114,109,97,108,105,122,101,
-3,112,111,119,
-3,115,105,110,
-4,115,113,114,116,
-3,116,97,110,
-3,109,105,110,
 9,36,103,101,110,73,84,121,112,101,
+1,121,
+3,109,105,110,
 3,105,110,116,
 3,109,97,120,
 6,109,105,110,86,97,108,
 6,109,97,120,86,97,108,
 5,99,108,97,109,112,
-8,115,97,116,117,114,97,116,101,
+8,36,103,101,110,84,121,112,101,
 1,97,
 9,36,103,101,110,66,84,121,112,101,
 3,109,105,120,
-4,36,118,101,99,
+9,36,103,101,110,72,84,121,112,101,
+5,36,105,118,101,99,
 8,108,101,115,115,84,104,97,110,
 5,36,98,118,101,99,
-5,36,104,118,101,99,
-5,36,105,118,101,99,
 5,36,117,118,101,99,
 13,108,101,115,115,84,104,97,110,69,113,117,97,108,
 11,103,114,101,97,116,101,114,84,104,97,110,
 16,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,
 5,101,113,117,97,108,
 8,110,111,116,69,113,117,97,108,
-3,97,110,121,
-4,98,111,111,108,
-3,97,108,108,
-3,110,111,116,
-3,114,97,100,
-7,100,101,103,114,101,101,115,
-6,102,108,111,97,116,50,
-6,102,108,111,97,116,51,
-6,102,108,111,97,116,52,
-3,100,101,103,
-7,114,97,100,105,97,110,115,
-1,98,
-8,100,105,115,116,97,110,99,101,
-5,99,114,111,115,115,
-43,74,1,
+43,84,0,
 47,1,0,
 9,2,0,
-44,2,0,11,0,3,
-23,3,0,
-9,20,0,1,1,0,
-41,2,0,
-47,4,0,
-9,2,0,
-44,5,0,25,0,3,
-46,6,0,2,
-41,3,0,
-23,7,0,
-9,20,0,1,4,0,
-41,5,0,
-41,7,0,
-47,8,0,
-9,35,0,
+44,2,0,4,0,3,
+47,3,0,
+9,14,0,
 41,2,0,3,
-23,9,0,
-9,37,0,1,8,0,
+23,4,0,
+9,16,0,2,1,0,3,0,
 41,2,0,
-47,10,0,
-9,35,0,
-41,5,0,3,
-46,11,0,2,
+47,5,0,
+9,2,0,
+41,2,0,3,
+47,6,0,
+9,14,0,
+44,7,0,20,0,3,
+46,8,0,2,
+41,4,0,
+23,9,0,
+9,16,0,2,5,0,6,0,
+41,2,0,
 41,9,0,
+47,10,0,
+9,2,0,
+41,2,0,3,
+47,11,0,
+9,14,0,
+41,2,0,3,
 23,12,0,
-9,37,0,1,10,0,
-41,5,0,
-41,12,0,
+9,24,0,2,10,0,11,0,
+41,2,0,
 47,13,0,
-9,41,0,
+9,2,0,
 41,2,0,3,
 47,14,0,
-9,35,0,
-41,2,0,3,
-23,15,0,
-9,43,0,2,13,0,14,0,
-44,16,0,47,0,
-47,17,0,
-9,41,0,
-41,5,0,3,
-47,18,0,
-9,35,0,
-41,5,0,3,
-46,19,0,2,
-41,15,0,
-23,20,0,
-9,43,0,2,17,0,18,0,
-44,21,0,53,0,
-41,20,0,
-47,22,0,
-9,41,0,
-41,2,0,3,
-23,23,0,
-9,58,0,1,22,0,
+9,14,0,
+41,7,0,3,
+46,15,0,2,
+41,12,0,
+23,16,0,
+9,24,0,2,13,0,14,0,
 41,2,0,
-47,24,0,
-9,41,0,
-41,5,0,3,
-46,25,0,2,
-41,23,0,
-23,26,0,
-9,58,0,1,24,0,
-41,5,0,
-41,26,0,
-47,27,0,
-9,64,0,
-44,28,0,66,0,3,
-23,29,0,
-9,75,0,1,27,0,
-41,28,0,
-47,30,0,
-9,64,0,
-44,31,0,83,0,3,
-46,32,0,2,
-41,29,0,
-23,33,0,
-9,75,0,1,30,0,
-41,31,0,
-41,33,0,
+41,16,0,
+47,17,0,
+9,2,0,
+41,2,0,3,
+47,18,0,
+9,28,0,
+41,2,0,3,
+47,19,0,
+9,35,0,
+41,2,0,3,
+23,20,0,
+9,42,0,3,17,0,18,0,19,0,
+41,2,0,
+47,21,0,
+9,2,0,
+41,2,0,3,
+47,22,0,
+9,28,0,
+41,7,0,3,
+47,23,0,
+9,35,0,
+41,7,0,3,
+46,24,0,2,
+41,20,0,
+23,25,0,
+9,42,0,3,21,0,22,0,23,0,
+41,2,0,
+41,25,0,
+47,26,0,
+9,2,0,
+44,27,0,48,0,3,
+47,28,0,
+9,14,0,
+41,27,0,3,
+47,29,0,
+9,57,0,
+44,30,0,59,0,3,
+23,31,0,
+9,69,0,3,26,0,28,0,29,0,
+41,27,0,
+47,32,0,
+9,2,0,
+44,33,0,73,0,3,
 47,34,0,
-9,64,0,
-44,35,0,92,0,3,
-46,36,0,3,
-41,29,0,
-41,33,0,
+9,14,0,
+41,33,0,3,
+47,35,0,
+9,57,0,
+41,30,0,3,
+46,36,0,2,
+41,31,0,
 23,37,0,
-9,75,0,1,34,0,
-41,35,0,
+9,69,0,3,32,0,34,0,35,0,
+41,33,0,
 41,37,0,
 47,38,0,
-9,64,0,
-44,39,0,101,0,3,
-46,40,0,4,
-41,29,0,
-41,33,0,
+9,2,0,
+41,2,0,3,
+47,39,0,
+9,14,0,
+41,2,0,3,
+47,40,0,
+9,57,0,
+41,30,0,3,
+46,41,0,3,
+41,31,0,
 41,37,0,
-23,41,0,
-9,75,0,1,38,0,
-41,39,0,
-41,41,0,
-47,42,0,
-9,64,0,
-44,43,0,109,0,3,
-46,44,0,5,
-41,29,0,
-41,33,0,
+23,42,0,
+9,69,0,3,38,0,39,0,40,0,
+41,2,0,
+41,42,0,
+47,43,0,
+9,2,0,
+41,30,0,3,
+47,44,0,
+9,14,0,
+41,30,0,3,
+47,45,0,
+9,57,0,
+41,30,0,3,
+46,46,0,4,
+41,31,0,
 41,37,0,
-41,41,0,
-23,45,0,
-9,75,0,1,42,0,
-41,43,0,
-41,45,0,
-47,46,0,
-9,64,0,
-44,47,0,117,0,3,
-46,48,0,6,
-41,29,0,
-41,33,0,
-41,37,0,
-41,41,0,
-41,45,0,
-23,49,0,
-9,75,0,1,46,0,
+41,42,0,
+23,47,0,
+9,69,0,3,43,0,44,0,45,0,
+41,30,0,
 41,47,0,
-41,49,0,
+47,48,0,
+9,2,0,
+44,49,0,83,0,3,
 47,50,0,
-9,41,0,
-41,2,0,3,
+9,14,0,
+41,49,0,3,
 23,51,0,
-9,125,0,1,50,0,
-41,16,0,
-47,52,0,
-9,41,0,
-41,5,0,3,
-46,53,0,2,
-41,51,0,
-23,54,0,
-9,125,0,1,52,0,
-41,21,0,
-41,54,0,
+9,89,0,2,48,0,50,0,
+44,52,0,98,0,
+47,53,0,
+9,2,0,
+44,54,0,104,0,3,
 47,55,0,
-9,41,0,
-41,2,0,3,
-23,56,0,
-9,132,0,1,55,0,
-41,2,0,
-47,57,0,
-9,41,0,
-41,5,0,3,
-46,58,0,2,
-41,56,0,
-23,59,0,
-9,132,0,1,57,0,
-41,5,0,
-41,59,0,
-47,60,0,
-9,41,0,
-41,2,0,3,
+9,14,0,
+41,54,0,3,
+46,56,0,2,
+41,51,0,
+23,57,0,
+9,89,0,2,53,0,55,0,
+41,52,0,
+41,57,0,
+47,58,0,
+9,2,0,
+41,49,0,3,
+47,59,0,
+9,14,0,
+41,49,0,3,
+23,60,0,
+9,110,0,2,58,0,59,0,
+41,52,0,
 47,61,0,
-9,35,0,
-41,2,0,3,
-23,62,0,
-9,142,0,2,60,0,61,0,
-41,2,0,
-47,63,0,
-9,41,0,
-41,5,0,3,
-47,64,0,
-9,35,0,
-41,5,0,3,
-46,65,0,2,
-41,62,0,
-23,66,0,
-9,142,0,2,63,0,64,0,
-41,5,0,
-41,66,0,
-47,67,0,
-9,41,0,
-41,2,0,3,
-23,68,0,
-9,146,0,1,67,0,
-41,2,0,
+9,2,0,
+41,54,0,3,
+47,62,0,
+9,14,0,
+41,54,0,3,
+46,63,0,2,
+41,60,0,
+23,64,0,
+9,110,0,2,61,0,62,0,
+41,52,0,
+41,64,0,
+47,65,0,
+9,2,0,
+41,49,0,3,
+47,66,0,
+9,14,0,
+41,49,0,3,
+23,67,0,
+9,124,0,2,65,0,66,0,
+41,52,0,
+47,68,0,
+9,2,0,
+41,54,0,3,
 47,69,0,
-9,41,0,
-41,5,0,3,
+9,14,0,
+41,54,0,3,
 46,70,0,2,
-41,68,0,
+41,67,0,
 23,71,0,
-9,146,0,1,69,0,
-41,5,0,
+9,124,0,2,68,0,69,0,
+41,52,0,
 41,71,0,
 47,72,0,
-9,41,0,
-41,2,0,3,
-23,73,0,
-9,150,0,1,72,0,
-41,2,0,
-47,74,0,
-9,41,0,
-41,5,0,3,
-46,75,0,2,
-41,73,0,
-23,76,0,
-9,150,0,1,74,0,
-41,5,0,
-41,76,0,
-47,77,0,
-9,41,0,
-41,2,0,3,
+9,2,0,
+41,49,0,3,
+47,73,0,
+9,14,0,
+41,49,0,3,
+23,74,0,
+9,136,0,2,72,0,73,0,
+41,52,0,
+47,75,0,
+9,2,0,
+41,54,0,3,
+47,76,0,
+9,14,0,
+41,54,0,3,
+46,77,0,2,
+41,74,0,
 23,78,0,
-9,155,0,1,77,0,
-41,2,0,
-47,79,0,
-9,41,0,
-41,5,0,3,
-46,80,0,2,
+9,136,0,2,75,0,76,0,
+41,52,0,
 41,78,0,
+47,79,0,
+9,2,0,
+41,49,0,3,
+47,80,0,
+9,14,0,
+41,49,0,3,
 23,81,0,
-9,155,0,1,79,0,
-41,5,0,
-41,81,0,
+9,153,0,2,79,0,80,0,
+41,52,0,
 47,82,0,
-9,41,0,
-41,2,0,3,
+9,2,0,
+41,54,0,3,
 47,83,0,
-9,35,0,
-41,2,0,3,
-23,84,0,
-9,159,0,2,82,0,83,0,
-41,2,0,
-47,85,0,
-9,41,0,
-41,2,0,3,
+9,14,0,
+41,54,0,3,
+46,84,0,2,
+41,81,0,
+23,85,0,
+9,153,0,2,82,0,83,0,
+41,52,0,
+41,85,0,
 47,86,0,
-9,35,0,
-41,16,0,3,
-46,87,0,2,
-41,84,0,
+9,2,0,
+41,49,0,3,
+47,87,0,
+9,14,0,
+41,49,0,3,
 23,88,0,
-9,159,0,2,85,0,86,0,
-41,2,0,
-41,88,0,
+9,159,0,2,86,0,87,0,
+41,52,0,
 47,89,0,
-9,41,0,
-41,5,0,3,
+9,2,0,
+41,54,0,3,
 47,90,0,
-9,35,0,
-41,5,0,3,
-46,91,0,3,
-41,84,0,
+9,14,0,
+41,54,0,3,
+46,91,0,2,
 41,88,0,
 23,92,0,
 9,159,0,2,89,0,90,0,
-41,5,0,
-41,92,0,
-47,93,0,
-9,41,0,
-41,5,0,3,
-47,94,0,
-9,35,0,
-41,21,0,3,
-46,95,0,4,
-41,84,0,
-41,88,0,
-41,92,0,
-23,96,0,
-9,159,0,2,93,0,94,0,
-41,5,0,
-41,96,0,
-47,97,0,
-9,41,0,
-44,98,0,163,0,3,
-47,99,0,
-9,35,0,
-41,98,0,3,
-46,100,0,5,
-41,84,0,
-41,88,0,
-41,92,0,
-41,96,0,
-23,101,0,
-9,159,0,2,97,0,99,0,
-41,98,0,
-41,101,0,
-47,102,0,
-9,41,0,
-41,98,0,3,
-47,103,0,
-9,35,0,
-44,104,0,173,0,3,
-46,105,0,6,
-41,84,0,
-41,88,0,
-41,92,0,
-41,96,0,
-41,101,0,
-23,106,0,
-9,159,0,2,102,0,103,0,
-41,98,0,
-41,106,0,
-47,107,0,
-9,41,0,
-41,2,0,3,
-47,108,0,
-9,35,0,
-41,2,0,3,
-23,109,0,
-9,177,0,2,107,0,108,0,
-41,2,0,
-47,110,0,
-9,41,0,
-41,2,0,3,
-47,111,0,
-9,35,0,
-41,16,0,3,
-46,112,0,2,
-41,109,0,
-23,113,0,
-9,177,0,2,110,0,111,0,
-41,2,0,
-41,113,0,
-47,114,0,
-9,41,0,
-41,5,0,3,
-47,115,0,
-9,35,0,
-41,5,0,3,
-46,116,0,3,
-41,109,0,
-41,113,0,
-23,117,0,
-9,177,0,2,114,0,115,0,
-41,5,0,
-41,117,0,
-47,118,0,
-9,41,0,
-41,5,0,3,
-47,119,0,
-9,35,0,
-41,21,0,3,
-46,120,0,4,
-41,109,0,
-41,113,0,
-41,117,0,
-23,121,0,
-9,177,0,2,118,0,119,0,
-41,5,0,
-41,121,0,
-47,122,0,
-9,41,0,
-41,98,0,3,
-47,123,0,
-9,35,0,
-41,98,0,3,
-46,124,0,5,
-41,109,0,
-41,113,0,
-41,117,0,
-41,121,0,
-23,125,0,
-9,177,0,2,122,0,123,0,
-41,98,0,
-41,125,0,
-47,126,0,
-9,41,0,
-41,98,0,3,
-47,127,0,
-9,35,0,
-41,104,0,3,
-46,128,0,6,
-41,109,0,
-41,113,0,
-41,117,0,
-41,121,0,
-41,125,0,
-23,129,0,
-9,177,0,2,126,0,127,0,
-41,98,0,
-41,129,0,
-47,130,0,
-9,41,0,
-41,2,0,3,
-47,131,0,
-9,181,0,
-41,2,0,3,
-47,132,0,
-9,188,0,
-41,2,0,3,
-23,133,0,
-9,195,0,3,130,0,131,0,132,0,
-41,2,0,
-47,134,0,
-9,41,0,
-41,2,0,3,
-47,135,0,
-9,181,0,
-41,16,0,3,
-47,136,0,
-9,188,0,
-41,16,0,3,
-46,137,0,2,
-41,133,0,
-23,138,0,
-9,195,0,3,134,0,135,0,136,0,
-41,2,0,
-41,138,0,
-47,139,0,
-9,41,0,
-41,5,0,3,
-47,140,0,
-9,181,0,
-41,5,0,3,
-47,141,0,
-9,188,0,
-41,5,0,3,
-46,142,0,3,
-41,133,0,
-41,138,0,
-23,143,0,
-9,195,0,3,139,0,140,0,141,0,
-41,5,0,
-41,143,0,
-47,144,0,
-9,41,0,
-41,5,0,3,
-47,145,0,
-9,181,0,
-41,21,0,3,
-47,146,0,
-9,188,0,
-41,21,0,3,
-46,147,0,4,
-41,133,0,
-41,138,0,
-41,143,0,
-23,148,0,
-9,195,0,3,144,0,145,0,146,0,
-41,5,0,
-41,148,0,
-47,149,0,
-9,41,0,
-41,98,0,3,
-47,150,0,
-9,181,0,
-41,98,0,3,
-47,151,0,
-9,188,0,
-41,98,0,3,
-46,152,0,5,
-41,133,0,
-41,138,0,
-41,143,0,
-41,148,0,
-23,153,0,
-9,195,0,3,149,0,150,0,151,0,
-41,98,0,
-41,153,0,
-47,154,0,
-9,41,0,
-41,98,0,3,
-47,155,0,
-9,181,0,
-41,104,0,3,
-47,156,0,
-9,188,0,
-41,104,0,3,
-46,157,0,6,
-41,133,0,
-41,138,0,
-41,143,0,
-41,148,0,
-41,153,0,
-23,158,0,
-9,195,0,3,154,0,155,0,156,0,
-41,98,0,
-41,158,0,
-47,159,0,
-9,41,0,
-41,2,0,3,
-23,160,0,
-9,201,0,1,159,0,
-41,2,0,
-47,161,0,
-9,41,0,
-41,5,0,3,
-46,162,0,2,
-41,160,0,
-23,163,0,
-9,201,0,1,161,0,
-41,5,0,
-41,163,0,
-47,164,0,
-9,41,0,
-41,2,0,3,
-47,165,0,
-9,35,0,
-41,2,0,3,
-47,166,0,
-9,210,0,
-44,167,0,212,0,3,
-23,168,0,
-9,222,0,3,164,0,165,0,166,0,
-41,2,0,
-47,169,0,
-9,41,0,
-41,5,0,3,
-47,170,0,
-9,35,0,
-41,5,0,3,
-47,171,0,
-9,210,0,
-41,167,0,3,
-46,172,0,2,
-41,168,0,
-23,173,0,
-9,222,0,3,169,0,170,0,171,0,
-41,5,0,
-41,173,0,
-47,174,0,
-9,41,0,
-41,98,0,3,
-47,175,0,
-9,35,0,
-41,98,0,3,
-47,176,0,
-9,210,0,
-41,167,0,3,
-46,177,0,3,
-41,168,0,
-41,173,0,
-23,178,0,
-9,222,0,3,174,0,175,0,176,0,
-41,98,0,
-41,178,0,
-47,179,0,
-9,41,0,
-41,167,0,3,
-47,180,0,
-9,35,0,
-41,167,0,3,
-47,181,0,
-9,210,0,
-41,167,0,3,
-46,182,0,4,
-41,168,0,
-41,173,0,
-41,178,0,
-23,183,0,
-9,222,0,3,179,0,180,0,181,0,
-41,167,0,
-41,183,0,
-47,184,0,
-9,41,0,
-41,2,0,3,
-47,185,0,
-9,35,0,
-41,2,0,3,
-47,186,0,
-9,210,0,
-41,2,0,3,
-46,187,0,5,
-41,168,0,
-41,173,0,
-41,178,0,
-41,183,0,
-23,188,0,
-9,222,0,3,184,0,185,0,186,0,
-41,2,0,
-41,188,0,
-47,189,0,
-9,41,0,
-41,2,0,3,
-47,190,0,
-9,35,0,
-41,2,0,3,
-47,191,0,
-9,210,0,
-41,16,0,3,
-46,192,0,6,
-41,168,0,
-41,173,0,
-41,178,0,
-41,183,0,
-41,188,0,
-23,193,0,
-9,222,0,3,189,0,190,0,191,0,
-41,2,0,
-41,193,0,
-47,194,0,
-9,41,0,
-41,5,0,3,
-47,195,0,
-9,35,0,
-41,5,0,3,
-47,196,0,
-9,210,0,
-41,5,0,3,
-46,197,0,7,
-41,168,0,
-41,173,0,
-41,178,0,
-41,183,0,
-41,188,0,
-41,193,0,
-23,198,0,
-9,222,0,3,194,0,195,0,196,0,
-41,5,0,
-41,198,0,
-47,199,0,
-9,41,0,
-41,5,0,3,
-47,200,0,
-9,35,0,
-41,5,0,3,
-47,201,0,
-9,210,0,
-41,21,0,3,
-46,202,0,8,
-41,168,0,
-41,173,0,
-41,178,0,
-41,183,0,
-41,188,0,
-41,193,0,
-41,198,0,
-23,203,0,
-9,222,0,3,199,0,200,0,201,0,
-41,5,0,
-41,203,0,
-47,204,0,
-9,41,0,
-44,205,0,226,0,3,
-47,206,0,
-9,35,0,
-41,205,0,3,
-23,207,0,
-9,231,0,2,204,0,206,0,
-44,208,0,240,0,
-47,209,0,
-9,41,0,
-44,210,0,246,0,3,
-47,211,0,
-9,35,0,
-41,210,0,3,
-46,212,0,2,
-41,207,0,
-23,213,0,
-9,231,0,2,209,0,211,0,
-41,208,0,
-41,213,0,
-47,214,0,
-9,41,0,
-44,215,0,252,0,3,
-47,216,0,
-9,35,0,
-41,215,0,3,
-46,217,0,3,
-41,207,0,
-41,213,0,
-23,218,0,
-9,231,0,2,214,0,216,0,
-41,208,0,
-41,218,0,
-47,219,0,
-9,41,0,
-44,220,0,2,1,3,
-47,221,0,
-9,35,0,
-41,220,0,3,
-46,222,0,4,
-41,207,0,
-41,213,0,
-41,218,0,
-23,223,0,
-9,231,0,2,219,0,221,0,
-41,208,0,
-41,223,0,
-47,224,0,
-9,41,0,
-41,205,0,3,
-47,225,0,
-9,35,0,
-41,205,0,3,
-23,226,0,
-9,8,1,2,224,0,225,0,
-41,208,0,
-47,227,0,
-9,41,0,
-41,210,0,3,
-47,228,0,
-9,35,0,
-41,210,0,3,
-46,229,0,2,
-41,226,0,
-23,230,0,
-9,8,1,2,227,0,228,0,
-41,208,0,
-41,230,0,
-47,231,0,
-9,41,0,
-41,215,0,3,
-47,232,0,
-9,35,0,
-41,215,0,3,
-46,233,0,3,
-41,226,0,
-41,230,0,
-23,234,0,
-9,8,1,2,231,0,232,0,
-41,208,0,
-41,234,0,
-47,235,0,
-9,41,0,
-41,220,0,3,
-47,236,0,
-9,35,0,
-41,220,0,3,
-46,237,0,4,
-41,226,0,
-41,230,0,
-41,234,0,
-23,238,0,
-9,8,1,2,235,0,236,0,
-41,208,0,
-41,238,0,
-47,239,0,
-9,41,0,
-41,205,0,3,
-47,240,0,
-9,35,0,
-41,205,0,3,
-23,241,0,
-9,22,1,2,239,0,240,0,
-41,208,0,
-47,242,0,
-9,41,0,
-41,210,0,3,
-47,243,0,
-9,35,0,
-41,210,0,3,
-46,244,0,2,
-41,241,0,
-23,245,0,
-9,22,1,2,242,0,243,0,
-41,208,0,
-41,245,0,
-47,246,0,
-9,41,0,
-41,215,0,3,
-47,247,0,
-9,35,0,
-41,215,0,3,
-46,248,0,3,
-41,241,0,
-41,245,0,
-23,249,0,
-9,22,1,2,246,0,247,0,
-41,208,0,
-41,249,0,
-47,250,0,
-9,41,0,
-41,220,0,3,
-47,251,0,
-9,35,0,
-41,220,0,3,
-46,252,0,4,
-41,241,0,
-41,245,0,
-41,249,0,
-23,253,0,
-9,22,1,2,250,0,251,0,
-41,208,0,
-41,253,0,
-47,254,0,
-9,41,0,
-41,205,0,3,
-47,255,0,
-9,35,0,
-41,205,0,3,
-23,0,1,
-9,34,1,2,254,0,255,0,
-41,208,0,
-47,1,1,
-9,41,0,
-41,210,0,3,
-47,2,1,
-9,35,0,
-41,210,0,3,
-46,3,1,2,
-41,0,1,
-23,4,1,
-9,34,1,2,1,1,2,1,
-41,208,0,
-41,4,1,
-47,5,1,
-9,41,0,
-41,215,0,3,
-47,6,1,
-9,35,0,
-41,215,0,3,
-46,7,1,3,
-41,0,1,
-41,4,1,
-23,8,1,
-9,34,1,2,5,1,6,1,
-41,208,0,
-41,8,1,
-47,9,1,
-9,41,0,
-41,220,0,3,
-47,10,1,
-9,35,0,
-41,220,0,3,
-46,11,1,4,
-41,0,1,
-41,4,1,
-41,8,1,
-23,12,1,
-9,34,1,2,9,1,10,1,
-41,208,0,
-41,12,1,
-47,13,1,
-9,41,0,
-41,205,0,3,
-47,14,1,
-9,35,0,
-41,205,0,3,
-23,15,1,
-9,51,1,2,13,1,14,1,
-41,208,0,
-47,16,1,
-9,41,0,
-41,210,0,3,
-47,17,1,
-9,35,0,
-41,210,0,3,
-46,18,1,2,
-41,15,1,
-23,19,1,
-9,51,1,2,16,1,17,1,
-41,208,0,
-41,19,1,
-47,20,1,
-9,41,0,
-41,215,0,3,
-47,21,1,
-9,35,0,
-41,215,0,3,
-46,22,1,3,
-41,15,1,
-41,19,1,
-23,23,1,
-9,51,1,2,20,1,21,1,
-41,208,0,
-41,23,1,
-47,24,1,
-9,41,0,
-41,220,0,3,
-47,25,1,
-9,35,0,
-41,220,0,3,
-46,26,1,4,
-41,15,1,
-41,19,1,
-41,23,1,
-23,27,1,
-9,51,1,2,24,1,25,1,
-41,208,0,
-41,27,1,
-47,28,1,
-9,41,0,
-41,208,0,3,
-47,29,1,
-9,35,0,
-41,208,0,3,
-46,30,1,5,
-41,15,1,
-41,19,1,
-41,23,1,
-41,27,1,
-23,31,1,
-9,51,1,2,28,1,29,1,
-41,208,0,
-41,31,1,
-47,32,1,
-9,41,0,
-41,205,0,3,
-47,33,1,
-9,35,0,
-41,205,0,3,
-23,34,1,
-9,57,1,2,32,1,33,1,
-41,208,0,
-47,35,1,
-9,41,0,
-41,210,0,3,
-47,36,1,
-9,35,0,
-41,210,0,3,
-46,37,1,2,
-41,34,1,
-23,38,1,
-9,57,1,2,35,1,36,1,
-41,208,0,
-41,38,1,
-47,39,1,
-9,41,0,
-41,215,0,3,
-47,40,1,
-9,35,0,
-41,215,0,3,
-46,41,1,3,
-41,34,1,
-41,38,1,
-23,42,1,
-9,57,1,2,39,1,40,1,
-41,208,0,
-41,42,1,
-47,43,1,
-9,41,0,
-41,220,0,3,
-47,44,1,
-9,35,0,
-41,220,0,3,
-46,45,1,4,
-41,34,1,
-41,38,1,
-41,42,1,
-23,46,1,
-9,57,1,2,43,1,44,1,
-41,208,0,
-41,46,1,
-47,47,1,
-9,41,0,
-41,208,0,3,
-47,48,1,
-9,35,0,
-41,208,0,3,
-46,49,1,5,
-41,34,1,
-41,38,1,
-41,42,1,
-41,46,1,
-23,50,1,
-9,57,1,2,47,1,48,1,
-41,208,0,
-41,50,1,
-47,51,1,
-9,41,0,
-41,208,0,3,
-23,52,1,
-9,66,1,1,51,1,
-44,53,1,70,1,
-47,54,1,
-9,41,0,
-41,208,0,3,
-23,55,1,
-9,75,1,1,54,1,
-41,53,1,
-47,56,1,
-9,41,0,
-41,208,0,3,
-23,57,1,
-9,79,1,1,56,1,
-41,208,0,
-47,58,1,
-9,83,1,
-41,16,0,3,
-23,59,1,
-9,87,1,1,58,1,
-41,16,0,
-47,60,1,
-9,83,1,
-44,61,1,95,1,3,
-46,62,1,2,
-41,59,1,
-23,63,1,
-9,87,1,1,60,1,
-41,61,1,
-41,63,1,
-47,64,1,
-9,83,1,
-44,65,1,102,1,3,
-46,66,1,3,
-41,59,1,
-41,63,1,
-23,67,1,
-9,87,1,1,64,1,
-41,65,1,
-41,67,1,
-47,68,1,
-9,83,1,
-44,69,1,109,1,3,
-46,70,1,4,
-41,59,1,
-41,63,1,
-41,67,1,
-23,71,1,
-9,87,1,1,68,1,
-41,69,1,
-41,71,1,
-47,72,1,
-9,116,1,
-41,16,0,3,
-23,73,1,
-9,120,1,1,72,1,
-41,16,0,
-47,74,1,
-9,116,1,
-41,61,1,3,
-46,75,1,2,
-41,73,1,
-23,76,1,
-9,120,1,1,74,1,
-41,61,1,
-41,76,1,
-47,77,1,
-9,116,1,
-41,65,1,3,
-46,78,1,3,
-41,73,1,
-41,76,1,
-23,79,1,
-9,120,1,1,77,1,
-41,65,1,
-41,79,1,
-47,80,1,
-9,116,1,
-41,69,1,3,
-46,81,1,4,
-41,73,1,
-41,76,1,
-41,79,1,
-23,82,1,
-9,120,1,1,80,1,
-41,69,1,
-41,82,1,
-47,83,1,
-9,210,0,
-41,61,1,3,
-47,84,1,
-9,128,1,
-41,61,1,3,
-23,85,1,
-9,130,1,2,83,1,84,1,
-41,16,0,
-47,86,1,
-9,210,0,
-41,65,1,3,
-47,87,1,
-9,128,1,
-41,65,1,3,
-46,88,1,2,
-41,85,1,
-23,89,1,
-9,130,1,2,86,1,87,1,
-41,16,0,
-41,89,1,
-47,90,1,
-9,210,0,
-41,69,1,3,
-47,91,1,
-9,128,1,
-41,69,1,3,
-46,92,1,3,
-41,85,1,
-41,89,1,
-23,93,1,
-9,130,1,2,90,1,91,1,
-41,16,0,
-41,93,1,
-47,94,1,
-9,210,0,
-41,65,1,3,
-47,95,1,
-9,128,1,
-41,65,1,3,
-23,96,1,
-9,139,1,2,94,1,95,1,
-41,65,1,29,0,
-35,1,
-33,1,
-3,0,
-144,0,
-8,0,
-73,1,
-47,1,
-69,1,
-15,0,
-11,1,
-20,0,
-233,0,
-248,0,
-37,0,
-42,0,
-203,0,
-218,0,
-115,0,
-92,0,
-188,0,
+41,52,0,
+41,92,0,10,0,
+21,0,
+75,0,
+61,0,
+68,0,
 47,0,
-37,1,
-30,1,
 54,0,
-58,1,
-149,0,
-59,0,
-64,0,
-69,0,
+12,0,
+5,0,
+40,0,
+82,0,
 12,
-22,59,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,58,1,0,59,
-19,225,46,101,66,
-41,16,0,1,0,
-22,63,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,60,1,0,59,
-19,225,46,101,66,
-41,61,1,1,0,
-22,67,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,64,1,0,59,
-19,225,46,101,66,
-41,65,1,1,0,
-22,71,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,68,1,0,59,
-19,225,46,101,66,
-41,69,1,1,0,
-22,73,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,72,1,0,59,
-19,53,250,142,60,
-41,16,0,1,0,
-22,76,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,74,1,0,59,
-19,53,250,142,60,
-41,61,1,1,0,
-22,79,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,77,1,0,59,
-19,53,250,142,60,
-41,65,1,1,0,
-22,82,1,
-2,
-43,0,0,0,0,1,
-36,
-1,
-50,80,1,0,59,
-19,53,250,142,60,
-41,69,1,1,0,
-22,85,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,16,0,51,0,1,
-1,
-50,83,1,0,58,
-50,84,1,0,
-41,61,1,1,0,
-22,89,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,16,0,51,0,1,
-1,
-50,86,1,0,58,
-50,87,1,0,
-41,65,1,1,0,
-22,93,1,
-2,
-43,0,0,0,0,1,
-36,
-21,
-41,16,0,51,0,1,
-1,
-50,90,1,0,58,
-50,91,1,0,
-41,69,1,1,0,
-22,96,1,
-2,
-43,0,0,0,0,1,
-36,
-6,
-41,65,1,3,
-1,
-1,
-40,
-50,94,1,0,1,1,59,
-40,
-50,95,1,0,1,2,
-41,16,0,58,
-1,
-40,
-50,94,1,0,1,2,59,
-40,
-50,95,1,0,1,1,
-41,16,0,
-41,16,0,
-1,
-1,
-40,
-50,94,1,0,1,2,59,
-40,
-50,95,1,0,1,0,
-41,16,0,58,
-1,
-40,
-50,94,1,0,1,0,59,
-40,
-50,95,1,0,1,2,
-41,16,0,
-41,16,0,
-1,
-1,
-40,
-50,94,1,0,1,0,59,
-40,
-50,95,1,0,1,1,
-41,16,0,58,
-1,
-40,
-50,94,1,0,1,1,59,
-40,
-50,95,1,0,1,0,
-41,16,0,
-41,16,0,1,0,
 13,};
 static constexpr size_t SKSL_INCLUDE_sksl_interp_LENGTH = sizeof(SKSL_INCLUDE_sksl_interp);
diff --git a/src/sksl/generated/sksl_public.dehydrated.sksl b/src/sksl/generated/sksl_public.dehydrated.sksl
new file mode 100644
index 0000000..0e23ef0
--- /dev/null
+++ b/src/sksl/generated/sksl_public.dehydrated.sksl
@@ -0,0 +1,1093 @@
+static uint8_t SKSL_INCLUDE_sksl_public[] = {175,1,
+3,100,101,103,
+5,102,108,111,97,116,
+7,114,97,100,105,97,110,115,
+6,102,108,111,97,116,50,
+6,102,108,111,97,116,51,
+6,102,108,111,97,116,52,
+3,114,97,100,
+7,100,101,103,114,101,101,115,
+5,97,110,103,108,101,
+8,36,103,101,110,84,121,112,101,
+3,115,105,110,
+9,36,103,101,110,72,84,121,112,101,
+3,99,111,115,
+3,116,97,110,
+8,121,95,111,118,101,114,95,120,
+4,97,116,97,110,
+1,120,
+1,121,
+3,112,111,119,
+4,115,113,114,116,
+3,97,98,115,
+4,115,105,103,110,
+5,102,108,111,111,114,
+4,99,101,105,108,
+5,102,114,97,99,116,
+3,109,105,110,
+4,104,97,108,102,
+3,109,97,120,
+6,109,105,110,86,97,108,
+6,109,97,120,86,97,108,
+5,99,108,97,109,112,
+1,97,
+3,109,105,120,
+8,115,97,116,117,114,97,116,101,
+6,108,101,110,103,116,104,
+1,98,
+8,100,105,115,116,97,110,99,101,
+3,100,111,116,
+5,99,114,111,115,115,
+9,110,111,114,109,97,108,105,122,101,
+1,109,
+8,102,108,111,97,116,50,120,50,
+7,105,110,118,101,114,115,101,
+8,102,108,111,97,116,51,120,51,
+8,102,108,111,97,116,52,120,52,
+7,104,97,108,102,50,120,50,
+7,104,97,108,102,51,120,51,
+7,104,97,108,102,52,120,52,
+4,36,118,101,99,
+8,108,101,115,115,84,104,97,110,
+5,36,98,118,101,99,
+5,36,104,118,101,99,
+13,108,101,115,115,84,104,97,110,69,113,117,97,108,
+11,103,114,101,97,116,101,114,84,104,97,110,
+16,103,114,101,97,116,101,114,84,104,97,110,69,113,117,97,108,
+5,101,113,117,97,108,
+8,110,111,116,69,113,117,97,108,
+3,97,110,121,
+4,98,111,111,108,
+3,97,108,108,
+3,110,111,116,
+5,99,111,108,111,114,
+5,104,97,108,102,52,
+8,117,110,112,114,101,109,117,108,
+14,117,110,112,114,101,109,117,108,95,102,108,111,97,116,
+5,104,97,108,102,51,
+43,4,1,
+47,1,0,
+9,2,0,
+44,2,0,6,0,3,
+23,3,0,
+9,12,0,1,1,0,
+41,2,0,
+47,4,0,
+9,2,0,
+44,5,0,20,0,3,
+46,6,0,2,
+41,3,0,
+23,7,0,
+9,12,0,1,4,0,
+41,5,0,
+41,7,0,
+47,8,0,
+9,2,0,
+44,9,0,27,0,3,
+46,10,0,3,
+41,3,0,
+41,7,0,
+23,11,0,
+9,12,0,1,8,0,
+41,9,0,
+41,11,0,
+47,12,0,
+9,2,0,
+44,13,0,34,0,3,
+46,14,0,4,
+41,3,0,
+41,7,0,
+41,11,0,
+23,15,0,
+9,12,0,1,12,0,
+41,13,0,
+41,15,0,
+47,16,0,
+9,41,0,
+41,2,0,3,
+23,17,0,
+9,45,0,1,16,0,
+41,2,0,
+47,18,0,
+9,41,0,
+41,5,0,3,
+46,19,0,2,
+41,17,0,
+23,20,0,
+9,45,0,1,18,0,
+41,5,0,
+41,20,0,
+47,21,0,
+9,41,0,
+41,9,0,3,
+46,22,0,3,
+41,17,0,
+41,20,0,
+23,23,0,
+9,45,0,1,21,0,
+41,9,0,
+41,23,0,
+47,24,0,
+9,41,0,
+41,13,0,3,
+46,25,0,4,
+41,17,0,
+41,20,0,
+41,23,0,
+23,26,0,
+9,45,0,1,24,0,
+41,13,0,
+41,26,0,
+47,27,0,
+9,53,0,
+44,28,0,59,0,3,
+23,29,0,
+9,68,0,1,27,0,
+41,28,0,
+47,30,0,
+9,53,0,
+44,31,0,72,0,3,
+46,32,0,2,
+41,29,0,
+23,33,0,
+9,68,0,1,30,0,
+41,31,0,
+41,33,0,
+47,34,0,
+9,53,0,
+41,28,0,3,
+23,35,0,
+9,82,0,1,34,0,
+41,28,0,
+47,36,0,
+9,53,0,
+41,31,0,3,
+46,37,0,2,
+41,35,0,
+23,38,0,
+9,82,0,1,36,0,
+41,31,0,
+41,38,0,
+47,39,0,
+9,53,0,
+41,28,0,3,
+23,40,0,
+9,86,0,1,39,0,
+41,28,0,
+47,41,0,
+9,53,0,
+41,31,0,3,
+46,42,0,2,
+41,40,0,
+23,43,0,
+9,86,0,1,41,0,
+41,31,0,
+41,43,0,
+47,44,0,
+9,90,0,
+41,28,0,3,
+23,45,0,
+9,99,0,1,44,0,
+41,28,0,
+47,46,0,
+9,90,0,
+41,31,0,3,
+46,47,0,2,
+41,45,0,
+23,48,0,
+9,99,0,1,46,0,
+41,31,0,
+41,48,0,
+47,49,0,
+9,104,0,
+41,28,0,3,
+47,50,0,
+9,106,0,
+41,28,0,3,
+23,51,0,
+9,108,0,2,49,0,50,0,
+41,28,0,
+47,52,0,
+9,104,0,
+41,31,0,3,
+47,53,0,
+9,106,0,
+41,31,0,3,
+46,54,0,2,
+41,51,0,
+23,55,0,
+9,108,0,2,52,0,53,0,
+41,31,0,
+41,55,0,
+47,56,0,
+9,104,0,
+41,28,0,3,
+23,57,0,
+9,112,0,1,56,0,
+41,28,0,
+47,58,0,
+9,104,0,
+41,31,0,3,
+46,59,0,2,
+41,57,0,
+23,60,0,
+9,112,0,1,58,0,
+41,31,0,
+41,60,0,
+47,61,0,
+9,104,0,
+41,28,0,3,
+23,62,0,
+9,117,0,1,61,0,
+41,28,0,
+47,63,0,
+9,104,0,
+41,31,0,3,
+46,64,0,2,
+41,62,0,
+23,65,0,
+9,117,0,1,63,0,
+41,31,0,
+41,65,0,
+47,66,0,
+9,104,0,
+41,28,0,3,
+23,67,0,
+9,121,0,1,66,0,
+41,28,0,
+47,68,0,
+9,104,0,
+41,31,0,3,
+46,69,0,2,
+41,67,0,
+23,70,0,
+9,121,0,1,68,0,
+41,31,0,
+41,70,0,
+47,71,0,
+9,104,0,
+41,28,0,3,
+23,72,0,
+9,126,0,1,71,0,
+41,28,0,
+47,73,0,
+9,104,0,
+41,31,0,3,
+46,74,0,2,
+41,72,0,
+23,75,0,
+9,126,0,1,73,0,
+41,31,0,
+41,75,0,
+47,76,0,
+9,104,0,
+41,28,0,3,
+23,77,0,
+9,132,0,1,76,0,
+41,28,0,
+47,78,0,
+9,104,0,
+41,31,0,3,
+46,79,0,2,
+41,77,0,
+23,80,0,
+9,132,0,1,78,0,
+41,31,0,
+41,80,0,
+47,81,0,
+9,104,0,
+41,28,0,3,
+23,82,0,
+9,137,0,1,81,0,
+41,28,0,
+47,83,0,
+9,104,0,
+41,31,0,3,
+46,84,0,2,
+41,82,0,
+23,85,0,
+9,137,0,1,83,0,
+41,31,0,
+41,85,0,
+47,86,0,
+9,104,0,
+41,28,0,3,
+47,87,0,
+9,106,0,
+41,28,0,3,
+23,88,0,
+9,143,0,2,86,0,87,0,
+41,28,0,
+47,89,0,
+9,104,0,
+41,28,0,3,
+47,90,0,
+9,106,0,
+41,2,0,3,
+46,91,0,2,
+41,88,0,
+23,92,0,
+9,143,0,2,89,0,90,0,
+41,28,0,
+41,92,0,
+47,93,0,
+9,104,0,
+41,31,0,3,
+47,94,0,
+9,106,0,
+41,31,0,3,
+46,95,0,3,
+41,88,0,
+41,92,0,
+23,96,0,
+9,143,0,2,93,0,94,0,
+41,31,0,
+41,96,0,
+47,97,0,
+9,104,0,
+41,31,0,3,
+47,98,0,
+9,106,0,
+44,99,0,147,0,3,
+46,100,0,4,
+41,88,0,
+41,92,0,
+41,96,0,
+23,101,0,
+9,143,0,2,97,0,98,0,
+41,31,0,
+41,101,0,
+47,102,0,
+9,104,0,
+41,28,0,3,
+47,103,0,
+9,106,0,
+41,28,0,3,
+23,104,0,
+9,152,0,2,102,0,103,0,
+41,28,0,
+47,105,0,
+9,104,0,
+41,28,0,3,
+47,106,0,
+9,106,0,
+41,2,0,3,
+46,107,0,2,
+41,104,0,
+23,108,0,
+9,152,0,2,105,0,106,0,
+41,28,0,
+41,108,0,
+47,109,0,
+9,104,0,
+41,31,0,3,
+47,110,0,
+9,106,0,
+41,31,0,3,
+46,111,0,3,
+41,104,0,
+41,108,0,
+23,112,0,
+9,152,0,2,109,0,110,0,
+41,31,0,
+41,112,0,
+47,113,0,
+9,104,0,
+41,31,0,3,
+47,114,0,
+9,106,0,
+41,99,0,3,
+46,115,0,4,
+41,104,0,
+41,108,0,
+41,112,0,
+23,116,0,
+9,152,0,2,113,0,114,0,
+41,31,0,
+41,116,0,
+47,117,0,
+9,104,0,
+41,28,0,3,
+47,118,0,
+9,156,0,
+41,28,0,3,
+47,119,0,
+9,163,0,
+41,28,0,3,
+23,120,0,
+9,170,0,3,117,0,118,0,119,0,
+41,28,0,
+47,121,0,
+9,104,0,
+41,28,0,3,
+47,122,0,
+9,156,0,
+41,2,0,3,
+47,123,0,
+9,163,0,
+41,2,0,3,
+46,124,0,2,
+41,120,0,
+23,125,0,
+9,170,0,3,121,0,122,0,123,0,
+41,28,0,
+41,125,0,
+47,126,0,
+9,104,0,
+41,31,0,3,
+47,127,0,
+9,156,0,
+41,31,0,3,
+47,128,0,
+9,163,0,
+41,31,0,3,
+46,129,0,3,
+41,120,0,
+41,125,0,
+23,130,0,
+9,170,0,3,126,0,127,0,128,0,
+41,31,0,
+41,130,0,
+47,131,0,
+9,104,0,
+41,31,0,3,
+47,132,0,
+9,156,0,
+41,99,0,3,
+47,133,0,
+9,163,0,
+41,99,0,3,
+46,134,0,4,
+41,120,0,
+41,125,0,
+41,130,0,
+23,135,0,
+9,170,0,3,131,0,132,0,133,0,
+41,31,0,
+41,135,0,
+47,136,0,
+9,104,0,
+41,28,0,3,
+47,137,0,
+9,106,0,
+41,28,0,3,
+47,138,0,
+9,176,0,
+41,28,0,3,
+23,139,0,
+9,178,0,3,136,0,137,0,138,0,
+41,28,0,
+47,140,0,
+9,104,0,
+41,28,0,3,
+47,141,0,
+9,106,0,
+41,28,0,3,
+47,142,0,
+9,176,0,
+41,2,0,3,
+46,143,0,2,
+41,139,0,
+23,144,0,
+9,178,0,3,140,0,141,0,142,0,
+41,28,0,
+41,144,0,
+47,145,0,
+9,104,0,
+41,31,0,3,
+47,146,0,
+9,106,0,
+41,31,0,3,
+47,147,0,
+9,176,0,
+41,31,0,3,
+46,148,0,3,
+41,139,0,
+41,144,0,
+23,149,0,
+9,178,0,3,145,0,146,0,147,0,
+41,31,0,
+41,149,0,
+47,150,0,
+9,104,0,
+41,31,0,3,
+47,151,0,
+9,106,0,
+41,31,0,3,
+47,152,0,
+9,176,0,
+41,99,0,3,
+46,153,0,4,
+41,139,0,
+41,144,0,
+41,149,0,
+23,154,0,
+9,178,0,3,150,0,151,0,152,0,
+41,31,0,
+41,154,0,
+47,155,0,
+9,104,0,
+41,28,0,3,
+23,156,0,
+9,182,0,1,155,0,
+41,28,0,
+47,157,0,
+9,104,0,
+41,31,0,3,
+46,158,0,2,
+41,156,0,
+23,159,0,
+9,182,0,1,157,0,
+41,31,0,
+41,159,0,
+47,160,0,
+9,104,0,
+41,28,0,3,
+23,161,0,
+9,191,0,1,160,0,
+41,2,0,
+47,162,0,
+9,104,0,
+41,31,0,3,
+46,163,0,2,
+41,161,0,
+23,164,0,
+9,191,0,1,162,0,
+41,99,0,
+41,164,0,
+47,165,0,
+9,176,0,
+41,5,0,3,
+47,166,0,
+9,198,0,
+41,5,0,3,
+23,167,0,
+9,200,0,2,165,0,166,0,
+41,2,0,
+47,168,0,
+9,176,0,
+41,9,0,3,
+47,169,0,
+9,198,0,
+41,9,0,3,
+46,170,0,2,
+41,167,0,
+23,171,0,
+9,200,0,2,168,0,169,0,
+41,2,0,
+41,171,0,
+47,172,0,
+9,176,0,
+41,13,0,3,
+47,173,0,
+9,198,0,
+41,13,0,3,
+46,174,0,3,
+41,167,0,
+41,171,0,
+23,175,0,
+9,200,0,2,172,0,173,0,
+41,2,0,
+41,175,0,
+47,176,0,
+9,104,0,
+41,28,0,3,
+47,177,0,
+9,106,0,
+41,28,0,3,
+23,178,0,
+9,209,0,2,176,0,177,0,
+41,2,0,
+47,179,0,
+9,104,0,
+41,31,0,3,
+47,180,0,
+9,106,0,
+41,31,0,3,
+46,181,0,2,
+41,178,0,
+23,182,0,
+9,209,0,2,179,0,180,0,
+41,99,0,
+41,182,0,
+47,183,0,
+9,176,0,
+41,9,0,3,
+47,184,0,
+9,198,0,
+41,9,0,3,
+23,185,0,
+9,213,0,2,183,0,184,0,
+41,9,0,
+47,186,0,
+9,104,0,
+41,28,0,3,
+23,187,0,
+9,219,0,1,186,0,
+41,28,0,
+47,188,0,
+9,104,0,
+41,31,0,3,
+46,189,0,2,
+41,187,0,
+23,190,0,
+9,219,0,1,188,0,
+41,31,0,
+41,190,0,
+47,191,0,
+9,229,0,
+44,192,0,231,0,3,
+23,193,0,
+9,240,0,1,191,0,
+41,192,0,
+47,194,0,
+9,229,0,
+44,195,0,248,0,3,
+46,196,0,2,
+41,193,0,
+23,197,0,
+9,240,0,1,194,0,
+41,195,0,
+41,197,0,
+47,198,0,
+9,229,0,
+44,199,0,1,1,3,
+46,200,0,3,
+41,193,0,
+41,197,0,
+23,201,0,
+9,240,0,1,198,0,
+41,199,0,
+41,201,0,
+47,202,0,
+9,229,0,
+44,203,0,10,1,3,
+46,204,0,4,
+41,193,0,
+41,197,0,
+41,201,0,
+23,205,0,
+9,240,0,1,202,0,
+41,203,0,
+41,205,0,
+47,206,0,
+9,229,0,
+44,207,0,18,1,3,
+46,208,0,5,
+41,193,0,
+41,197,0,
+41,201,0,
+41,205,0,
+23,209,0,
+9,240,0,1,206,0,
+41,207,0,
+41,209,0,
+47,210,0,
+9,229,0,
+44,211,0,26,1,3,
+46,212,0,6,
+41,193,0,
+41,197,0,
+41,201,0,
+41,205,0,
+41,209,0,
+23,213,0,
+9,240,0,1,210,0,
+41,211,0,
+41,213,0,
+47,214,0,
+9,104,0,
+44,215,0,34,1,3,
+47,216,0,
+9,106,0,
+41,215,0,3,
+23,217,0,
+9,39,1,2,214,0,216,0,
+44,218,0,48,1,
+47,219,0,
+9,104,0,
+44,220,0,54,1,3,
+47,221,0,
+9,106,0,
+41,220,0,3,
+46,222,0,2,
+41,217,0,
+23,223,0,
+9,39,1,2,219,0,221,0,
+41,218,0,
+41,223,0,
+47,224,0,
+9,104,0,
+41,215,0,3,
+47,225,0,
+9,106,0,
+41,215,0,3,
+23,226,0,
+9,60,1,2,224,0,225,0,
+41,218,0,
+47,227,0,
+9,104,0,
+41,220,0,3,
+47,228,0,
+9,106,0,
+41,220,0,3,
+46,229,0,2,
+41,226,0,
+23,230,0,
+9,60,1,2,227,0,228,0,
+41,218,0,
+41,230,0,
+47,231,0,
+9,104,0,
+41,215,0,3,
+47,232,0,
+9,106,0,
+41,215,0,3,
+23,233,0,
+9,74,1,2,231,0,232,0,
+41,218,0,
+47,234,0,
+9,104,0,
+41,220,0,3,
+47,235,0,
+9,106,0,
+41,220,0,3,
+46,236,0,2,
+41,233,0,
+23,237,0,
+9,74,1,2,234,0,235,0,
+41,218,0,
+41,237,0,
+47,238,0,
+9,104,0,
+41,215,0,3,
+47,239,0,
+9,106,0,
+41,215,0,3,
+23,240,0,
+9,86,1,2,238,0,239,0,
+41,218,0,
+47,241,0,
+9,104,0,
+41,220,0,3,
+47,242,0,
+9,106,0,
+41,220,0,3,
+46,243,0,2,
+41,240,0,
+23,244,0,
+9,86,1,2,241,0,242,0,
+41,218,0,
+41,244,0,
+47,245,0,
+9,104,0,
+41,215,0,3,
+47,246,0,
+9,106,0,
+41,215,0,3,
+23,247,0,
+9,103,1,2,245,0,246,0,
+41,218,0,
+47,248,0,
+9,104,0,
+41,220,0,3,
+47,249,0,
+9,106,0,
+41,220,0,3,
+46,250,0,2,
+41,247,0,
+23,251,0,
+9,103,1,2,248,0,249,0,
+41,218,0,
+41,251,0,
+47,252,0,
+9,104,0,
+41,218,0,3,
+47,253,0,
+9,106,0,
+41,218,0,3,
+46,254,0,3,
+41,247,0,
+41,251,0,
+23,255,0,
+9,103,1,2,252,0,253,0,
+41,218,0,
+41,255,0,
+47,0,1,
+9,104,0,
+41,215,0,3,
+47,1,1,
+9,106,0,
+41,215,0,3,
+23,2,1,
+9,109,1,2,0,1,1,1,
+41,218,0,
+47,3,1,
+9,104,0,
+41,220,0,3,
+47,4,1,
+9,106,0,
+41,220,0,3,
+46,5,1,2,
+41,2,1,
+23,6,1,
+9,109,1,2,3,1,4,1,
+41,218,0,
+41,6,1,
+47,7,1,
+9,104,0,
+41,218,0,3,
+47,8,1,
+9,106,0,
+41,218,0,3,
+46,9,1,3,
+41,2,1,
+41,6,1,
+23,10,1,
+9,109,1,2,7,1,8,1,
+41,218,0,
+41,10,1,
+47,11,1,
+9,104,0,
+41,218,0,3,
+23,12,1,
+9,118,1,1,11,1,
+44,13,1,122,1,
+47,14,1,
+9,104,0,
+41,218,0,3,
+23,15,1,
+9,127,1,1,14,1,
+41,13,1,
+47,16,1,
+9,104,0,
+41,218,0,3,
+23,17,1,
+9,131,1,1,16,1,
+41,218,0,
+47,18,1,
+9,135,1,
+44,19,1,141,1,3,
+23,20,1,
+9,147,1,1,18,1,
+41,19,1,
+47,21,1,
+9,135,1,
+41,13,0,3,
+23,22,1,
+9,156,1,1,21,1,
+41,13,0,35,0,
+57,0,
+253,0,
+251,0,
+40,0,
+72,0,
+126,0,
+30,0,
+177,0,
+20,0,
+166,0,
+173,0,
+237,0,
+67,0,
+77,0,
+219,0,
+226,0,
+198,0,
+155,0,
+205,0,
+212,0,
+107,0,
+92,0,
+145,0,
+181,0,
+255,0,
+248,0,
+47,0,
+9,0,
+150,0,
+62,0,
+25,0,
+52,0,
+35,0,
+1,1,
+3,1,
+12,
+22,3,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,1,0,0,59,
+19,53,250,142,60,
+41,2,0,1,0,
+22,7,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,4,0,0,59,
+19,53,250,142,60,
+41,5,0,1,0,
+22,11,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,8,0,0,59,
+19,53,250,142,60,
+41,9,0,1,0,
+22,15,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,12,0,0,59,
+19,53,250,142,60,
+41,13,0,1,0,
+22,17,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,16,0,0,59,
+19,225,46,101,66,
+41,2,0,1,0,
+22,20,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,18,0,0,59,
+19,225,46,101,66,
+41,5,0,1,0,
+22,23,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,21,0,0,59,
+19,225,46,101,66,
+41,9,0,1,0,
+22,26,0,
+2,
+43,0,0,0,0,1,
+36,
+1,
+50,24,0,0,59,
+19,225,46,101,66,
+41,13,0,1,0,
+22,167,0,
+2,
+43,0,0,0,0,1,
+36,
+21,
+41,2,0,161,0,1,
+1,
+50,165,0,0,58,
+50,166,0,0,
+41,5,0,1,0,
+22,171,0,
+2,
+43,0,0,0,0,1,
+36,
+21,
+41,2,0,161,0,1,
+1,
+50,168,0,0,58,
+50,169,0,0,
+41,9,0,1,0,
+22,175,0,
+2,
+43,0,0,0,0,1,
+36,
+21,
+41,2,0,161,0,1,
+1,
+50,172,0,0,58,
+50,173,0,0,
+41,13,0,1,0,
+22,185,0,
+2,
+43,0,0,0,0,1,
+36,
+6,
+41,9,0,3,
+1,
+1,
+40,
+50,183,0,0,1,1,59,
+40,
+50,184,0,0,1,2,
+41,2,0,58,
+1,
+40,
+50,183,0,0,1,2,59,
+40,
+50,184,0,0,1,1,
+41,2,0,
+41,2,0,
+1,
+1,
+40,
+50,183,0,0,1,2,59,
+40,
+50,184,0,0,1,0,
+41,2,0,58,
+1,
+40,
+50,183,0,0,1,0,59,
+40,
+50,184,0,0,1,2,
+41,2,0,
+41,2,0,
+1,
+1,
+40,
+50,183,0,0,1,0,59,
+40,
+50,184,0,0,1,1,
+41,2,0,58,
+1,
+40,
+50,183,0,0,1,1,59,
+40,
+50,184,0,0,1,0,
+41,2,0,
+41,2,0,1,0,
+22,20,1,
+2,
+43,0,0,0,0,1,
+36,
+6,
+41,19,1,2,
+1,
+40,
+50,18,1,0,3,0,1,2,60,
+21,
+41,99,0,112,0,2,
+40,
+50,18,1,0,1,3,
+19,23,183,209,56,
+44,23,1,171,1,
+40,
+50,18,1,0,1,3,1,0,
+22,22,1,
+2,
+43,0,0,0,0,1,
+36,
+6,
+41,13,0,2,
+1,
+40,
+50,21,1,0,3,0,1,2,60,
+21,
+41,2,0,104,0,2,
+40,
+50,21,1,0,1,3,
+19,23,183,209,56,
+41,9,0,
+40,
+50,21,1,0,1,3,1,0,
+13,};
+static constexpr size_t SKSL_INCLUDE_sksl_public_LENGTH = sizeof(SKSL_INCLUDE_sksl_public);
diff --git a/src/sksl/sksl_interp.sksl b/src/sksl/sksl_interp.sksl
index 67854cf..2a274fc 100644
--- a/src/sksl/sksl_interp.sksl
+++ b/src/sksl/sksl_interp.sksl
@@ -1,108 +1,27 @@
-$genType atan($genType y_over_x);
-$genHType atan($genHType y_over_x);
-$genType cos($genType y);
-$genHType cos($genHType y);
-float dot($genType x, $genType y);
-half dot($genHType x, $genHType y);
-$genType fract($genType x);
-$genHType fract($genHType x);
-float2x2 inverse(float2x2 m);
-float3x3 inverse(float3x3 m);
-float4x4 inverse(float4x4 m);
-half2x2 inverse(half2x2 m);
-half3x3 inverse(half3x3 m);
-half4x4 inverse(half4x4 m);
-float length($genType x);
-half length($genHType x);
-$genType normalize($genType x);
-$genHType normalize($genHType x);
-$genType pow($genType x, $genType y);
-$genHType pow($genHType x, $genHType y);
-$genType sin($genType x);
-$genHType sin($genHType x);
-$genType sqrt($genType x);
-$genHType sqrt($genHType x);
-$genType tan($genType x);
-$genHType tan($genHType x);
+// Certain useful GLSL intrinsics (or integer versions of those) that aren't in GLSL ES 1.00,
+// but are supported by the ByteCode interpreter.
 
-$genType min($genType x, $genType y);
-$genType min($genType x, float y);
-$genHType min($genHType x, $genHType y);
-$genHType min($genHType x, half y);
 $genIType min($genIType x, $genIType y);
-$genIType min($genIType x, int y);
-$genType max($genType x, $genType y);
-$genType max($genType x, float y);
-$genHType max($genHType x, $genHType y);
-$genHType max($genHType x, half y);
+$genIType min($genIType x, int       y);
 $genIType max($genIType x, $genIType y);
-$genIType max($genIType x, int y);
-$genType clamp($genType x, $genType minVal, $genType maxVal);
-$genType clamp($genType x, float minVal, float maxVal);
-$genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
-$genHType clamp($genHType x, half minVal, half maxVal);
+$genIType max($genIType x, int       y);
 $genIType clamp($genIType x, $genIType minVal, $genIType maxVal);
-$genIType clamp($genIType x, int minVal, int maxVal);
-$genType saturate($genType x);
-$genHType saturate($genHType x);
+$genIType clamp($genIType x, int       minVal, int       maxVal);
 
 $genType  mix($genType  x, $genType  y, $genBType a);
 $genHType mix($genHType x, $genHType y, $genBType a);
 $genIType mix($genIType x, $genIType y, $genBType a);
 $genBType mix($genBType x, $genBType y, $genBType a);
 
-$genType  mix($genType  x, $genType  y, $genType a);
-$genType  mix($genType  x, $genType  y, float a);
-$genHType mix($genHType x, $genHType y, $genHType a);
-$genHType mix($genHType x, $genHType y, half a);
-
-$bvec lessThan($vec  x, $vec  y);
-$bvec lessThan($hvec x, $hvec y);
 $bvec lessThan($ivec x, $ivec y);
 $bvec lessThan($uvec x, $uvec y);
-$bvec lessThanEqual($vec  x, $vec  y);
-$bvec lessThanEqual($hvec x, $hvec y);
 $bvec lessThanEqual($ivec x, $ivec y);
 $bvec lessThanEqual($uvec x, $uvec y);
-$bvec greaterThan($vec  x, $vec  y);
-$bvec greaterThan($hvec x, $hvec y);
 $bvec greaterThan($ivec x, $ivec y);
 $bvec greaterThan($uvec x, $uvec y);
-$bvec greaterThanEqual($vec  x, $vec  y);
-$bvec greaterThanEqual($hvec x, $hvec y);
 $bvec greaterThanEqual($ivec x, $ivec y);
 $bvec greaterThanEqual($uvec x, $uvec y);
-$bvec equal($vec  x, $vec  y);
-$bvec equal($hvec x, $hvec y);
 $bvec equal($ivec x, $ivec y);
 $bvec equal($uvec x, $uvec y);
-$bvec equal($bvec x, $bvec y);
-$bvec notEqual($vec  x, $vec  y);
-$bvec notEqual($hvec x, $hvec y);
 $bvec notEqual($ivec x, $ivec y);
 $bvec notEqual($uvec x, $uvec y);
-$bvec notEqual($bvec x, $bvec y);
-
-bool  any($bvec x);
-bool  all($bvec x);
-$bvec not($bvec x);
-
-float  degrees(float  rad) { return rad * 57.2957795; }
-float2 degrees(float2 rad) { return rad * 57.2957795; }
-float3 degrees(float3 rad) { return rad * 57.2957795; }
-float4 degrees(float4 rad) { return rad * 57.2957795; }
-
-float  radians(float  deg) { return deg * 0.0174532925; }
-float2 radians(float2 deg) { return deg * 0.0174532925; }
-float3 radians(float3 deg) { return deg * 0.0174532925; }
-float4 radians(float4 deg) { return deg * 0.0174532925; }
-
-float distance(float2 a, float2 b) { return length(a - b); }
-float distance(float3 a, float3 b) { return length(a - b); }
-float distance(float4 a, float4 b) { return length(a - b); }
-
-float3 cross(float3 a, float3 b) {
-    return float3(a.y * b.z - a.z * b.y,
-                  a.z * b.x - a.x * b.z,
-                  a.x * b.y - a.y * b.x);
-}
diff --git a/src/sksl/sksl_public.sksl b/src/sksl/sksl_public.sksl
new file mode 100644
index 0000000..5b80333
--- /dev/null
+++ b/src/sksl/sksl_public.sksl
@@ -0,0 +1,134 @@
+// Reduced set of intrinsics that are available to public SkSL (RuntimeEffect and Interpreter)
+
+// See "The OpenGL ES Shading Language, Version 1.00, Section 8"
+// For all of the TODO comments, refer to skbug.com/10913
+
+// 8.1 : Angle and Trigonometry Functions
+float  radians(float  deg) { return deg * 0.0174532925; }
+float2 radians(float2 deg) { return deg * 0.0174532925; }
+float3 radians(float3 deg) { return deg * 0.0174532925; }
+float4 radians(float4 deg) { return deg * 0.0174532925; }
+
+float  degrees(float  rad) { return rad * 57.2957795; }
+float2 degrees(float2 rad) { return rad * 57.2957795; }
+float3 degrees(float3 rad) { return rad * 57.2957795; }
+float4 degrees(float4 rad) { return rad * 57.2957795; }
+
+$genType  sin($genType  angle);
+$genHType sin($genHType angle);
+$genType  cos($genType  angle);
+$genHType cos($genHType angle);
+$genType  tan($genType  angle);
+$genHType tan($genHType angle);
+// TODO: asin(x)
+// TODO: acos(y)
+// TODO: atan(y, x)
+$genType  atan($genType  y_over_x);
+$genHType atan($genHType y_over_x);
+
+// 8.2 : Exponential Functions
+$genType  pow($genType  x, $genType  y);
+$genHType pow($genHType x, $genHType y);
+// TODO: exp
+// TODO: log
+// TODO: exp2
+// TODO: log2
+$genType  sqrt($genType  x);
+$genHType sqrt($genHType x);
+// TODO: inversesqrt
+
+// 8.3 : Common Functions
+$genType  abs($genType  x);
+$genHType abs($genHType x);
+$genType  sign($genType  x);
+$genHType sign($genHType x);
+$genType  floor($genType  x);
+$genHType floor($genHType x);
+$genType  ceil($genType  x);
+$genHType ceil($genHType x);
+$genType  fract($genType  x);
+$genHType fract($genHType x);
+// TODO: mod(x, y)
+
+$genType  min($genType  x, $genType  y);
+$genType  min($genType  x, float     y);
+$genHType min($genHType x, $genHType y);
+$genHType min($genHType x, half      y);
+$genType  max($genType  x, $genType  y);
+$genType  max($genType  x, float     y);
+$genHType max($genHType x, $genHType y);
+$genHType max($genHType x, half      y);
+$genType  clamp($genType  x, $genType  minVal, $genType  maxVal);
+$genType  clamp($genType  x, float     minVal, float     maxVal);
+$genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
+$genHType clamp($genHType x, half      minVal, half      maxVal);
+$genType  mix($genType  x, $genType  y, $genType a);
+$genType  mix($genType  x, $genType  y, float a);
+$genHType mix($genHType x, $genHType y, $genHType a);
+$genHType mix($genHType x, $genHType y, half a);
+// TODO: step(edge, x)
+// TODO: smoothstep(edge0, edge1, x)
+
+// SkSL Extension to GLSL:
+$genType  saturate($genType  x);
+$genHType saturate($genHType x);
+
+// 8.4 : Geometric Functions
+float length($genType  x);
+half  length($genHType x);
+
+float distance(float2 a, float2 b) { return length(a - b); }
+float distance(float3 a, float3 b) { return length(a - b); }
+float distance(float4 a, float4 b) { return length(a - b); }
+
+float dot($genType  x, $genType  y);
+half  dot($genHType x, $genHType y);
+
+float3 cross(float3 a, float3 b) {
+    return float3(a.y * b.z - a.z * b.y,
+                  a.z * b.x - a.x * b.z,
+                  a.x * b.y - a.y * b.x);
+}
+
+$genType  normalize($genType  x);
+$genHType normalize($genHType x);
+// TODO: faceforward(N, I, Nref)
+// TODO: reflect(I, N)
+// TODO: refract(I, N, eta)
+
+// 8.5 : Matrix Functions
+// TODO: matrixCompMult(x, y)
+
+// Not supported until GLSL 1.40. Poly-filled by SkSL:
+float2x2 inverse(float2x2 m);
+float3x3 inverse(float3x3 m);
+float4x4 inverse(float4x4 m);
+half2x2  inverse(half2x2 m);
+half3x3  inverse(half3x3 m);
+half4x4  inverse(half4x4 m);
+
+// 8.6 : Vector Relational Functions
+$bvec lessThan($vec  x, $vec  y);
+$bvec lessThan($hvec x, $hvec y);
+$bvec lessThanEqual($vec  x, $vec  y);
+$bvec lessThanEqual($hvec x, $hvec y);
+$bvec greaterThan($vec  x, $vec  y);
+$bvec greaterThan($hvec x, $hvec y);
+$bvec greaterThanEqual($vec  x, $vec  y);
+$bvec greaterThanEqual($hvec x, $hvec y);
+$bvec equal($vec  x, $vec  y);
+$bvec equal($hvec x, $hvec y);
+$bvec equal($bvec x, $bvec y);
+$bvec notEqual($vec  x, $vec  y);
+$bvec notEqual($hvec x, $hvec y);
+$bvec notEqual($bvec x, $bvec y);
+
+bool  any($bvec x);
+bool  all($bvec x);
+$bvec not($bvec x);
+
+// Miscellaneous SkSL intrinsics that are not part of GLSL:
+
+// The max() guards against division by zero when the incoming color is transparent black
+half4  unpremul      (half4  color) { return half4 (color.rgb / max(color.a, 0.0001), color.a); }
+float4 unpremul_float(float4 color) { return float4(color.rgb / max(color.a, 0.0001), color.a); }
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index 21185eb..ab24457 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -39,8 +39,11 @@
     test("in bool Flag; layout(when=Flag) uniform float Input;", "", "when");
     test("layout(tracked) uniform float Input;", "", "tracked");
 
-    // Runtime SkSL supports a limited set of uniform types. No samplers, bool, or int, for example:
-    test("uniform sampler2D s;", "", "uniform");
+    // GLSL types like sampler2D and texture2D are not allowed anywhere:
+    test("uniform sampler2D s;", "", "no type named 'sampler2D'");
+    test("uniform texture2D s;", "", "no type named 'texture2D'");
+
+    // Runtime SkSL supports a limited set of uniform types. No bool, or int, for example:
     test("uniform bool b;", "", "uniform");
     test("uniform int i;", "", "uniform");
 
@@ -75,6 +78,9 @@
          "half4 color = sample(p.x > 10 ? child1 : child2);",
          "expression");
 
+    // sk_Caps is an internal system. It should not be visible to runtime effects
+    test("", "if (sk_Caps.integerSupport) { p = p.yx; }", "unknown identifier 'sk_Caps'");
+
     // Errors that aren't caught until later in the compilation process (during optimize())
     test("", "return half4(1);", "unreachable");
     test("half badFunc() { }", "", "without returning");