diff --git a/.buildkite/ci.mjs b/.buildkite/ci.mjs index 7beccb6cf9be86..c4e114b16d3e89 100755 --- a/.buildkite/ci.mjs +++ b/.buildkite/ci.mjs @@ -96,6 +96,7 @@ function getTargetLabel(target) { * @property {string} release * @property {Tier} [tier] * @property {string[]} [features] + * @property {boolean} [zigTests] This platform wants Zig unit tests. */ /** @@ -105,7 +106,7 @@ const buildPlatforms = [ { os: "darwin", arch: "aarch64", release: "14" }, { os: "darwin", arch: "x64", release: "14" }, { os: "linux", arch: "aarch64", distro: "amazonlinux", release: "2023", features: ["docker"] }, - { os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"] }, + { os: "linux", arch: "x64", distro: "amazonlinux", release: "2023", features: ["docker"], zigTests: true }, { os: "linux", arch: "x64", baseline: true, distro: "amazonlinux", release: "2023", features: ["docker"] }, { os: "linux", arch: "aarch64", abi: "musl", distro: "alpine", release: "3.21" }, { os: "linux", arch: "x64", abi: "musl", distro: "alpine", release: "3.21" }, @@ -476,18 +477,42 @@ function getBuildZigStep(platform, options) { } /** + * Similar to {@link getBuildZigStep}, but builds Zig unit tests instead of the + * normal `bun-zig` object file. * @param {Platform} platform * @param {PipelineOptions} options * @returns {Step} */ -function getLinkBunStep(platform, options) { +function getBuildZigTestsStep(platform, options) { + const toolchain = getBuildToolchain(platform); return { - key: `${getTargetKey(platform)}-build-bun`, - label: `${getTargetLabel(platform)} - build-bun`, + key: `${getTargetKey(platform)}-build-zig-tests`, + label: `${getTargetLabel(platform)} - build-zig-tests`, + agents: getZigAgent(platform, options), + retry: getRetry(), + cancel_on_build_failing: isMergeQueue(), + env: getBuildEnv(platform, options), + // note: uses same target name. See `BuildBun.cmake` for details. + command: `bun run zig:test:ci --target bun-zig --toolchain ${toolchain}`, + timeout_in_minutes: 35, + }; +} + +/** + * @param {Platform} platform + * @param {PipelineOptions} options + * @param {boolean} zigTests link Zig unit tests instead of the normal `bun-zig` object file. Default: `false` + * @returns {Step} + */ +function getLinkBunStep(platform, options, zigTests = false) { + const suffix = zigTests ? "build-bug-zig-tests" : "build-bun"; + return { + key: `${getTargetKey(platform)}-${suffix}`, + label: `${getTargetLabel(platform)} - ${suffix}`, depends_on: [ `${getTargetKey(platform)}-build-vendor`, `${getTargetKey(platform)}-build-cpp`, - `${getTargetKey(platform)}-build-zig`, + `${getTargetKey(platform)}-build-zig${zigTests ? "-tests" : ""}`, ], agents: getCppAgent(platform, options), retry: getRetry(), @@ -496,7 +521,7 @@ function getLinkBunStep(platform, options) { BUN_LINK_ONLY: "ON", ...getBuildEnv(platform, options), }, - command: "bun run build:ci --target bun", + command: `bun run ${zigTests ? "zig:test:ci" : "build:ci"} --target bun`, }; } @@ -563,6 +588,33 @@ function getTestBunStep(platform, options, testOptions = {}) { }; } +/** + * @param {Platform} platform + * @param {PipelineOptions} options + * @param {TestOptions} [testOptions] + * @returns {Step} + */ +function getZigTestBunStep(platform, options, testOptions = {}) { + const { buildId } = testOptions; + + const depends = []; + if (!buildId) { + depends.push(`${getTargetKey(platform)}-build-bun-zig-tests`); + } + const profile = platform.profile?.toLowerCase() ?? "release"; + return { + key: `${getPlatformKey(platform)}-test-zig-bun`, + label: `${getPlatformLabel(platform)} - test-zig-bun`, + depends_on: depends, + agents: getTestAgent(platform, options), + retry: getRetry(), + cancel_on_build_failing: isMergeQueue(), + // TODO: run tests in parallel + // parallelism: unifiedTests ? undefined : os === "darwin" ? 2 : 10, + command: `./build/${profile}/bun-test`, + }; +} + /** * @param {Platform} platform * @param {PipelineOptions} options @@ -1028,6 +1080,7 @@ async function getPipelineOptions() { */ async function getPipeline(options = {}) { const priority = getPriority(); + const isMain = isMainBranch(); if (isBuildManual() && !Object.keys(options).length) { return { @@ -1076,6 +1129,13 @@ async function getPipeline(options = {}) { } } + /** + * @param {Platform} target + * @returns {boolean} + */ + const targetWantsZigTest = target => + Boolean(target.zigTests && (!(isMain || options.skipTests) || options.forceTests)); + if (!buildId) { steps.push( ...buildPlatforms @@ -1094,6 +1154,11 @@ async function getPipeline(options = {}) { getBuildCppStep(target, options), getBuildZigStep(target, options), getLinkBunStep(target, options), + // TODO: blocked by https://github.com/ziglang/zig/issues/23281 + // un-comment once fixed. + // ...(targetWantsZigTest(target) + // ? [getBuildZigTestsStep(target, options), getLinkBunStep(target, options, true)] + // : []), ], }, imagePlatforms.has(imageKey) ? `${imageKey}-build-image` : undefined, @@ -1102,7 +1167,7 @@ async function getPipeline(options = {}) { ); } - if (!isMainBranch()) { + if (!isMain) { const { skipTests, forceTests, unifiedTests, testFiles } = options; if (!skipTests || forceTests) { steps.push( @@ -1111,13 +1176,18 @@ async function getPipeline(options = {}) { .map(target => ({ key: getTargetKey(target), group: getTargetLabel(target), - steps: [getTestBunStep(target, options, { unifiedTests, testFiles, buildId })], + steps: [ + getTestBunStep(target, options, { unifiedTests, testFiles, buildId }), + // TODO: blocked by https://github.com/ziglang/zig/issues/23281 + // un-comment once fixed. + // ...(targetWantsZigTest(target) + // ? [getZigTestBunStep(target, options, { unifiedTests, testFiles, buildId })] + // : []), + ], })), ); } - } - - if (isMainBranch()) { + } else { steps.push(getReleaseStep(buildPlatforms, options)); } diff --git a/build.zig b/build.zig index 5bb280418240ba..a29fa6c3dd4273 100644 --- a/build.zig +++ b/build.zig @@ -285,6 +285,40 @@ pub fn build(b: *Build) !void { step.dependOn(addInstallObjectFile(b, bun_obj, "bun-zig", obj_format)); } + // zig build test + { + var step = b.step("test", "Build Bun's unit test suite"); + var o = build_options; + var unit_tests = b.addTest(.{ + .name = "bun-test", + .optimize = build_options.optimize, + .root_source_file = b.path("src/unit_test.zig"), + .test_runner = .{ .path = b.path("src/main_test.zig"), .mode = .simple }, + .target = build_options.target, + .use_llvm = !build_options.no_llvm, + .use_lld = if (build_options.os == .mac) false else !build_options.no_llvm, + .omit_frame_pointer = false, + .strip = false, + }); + configureObj(b, &o, unit_tests); + // Setting `linker_allow_shlib_undefined` causes the linker to ignore + // all undefined symbols. We want this because all we care about is the + // object file Zig creates; we perform our own linking later. There is + // currently no way to make a test build that only creates an object + // file w/o creating an executable. + // + // See: https://github.com/ziglang/zig/issues/23374 + unit_tests.linker_allow_shlib_undefined = true; + unit_tests.link_function_sections = true; + unit_tests.link_data_sections = true; + unit_tests.bundle_ubsan_rt = false; + + const bin = unit_tests.getEmittedBin(); + const obj = bin.dirname().path(b, "bun-test.o"); + const cpy_obj = b.addInstallFile(obj, "bun-test.o"); + step.dependOn(&cpy_obj.step); + } + // zig build windows-shim { var step = b.step("windows-shim", "Build the Windows shim (bun_shim_impl.exe + bun_shim_debug.exe)"); @@ -456,6 +490,11 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile { .omit_frame_pointer = false, .strip = false, // stripped at the end }); + configureObj(b, opts, obj); + return obj; +} + +fn configureObj(b: *Build, opts: *BunBuildOptions, obj: *Compile) void { if (opts.enable_asan) { if (@hasField(Build.Module, "sanitize_address")) { obj.root_module.sanitize_address = true; @@ -494,8 +533,6 @@ pub fn addBunObject(b: *Build, opts: *BunBuildOptions) *Compile { const translate_c = getTranslateC(b, opts.target, opts.optimize); obj.root_module.addImport("translated-c-headers", translate_c.createModule()); - - return obj; } const ObjectFormat = enum { diff --git a/cmake/Options.cmake b/cmake/Options.cmake index 5874cf644e4649..ac3f2fd439ba8a 100644 --- a/cmake/Options.cmake +++ b/cmake/Options.cmake @@ -26,6 +26,15 @@ else() setx(DEBUG OFF) endif() +optionx(BUN_TEST BOOL "Build Bun's unit test suite instead of the normal build" DEFAULT OFF) + +if (BUN_TEST) + setx(TEST ON) +else() + setx(TEST OFF) +endif() + + if(CMAKE_BUILD_TYPE MATCHES "MinSizeRel") setx(ENABLE_SMOL ON) endif() @@ -62,7 +71,14 @@ if(ARCH STREQUAL "x64") optionx(ENABLE_BASELINE BOOL "If baseline features should be used for older CPUs (e.g. disables AVX, AVX2)" DEFAULT OFF) endif() -optionx(ENABLE_LOGS BOOL "If debug logs should be enabled" DEFAULT ${DEBUG}) +# Disabling logs by default for tests yields faster builds +if (DEBUG AND NOT TEST) + set(DEFAULT_ENABLE_LOGS ON) +else() + set(DEFAULT_ENABLE_LOGS OFF) +endif() + +optionx(ENABLE_LOGS BOOL "If debug logs should be enabled" DEFAULT ${DEFAULT_ENABLE_LOGS}) optionx(ENABLE_ASSERTIONS BOOL "If debug assertions should be enabled" DEFAULT ${DEBUG}) optionx(ENABLE_CANARY BOOL "If canary features should be enabled" DEFAULT ON) diff --git a/cmake/scripts/DownloadZig.cmake b/cmake/scripts/DownloadZig.cmake index d5bced5b715a42..df5459da2352d6 100644 --- a/cmake/scripts/DownloadZig.cmake +++ b/cmake/scripts/DownloadZig.cmake @@ -29,6 +29,9 @@ else() endif() set(ZIG_NAME bootstrap-${ZIG_ARCH}-${ZIG_OS_ABI}) +if(ZIG_COMPILER_SAFE) + set(ZIG_NAME ${ZIG_NAME}-ReleaseSafe) +endif() set(ZIG_FILENAME ${ZIG_NAME}.zip) if(CMAKE_HOST_WIN32) diff --git a/cmake/targets/BuildBun.cmake b/cmake/targets/BuildBun.cmake index 084dcc90543723..502a6325808957 100644 --- a/cmake/targets/BuildBun.cmake +++ b/cmake/targets/BuildBun.cmake @@ -12,6 +12,10 @@ else() set(bunStrip bun) endif() +if(TEST) + set(bun ${bun}-test) +endif() + set(bunExe ${bun}${CMAKE_EXECUTABLE_SUFFIX}) if(bunStrip) @@ -528,7 +532,6 @@ file(GLOB_RECURSE BUN_ZIG_SOURCES ${CONFIGURE_DEPENDS} list(APPEND BUN_ZIG_SOURCES ${CWD}/build.zig - ${CWD}/src/main.zig ${BUN_BINDGEN_ZIG_OUTPUTS} ) @@ -550,7 +553,13 @@ else() list(APPEND BUN_ZIG_GENERATED_SOURCES ${BUN_BAKE_RUNTIME_OUTPUTS}) endif() -set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-zig.o) +if (TEST) + set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-test.o) + set(ZIG_STEPS test) +else() + set(BUN_ZIG_OUTPUT ${BUILD_PATH}/bun-zig.o) + set(ZIG_STEPS obj) +endif() if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM|arm64|ARM64|aarch64|AARCH64") if(APPLE) @@ -579,10 +588,10 @@ register_command( GROUP console COMMENT - "Building src/*.zig for ${ZIG_TARGET}" + "Building src/*.zig into ${BUN_ZIG_OUTPUT} for ${ZIG_TARGET}" COMMAND ${ZIG_EXECUTABLE} - build obj + build ${ZIG_STEPS} ${CMAKE_ZIG_FLAGS} --prefix ${BUILD_PATH} -Dobj_format=${ZIG_OBJECT_FORMAT} @@ -596,6 +605,7 @@ register_command( -Dcodegen_path=${CODEGEN_PATH} -Dcodegen_embed=$<IF:$<BOOL:${CODEGEN_EMBED}>,true,false> --prominent-compile-errors + --summary all ${ZIG_FLAGS_BUN} ARTIFACTS ${BUN_ZIG_OUTPUT} diff --git a/cmake/tools/SetupZig.cmake b/cmake/tools/SetupZig.cmake index 048aa40b3fada0..2de33023f3d9de 100644 --- a/cmake/tools/SetupZig.cmake +++ b/cmake/tools/SetupZig.cmake @@ -50,6 +50,7 @@ optionx(ZIG_OBJECT_FORMAT "obj|bc" "Output file format for Zig object files" DEF optionx(ZIG_LOCAL_CACHE_DIR FILEPATH "The path to local the zig cache directory" DEFAULT ${CACHE_PATH}/zig/local) optionx(ZIG_GLOBAL_CACHE_DIR FILEPATH "The path to the global zig cache directory" DEFAULT ${CACHE_PATH}/zig/global) +optionx(ZIG_COMPILER_SAFE BOOL "Download a ReleaseSafe build of the Zig compiler. Only availble on macos aarch64." DEFAULT OFF) setenv(ZIG_LOCAL_CACHE_DIR ${ZIG_LOCAL_CACHE_DIR}) setenv(ZIG_GLOBAL_CACHE_DIR ${ZIG_GLOBAL_CACHE_DIR}) @@ -78,6 +79,7 @@ register_command( -DZIG_PATH=${ZIG_PATH} -DZIG_COMMIT=${ZIG_COMMIT} -DENABLE_ASAN=${ENABLE_ASAN} + -DZIG_COMPILER_SAFE=${ZIG_COMPILER_SAFE} -P ${CWD}/cmake/scripts/DownloadZig.cmake SOURCES ${CWD}/cmake/scripts/DownloadZig.cmake diff --git a/package.json b/package.json index cfc27daf7f2394..433f21f70dca12 100644 --- a/package.json +++ b/package.json @@ -57,6 +57,9 @@ "test:release": "node scripts/runner.node.mjs --exec-path ./build/release/bun", "banned": "bun test test/internal/ban-words.test.ts", "zig": "vendor/zig/zig.exe", + "zig:test": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Debug -DBUN_TEST=ON -B build/debug", + "zig:test:release": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DBUNTEST=ON -B build/release", + "zig:test:ci": "bun ./scripts/build.mjs -GNinja -DCMAKE_BUILD_TYPE=Release -DBUN_TEST=ON -DZIG_OPTIMIZE=ReleaseSafe -DCMAKE_VERBOSE_MAKEFILE=ON -DCI=true -B build/release-ci --verbose --fresh", "zig:fmt": "bun run zig-format", "zig:check": "bun run zig build check --summary new", "zig:check-all": "bun run zig build check-all --summary new", @@ -76,6 +79,7 @@ "prettier:check": "bun run analysis:no-llvm --target prettier-check", "prettier:extra": "bun run analysis:no-llvm --target prettier-extra", "prettier:diff": "bun run analysis:no-llvm --target prettier-diff", - "node:test": "node ./scripts/runner.node.mjs --quiet --exec-path=$npm_execpath --node-tests " + "node:test": "node ./scripts/runner.node.mjs --quiet --exec-path=$npm_execpath --node-tests ", + "clean:zig": "rm -rf build/debug/cache/zig build/debug/CMakeCache.txt 'build/debug/*.o' .zig-cache zig-out || true" } } diff --git a/src/bake/production.zig b/src/bake/production.zig index 5c8892bc65d9e2..fdec16e74f96fe 100644 --- a/src/bake/production.zig +++ b/src/bake/production.zig @@ -626,7 +626,7 @@ fn BakeRegisterProductionChunk(global: *JSC.JSGlobalObject, key: bun.String, sou return result; } -export fn BakeProdResolve(global: *JSC.JSGlobalObject, a_str: bun.String, specifier_str: bun.String) callconv(.C) bun.String { +pub export fn BakeProdResolve(global: *JSC.JSGlobalObject, a_str: bun.String, specifier_str: bun.String) callconv(.C) bun.String { var sfa = std.heap.stackFallback(@sizeOf(bun.PathBuffer) * 2, bun.default_allocator); const alloc = sfa.get(); @@ -836,7 +836,7 @@ pub const PerThread = struct { }; /// Given a key, returns the source code to load. -export fn BakeProdLoad(pt: *PerThread, key: bun.String) bun.String { +pub export fn BakeProdLoad(pt: *PerThread, key: bun.String) bun.String { var sfa = std.heap.stackFallback(4096, bun.default_allocator); const allocator = sfa.get(); const utf8 = key.toUTF8(allocator); @@ -866,3 +866,8 @@ const OpaqueFileId = FrameworkRouter.OpaqueFileId; const JSC = bun.JSC; const JSValue = JSC.JSValue; const VirtualMachine = JSC.VirtualMachine; + +fn @"export"() void { + _ = BakeProdResolve; + _ = BakeProdLoad; +} diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig index f0bc0dc5767801..d2f9fdb60cecf1 100644 --- a/src/bun.js/base.zig +++ b/src/bun.js/base.zig @@ -780,10 +780,6 @@ pub const RefString = struct { } }; -comptime { - std.testing.refAllDecls(RefString); -} - pub export fn MarkedArrayBuffer_deallocator(bytes_: *anyopaque, _: *anyopaque) void { const mimalloc = @import("../allocators/mimalloc.zig"); // zig's memory allocator interface won't work here diff --git a/src/bun.js/node/buffer.zig b/src/bun.js/node/buffer.zig index 5ee8ecb0922112..f6e4bc98cf94a3 100644 --- a/src/bun.js/node/buffer.zig +++ b/src/bun.js/node/buffer.zig @@ -84,6 +84,6 @@ pub const BufferVectorized = struct { } }; -comptime { +pub fn @"export"() void { @export(&BufferVectorized.fill, .{ .name = "Bun__Buffer_fill" }); } diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 2a98022a653c1a..8ce4aae539de17 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -2180,10 +2180,6 @@ pub const PathOrBlob = union(enum) { } }; -comptime { - std.testing.refAllDecls(Process); -} - /// StatFS and BigIntStatFS classes from node:fs pub fn StatFSType(comptime big: bool) type { const Int = if (big) i64 else i32; diff --git a/src/bun.js/node/util/parse_args_utils.zig b/src/bun.js/node/util/parse_args_utils.zig index e94d91bb3b1f41..07987707ada301 100644 --- a/src/bun.js/node/util/parse_args_utils.zig +++ b/src/bun.js/node/util/parse_args_utils.zig @@ -1,8 +1,8 @@ const std = @import("std"); const bun = @import("root").bun; const testing = std.testing; -const String = if (@import("builtin").is_test) TestString else bun.String; -const JSValue = if (@import("builtin").is_test) usize else bun.JSC.JSValue; +const String = bun.String; +const JSValue = bun.JSC.JSValue; pub const OptionValueType = enum { boolean, string }; @@ -74,10 +74,12 @@ pub fn isOptionLikeValue(value: String) bool { /// Find the long option associated with a short option. Looks for a configured /// `short` and returns the short option itself if a long option is not found. /// Example: +/// ```zig /// findOptionByShortName('a', {}) // returns 'a' /// findOptionByShortName('b', { /// options: { bar: { short: 'b' } } /// }) // returns "bar" +/// ``` pub fn findOptionByShortName(short_name: String, options: []const OptionDefinition) ?usize { var long_option_index: ?usize = null; for (options, 0..) |option, i| { @@ -90,366 +92,3 @@ pub fn findOptionByShortName(short_name: String, options: []const OptionDefiniti } return long_option_index; } - -// -// TESTS -// - -var no_options: []const OptionDefinition = &[_]OptionDefinition{}; - -/// Used only for tests, as lightweight substitute for bun.String -const TestString = struct { - str: []const u8, - fn length(this: TestString) usize { - return this.str.len; - } - fn hasPrefixComptime(this: TestString, comptime prefix: []const u8) bool { - return std.mem.startsWith(u8, this.str, prefix); - } - fn charAtU8(this: TestString, i: usize) u8 { - return this.str[i]; - } - fn indexOfCharU8(this: TestString, chr: u8) ?usize { - return std.mem.indexOfScalar(u8, this.str, chr); - } -}; -fn s(str: []const u8) TestString { - return TestString{ .str = str }; -} - -// -// misc -// - -test "classifyToken: is option terminator" { - try testing.expectEqual(classifyToken(s("--"), no_options), .option_terminator); -} - -test "classifyToken: is positional" { - try testing.expectEqual(classifyToken(s("abc"), no_options), .positional); -} - -// -// isLoneLongOption -// - -pub fn isLoneLongOption(value: String) bool { - return classifyToken(value, no_options) == .lone_long_option; -} - -test "isLoneLongOption: when passed short option then returns false" { - try testing.expectEqual(isLoneLongOption(s("-s")), false); -} - -test "isLoneLongOption: when passed short option group then returns false" { - try testing.expectEqual(isLoneLongOption(s("-abc")), false); -} - -test "isLoneLongOption: when passed lone long option then returns true" { - try testing.expectEqual(isLoneLongOption(s("--foo")), true); -} - -test "isLoneLongOption: when passed single character long option then returns true" { - try testing.expectEqual(isLoneLongOption(s("--f")), true); -} - -test "isLoneLongOption: when passed long option and value then returns false" { - try testing.expectEqual(isLoneLongOption(s("--foo=bar")), false); -} - -test "isLoneLongOption: when passed empty string then returns false" { - try testing.expectEqual(isLoneLongOption(s("")), false); -} - -test "isLoneLongOption: when passed plain text then returns false" { - try testing.expectEqual(isLoneLongOption(s("foo")), false); -} - -test "isLoneLongOption: when passed single dash then returns false" { - try testing.expectEqual(isLoneLongOption(s("-")), false); -} - -test "isLoneLongOption: when passed double dash then returns false" { - try testing.expectEqual(isLoneLongOption(s("--")), false); -} - -// This is a bit bogus, but simple consistent behaviour: long option follows double dash. -test "isLoneLongOption: when passed arg starting with triple dash then returns true" { - try testing.expectEqual(isLoneLongOption(s("---foo")), true); -} - -// This is a bit bogus, but simple consistent behaviour: long option follows double dash. -test "isLoneLongOption: when passed '--=' then returns true" { - try testing.expectEqual(isLoneLongOption(s("--=")), true); -} - -// -// isLoneShortOption -// - -pub fn isLoneShortOption(value: String) bool { - return classifyToken(value, no_options) == .lone_short_option; -} - -test "isLoneShortOption: when passed short option then returns true" { - try testing.expectEqual(isLoneShortOption(s("-s")), true); -} - -test "isLoneShortOption: when passed short option group (or might be short and value) then returns false" { - try testing.expectEqual(isLoneShortOption(s("-abc")), false); -} - -test "isLoneShortOption: when passed long option then returns false" { - try testing.expectEqual(isLoneShortOption(s("--foo")), false); -} - -test "isLoneShortOption: when passed long option with value then returns false" { - try testing.expectEqual(isLoneShortOption(s("--foo=bar")), false); -} - -test "isLoneShortOption: when passed empty string then returns false" { - try testing.expectEqual(isLoneShortOption(s("")), false); -} - -test "isLoneShortOption: when passed plain text then returns false" { - try testing.expectEqual(isLoneShortOption(s("foo")), false); -} - -test "isLoneShortOption: when passed single dash then returns false" { - try testing.expectEqual(isLoneShortOption(s("-")), false); -} - -test "isLoneShortOption: when passed double dash then returns false" { - try testing.expectEqual(isLoneShortOption(s("--")), false); -} - -// -// isLongOptionAndValue -// - -pub fn isLongOptionAndValue(value: String) bool { - return classifyToken(value, no_options) == .long_option_and_value; -} - -test "isLongOptionAndValue: when passed short option then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("-s")), false); -} - -test "isLongOptionAndValue: when passed short option group then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("-abc")), false); -} - -test "isLongOptionAndValue: when passed lone long option then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("--foo")), false); -} - -test "isLongOptionAndValue: when passed long option and value then returns true" { - try testing.expectEqual(isLongOptionAndValue(s("--foo=bar")), true); -} - -test "isLongOptionAndValue: when passed single character long option and value then returns true" { - try testing.expectEqual(isLongOptionAndValue(s("--f=bar")), true); -} - -test "isLongOptionAndValue: when passed empty string then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("")), false); -} - -test "isLongOptionAndValue: when passed plain text then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("foo")), false); -} - -test "isLongOptionAndValue: when passed single dash then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("-")), false); -} - -test "isLongOptionAndValue: when passed double dash then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("--")), false); -} - -// This is a bit bogus, but simple consistent behaviour: long option follows double dash. -test "isLongOptionAndValue: when passed arg starting with triple dash and value then returns true" { - try testing.expectEqual(isLongOptionAndValue(s("---foo=bar")), true); -} - -// This is a bit bogus, but simple consistent behaviour: long option follows double dash. -test "isLongOptionAndValue: when passed '--=' then returns false" { - try testing.expectEqual(isLongOptionAndValue(s("--=")), false); -} - -// -// isOptionLikeValue -// -// Basically rejecting values starting with a dash, but run through the interesting possibilities. - -test "isOptionLikeValue: when passed plain text then returns false" { - try testing.expectEqual(isOptionLikeValue(s("abc")), false); -} - -//test "isOptionLikeValue: when passed digits then returns false" { -// try testing.expectEqual(isOptionLikeValue(123), false); -//} - -test "isOptionLikeValue: when passed empty string then returns false" { - try testing.expectEqual(isOptionLikeValue(s("")), false); -} - -// Special case, used as stdin/stdout et al and not reason to reject -test "isOptionLikeValue: when passed dash then returns false" { - try testing.expectEqual(isOptionLikeValue(s("-")), false); -} - -test "isOptionLikeValue: when passed -- then returns true" { - // Not strictly option-like, but is supect - try testing.expectEqual(isOptionLikeValue(s("--")), true); -} - -// Supporting undefined so can pass element off end of array without checking -//test "isOptionLikeValue: when passed undefined then returns false" { -// try testing.expectEqual(isOptionLikeValue(undefined), false); -//} - -test "isOptionLikeValue: when passed short option then returns true" { - try testing.expectEqual(isOptionLikeValue(s("-a")), true); -} - -test "isOptionLikeValue: when passed short option digit then returns true" { - try testing.expectEqual(isOptionLikeValue(s("-1")), true); -} - -test "isOptionLikeValue: when passed negative number then returns true" { - try testing.expectEqual(isOptionLikeValue(s("-123")), true); -} - -test "isOptionLikeValue: when passed short option group of short option with value then returns true" { - try testing.expectEqual(isOptionLikeValue(s("-abd")), true); -} - -test "isOptionLikeValue: when passed long option then returns true" { - try testing.expectEqual(isOptionLikeValue(s("--foo")), true); -} - -test "isOptionLikeValue: when passed long option with value then returns true" { - try testing.expectEqual(isOptionLikeValue(s("--foo=bar")), true); -} - -// -// isShortOptionAndValue -// - -pub fn isShortOptionAndValue(value: String, options: []const OptionDefinition) bool { - return classifyToken(value, options) == .short_option_and_value; -} - -test "isShortOptionAndValue: when passed lone short option then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("-s"), no_options), false); -} - -test "isShortOptionAndValue: when passed group with leading zero-config boolean then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("-ab"), no_options), false); -} - -test "isShortOptionAndValue: when passed group with leading configured implicit boolean then returns false" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a' }}; - try testing.expectEqual(isShortOptionAndValue(s("-ab"), options), false); -} - -test "isShortOptionAndValue: when passed group with leading configured explicit boolean then returns false" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a', .type = .boolean }}; - try testing.expectEqual(isShortOptionAndValue(s("-ab"), options), false); -} - -test "isShortOptionAndValue: when passed group with leading configured string then returns true" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a', .type = .string }}; - try testing.expectEqual(isShortOptionAndValue(s("-ab"), options), true); -} - -test "isShortOptionAndValue: when passed long option then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("--foo"), no_options), false); -} - -test "isShortOptionAndValue: when passed long option with value then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("--foo=bar"), no_options), false); -} - -test "isShortOptionAndValue: when passed empty string then returns false" { - try testing.expectEqual(isShortOptionAndValue(s(""), no_options), false); -} - -test "isShortOptionAndValue: when passed plain text then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("foo"), no_options), false); -} - -test "isShortOptionAndValue: when passed single dash then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("-"), no_options), false); -} - -test "isShortOptionAndValue: when passed double dash then returns false" { - try testing.expectEqual(isShortOptionAndValue(s("--"), no_options), false); -} - -// -// isShortOptionGroup -// - -pub fn isShortOptionGroup(value: String, options: []const OptionDefinition) bool { - return classifyToken(value, options) == .short_option_group; -} - -test "isShortOptionGroup: when passed lone short option then returns false" { - try testing.expectEqual(isShortOptionGroup(s("-s"), no_options), false); -} - -test "isShortOptionGroup: when passed group with leading zero-config boolean then returns true" { - try testing.expectEqual(isShortOptionGroup(s("-ab"), no_options), true); -} - -test "isShortOptionGroup: when passed group with leading configured implicit boolean then returns true" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a' }}; - try testing.expectEqual(isShortOptionGroup(s("-ab"), options), true); -} - -test "isShortOptionGroup: when passed group with leading configured explicit boolean then returns true" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a', .type = .boolean }}; - try testing.expectEqual(isShortOptionGroup(s("-ab"), options), true); -} - -test "isShortOptionGroup: when passed group with leading configured string then returns false" { - const options = &[_]OptionDefinition{.{ .long_name = s("aaa"), .short_name = 'a', .type = .string }}; - try testing.expectEqual(isShortOptionGroup(s("-ab"), options), false); -} - -test "isShortOptionGroup: when passed group with trailing configured string then returns true" { - const options = &[_]OptionDefinition{.{ .long_name = s("bbb"), .short_name = 'b', .type = .string }}; - try testing.expectEqual(isShortOptionGroup(s("-ab"), options), true); -} - -// This one is dubious, but leave it to caller to handle. -test "isShortOptionGroup: when passed group with middle configured string then returns true" { - const options = &[_]OptionDefinition{.{ .long_name = s("bbb"), .short_name = 'b', .type = .string }}; - try testing.expectEqual(isShortOptionGroup(s("-abc"), options), true); -} - -test "isShortOptionGroup: when passed long option then returns false" { - try testing.expectEqual(isShortOptionGroup(s("--foo"), no_options), false); -} - -test "isShortOptionGroup: when passed long option with value then returns false" { - try testing.expectEqual(isShortOptionGroup(s("--foo=bar"), no_options), false); -} - -test "isShortOptionGroup: when passed empty string then returns false" { - try testing.expectEqual(isShortOptionGroup(s(""), no_options), false); -} - -test "isShortOptionGroup: when passed plain text then returns false" { - try testing.expectEqual(isShortOptionGroup(s("foo"), no_options), false); -} - -test "isShortOptionGroup: when passed single dash then returns false" { - try testing.expectEqual(isShortOptionGroup(s("-"), no_options), false); -} - -test "isShortOptionGroup: when passed double dash then returns false" { - try testing.expectEqual(isShortOptionGroup(s("--"), no_options), false); -} diff --git a/src/cli/test_command.zig b/src/cli/test_command.zig index 47340e584a8d35..36aff87292adc0 100644 --- a/src/cli/test_command.zig +++ b/src/cli/test_command.zig @@ -1335,7 +1335,7 @@ pub const TestCommand = struct { strings.startsWith(arg, "./") or strings.startsWith(arg, "../") or (Environment.isWindows and (strings.startsWith(arg, ".\\") or - strings.startsWith(arg, "..\\")))) break true; + strings.startsWith(arg, "..\\")))) break true; } else false) { // One of the files is a filepath. Instead of treating the arguments as filters, treat them as filepaths for (ctx.positionals[1..]) |arg| { @@ -1453,9 +1453,9 @@ pub const TestCommand = struct { if (has_file_like == null and (strings.hasSuffixComptime(filter, ".ts") or - strings.hasSuffixComptime(filter, ".tsx") or - strings.hasSuffixComptime(filter, ".js") or - strings.hasSuffixComptime(filter, ".jsx"))) + strings.hasSuffixComptime(filter, ".tsx") or + strings.hasSuffixComptime(filter, ".js") or + strings.hasSuffixComptime(filter, ".jsx"))) { has_file_like = i; } @@ -1806,3 +1806,7 @@ fn handleTopLevelTestErrorBeforeJavaScriptStart(err: anyerror) noreturn { } Global.exit(1); } + +pub fn @"export"() void { + _ = &Scanner.BunTest__shouldGenerateCodeCoverage; +} diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig index 8f38f9eb0f5d51..29d9a89239e04e 100644 --- a/src/cli/upgrade_command.zig +++ b/src/cli/upgrade_command.zig @@ -113,53 +113,9 @@ pub const Version = struct { return strings.eqlComptime(this.tag, current_version); } - comptime { - _ = Bun__githubURL; - } -}; - -pub const UpgradeCheckerThread = struct { - pub fn spawn(env_loader: *DotEnv.Loader) void { - if (env_loader.map.get("BUN_DISABLE_UPGRADE_CHECK") != null or - env_loader.map.get("CI") != null or - strings.eqlComptime(env_loader.get("BUN_CANARY") orelse "0", "1")) - return; - var update_checker_thread = std.Thread.spawn(.{}, run, .{env_loader}) catch return; - update_checker_thread.detach(); - } - - fn _run(env_loader: *DotEnv.Loader) anyerror!void { - var rand = std.rand.DefaultPrng.init(@as(u64, @intCast(@max(std.time.milliTimestamp(), 0)))); - const delay = rand.random().intRangeAtMost(u64, 100, 10000); - std.time.sleep(std.time.ns_per_ms * delay); - - Output.Source.configureThread(); - HTTP.HTTPThread.init(&.{}); - - defer { - js_ast.Expr.Data.Store.deinit(); - js_ast.Stmt.Data.Store.deinit(); - } - - var version = (try UpgradeCommand.getLatestVersion(default_allocator, env_loader, null, null, false, true)) orelse return; - - if (!version.isCurrent()) { - if (version.name()) |name| { - Output.prettyErrorln("\n<r><d>Bun v{s} is out. Run <b><cyan>bun upgrade<r> to upgrade.\n", .{name}); - Output.flush(); - } - } - - version.buf.deinit(); - } - - fn run(env_loader: *DotEnv.Loader) void { - _run(env_loader) catch |err| { - if (Environment.isDebug) { - Output.prettyError("\n[UpgradeChecker] ERROR: {s}\n", .{@errorName(err)}); - Output.flush(); - } - }; + pub fn @"export"() void { + _ = &Bun__githubURL; + _ = &Bun__githubBaselineURL; } }; @@ -656,14 +612,14 @@ pub const UpgradeCommand = struct { const powershell_path = bun.which(&buf, bun.getenvZ("PATH") orelse "", "", "powershell") orelse hardcoded_system_powershell: { - const system_root = bun.getenvZ("SystemRoot") orelse "C:\\Windows"; - const hardcoded_system_powershell = bun.path.joinAbsStringBuf(system_root, &buf, &.{ system_root, "System32\\WindowsPowerShell\\v1.0\\powershell.exe" }, .windows); - if (bun.sys.exists(hardcoded_system_powershell)) { - break :hardcoded_system_powershell hardcoded_system_powershell; - } - Output.prettyErrorln("<r><red>error:<r> Failed to unzip {s} due to PowerShell not being installed.", .{tmpname}); - Global.exit(1); - }; + const system_root = bun.getenvZ("SystemRoot") orelse "C:\\Windows"; + const hardcoded_system_powershell = bun.path.joinAbsStringBuf(system_root, &buf, &.{ system_root, "System32\\WindowsPowerShell\\v1.0\\powershell.exe" }, .windows); + if (bun.sys.exists(hardcoded_system_powershell)) { + break :hardcoded_system_powershell hardcoded_system_powershell; + } + Output.prettyErrorln("<r><red>error:<r> Failed to unzip {s} due to PowerShell not being installed.", .{tmpname}); + Global.exit(1); + }; var unzip_argv = [_]string{ powershell_path, @@ -1058,3 +1014,8 @@ pub const upgrade_js_bindings = struct { return .undefined; } }; + +pub fn @"export"() void { + _ = &upgrade_js_bindings; + Version.@"export"(); +} diff --git a/src/deps/zig-clap/clap.zig b/src/deps/zig-clap/clap.zig index 1904c7e0172ece..f814f629269a16 100644 --- a/src/deps/zig-clap/clap.zig +++ b/src/deps/zig-clap/clap.zig @@ -10,10 +10,6 @@ const Output = @import("../../output.zig"); pub const args = @import("clap/args.zig"); -test "clap" { - testing.refAllDecls(@This()); -} - pub const ComptimeClap = @import("clap/comptime.zig").ComptimeClap; pub const StreamingClap = @import("clap/streaming.zig").StreamingClap; diff --git a/src/env.zig b/src/env.zig index 58b873432804d6..986259f9bf3d67 100644 --- a/src/env.zig +++ b/src/env.zig @@ -30,7 +30,7 @@ pub const allow_assert = isDebug or isTest or std.builtin.Mode.ReleaseSafe == @i /// All calls to `@export` should be gated behind this check, so that code /// generators that compile Zig code know not to reference and compile a ton of /// unused code. -pub const export_cpp_apis = @import("builtin").output_mode == .Obj; +pub const export_cpp_apis = @import("builtin").output_mode == .Obj or isTest; pub const build_options = @import("build_options"); @@ -45,7 +45,6 @@ pub const canary_revision = if (is_canary) build_options.canary_revision else "" pub const dump_source = isDebug and !isTest; pub const base_path = build_options.base_path; pub const enable_logs = build_options.enable_logs; - pub const codegen_path = build_options.codegen_path; pub const codegen_embed = build_options.codegen_embed; diff --git a/src/main_test.zig b/src/main_test.zig new file mode 100644 index 00000000000000..dd4a28634a6d72 --- /dev/null +++ b/src/main_test.zig @@ -0,0 +1,206 @@ +const std = @import("std"); +const builtin = @import("builtin"); +pub const bun = @import("./bun.zig"); +const recover = @import("test/recover.zig"); + +const TestFn = std.builtin.TestFn; +const Output = bun.Output; +const Environment = bun.Environment; + +// pub const panic = bun.crash_handler.panic; +pub const panic = recover.panic; +pub const std_options = std.Options{ + .enable_segfault_handler = false, +}; + +pub const io_mode = .blocking; + +comptime { + bun.assert(builtin.target.cpu.arch.endian() == .little); +} + +pub extern "C" var _environ: ?*anyopaque; +pub extern "C" var environ: ?*anyopaque; + +pub fn main() void { + // This should appear before we make any calls at all to libuv. + // So it's safest to put it very early in the main function. + if (Environment.isWindows) { + _ = bun.windows.libuv.uv_replace_allocator( + @ptrCast(&bun.Mimalloc.mi_malloc), + @ptrCast(&bun.Mimalloc.mi_realloc), + @ptrCast(&bun.Mimalloc.mi_calloc), + @ptrCast(&bun.Mimalloc.mi_free), + ); + environ = @ptrCast(std.os.environ.ptr); + _environ = @ptrCast(std.os.environ.ptr); + } + + bun.initArgv(bun.default_allocator) catch |err| { + Output.panic("Failed to initialize argv: {s}\n", .{@errorName(err)}); + }; + + Output.Source.Stdio.init(); + defer Output.flush(); + bun.StackCheck.configureThread(); + const exit_code = runTests(); + bun.Global.exit(exit_code); +} + +const Stats = struct { + pass: u32, + fail: u32, + leak: u32, + panic: u32, + start: i64, + + fn init() Stats { + var stats = std.mem.zeroes(Stats); + stats.start = std.time.milliTimestamp(); + return stats; + } + + /// Time elapsed since start in milliseconds + fn elapsed(this: *const Stats) i64 { + return std.time.milliTimestamp() - this.start; + } + + /// Total number of tests run + fn total(this: *const Stats) u32 { + return this.pass + this.fail + this.leak + this.panic; + } + + fn exitCode(this: *const Stats) u8 { + var result: u8 = 0; + if (this.fail > 0) result |= 1; + if (this.leak > 0) result |= 2; + if (this.panic > 0) result |= 4; + return result; + } +}; + +fn runTests() u8 { + var stats = Stats.init(); + var stderr = std.io.getStdErr(); + + namebuf = std.heap.page_allocator.alloc(u8, namebuf_size) catch { + Output.panic("Failed to allocate name buffer", .{}); + }; + defer std.heap.page_allocator.free(namebuf); + + const tests: []const TestFn = builtin.test_functions; + for (tests) |t| { + std.testing.allocator_instance = .{}; + + var did_lock = true; + stderr.lock(.exclusive) catch { + did_lock = false; + }; + defer if (did_lock) stderr.unlock(); + + const start = std.time.milliTimestamp(); + const result = recover.callForTest(t.func); + const elapsed = std.time.milliTimestamp() - start; + + const name = extractName(t); + const memory_check = std.testing.allocator_instance.deinit(); + + if (result) |_| { + if (memory_check == .leak) { + Output.pretty("<yellow>leak</r> - {s} <i>({d}ms)</r>\n", .{ name, elapsed }); + stats.leak += 1; + } else { + Output.pretty("<green>pass</r> - {s} <i>({d}ms)</r>\n", .{ name, elapsed }); + stats.pass += 1; + } + } else |err| { + switch (err) { + error.Panic => { + Output.pretty("<magenta><b>panic</r> - {s} <i>({d}ms)</r>\n{s}", .{ t.name, elapsed, @errorName(err) }); + stats.panic += 1; + }, + else => { + Output.pretty("<red>fail</r> - {s} <i>({d}ms)</r>\n{s}", .{ t.name, elapsed, @errorName(err) }); + stats.fail += 1; + }, + } + } + } + + const total = stats.total(); + const total_time = stats.elapsed(); + + if (total == stats.pass) { + Output.pretty("\n<green>All tests passed</r>\n", .{}); + } else { + Output.pretty("\n<green>{d}</r> passed", .{stats.pass}); + if (stats.fail > 0) + Output.pretty(", <red>{d}</r> failed", .{stats.fail}) + else + Output.pretty(", 0 failed", .{}); + if (stats.leak > 0) Output.pretty(", <yellow>{d}</r> leaked", .{stats.leak}); + if (stats.panic > 0) Output.pretty(", <magenta>{d}</r> panicked", .{stats.panic}); + } + + Output.pretty("\n\tRan <b>{d}</r> tests in <b>{d}</r>ms\n\n", .{ total, total_time }); + return stats.exitCode(); +} + +// heap-allocated on start to avoid increasing binary size +threadlocal var namebuf: []u8 = undefined; +const namebuf_size = 4096; +comptime { + std.debug.assert(std.math.isPowerOfTwo(namebuf_size)); +} + +fn extractName(t: TestFn) []const u8 { + inline for (.{ ".test.", ".decltest." }) |test_sep| { + if (std.mem.lastIndexOf(u8, t.name, test_sep)) |marker| { + const prefix = t.name[0..marker]; + const test_name = t.name[marker + test_sep.len ..]; + const full_name = std.fmt.bufPrint(namebuf, "{s}\t{s}", .{ prefix, test_name }) catch @panic("name buffer too small"); + return full_name; + } + } + + return t.name; +} + +pub const overrides = struct { + pub const mem = struct { + extern "C" fn wcslen(s: [*:0]const u16) usize; + + pub fn indexOfSentinel(comptime T: type, comptime sentinel: T, p: [*:sentinel]const T) usize { + if (comptime T == u16 and sentinel == 0 and Environment.isWindows) { + return wcslen(p); + } + + if (comptime T == u8 and sentinel == 0) { + return bun.C.strlen(p); + } + + var i: usize = 0; + while (p[i] != sentinel) { + i += 1; + } + return i; + } + }; +}; + +pub export fn Bun__panic(msg: [*]const u8, len: usize) noreturn { + Output.panic("{s}", .{msg[0..len]}); +} + +comptime { + // _ = bun.bake.production.@"export"(); + + _ = bun.bake.production.BakeProdResolve; + _ = bun.bake.production.BakeProdLoad; + + _ = bun.bun_js.Bun__onRejectEntryPointResult; + _ = bun.bun_js.Bun__onResolveEntryPointResult; + @import("bun.js/node/buffer.zig").@"export"(); + @import("cli/upgrade_command.zig").@"export"(); + @import("cli/test_command.zig").@"export"(); +} diff --git a/src/output.zig b/src/output.zig index 6dce0e33bf7e4f..b9b3e429ab5999 100644 --- a/src/output.zig +++ b/src/output.zig @@ -870,7 +870,7 @@ pub const color_map = ComptimeStringMap(string, .{ const RESET: string = "\x1b[0m"; pub fn prettyFmt(comptime fmt: string, comptime is_enabled: bool) [:0]const u8 { if (comptime bun.fast_debug_build_mode) - return fmt; + return fmt ++ "\x00"; comptime var new_fmt: [fmt.len * 4]u8 = undefined; comptime var new_fmt_i: usize = 0; diff --git a/src/resolver/resolve_path.zig b/src/resolver/resolve_path.zig index 4f833e1bcfa328..5607e772976a63 100644 --- a/src/resolver/resolve_path.zig +++ b/src/resolver/resolve_path.zig @@ -1,8 +1,6 @@ -const tester = @import("../test/tester.zig"); const std = @import("std"); const strings = @import("../string_immutable.zig"); const FeatureFlags = @import("../feature_flags.zig"); -const default_allocator = @import("../allocators/memory_allocator.zig").c_allocator; const bun = @import("root").bun; const Fs = @import("../fs.zig"); diff --git a/src/router.zig b/src/router.zig index 23f61bf3155149..d7374895edd187 100644 --- a/src/router.zig +++ b/src/router.zig @@ -1027,7 +1027,6 @@ pub const Test = struct { } pub fn make(comptime testName: string, data: anytype) !Router { - std.testing.refAllDecls(@import("./bun.js/bindings/exports.zig")); try makeTest(testName, data); const JSAst = bun.JSAst; JSAst.Expr.Data.Store.create(default_allocator); diff --git a/src/shell/braces.zig b/src/shell/braces.zig index 522567e80c25c4..b714b25aedb94d 100644 --- a/src/shell/braces.zig +++ b/src/shell/braces.zig @@ -1,27 +1,28 @@ const bun = @import("root").bun; -const ArrayList = std.ArrayList; const std = @import("std"); const builtin = @import("builtin"); +const ArrayList = std.ArrayList; const Arena = std.heap.ArenaAllocator; const Allocator = std.mem.Allocator; const SmolStr = @import("../string.zig").SmolStr; +const assert = bun.assert; +const log = bun.Output.scoped(.BRACES, false); + /// Using u16 because anymore tokens than that results in an unreasonably high /// amount of brace expansion (like around 32k variants to expand) -pub const ExpansionVariant = packed struct { +const ExpansionVariant = packed struct { start: u16 = 0, - end: u16 = 0, + end: u16 = 0, // must be >= start }; -const log = bun.Output.scoped(.BRACES, false); - -const TokenTag = enum { open, comma, text, close, eof }; -const Token = union(TokenTag) { +const Token = union(enum) { open: ExpansionVariants, comma, text: SmolStr, close, eof, + const Tag = @typeInfo(Token).@"union".tag_type.?; const ExpansionVariants = struct { idx: u16 = 0, @@ -58,33 +59,33 @@ pub const AST = struct { const MAX_NESTED_BRACES = 10; +const StackError = error{ + StackFull, +}; + /// A stack on the stack -pub fn StackStack(comptime T: type, comptime SizeType: type, comptime N: SizeType) type { +fn StackStack(comptime T: type, comptime SizeType: type, comptime N: SizeType) type { return struct { items: [N]T = undefined, len: SizeType = 0, - pub const Error = error{ - StackFull, - }; - - pub fn top(this: *@This()) ?T { + fn top(this: *@This()) ?T { if (this.len == 0) return null; return this.items[this.len - 1]; } - pub fn topPtr(this: *@This()) ?*T { + fn topPtr(this: *@This()) ?*T { if (this.len == 0) return null; return &this.items[this.len - 1]; } - pub fn push(this: *@This(), value: T) Error!void { - if (this.len == N) return Error.StackFull; + fn push(this: *@This(), value: T) StackError!void { + if (this.len == N) return StackError.StackFull; this.items[this.len] = value; this.len += 1; } - pub fn pop(this: *@This()) ?T { + fn pop(this: *@This()) ?T { if (this.top()) |v| { this.len -= 1; return v; @@ -95,10 +96,7 @@ pub fn StackStack(comptime T: type, comptime SizeType: type, comptime N: SizeTyp } /// This may have false positives but it is fast -pub fn fastDetect(src: []const u8) bool { - const Quote = enum { single, double }; - _ = Quote; - +fn fastDetect(src: []const u8) bool { var has_open = false; var has_close = false; if (src.len < 16) { @@ -151,13 +149,15 @@ pub fn fastDetect(src: []const u8) bool { return false; } +const ExpandError = StackError || ParserError; + /// `out` is preallocated by using the result from `calculateExpandedAmount` pub fn expand( allocator: Allocator, tokens: []Token, out: []std.ArrayList(u8), contains_nested: bool, -) (error{StackFull} || ParserError)!void { +) ExpandError!void { var out_key_counter: u16 = 1; if (!contains_nested) { var expansions_table = try buildExpansionTableAlloc(allocator, tokens); @@ -176,7 +176,7 @@ fn expandNested( out_key: u16, out_key_counter: *u16, start: u32, -) !void { +) ExpandError!void { if (root.atoms == .single) { if (start > 0) { if (root.bubble_up) |bubble_up| { @@ -302,9 +302,7 @@ fn expandFlat( } } -// pub fn expandNested() - -pub fn calculateVariantsAmount(tokens: []const Token) u32 { +fn calculateVariantsAmount(tokens: []const Token) u32 { var brace_count: u32 = 0; var count: u32 = 0; for (tokens) |tok| { @@ -415,8 +413,8 @@ pub const Parser = struct { return self.peek() == .eof; } - fn expect(self: *Parser, toktag: TokenTag) Token { - assert(toktag == @as(TokenTag, self.peek())); + fn expect(self: *Parser, toktag: Token.Tag) Token { + assert(toktag == @as(Token.Tag, self.peek())); if (self.check(toktag)) { return self.advance(); } @@ -424,15 +422,15 @@ pub const Parser = struct { } /// Consumes token if it matches - fn match(self: *Parser, toktag: TokenTag) bool { - if (@as(TokenTag, self.peek()) == toktag) { + fn match(self: *Parser, toktag: Token.Tag) bool { + if (@as(Token.Tag, self.peek()) == toktag) { _ = self.advance(); return true; } return false; } - fn match_any2(self: *Parser, comptime toktags: []const TokenTag) ?Token { + fn match_any2(self: *Parser, comptime toktags: []const Token.Tag) ?Token { const peeked = self.peek(); inline for (toktags) |tag| { if (peeked == tag) { @@ -443,8 +441,8 @@ pub const Parser = struct { return null; } - fn match_any(self: *Parser, comptime toktags: []const TokenTag) bool { - const peeked = @as(TokenTag, self.peek()); + fn match_any(self: *Parser, comptime toktags: []const Token.Tag) bool { + const peeked = @as(Token.Tag, self.peek()); inline for (toktags) |tag| { if (peeked == tag) { _ = self.advance(); @@ -454,8 +452,8 @@ pub const Parser = struct { return false; } - fn check(self: *Parser, toktag: TokenTag) bool { - return @as(TokenTag, self.peek()) == @as(TokenTag, toktag); + fn check(self: *Parser, toktag: Token.Tag) bool { + return @as(Token.Tag, self.peek()) == @as(Token.Tag, toktag); } fn peek(self: *Parser) Token { @@ -480,18 +478,15 @@ pub const Parser = struct { } }; -pub fn calculateExpandedAmount(tokens: []const Token) !u32 { +pub fn calculateExpandedAmount(tokens: []const Token) StackError!u32 { var nested_brace_stack = StackStack(u8, u8, MAX_NESTED_BRACES){}; var variant_count: u32 = 0; - var i: usize = 0; - var prev_comma: bool = false; - while (i < tokens.len) : (i += 1) { + + for (tokens) |tok| { prev_comma = false; - switch (tokens[i]) { - .open => { - try nested_brace_stack.push(0); - }, + switch (tok) { + .open => try nested_brace_stack.push(0), .comma => { const val = nested_brace_stack.topPtr().?; val.* += 1; @@ -518,16 +513,13 @@ pub fn calculateExpandedAmount(tokens: []const Token) !u32 { return variant_count; } -pub fn buildExpansionTableAlloc(alloc: Allocator, tokens: []Token) !std.ArrayList(ExpansionVariant) { +fn buildExpansionTableAlloc(alloc: Allocator, tokens: []Token) !std.ArrayList(ExpansionVariant) { var table = std.ArrayList(ExpansionVariant).init(alloc); try buildExpansionTable(tokens, &table); return table; } -pub fn buildExpansionTable( - tokens: []Token, - table: *std.ArrayList(ExpansionVariant), -) !void { +fn buildExpansionTable(tokens: []Token, table: *std.ArrayList(ExpansionVariant)) !void { const BraceState = struct { tok_idx: u16, variants: u16, @@ -594,7 +586,7 @@ const NewChars = @import("./shell.zig").ShellCharIter; pub const Lexer = NewLexer(.ascii); -pub fn NewLexer(comptime encoding: Encoding) type { +fn NewLexer(comptime encoding: Encoding) type { const Chars = NewChars(encoding); return struct { chars: Chars, @@ -803,4 +795,32 @@ pub fn NewLexer(comptime encoding: Encoding) type { }; } -const assert = bun.assert; +const t = std.testing; +test Lexer { + var arena = std.heap.ArenaAllocator.init(t.allocator); + defer arena.deinit(); + + const TestCase = struct { []const u8, []const Token }; + const test_cases: []const TestCase = &[_]TestCase{ + .{ + "{}", + &[_]Token{ .{ .open = .{} }, .close, .eof }, + }, + .{ + "{foo}", + &[_]Token{ .{ .open = .{} }, .{ .text = try SmolStr.fromSlice(arena.allocator(), "foo") }, .close, .eof }, + }, + }; + + for (test_cases) |test_case| { + const src, const expected = test_case; + // NOTE: don't use arena here so that we can test for memory leaks + var result = try Lexer.tokenize(t.allocator, src); + defer result.tokens.deinit(); + try t.expectEqualSlices( + Token, + expected, + result.tokens.items, + ); + } +} diff --git a/src/string/SmolStr.zig b/src/string/SmolStr.zig index d6d9f5efca4eb8..4f0a233613ff53 100644 --- a/src/string/SmolStr.zig +++ b/src/string/SmolStr.zig @@ -9,7 +9,7 @@ pub const SmolStr = packed struct { cap: u32, __ptr: [*]u8, - const Tag: usize = 0x8000000000000000; + const Tag: usize = 0x8000000000000000; // NOTE: only works on little endian systems const NegatedTag: usize = ~Tag; pub fn jsonStringify(self: *const SmolStr, writer: anytype) !void { @@ -21,7 +21,30 @@ pub const SmolStr = packed struct { __len: u7, _tag: u1, - pub fn len(this: Inlined) u8 { + const max_len: comptime_int = @sizeOf(@FieldType(Inlined, "data")) - 1; + const empty: Inlined = .{ + .data = 0, + .__len = 0, + ._tag = 1, + }; + + /// ## Errors + /// if `str` is longer than `max_len` + pub fn init(str: []const u8) !Inlined { + if (str.len > max_len) { + @branchHint(.unlikely); + return error.StringTooLong; + } + var inlined = Inlined.empty; + + if (str.len > 0) { + @memcpy(inlined.allChars()[0..str.len], str[0..str.len]); + inlined.setLen(@intCast(str.len)); + } + return inlined; + } + + pub inline fn len(this: Inlined) u8 { return @intCast(this.__len); } @@ -29,12 +52,20 @@ pub const SmolStr = packed struct { this.__len = new_len; } - pub fn slice(this: *Inlined) []const u8 { - return this.allChars()[0..this.__len]; + pub fn slice(this: *const Inlined) []const u8 { + return @constCast(this).ptr()[0..this.__len]; + } + + pub fn sliceMut(this: *Inlined) []u8 { + return this.ptr()[0..this.__len]; + } + + pub fn allChars(this: *Inlined) *[max_len]u8 { + return this.ptr()[0..max_len]; } - pub fn allChars(this: *Inlined) *[15]u8 { - return @as([*]u8, @ptrCast(@as(*u128, @ptrCast(this))))[0..15]; + inline fn ptr(this: *Inlined) [*]u8 { + return @as([*]u8, @ptrCast(@as(*u128, @ptrCast(this)))); } }; @@ -43,12 +74,7 @@ pub const SmolStr = packed struct { } pub fn empty() SmolStr { - const inlined = Inlined{ - .data = 0, - .__len = 0, - ._tag = 1, - }; - return SmolStr.fromInlined(inlined); + return SmolStr.fromInlined(Inlined.empty); } pub fn len(this: *const SmolStr) u32 { @@ -79,7 +105,10 @@ pub const SmolStr = packed struct { return @as(usize, @intFromPtr(this.__ptr)) & Tag != 0; } + /// ## Panics + /// if `this` is too long to fit in an inlined string pub fn toInlined(this: *const SmolStr) Inlined { + assert(this.len() <= Inlined.max_len); var inlined: Inlined = @bitCast(@as(u128, @bitCast(this.*))); inlined._tag = 1; return inlined; @@ -113,25 +142,21 @@ pub const SmolStr = packed struct { return SmolStr.fromInlined(inlined); } + pub fn deinit(this: *SmolStr, allocator: Allocator) void { + if (!this.isInlined()) { + allocator.free(this.slice()); + } + } pub fn fromSlice(allocator: Allocator, values: []const u8) Allocator.Error!SmolStr { - if (values.len > 15) { + if (values.len > Inlined.max_len) { var baby_list = try BabyList(u8).initCapacity(allocator, values.len); baby_list.appendSliceAssumeCapacity(values); return SmolStr.fromBabyList(baby_list); } - var inlined = Inlined{ - .data = 0, - .__len = 0, - ._tag = 1, - }; - - if (values.len > 0) { - @memcpy(inlined.allChars()[0..values.len], values[0..values.len]); - inlined.setLen(@intCast(values.len)); - } - + // SAFETY: we already checked that `values` can fit in an inlined string + const inlined = Inlined.init(values) catch unreachable; return SmolStr.fromInlined(inlined); } @@ -146,11 +171,10 @@ pub const SmolStr = packed struct { pub fn appendChar(this: *SmolStr, allocator: Allocator, char: u8) Allocator.Error!void { if (this.isInlined()) { var inlined = this.toInlined(); - if (inlined.len() + 1 > 15) { + if (inlined.len() + 1 > Inlined.max_len) { var baby_list = try BabyList(u8).initCapacity(allocator, inlined.len() + 1); baby_list.appendSliceAssumeCapacity(inlined.slice()); try baby_list.push(allocator, char); - // this.* = SmolStr.fromBabyList(baby_list); this.__len = baby_list.len; this.__ptr = baby_list.ptr; this.cap = baby_list.cap; @@ -159,7 +183,6 @@ pub const SmolStr = packed struct { } inlined.allChars()[inlined.len()] = char; inlined.setLen(@intCast(inlined.len() + 1)); - // this.* = SmolStr.fromInlined(inlined); this.* = @bitCast(inlined); this.markInlined(); return; @@ -172,7 +195,6 @@ pub const SmolStr = packed struct { }; try baby_list.push(allocator, char); - // this.* = SmolStr.fromBabyList(baby_list); this.__len = baby_list.len; this.__ptr = baby_list.ptr; this.cap = baby_list.cap; @@ -182,7 +204,7 @@ pub const SmolStr = packed struct { pub fn appendSlice(this: *SmolStr, allocator: Allocator, values: []const u8) Allocator.Error!void { if (this.isInlined()) { var inlined = this.toInlined(); - if (inlined.len() + values.len > 15) { + if (inlined.len() + values.len > Inlined.max_len) { var baby_list = try BabyList(u8).initCapacity(allocator, inlined.len() + values.len); baby_list.appendSliceAssumeCapacity(inlined.slice()); baby_list.appendSliceAssumeCapacity(values); @@ -206,3 +228,47 @@ pub const SmolStr = packed struct { return; } }; + +const t = std.testing; + +test SmolStr { + // large strings are heap-allocated + { + var str = try SmolStr.fromSlice(t.allocator, "oh wow this is a long string"); + defer str.deinit(t.allocator); + try t.expectEqualStrings("oh wow this is a long string", str.slice()); + try t.expect(!str.isInlined()); + } + + // small strings are inlined + { + var str = try SmolStr.fromSlice(t.allocator, "hello"); + defer str.deinit(t.allocator); + try t.expectEqualStrings("hello", str.slice()); + try t.expect(str.isInlined()); + + // operations that grow a string beyond the inlined capacity force an allocation. + try str.appendSlice(t.allocator, " world, this makes it too long to be inlined"); + try t.expectEqualStrings("hello world, this makes it too long to be inlined", str.slice()); + try t.expect(!str.isInlined()); + } +} + +test "SmolStr.Inlined.init" { + var hello = try SmolStr.Inlined.init("hello"); + try t.expectEqualStrings("hello", hello.slice()); + try t.expectEqual(5, hello.len()); + try t.expectEqual(1, hello._tag); // 1 = inlined + + try t.expectError(error.StringTooLong, SmolStr.Inlined.init("this string is too long to be inlined within a u120")); + + const empty = try SmolStr.Inlined.init(""); + try t.expectEqual(empty, SmolStr.Inlined.empty); +} + +test "Creating an inlined SmolStr does not allocate" { + var hello = try SmolStr.fromSlice(t.allocator, "hello"); + // no `defer hello.deinit()` to ensure fromSlice does not allocate + try t.expectEqual(5, hello.len()); + try t.expect(hello.isInlined()); +} diff --git a/src/test/project.zig b/src/test/project.zig deleted file mode 100644 index 26dadbc94b77d0..00000000000000 --- a/src/test/project.zig +++ /dev/null @@ -1,1605 +0,0 @@ -pub const lodash = [_][]const u8{ - "/project/node_modules/lodash/_apply.js", - "/project/node_modules/lodash/_arrayAggregator.js", - "/project/node_modules/lodash/_arrayEach.js", - "/project/node_modules/lodash/_arrayEachRight.js", - "/project/node_modules/lodash/_arrayEvery.js", - "/project/node_modules/lodash/_arrayFilter.js", - "/project/node_modules/lodash/_arrayIncludes.js", - "/project/node_modules/lodash/_arrayIncludesWith.js", - "/project/node_modules/lodash/_arrayLikeKeys.js", - "/project/node_modules/lodash/_arrayMap.js", - "/project/node_modules/lodash/_arrayPush.js", - "/project/node_modules/lodash/_arrayReduce.js", - "/project/node_modules/lodash/_arrayReduceRight.js", - "/project/node_modules/lodash/_arraySample.js", - "/project/node_modules/lodash/_arraySampleSize.js", - "/project/node_modules/lodash/_arrayShuffle.js", - "/project/node_modules/lodash/_arraySome.js", - "/project/node_modules/lodash/_asciiSize.js", - "/project/node_modules/lodash/_asciiToArray.js", - "/project/node_modules/lodash/_asciiWords.js", - "/project/node_modules/lodash/_assignMergeValue.js", - "/project/node_modules/lodash/_assignValue.js", - "/project/node_modules/lodash/_assocIndexOf.js", - "/project/node_modules/lodash/_baseAggregator.js", - "/project/node_modules/lodash/_baseAssign.js", - "/project/node_modules/lodash/_baseAssignIn.js", - "/project/node_modules/lodash/_baseAssignValue.js", - "/project/node_modules/lodash/_baseAt.js", - "/project/node_modules/lodash/_baseClamp.js", - "/project/node_modules/lodash/_baseClone.js", - "/project/node_modules/lodash/_baseConforms.js", - "/project/node_modules/lodash/_baseConformsTo.js", - "/project/node_modules/lodash/_baseCreate.js", - "/project/node_modules/lodash/_baseDelay.js", - "/project/node_modules/lodash/_baseDifference.js", - "/project/node_modules/lodash/_baseEach.js", - "/project/node_modules/lodash/_baseEachRight.js", - "/project/node_modules/lodash/_baseEvery.js", - "/project/node_modules/lodash/_baseExtremum.js", - "/project/node_modules/lodash/_baseFill.js", - "/project/node_modules/lodash/_baseFilter.js", - "/project/node_modules/lodash/_baseFindIndex.js", - "/project/node_modules/lodash/_baseFindKey.js", - "/project/node_modules/lodash/_baseFlatten.js", - "/project/node_modules/lodash/_baseFor.js", - "/project/node_modules/lodash/_baseForOwn.js", - "/project/node_modules/lodash/_baseForOwnRight.js", - "/project/node_modules/lodash/_baseForRight.js", - "/project/node_modules/lodash/_baseFunctions.js", - "/project/node_modules/lodash/_baseGet.js", - "/project/node_modules/lodash/_baseGetAllKeys.js", - "/project/node_modules/lodash/_baseGetTag.js", - "/project/node_modules/lodash/_baseGt.js", - "/project/node_modules/lodash/_baseHas.js", - "/project/node_modules/lodash/_baseHasIn.js", - "/project/node_modules/lodash/_baseIndexOf.js", - "/project/node_modules/lodash/_baseIndexOfWith.js", - "/project/node_modules/lodash/_baseInRange.js", - "/project/node_modules/lodash/_baseIntersection.js", - "/project/node_modules/lodash/_baseInverter.js", - "/project/node_modules/lodash/_baseInvoke.js", - "/project/node_modules/lodash/_baseIsArguments.js", - "/project/node_modules/lodash/_baseIsArrayBuffer.js", - "/project/node_modules/lodash/_baseIsDate.js", - "/project/node_modules/lodash/_baseIsEqual.js", - "/project/node_modules/lodash/_baseIsEqualDeep.js", - "/project/node_modules/lodash/_baseIsMap.js", - "/project/node_modules/lodash/_baseIsMatch.js", - "/project/node_modules/lodash/_baseIsNaN.js", - "/project/node_modules/lodash/_baseIsNative.js", - "/project/node_modules/lodash/_baseIsRegExp.js", - "/project/node_modules/lodash/_baseIsSet.js", - "/project/node_modules/lodash/_baseIsTypedArray.js", - "/project/node_modules/lodash/_baseIteratee.js", - "/project/node_modules/lodash/_baseKeys.js", - "/project/node_modules/lodash/_baseKeysIn.js", - "/project/node_modules/lodash/_baseLodash.js", - "/project/node_modules/lodash/_baseLt.js", - "/project/node_modules/lodash/_baseMap.js", - "/project/node_modules/lodash/_baseMatches.js", - "/project/node_modules/lodash/_baseMatchesProperty.js", - "/project/node_modules/lodash/_baseMean.js", - "/project/node_modules/lodash/_baseMerge.js", - "/project/node_modules/lodash/_baseMergeDeep.js", - "/project/node_modules/lodash/_baseNth.js", - "/project/node_modules/lodash/_baseOrderBy.js", - "/project/node_modules/lodash/_basePick.js", - "/project/node_modules/lodash/_basePickBy.js", - "/project/node_modules/lodash/_baseProperty.js", - "/project/node_modules/lodash/_basePropertyDeep.js", - "/project/node_modules/lodash/_basePropertyOf.js", - "/project/node_modules/lodash/_basePullAll.js", - "/project/node_modules/lodash/_basePullAt.js", - "/project/node_modules/lodash/_baseRandom.js", - "/project/node_modules/lodash/_baseRange.js", - "/project/node_modules/lodash/_baseReduce.js", - "/project/node_modules/lodash/_baseRepeat.js", - "/project/node_modules/lodash/_baseRest.js", - "/project/node_modules/lodash/_baseSample.js", - "/project/node_modules/lodash/_baseSampleSize.js", - "/project/node_modules/lodash/_baseSet.js", - "/project/node_modules/lodash/_baseSetData.js", - "/project/node_modules/lodash/_baseSetToString.js", - "/project/node_modules/lodash/_baseShuffle.js", - "/project/node_modules/lodash/_baseSlice.js", - "/project/node_modules/lodash/_baseSome.js", - "/project/node_modules/lodash/_baseSortBy.js", - "/project/node_modules/lodash/_baseSortedIndex.js", - "/project/node_modules/lodash/_baseSortedIndexBy.js", - "/project/node_modules/lodash/_baseSortedUniq.js", - "/project/node_modules/lodash/_baseSum.js", - "/project/node_modules/lodash/_baseTimes.js", - "/project/node_modules/lodash/_baseToNumber.js", - "/project/node_modules/lodash/_baseToPairs.js", - "/project/node_modules/lodash/_baseToString.js", - "/project/node_modules/lodash/_baseTrim.js", - "/project/node_modules/lodash/_baseUnary.js", - "/project/node_modules/lodash/_baseUniq.js", - "/project/node_modules/lodash/_baseUnset.js", - "/project/node_modules/lodash/_baseUpdate.js", - "/project/node_modules/lodash/_baseValues.js", - "/project/node_modules/lodash/_baseWhile.js", - "/project/node_modulges/lodash/_baseWrapperValue.js", - "/project/node_modules/lodash/_baseXor.js", - "/project/node_modules/lodash/_baseZipObject.js", - "/project/node_modules/lodash/_cacheHas.js", - "/project/node_modules/lodash/_castArrayLikeObject.js", - "/project/node_modules/lodash/_castFunction.js", - "/project/node_modules/lodash/_castPath.js", - "/project/node_modules/lodash/_castRest.js", - "/project/node_modules/lodash/_castSlice.js", - "/project/node_modules/lodash/_charsEndIndex.js", - "/project/node_modules/lodash/_charsStartIndex.js", - "/project/node_modules/lodash/_cloneArrayBuffer.js", - "/project/node_modules/lodash/_cloneBuffer.js", - "/project/node_modules/lodash/_cloneDataView.js", - "/project/node_modules/lodash/_cloneRegExp.js", - "/project/node_modules/lodash/_cloneSymbol.js", - "/project/node_modules/lodash/_cloneTypedArray.js", - "/project/node_modules/lodash/_compareAscending.js", - "/project/node_modules/lodash/_compareMultiple.js", - "/project/node_modules/lodash/_composeArgs.js", - "/project/node_modules/lodash/_composeArgsRight.js", - "/project/node_modules/lodash/_copyArray.js", - "/project/node_modules/lodash/_copyObject.js", - "/project/node_modules/lodash/_copySymbols.js", - "/project/node_modules/lodash/_copySymbolsIn.js", - "/project/node_modules/lodash/_coreJsData.js", - "/project/node_modules/lodash/_countHolders.js", - "/project/node_modules/lodash/_createAggregator.js", - "/project/node_modules/lodash/_createAssigner.js", - "/project/node_modules/lodash/_createBaseEach.js", - "/project/node_modules/lodash/_createBaseFor.js", - "/project/node_modules/lodash/_createBind.js", - "/project/node_modules/lodash/_createCaseFirst.js", - "/project/node_modules/lodash/_createCompounder.js", - "/project/node_modules/lodash/_createCtor.js", - "/project/node_modules/lodash/_createCurry.js", - "/project/node_modules/lodash/_createFind.js", - "/project/node_modules/lodash/_createFlow.js", - "/project/node_modules/lodash/_createHybrid.js", - "/project/node_modules/lodash/_createInverter.js", - "/project/node_modules/lodash/_createMathOperation.js", - "/project/node_modules/lodash/_createOver.js", - "/project/node_modules/lodash/_createPadding.js", - "/project/node_modules/lodash/_createPartial.js", - "/project/node_modules/lodash/_createRange.js", - "/project/node_modules/lodash/_createRecurry.js", - "/project/node_modules/lodash/_createRelationalOperation.js", - "/project/node_modules/lodash/_createRound.js", - "/project/node_modules/lodash/_createSet.js", - "/project/node_modules/lodash/_createToPairs.js", - "/project/node_modules/lodash/_createWrap.js", - "/project/node_modules/lodash/_customDefaultsAssignIn.js", - "/project/node_modules/lodash/_customDefaultsMerge.js", - "/project/node_modules/lodash/_customOmitClone.js", - "/project/node_modules/lodash/_DataView.js", - "/project/node_modules/lodash/_deburrLetter.js", - "/project/node_modules/lodash/_defineProperty.js", - "/project/node_modules/lodash/_equalArrays.js", - "/project/node_modules/lodash/_equalByTag.js", - "/project/node_modules/lodash/_equalObjects.js", - "/project/node_modules/lodash/_escapeHtmlChar.js", - "/project/node_modules/lodash/_escapeStringChar.js", - "/project/node_modules/lodash/_flatRest.js", - "/project/node_modules/lodash/_freeGlobal.js", - "/project/node_modules/lodash/_getAllKeys.js", - "/project/node_modules/lodash/_getAllKeysIn.js", - "/project/node_modules/lodash/_getData.js", - "/project/node_modules/lodash/_getFuncName.js", - "/project/node_modules/lodash/_getHolder.js", - "/project/node_modules/lodash/_getMapData.js", - "/project/node_modules/lodash/_getMatchData.js", - "/project/node_modules/lodash/_getNative.js", - "/project/node_modules/lodash/_getPrototype.js", - "/project/node_modules/lodash/_getRawTag.js", - "/project/node_modules/lodash/_getSymbols.js", - "/project/node_modules/lodash/_getSymbolsIn.js", - "/project/node_modules/lodash/_getTag.js", - "/project/node_modules/lodash/_getValue.js", - "/project/node_modules/lodash/_getView.js", - "/project/node_modules/lodash/_getWrapDetails.js", - "/project/node_modules/lodash/_Hash.js", - "/project/node_modules/lodash/_hashClear.js", - "/project/node_modules/lodash/_hashDelete.js", - "/project/node_modules/lodash/_hashGet.js", - "/project/node_modules/lodash/_hashHas.js", - "/project/node_modules/lodash/_hashSet.js", - "/project/node_modules/lodash/_hasPath.js", - "/project/node_modules/lodash/_hasUnicode.js", - "/project/node_modules/lodash/_hasUnicodeWord.js", - "/project/node_modules/lodash/_initCloneArray.js", - "/project/node_modules/lodash/_initCloneByTag.js", - "/project/node_modules/lodash/_initCloneObject.js", - "/project/node_modules/lodash/_insertWrapDetails.js", - "/project/node_modules/lodash/_isFlattenable.js", - "/project/node_modules/lodash/_isIndex.js", - "/project/node_modules/lodash/_isIterateeCall.js", - "/project/node_modules/lodash/_isKey.js", - "/project/node_modules/lodash/_isKeyable.js", - "/project/node_modules/lodash/_isLaziable.js", - "/project/node_modules/lodash/_isMaskable.js", - "/project/node_modules/lodash/_isMasked.js", - "/project/node_modules/lodash/_isPrototype.js", - "/project/node_modules/lodash/_isStrictComparable.js", - "/project/node_modules/lodash/_iteratorToArray.js", - "/project/node_modules/lodash/_lazyClone.js", - "/project/node_modules/lodash/_lazyReverse.js", - "/project/node_modules/lodash/_lazyValue.js", - "/project/node_modules/lodash/_LazyWrapper.js", - "/project/node_modules/lodash/_ListCache.js", - "/project/node_modules/lodash/_listCacheClear.js", - "/project/node_modules/lodash/_listCacheDelete.js", - "/project/node_modules/lodash/_listCacheGet.js", - "/project/node_modules/lodash/_listCacheHas.js", - "/project/node_modules/lodash/_listCacheSet.js", - "/project/node_modules/lodash/_LodashWrapper.js", - "/project/node_modules/lodash/_Map.js", - "/project/node_modules/lodash/_MapCache.js", - "/project/node_modules/lodash/_mapCacheClear.js", - "/project/node_modules/lodash/_mapCacheDelete.js", - "/project/node_modules/lodash/_mapCacheGet.js", - "/project/node_modules/lodash/_mapCacheHas.js", - "/project/node_modules/lodash/_mapCacheSet.js", - "/project/node_modules/lodash/_mapToArray.js", - "/project/node_modules/lodash/_matchesStrictComparable.js", - "/project/node_modules/lodash/_memoizeCapped.js", - "/project/node_modules/lodash/_mergeData.js", - "/project/node_modules/lodash/_metaMap.js", - "/project/node_modules/lodash/_nativeCreate.js", - "/project/node_modules/lodash/_nativeKeys.js", - "/project/node_modules/lodash/_nativeKeysIn.js", - "/project/node_modules/lodash/_nodeUtil.js", - "/project/node_modules/lodash/_objectToString.js", - "/project/node_modules/lodash/_overArg.js", - "/project/node_modules/lodash/_overRest.js", - "/project/node_modules/lodash/_parent.js", - "/project/node_modules/lodash/_Promise.js", - "/project/node_modules/lodash/_realNames.js", - "/project/node_modules/lodash/_reEscape.js", - "/project/node_modules/lodash/_reEvaluate.js", - "/project/node_modules/lodash/_reInterpolate.js", - "/project/node_modules/lodash/_reorder.js", - "/project/node_modules/lodash/_replaceHolders.js", - "/project/node_modules/lodash/_root.js", - "/project/node_modules/lodash/_safeGet.js", - "/project/node_modules/lodash/_Set.js", - "/project/node_modules/lodash/_SetCache.js", - "/project/node_modules/lodash/_setCacheAdd.js", - "/project/node_modules/lodash/_setCacheHas.js", - "/project/node_modules/lodash/_setData.js", - "/project/node_modules/lodash/_setToArray.js", - "/project/node_modules/lodash/_setToPairs.js", - "/project/node_modules/lodash/_setToString.js", - "/project/node_modules/lodash/_setWrapToString.js", - "/project/node_modules/lodash/_shortOut.js", - "/project/node_modules/lodash/_shuffleSelf.js", - "/project/node_modules/lodash/_Stack.js", - "/project/node_modules/lodash/_stackClear.js", - "/project/node_modules/lodash/_stackDelete.js", - "/project/node_modules/lodash/_stackGet.js", - "/project/node_modules/lodash/_stackHas.js", - "/project/node_modules/lodash/_stackSet.js", - "/project/node_modules/lodash/_strictIndexOf.js", - "/project/node_modules/lodash/_strictLastIndexOf.js", - "/project/node_modules/lodash/_stringSize.js", - "/project/node_modules/lodash/_stringToArray.js", - "/project/node_modules/lodash/_stringToPath.js", - "/project/node_modules/lodash/_Symbol.js", - "/project/node_modules/lodash/_toKey.js", - "/project/node_modules/lodash/_toSource.js", - "/project/node_modules/lodash/_trimmedEndIndex.js", - "/project/node_modules/lodash/_Uint8Array.js", - "/project/node_modules/lodash/_unescapeHtmlChar.js", - "/project/node_modules/lodash/_unicodeSize.js", - "/project/node_modules/lodash/_unicodeToArray.js", - "/project/node_modules/lodash/_unicodeWords.js", - "/project/node_modules/lodash/_updateWrapDetails.js", - "/project/node_modules/lodash/_WeakMap.js", - "/project/node_modules/lodash/_wrapperClone.js", - "/project/node_modules/lodash/add.js", - "/project/node_modules/lodash/after.js", - "/project/node_modules/lodash/array.js", - "/project/node_modules/lodash/ary.js", - "/project/node_modules/lodash/assign.js", - "/project/node_modules/lodash/assignIn.js", - "/project/node_modules/lodash/assignInWith.js", - "/project/node_modules/lodash/assignWith.js", - "/project/node_modules/lodash/at.js", - "/project/node_modules/lodash/attempt.js", - "/project/node_modules/lodash/before.js", - "/project/node_modules/lodash/bind.js", - "/project/node_modules/lodash/bindAll.js", - "/project/node_modules/lodash/bindKey.js", - "/project/node_modules/lodash/camelCase.js", - "/project/node_modules/lodash/capitalize.js", - "/project/node_modules/lodash/castArray.js", - "/project/node_modules/lodash/ceil.js", - "/project/node_modules/lodash/chain.js", - "/project/node_modules/lodash/chunk.js", - "/project/node_modules/lodash/clamp.js", - "/project/node_modules/lodash/clone.js", - "/project/node_modules/lodash/cloneDeep.js", - "/project/node_modules/lodash/cloneDeepWith.js", - "/project/node_modules/lodash/cloneWith.js", - "/project/node_modules/lodash/collection.js", - "/project/node_modules/lodash/commit.js", - "/project/node_modules/lodash/compact.js", - "/project/node_modules/lodash/concat.js", - "/project/node_modules/lodash/cond.js", - "/project/node_modules/lodash/conforms.js", - "/project/node_modules/lodash/conformsTo.js", - "/project/node_modules/lodash/constant.js", - "/project/node_modules/lodash/core.js", - "/project/node_modules/lodash/core.min.js", - "/project/node_modules/lodash/countBy.js", - "/project/node_modules/lodash/create.js", - "/project/node_modules/lodash/curry.js", - "/project/node_modules/lodash/curryRight.js", - "/project/node_modules/lodash/date.js", - "/project/node_modules/lodash/debounce.js", - "/project/node_modules/lodash/deburr.js", - "/project/node_modules/lodash/defaults.js", - "/project/node_modules/lodash/defaultsDeep.js", - "/project/node_modules/lodash/defaultTo.js", - "/project/node_modules/lodash/defer.js", - "/project/node_modules/lodash/delay.js", - "/project/node_modules/lodash/difference.js", - "/project/node_modules/lodash/differenceBy.js", - "/project/node_modules/lodash/differenceWith.js", - "/project/node_modules/lodash/divide.js", - "/project/node_modules/lodash/drop.js", - "/project/node_modules/lodash/dropRight.js", - "/project/node_modules/lodash/dropRightWhile.js", - "/project/node_modules/lodash/dropWhile.js", - "/project/node_modules/lodash/each.js", - "/project/node_modules/lodash/eachRight.js", - "/project/node_modules/lodash/endsWith.js", - "/project/node_modules/lodash/entries.js", - "/project/node_modules/lodash/entriesIn.js", - "/project/node_modules/lodash/eq.js", - "/project/node_modules/lodash/escape.js", - "/project/node_modules/lodash/escapeRegExp.js", - "/project/node_modules/lodash/every.js", - "/project/node_modules/lodash/extend.js", - "/project/node_modules/lodash/extendWith.js", - "/project/node_modules/lodash/fill.js", - "/project/node_modules/lodash/filter.js", - "/project/node_modules/lodash/find.js", - "/project/node_modules/lodash/findIndex.js", - "/project/node_modules/lodash/findKey.js", - "/project/node_modules/lodash/findLast.js", - "/project/node_modules/lodash/findLastIndex.js", - "/project/node_modules/lodash/findLastKey.js", - "/project/node_modules/lodash/first.js", - "/project/node_modules/lodash/flake.lock", - "/project/node_modules/lodash/flake.nix", - "/project/node_modules/lodash/flatMap.js", - "/project/node_modules/lodash/flatMapDeep.js", - "/project/node_modules/lodash/flatMapDepth.js", - "/project/node_modules/lodash/flatten.js", - "/project/node_modules/lodash/flattenDeep.js", - "/project/node_modules/lodash/flattenDepth.js", - "/project/node_modules/lodash/flip.js", - "/project/node_modules/lodash/floor.js", - "/project/node_modules/lodash/flow.js", - "/project/node_modules/lodash/flowRight.js", - "/project/node_modules/lodash/forEach.js", - "/project/node_modules/lodash/forEachRight.js", - "/project/node_modules/lodash/forIn.js", - "/project/node_modules/lodash/forInRight.js", - "/project/node_modules/lodash/forOwn.js", - "/project/node_modules/lodash/forOwnRight.js", - "/project/node_modules/lodash/fp", - "/project/node_modules/lodash/fp.js", - "/project/node_modules/lodash/fromPairs.js", - "/project/node_modules/lodash/function.js", - "/project/node_modules/lodash/functions.js", - "/project/node_modules/lodash/functionsIn.js", - "/project/node_modules/lodash/get.js", - "/project/node_modules/lodash/groupBy.js", - "/project/node_modules/lodash/gt.js", - "/project/node_modules/lodash/gte.js", - "/project/node_modules/lodash/has.js", - "/project/node_modules/lodash/hasIn.js", - "/project/node_modules/lodash/head.js", - "/project/node_modules/lodash/identity.js", - "/project/node_modules/lodash/includes.js", - "/project/node_modules/lodash/index.js", - "/project/node_modules/lodash/indexOf.js", - "/project/node_modules/lodash/initial.js", - "/project/node_modules/lodash/inRange.js", - "/project/node_modules/lodash/intersection.js", - "/project/node_modules/lodash/intersectionBy.js", - "/project/node_modules/lodash/intersectionWith.js", - "/project/node_modules/lodash/invert.js", - "/project/node_modules/lodash/invertBy.js", - "/project/node_modules/lodash/invoke.js", - "/project/node_modules/lodash/invokeMap.js", - "/project/node_modules/lodash/isArguments.js", - "/project/node_modules/lodash/isArray.js", - "/project/node_modules/lodash/isArrayBuffer.js", - "/project/node_modules/lodash/isArrayLike.js", - "/project/node_modules/lodash/isArrayLikeObject.js", - "/project/node_modules/lodash/isBoolean.js", - "/project/node_modules/lodash/isBuffer.js", - "/project/node_modules/lodash/isDate.js", - "/project/node_modules/lodash/isElement.js", - "/project/node_modules/lodash/isEmpty.js", - "/project/node_modules/lodash/isEqual.js", - "/project/node_modules/lodash/isEqualWith.js", - "/project/node_modules/lodash/isError.js", - "/project/node_modules/lodash/isFinite.js", - "/project/node_modules/lodash/isFunction.js", - "/project/node_modules/lodash/isInteger.js", - "/project/node_modules/lodash/isLength.js", - "/project/node_modules/lodash/isMap.js", - "/project/node_modules/lodash/isMatch.js", - "/project/node_modules/lodash/isMatchWith.js", - "/project/node_modules/lodash/isNaN.js", - "/project/node_modules/lodash/isNative.js", - "/project/node_modules/lodash/isNil.js", - "/project/node_modules/lodash/isNull.js", - "/project/node_modules/lodash/isNumber.js", - "/project/node_modules/lodash/isObject.js", - "/project/node_modules/lodash/isObjectLike.js", - "/project/node_modules/lodash/isPlainObject.js", - "/project/node_modules/lodash/isRegExp.js", - "/project/node_modules/lodash/isSafeInteger.js", - "/project/node_modules/lodash/isSet.js", - "/project/node_modules/lodash/isString.js", - "/project/node_modules/lodash/isSymbol.js", - "/project/node_modules/lodash/isTypedArray.js", - "/project/node_modules/lodash/isUndefined.js", - "/project/node_modules/lodash/isWeakMap.js", - "/project/node_modules/lodash/isWeakSet.js", - "/project/node_modules/lodash/iteratee.js", - "/project/node_modules/lodash/join.js", - "/project/node_modules/lodash/kebabCase.js", - "/project/node_modules/lodash/keyBy.js", - "/project/node_modules/lodash/keys.js", - "/project/node_modules/lodash/keysIn.js", - "/project/node_modules/lodash/lang.js", - "/project/node_modules/lodash/last.js", - "/project/node_modules/lodash/lastIndexOf.js", - "/project/node_modules/lodash/LICENSE", - "/project/node_modules/lodash/lodash.js", - "/project/node_modules/lodash/lodash.min.js", - "/project/node_modules/lodash/lowerCase.js", - "/project/node_modules/lodash/lowerFirst.js", - "/project/node_modules/lodash/lt.js", - "/project/node_modules/lodash/lte.js", - "/project/node_modules/lodash/map.js", - "/project/node_modules/lodash/mapKeys.js", - "/project/node_modules/lodash/mapValues.js", - "/project/node_modules/lodash/matches.js", - "/project/node_modules/lodash/matchesProperty.js", - "/project/node_modules/lodash/math.js", - "/project/node_modules/lodash/max.js", - "/project/node_modules/lodash/maxBy.js", - "/project/node_modules/lodash/mean.js", - "/project/node_modules/lodash/meanBy.js", - "/project/node_modules/lodash/memoize.js", - "/project/node_modules/lodash/merge.js", - "/project/node_modules/lodash/mergeWith.js", - "/project/node_modules/lodash/method.js", - "/project/node_modules/lodash/methodOf.js", - "/project/node_modules/lodash/min.js", - "/project/node_modules/lodash/minBy.js", - "/project/node_modules/lodash/mixin.js", - "/project/node_modules/lodash/multiply.js", - "/project/node_modules/lodash/negate.js", - "/project/node_modules/lodash/next.js", - "/project/node_modules/lodash/noop.js", - "/project/node_modules/lodash/now.js", - "/project/node_modules/lodash/nth.js", - "/project/node_modules/lodash/nthArg.js", - "/project/node_modules/lodash/number.js", - "/project/node_modules/lodash/object.js", - "/project/node_modules/lodash/omit.js", - "/project/node_modules/lodash/omitBy.js", - "/project/node_modules/lodash/once.js", - "/project/node_modules/lodash/orderBy.js", - "/project/node_modules/lodash/over.js", - "/project/node_modules/lodash/overArgs.js", - "/project/node_modules/lodash/overEvery.js", - "/project/node_modules/lodash/overSome.js", - "/project/node_modules/lodash/package.json", - "/project/node_modules/lodash/pad.js", - "/project/node_modules/lodash/padEnd.js", - "/project/node_modules/lodash/padStart.js", - "/project/node_modules/lodash/parseInt.js", - "/project/node_modules/lodash/partial.js", - "/project/node_modules/lodash/partialRight.js", - "/project/node_modules/lodash/partition.js", - "/project/node_modules/lodash/pick.js", - "/project/node_modules/lodash/pickBy.js", - "/project/node_modules/lodash/plant.js", - "/project/node_modules/lodash/property.js", - "/project/node_modules/lodash/propertyOf.js", - "/project/node_modules/lodash/pull.js", - "/project/node_modules/lodash/pullAll.js", - "/project/node_modules/lodash/pullAllBy.js", - "/project/node_modules/lodash/pullAllWith.js", - "/project/node_modules/lodash/pullAt.js", - "/project/node_modules/lodash/random.js", - "/project/node_modules/lodash/range.js", - "/project/node_modules/lodash/rangeRight.js", - "/project/node_modules/lodash/README.md", - "/project/node_modules/lodash/rearg.js", - "/project/node_modules/lodash/reduce.js", - "/project/node_modules/lodash/reduceRight.js", - "/project/node_modules/lodash/reject.js", - "/project/node_modules/lodash/release.md", - "/project/node_modules/lodash/remove.js", - "/project/node_modules/lodash/repeat.js", - "/project/node_modules/lodash/replace.js", - "/project/node_modules/lodash/rest.js", - "/project/node_modules/lodash/result.js", - "/project/node_modules/lodash/reverse.js", - "/project/node_modules/lodash/round.js", - "/project/node_modules/lodash/sample.js", - "/project/node_modules/lodash/sampleSize.js", - "/project/node_modules/lodash/seq.js", - "/project/node_modules/lodash/set.js", - "/project/node_modules/lodash/setWith.js", - "/project/node_modules/lodash/shuffle.js", - "/project/node_modules/lodash/size.js", - "/project/node_modules/lodash/slice.js", - "/project/node_modules/lodash/snakeCase.js", - "/project/node_modules/lodash/some.js", - "/project/node_modules/lodash/sortBy.js", - "/project/node_modules/lodash/sortedIndex.js", - "/project/node_modules/lodash/sortedIndexBy.js", - "/project/node_modules/lodash/sortedIndexOf.js", - "/project/node_modules/lodash/sortedLastIndex.js", - "/project/node_modules/lodash/sortedLastIndexBy.js", - "/project/node_modules/lodash/sortedLastIndexOf.js", - "/project/node_modules/lodash/sortedUniq.js", - "/project/node_modules/lodash/sortedUniqBy.js", - "/project/node_modules/lodash/split.js", - "/project/node_modules/lodash/spread.js", - "/project/node_modules/lodash/startCase.js", - "/project/node_modules/lodash/startsWith.js", - "/project/node_modules/lodash/string.js", - "/project/node_modules/lodash/stubArray.js", - "/project/node_modules/lodash/stubFalse.js", - "/project/node_modules/lodash/stubObject.js", - "/project/node_modules/lodash/stubString.js", - "/project/node_modules/lodash/stubTrue.js", - "/project/node_modules/lodash/subtract.js", - "/project/node_modules/lodash/sum.js", - "/project/node_modules/lodash/sumBy.js", - "/project/node_modules/lodash/tail.js", - "/project/node_modules/lodash/take.js", - "/project/node_modules/lodash/takeRight.js", - "/project/node_modules/lodash/takeRightWhile.js", - "/project/node_modules/lodash/takeWhile.js", - "/project/node_modules/lodash/tap.js", - "/project/node_modules/lodash/template.js", - "/project/node_modules/lodash/templateSettings.js", - "/project/node_modules/lodash/throttle.js", - "/project/node_modules/lodash/thru.js", - "/project/node_modules/lodash/times.js", - "/project/node_modules/lodash/toArray.js", - "/project/node_modules/lodash/toFinite.js", - "/project/node_modules/lodash/toInteger.js", - "/project/node_modules/lodash/toIterator.js", - "/project/node_modules/lodash/toJSON.js", - "/project/node_modules/lodash/toLength.js", - "/project/node_modules/lodash/toLower.js", - "/project/node_modules/lodash/toNumber.js", - "/project/node_modules/lodash/toPairs.js", - "/project/node_modules/lodash/toPairsIn.js", - "/project/node_modules/lodash/toPath.js", - "/project/node_modules/lodash/toPlainObject.js", - "/project/node_modules/lodash/toSafeInteger.js", - "/project/node_modules/lodash/toString.js", - "/project/node_modules/lodash/toUpper.js", - "/project/node_modules/lodash/transform.js", - "/project/node_modules/lodash/trim.js", - "/project/node_modules/lodash/trimEnd.js", - "/project/node_modules/lodash/trimStart.js", - "/project/node_modules/lodash/truncate.js", - "/project/node_modules/lodash/unary.js", - "/project/node_modules/lodash/unescape.js", - "/project/node_modules/lodash/union.js", - "/project/node_modules/lodash/unionBy.js", - "/project/node_modules/lodash/unionWith.js", - "/project/node_modules/lodash/uniq.js", - "/project/node_modules/lodash/uniqBy.js", - "/project/node_modules/lodash/uniqueId.js", - "/project/node_modules/lodash/uniqWith.js", - "/project/node_modules/lodash/unset.js", - "/project/node_modules/lodash/unzip.js", - "/project/node_modules/lodash/unzipWith.js", - "/project/node_modules/lodash/update.js", - "/project/node_modules/lodash/updateWith.js", - "/project/node_modules/lodash/upperCase.js", - "/project/node_modules/lodash/upperFirst.js", - "/project/node_modules/lodash/util.js", - "/project/node_modules/lodash/value.js", - "/project/node_modules/lodash/valueOf.js", - "/project/node_modules/lodash/values.js", - "/project/node_modules/lodash/valuesIn.js", - "/project/node_modules/lodash/without.js", - "/project/node_modules/lodash/words.js", - "/project/node_modules/lodash/wrap.js", - "/project/node_modules/lodash/wrapperAt.js", - "/project/node_modules/lodash/wrapperChain.js", - "/project/node_modules/lodash/wrapperLodash.js", - "/project/node_modules/lodash/wrapperReverse.js", - "/project/node_modules/lodash/wrapperValue.js", - "/project/node_modules/lodash/xor.js", - "/project/node_modules/lodash/xorBy.js", - "/project/node_modules/lodash/xorWith.js", - "/project/node_modules/lodash/zip.js", - "/project/node_modules/lodash/zipObject.js", - "/project/node_modules/lodash/zipObjectDeep.js", - "/project/node_modules/lodash/zipWith.js", -}; - -pub const three = [_][]const u8{ - "/project/node_modules/three/src", - "/project/node_modules/three/src/renderers", - "/project/node_modules/three/src/renderers/webgl", - "/project/node_modules/three/src/renderers/webgl/WebGLPrograms.js", - "/project/node_modules/three/src/renderers/webgl/WebGLGeometries.js", - "/project/node_modules/three/src/renderers/webgl/WebGLClipping.js", - "/project/node_modules/three/src/renderers/webgl/WebGLUniforms.js", - "/project/node_modules/three/src/renderers/webgl/WebGLShader.js", - "/project/node_modules/three/src/renderers/webgl/plugins", - "/project/node_modules/three/src/renderers/webgl/plugins/SpritePlugin.js", - "/project/node_modules/three/src/renderers/webgl/plugins/LensFlarePlugin.js", - "/project/node_modules/three/src/renderers/webgl/WebGLExtensions.js", - "/project/node_modules/three/src/renderers/webgl/WebGLBufferRenderer.js", - "/project/node_modules/three/src/renderers/webgl/WebGLObjects.js", - "/project/node_modules/three/src/renderers/webgl/WebGLLights.js", - "/project/node_modules/three/src/renderers/webgl/WebGLCapabilities.js", - "/project/node_modules/three/src/renderers/webgl/WebGLIndexedBufferRenderer.js", - "/project/node_modules/three/src/renderers/webgl/WebGLProperties.js", - "/project/node_modules/three/src/renderers/webgl/WebGLState.js", - "/project/node_modules/three/src/renderers/webgl/WebGLShadowMap.js", - "/project/node_modules/three/src/renderers/webgl/WebGLProgram.js", - "/project/node_modules/three/src/renderers/WebGLRenderTargetCube.js", - "/project/node_modules/three/src/renderers/shaders", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_phong_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/normalmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphnormal_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/fog_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinnormal_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/ambient_pars.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphtarget_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/emissivemap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/roughnessmap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/roughnessmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_particle_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lightmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/encodings_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmask_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphatest_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_phong_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/worldpos_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/normal_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_particle_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/metalnessmap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/morphtarget_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/common.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lightmap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_pars.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/specularmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/aomap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/envmap_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/tonemapping_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinning_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinning_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/tonemapping_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/logdepthbuf_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/aomap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/encodings_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_lambert_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphamap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/map_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/project_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/bumpmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/clipping_planes_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_template.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/packing.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/alphamap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/skinbase_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/shadowmap_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/specularmap_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/fog_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/bsdfs.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/begin_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/color_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/defaultnormal_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/metalnessmap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/cube_uv_reflection_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/uv2_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/displacementmap_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/emissivemap_pars_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/lights_physical_fragment.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk/displacementmap_pars_vertex.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderChunk.js", - "/project/node_modules/three/src/renderers/shaders/UniformsUtils.js", - "/project/node_modules/three/src/renderers/shaders/ShaderLib.js", - "/project/node_modules/three/src/renderers/shaders/DefinesUtils.js", - "/project/node_modules/three/src/renderers/shaders/ShaderLib", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/UniformsLib.js", - "/project/node_modules/three/src/renderers/WebGLRenderer.js", - "/project/node_modules/three/src/renderers/WebGLRenderTarget.js", - "/project/node_modules/three/src/textures", - "/project/node_modules/three/src/textures/DepthTexture.js", - "/project/node_modules/three/src/textures/CompressedTexture.js", - "/project/node_modules/three/src/textures/VideoTexture.js", - "/project/node_modules/three/src/textures/CubeTexture.js", - "/project/node_modules/three/src/textures/CanvasTexture.js", - "/project/node_modules/three/src/textures/Texture.js", - "/project/node_modules/three/src/textures/DataTexture.js", - "/project/node_modules/three/src/scenes", - "/project/node_modules/three/src/scenes/Fog.js", - "/project/node_modules/three/src/scenes/Scene.js", - "/project/node_modules/three/src/scenes/FogExp2.js", - "/project/node_modules/three/src/materials", - "/project/node_modules/three/src/materials/MultiMaterial.js", - "/project/node_modules/three/src/materials/LineDashedMaterial.js", - "/project/node_modules/three/src/materials/LineBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshNormalMaterial.js", - "/project/node_modules/three/src/materials/Material.js", - "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js", - "/project/node_modules/three/src/materials/MeshBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshStandardMaterial.js", - "/project/node_modules/three/src/materials/MeshPhongMaterial.js", - "/project/node_modules/three/src/materials/SpriteMaterial.js", - "/project/node_modules/three/src/materials/MeshDepthMaterial.js", - "/project/node_modules/three/src/materials/ShadowMaterial.js", - "/project/node_modules/three/src/materials/PointsMaterial.js", - "/project/node_modules/three/src/materials/ShaderMaterial.js", - "/project/node_modules/three/src/materials/MeshLambertMaterial.js", - "/project/node_modules/three/src/materials/RawShaderMaterial.js", - "/project/node_modules/three/src/core", - "/project/node_modules/three/src/core/InstancedBufferAttribute.js", - "/project/node_modules/three/src/core/Face3.js", - "/project/node_modules/three/src/core/Clock.js", - "/project/node_modules/three/src/core/BufferAttribute.js", - "/project/node_modules/three/src/core/Raycaster.js", - "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js", - "/project/node_modules/three/src/core/InterleavedBufferAttribute.js", - "/project/node_modules/three/src/core/EventDispatcher.js", - "/project/node_modules/three/src/core/InstancedBufferGeometry.js", - "/project/node_modules/three/src/core/Layers.js", - "/project/node_modules/three/src/core/Uniform.js", - "/project/node_modules/three/src/core/BufferGeometry.js", - "/project/node_modules/three/src/core/DirectGeometry.js", - "/project/node_modules/three/src/core/Geometry.js", - "/project/node_modules/three/src/core/InterleavedBuffer.js", - "/project/node_modules/three/src/core/Object3D.js", - "/project/node_modules/three/src/Three.js", - "/project/node_modules/three/src/animation", - "/project/node_modules/three/src/animation/AnimationUtils.js", - "/project/node_modules/three/src/animation/PropertyBinding.js", - "/project/node_modules/three/src/animation/KeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks", - "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js", - "/project/node_modules/three/src/animation/AnimationMixer.js", - "/project/node_modules/three/src/animation/PropertyMixer.js", - "/project/node_modules/three/src/animation/AnimationClip.js", - "/project/node_modules/three/src/animation/AnimationAction.js", - "/project/node_modules/three/src/animation/AnimationObjectGroup.js", - "/project/node_modules/three/src/objects", - "/project/node_modules/three/src/objects/Line.js", - "/project/node_modules/three/src/objects/Skeleton.js", - "/project/node_modules/three/src/objects/Mesh.js", - "/project/node_modules/three/src/objects/LensFlare.js", - "/project/node_modules/three/src/objects/Points.js", - "/project/node_modules/three/src/objects/LOD.js", - "/project/node_modules/three/src/objects/LineSegments.js", - "/project/node_modules/three/src/objects/Bone.js", - "/project/node_modules/three/src/objects/Sprite.js", - "/project/node_modules/three/src/objects/SkinnedMesh.js", - "/project/node_modules/three/src/objects/Group.js", - "/project/node_modules/three/src/cameras", - "/project/node_modules/three/src/cameras/CubeCamera.js", - "/project/node_modules/three/src/cameras/StereoCamera.js", - "/project/node_modules/three/src/cameras/PerspectiveCamera.js", - "/project/node_modules/three/src/cameras/Camera.js", - "/project/node_modules/three/src/cameras/OrthographicCamera.js", - "/project/node_modules/three/src/math", - "/project/node_modules/three/src/math/Vector2.js", - "/project/node_modules/three/src/math/Quaternion.js", - "/project/node_modules/three/src/math/Matrix3.js", - "/project/node_modules/three/src/math/Vector3.js", - "/project/node_modules/three/src/math/Ray.js", - "/project/node_modules/three/src/math/Spline.js", - "/project/node_modules/three/src/math/Color.js", - "/project/node_modules/three/src/math/Box3.js", - "/project/node_modules/three/src/math/Math.js", - "/project/node_modules/three/src/math/Euler.js", - "/project/node_modules/three/src/math/Frustum.js", - "/project/node_modules/three/src/math/Plane.js", - "/project/node_modules/three/src/math/Sphere.js", - "/project/node_modules/three/src/math/Interpolant.js", - "/project/node_modules/three/src/math/Box2.js", - "/project/node_modules/three/src/math/Line3.js", - "/project/node_modules/three/src/math/interpolants", - "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js", - "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js", - "/project/node_modules/three/src/math/Vector4.js", - "/project/node_modules/three/src/math/Matrix4.js", - "/project/node_modules/three/src/math/Spherical.js", - "/project/node_modules/three/src/math/Triangle.js", - "/project/node_modules/three/src/audio", - "/project/node_modules/three/src/audio/AudioContext.js", - "/project/node_modules/three/src/audio/AudioAnalyser.js", - "/project/node_modules/three/src/audio/AudioListener.js", - "/project/node_modules/three/src/audio/PositionalAudio.js", - "/project/node_modules/three/src/audio/Audio.js", - "/project/node_modules/three/src/Three.Legacy.js", - "/project/node_modules/three/src/loaders", - "/project/node_modules/three/src/loaders/ImageLoader.js", - "/project/node_modules/three/src/loaders/FontLoader.js", - "/project/node_modules/three/src/loaders/AnimationLoader.js", - "/project/node_modules/three/src/loaders/Cache.js", - "/project/node_modules/three/src/loaders/MaterialLoader.js", - "/project/node_modules/three/src/loaders/TextureLoader.js", - "/project/node_modules/three/src/loaders/LoadingManager.js", - "/project/node_modules/three/src/loaders/ObjectLoader.js", - "/project/node_modules/three/src/loaders/XHRLoader.js", - "/project/node_modules/three/src/loaders/CubeTextureLoader.js", - "/project/node_modules/three/src/loaders/AudioLoader.js", - "/project/node_modules/three/src/loaders/BufferGeometryLoader.js", - "/project/node_modules/three/src/loaders/CompressedTextureLoader.js", - "/project/node_modules/three/src/loaders/JSONLoader.js", - "/project/node_modules/three/src/loaders/BinaryTextureLoader.js", - "/project/node_modules/three/src/loaders/Loader.js", - "/project/node_modules/three/src/lights", - "/project/node_modules/three/src/lights/DirectionalLight.js", - "/project/node_modules/three/src/lights/SpotLightShadow.js", - "/project/node_modules/three/src/lights/AmbientLight.js", - "/project/node_modules/three/src/lights/SpotLight.js", - "/project/node_modules/three/src/lights/HemisphereLight.js", - "/project/node_modules/three/src/lights/Light.js", - "/project/node_modules/three/src/lights/DirectionalLightShadow.js", - "/project/node_modules/three/src/lights/LightShadow.js", - "/project/node_modules/three/src/lights/PointLight.js", - "/project/node_modules/three/src/extras", - "/project/node_modules/three/src/extras/SceneUtils.js", - "/project/node_modules/three/src/extras/core", - "/project/node_modules/three/src/extras/core/Font.js", - "/project/node_modules/three/src/extras/core/Path.js", - "/project/node_modules/three/src/extras/core/CurvePath.js", - "/project/node_modules/three/src/extras/core/Curve.js", - "/project/node_modules/three/src/extras/core/Shape.js", - "/project/node_modules/three/src/extras/ShapeUtils.js", - "/project/node_modules/three/src/extras/objects", - "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js", - "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js", - "/project/node_modules/three/src/extras/geometries", - "/project/node_modules/three/src/extras/geometries/TextGeometry.js", - "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js", - "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxGeometry.js", - "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js", - "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusGeometry.js", - "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleGeometry.js", - "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js", - "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js", - "/project/node_modules/three/src/extras/geometries/TubeGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js", - "/project/node_modules/three/src/extras/CurveUtils.js", - "/project/node_modules/three/src/extras/helpers", - "/project/node_modules/three/src/extras/helpers/WireframeHelper.js", - "/project/node_modules/three/src/extras/helpers/ArrowHelper.js", - "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js", - "/project/node_modules/three/src/extras/helpers/PointLightHelper.js", - "/project/node_modules/three/src/extras/helpers/AxisHelper.js", - "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js", - "/project/node_modules/three/src/extras/helpers/CameraHelper.js", - "/project/node_modules/three/src/extras/helpers/BoxHelper.js", - "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js", - "/project/node_modules/three/src/extras/helpers/EdgesHelper.js", - "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/GridHelper.js", - "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js", - "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js", - "/project/node_modules/three/src/extras/curves", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js", - "/project/node_modules/three/src/extras/curves/EllipseCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve3.js", - "/project/node_modules/three/src/extras/curves/ArcCurve.js", - "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve.js", - "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve.js", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/UniformsLib.js", - "/project/node_modules/three/src/renderers/WebGLRenderer.js", - "/project/node_modules/three/src/renderers/WebGLRenderTarget.js", - "/project/node_modules/three/src/textures", - "/project/node_modules/three/src/textures/DepthTexture.js", - "/project/node_modules/three/src/textures/CompressedTexture.js", - "/project/node_modules/three/src/textures/VideoTexture.js", - "/project/node_modules/three/src/textures/CubeTexture.js", - "/project/node_modules/three/src/textures/CanvasTexture.js", - "/project/node_modules/three/src/textures/Texture.js", - "/project/node_modules/three/src/textures/DataTexture.js", - "/project/node_modules/three/src/scenes", - "/project/node_modules/three/src/scenes/Fog.js", - "/project/node_modules/three/src/scenes/Scene.js", - "/project/node_modules/three/src/scenes/FogExp2.js", - "/project/node_modules/three/src/materials", - "/project/node_modules/three/src/materials/MultiMaterial.js", - "/project/node_modules/three/src/materials/LineDashedMaterial.js", - "/project/node_modules/three/src/materials/LineBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshNormalMaterial.js", - "/project/node_modules/three/src/materials/Material.js", - "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js", - "/project/node_modules/three/src/materials/MeshBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshStandardMaterial.js", - "/project/node_modules/three/src/materials/MeshPhongMaterial.js", - "/project/node_modules/three/src/materials/SpriteMaterial.js", - "/project/node_modules/three/src/materials/MeshDepthMaterial.js", - "/project/node_modules/three/src/materials/ShadowMaterial.js", - "/project/node_modules/three/src/materials/PointsMaterial.js", - "/project/node_modules/three/src/materials/ShaderMaterial.js", - "/project/node_modules/three/src/materials/MeshLambertMaterial.js", - "/project/node_modules/three/src/materials/RawShaderMaterial.js", - "/project/node_modules/three/src/core", - "/project/node_modules/three/src/core/InstancedBufferAttribute.js", - "/project/node_modules/three/src/core/Face3.js", - "/project/node_modules/three/src/core/Clock.js", - "/project/node_modules/three/src/core/BufferAttribute.js", - "/project/node_modules/three/src/core/Raycaster.js", - "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js", - "/project/node_modules/three/src/core/InterleavedBufferAttribute.js", - "/project/node_modules/three/src/core/EventDispatcher.js", - "/project/node_modules/three/src/core/InstancedBufferGeometry.js", - "/project/node_modules/three/src/core/Layers.js", - "/project/node_modules/three/src/core/Uniform.js", - "/project/node_modules/three/src/core/BufferGeometry.js", - "/project/node_modules/three/src/core/DirectGeometry.js", - "/project/node_modules/three/src/core/Geometry.js", - "/project/node_modules/three/src/core/InterleavedBuffer.js", - "/project/node_modules/three/src/core/Object3D.js", - "/project/node_modules/three/src/Three.js", - "/project/node_modules/three/src/animation", - "/project/node_modules/three/src/animation/AnimationUtils.js", - "/project/node_modules/three/src/animation/PropertyBinding.js", - "/project/node_modules/three/src/animation/KeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks", - "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js", - "/project/node_modules/three/src/animation/AnimationMixer.js", - "/project/node_modules/three/src/animation/PropertyMixer.js", - "/project/node_modules/three/src/animation/AnimationClip.js", - "/project/node_modules/three/src/animation/AnimationAction.js", - "/project/node_modules/three/src/animation/AnimationObjectGroup.js", - "/project/node_modules/three/src/objects", - "/project/node_modules/three/src/objects/Line.js", - "/project/node_modules/three/src/objects/Skeleton.js", - "/project/node_modules/three/src/objects/Mesh.js", - "/project/node_modules/three/src/objects/LensFlare.js", - "/project/node_modules/three/src/objects/Points.js", - "/project/node_modules/three/src/objects/LOD.js", - "/project/node_modules/three/src/objects/LineSegments.js", - "/project/node_modules/three/src/objects/Bone.js", - "/project/node_modules/three/src/objects/Sprite.js", - "/project/node_modules/three/src/objects/SkinnedMesh.js", - "/project/node_modules/three/src/objects/Group.js", - "/project/node_modules/three/src/cameras", - "/project/node_modules/three/src/cameras/CubeCamera.js", - "/project/node_modules/three/src/cameras/StereoCamera.js", - "/project/node_modules/three/src/cameras/PerspectiveCamera.js", - "/project/node_modules/three/src/cameras/Camera.js", - "/project/node_modules/three/src/cameras/OrthographicCamera.js", - "/project/node_modules/three/src/math", - "/project/node_modules/three/src/math/Vector2.js", - "/project/node_modules/three/src/math/Quaternion.js", - "/project/node_modules/three/src/math/Matrix3.js", - "/project/node_modules/three/src/math/Vector3.js", - "/project/node_modules/three/src/math/Ray.js", - "/project/node_modules/three/src/math/Spline.js", - "/project/node_modules/three/src/math/Color.js", - "/project/node_modules/three/src/math/Box3.js", - "/project/node_modules/three/src/math/Math.js", - "/project/node_modules/three/src/math/Euler.js", - "/project/node_modules/three/src/math/Frustum.js", - "/project/node_modules/three/src/math/Plane.js", - "/project/node_modules/three/src/math/Sphere.js", - "/project/node_modules/three/src/math/Interpolant.js", - "/project/node_modules/three/src/math/Box2.js", - "/project/node_modules/three/src/math/Line3.js", - "/project/node_modules/three/src/math/interpolants", - "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js", - "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js", - "/project/node_modules/three/src/math/Vector4.js", - "/project/node_modules/three/src/math/Matrix4.js", - "/project/node_modules/three/src/math/Spherical.js", - "/project/node_modules/three/src/math/Triangle.js", - "/project/node_modules/three/src/audio", - "/project/node_modules/three/src/audio/AudioContext.js", - "/project/node_modules/three/src/audio/AudioAnalyser.js", - "/project/node_modules/three/src/audio/AudioListener.js", - "/project/node_modules/three/src/audio/PositionalAudio.js", - "/project/node_modules/three/src/audio/Audio.js", - "/project/node_modules/three/src/Three.Legacy.js", - "/project/node_modules/three/src/loaders", - "/project/node_modules/three/src/loaders/ImageLoader.js", - "/project/node_modules/three/src/loaders/FontLoader.js", - "/project/node_modules/three/src/loaders/AnimationLoader.js", - "/project/node_modules/three/src/loaders/Cache.js", - "/project/node_modules/three/src/loaders/MaterialLoader.js", - "/project/node_modules/three/src/loaders/TextureLoader.js", - "/project/node_modules/three/src/loaders/LoadingManager.js", - "/project/node_modules/three/src/loaders/ObjectLoader.js", - "/project/node_modules/three/src/loaders/XHRLoader.js", - "/project/node_modules/three/src/loaders/CubeTextureLoader.js", - "/project/node_modules/three/src/loaders/AudioLoader.js", - "/project/node_modules/three/src/loaders/BufferGeometryLoader.js", - "/project/node_modules/three/src/loaders/CompressedTextureLoader.js", - "/project/node_modules/three/src/loaders/JSONLoader.js", - "/project/node_modules/three/src/loaders/BinaryTextureLoader.js", - "/project/node_modules/three/src/loaders/Loader.js", - "/project/node_modules/three/src/lights", - "/project/node_modules/three/src/lights/DirectionalLight.js", - "/project/node_modules/three/src/lights/SpotLightShadow.js", - "/project/node_modules/three/src/lights/AmbientLight.js", - "/project/node_modules/three/src/lights/SpotLight.js", - "/project/node_modules/three/src/lights/HemisphereLight.js", - "/project/node_modules/three/src/lights/Light.js", - "/project/node_modules/three/src/lights/DirectionalLightShadow.js", - "/project/node_modules/three/src/lights/LightShadow.js", - "/project/node_modules/three/src/lights/PointLight.js", - "/project/node_modules/three/src/extras", - "/project/node_modules/three/src/extras/SceneUtils.js", - "/project/node_modules/three/src/extras/core", - "/project/node_modules/three/src/extras/core/Font.js", - "/project/node_modules/three/src/extras/core/Path.js", - "/project/node_modules/three/src/extras/core/CurvePath.js", - "/project/node_modules/three/src/extras/core/Curve.js", - "/project/node_modules/three/src/extras/core/Shape.js", - "/project/node_modules/three/src/extras/ShapeUtils.js", - "/project/node_modules/three/src/extras/objects", - "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js", - "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js", - "/project/node_modules/three/src/extras/geometries", - "/project/node_modules/three/src/extras/geometries/TextGeometry.js", - "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js", - "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxGeometry.js", - "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js", - "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusGeometry.js", - "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleGeometry.js", - "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js", - "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js", - "/project/node_modules/three/src/extras/geometries/TubeGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js", - "/project/node_modules/three/src/extras/CurveUtils.js", - "/project/node_modules/three/src/extras/helpers", - "/project/node_modules/three/src/extras/helpers/WireframeHelper.js", - "/project/node_modules/three/src/extras/helpers/ArrowHelper.js", - "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js", - "/project/node_modules/three/src/extras/helpers/PointLightHelper.js", - "/project/node_modules/three/src/extras/helpers/AxisHelper.js", - "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js", - "/project/node_modules/three/src/extras/helpers/CameraHelper.js", - "/project/node_modules/three/src/extras/helpers/BoxHelper.js", - "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js", - "/project/node_modules/three/src/extras/helpers/EdgesHelper.js", - "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/GridHelper.js", - "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js", - "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js", - "/project/node_modules/three/src/extras/curves", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js", - "/project/node_modules/three/src/extras/curves/EllipseCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve3.js", - "/project/node_modules/three/src/extras/curves/ArcCurve.js", - "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve.js", - "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve.js", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/normal_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/depth_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/distanceRGBA_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/linedashed_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/shadow_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshbasic_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshlambert_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/points_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/equirect_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/cube_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphysical_vert.glsl", - "/project/node_modules/three/src/renderers/shaders/ShaderLib/meshphong_frag.glsl", - "/project/node_modules/three/src/renderers/shaders/UniformsLib.js", - "/project/node_modules/three/src/renderers/WebGLRenderer.js", - "/project/node_modules/three/src/renderers/WebGLRenderTarget.js", - "/project/node_modules/three/src/textures", - "/project/node_modules/three/src/textures/DepthTexture.js", - "/project/node_modules/three/src/textures/CompressedTexture.js", - "/project/node_modules/three/src/textures/VideoTexture.js", - "/project/node_modules/three/src/textures/CubeTexture.js", - "/project/node_modules/three/src/textures/CanvasTexture.js", - "/project/node_modules/three/src/textures/Texture.js", - "/project/node_modules/three/src/textures/DataTexture.js", - "/project/node_modules/three/src/scenes", - "/project/node_modules/three/src/scenes/Fog.js", - "/project/node_modules/three/src/scenes/Scene.js", - "/project/node_modules/three/src/scenes/FogExp2.js", - "/project/node_modules/three/src/materials", - "/project/node_modules/three/src/materials/MultiMaterial.js", - "/project/node_modules/three/src/materials/LineDashedMaterial.js", - "/project/node_modules/three/src/materials/LineBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshNormalMaterial.js", - "/project/node_modules/three/src/materials/Material.js", - "/project/node_modules/three/src/materials/MeshPhysicalMaterial.js", - "/project/node_modules/three/src/materials/MeshBasicMaterial.js", - "/project/node_modules/three/src/materials/MeshStandardMaterial.js", - "/project/node_modules/three/src/materials/MeshPhongMaterial.js", - "/project/node_modules/three/src/materials/SpriteMaterial.js", - "/project/node_modules/three/src/materials/MeshDepthMaterial.js", - "/project/node_modules/three/src/materials/ShadowMaterial.js", - "/project/node_modules/three/src/materials/PointsMaterial.js", - "/project/node_modules/three/src/materials/ShaderMaterial.js", - "/project/node_modules/three/src/materials/MeshLambertMaterial.js", - "/project/node_modules/three/src/materials/RawShaderMaterial.js", - "/project/node_modules/three/src/core", - "/project/node_modules/three/src/core/InstancedBufferAttribute.js", - "/project/node_modules/three/src/core/Face3.js", - "/project/node_modules/three/src/core/Clock.js", - "/project/node_modules/three/src/core/BufferAttribute.js", - "/project/node_modules/three/src/core/Raycaster.js", - "/project/node_modules/three/src/core/InstancedInterleavedBuffer.js", - "/project/node_modules/three/src/core/InterleavedBufferAttribute.js", - "/project/node_modules/three/src/core/EventDispatcher.js", - "/project/node_modules/three/src/core/InstancedBufferGeometry.js", - "/project/node_modules/three/src/core/Layers.js", - "/project/node_modules/three/src/core/Uniform.js", - "/project/node_modules/three/src/core/BufferGeometry.js", - "/project/node_modules/three/src/core/DirectGeometry.js", - "/project/node_modules/three/src/core/Geometry.js", - "/project/node_modules/three/src/core/InterleavedBuffer.js", - "/project/node_modules/three/src/core/Object3D.js", - "/project/node_modules/three/src/Three.js", - "/project/node_modules/three/src/animation", - "/project/node_modules/three/src/animation/AnimationUtils.js", - "/project/node_modules/three/src/animation/PropertyBinding.js", - "/project/node_modules/three/src/animation/KeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks", - "/project/node_modules/three/src/animation/tracks/VectorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/NumberKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/ColorKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/StringKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/QuaternionKeyframeTrack.js", - "/project/node_modules/three/src/animation/tracks/BooleanKeyframeTrack.js", - "/project/node_modules/three/src/animation/AnimationMixer.js", - "/project/node_modules/three/src/animation/PropertyMixer.js", - "/project/node_modules/three/src/animation/AnimationClip.js", - "/project/node_modules/three/src/animation/AnimationAction.js", - "/project/node_modules/three/src/animation/AnimationObjectGroup.js", - "/project/node_modules/three/src/objects", - "/project/node_modules/three/src/objects/Line.js", - "/project/node_modules/three/src/objects/Skeleton.js", - "/project/node_modules/three/src/objects/Mesh.js", - "/project/node_modules/three/src/objects/LensFlare.js", - "/project/node_modules/three/src/objects/Points.js", - "/project/node_modules/three/src/objects/LOD.js", - "/project/node_modules/three/src/objects/LineSegments.js", - "/project/node_modules/three/src/objects/Bone.js", - "/project/node_modules/three/src/objects/Sprite.js", - "/project/node_modules/three/src/objects/SkinnedMesh.js", - "/project/node_modules/three/src/objects/Group.js", - "/project/node_modules/three/src/cameras", - "/project/node_modules/three/src/cameras/CubeCamera.js", - "/project/node_modules/three/src/cameras/StereoCamera.js", - "/project/node_modules/three/src/cameras/PerspectiveCamera.js", - "/project/node_modules/three/src/cameras/Camera.js", - "/project/node_modules/three/src/cameras/OrthographicCamera.js", - "/project/node_modules/three/src/math", - "/project/node_modules/three/src/math/Vector2.js", - "/project/node_modules/three/src/math/Quaternion.js", - "/project/node_modules/three/src/math/Matrix3.js", - "/project/node_modules/three/src/math/Vector3.js", - "/project/node_modules/three/src/math/Ray.js", - "/project/node_modules/three/src/math/Spline.js", - "/project/node_modules/three/src/math/Color.js", - "/project/node_modules/three/src/math/Box3.js", - "/project/node_modules/three/src/math/Math.js", - "/project/node_modules/three/src/math/Euler.js", - "/project/node_modules/three/src/math/Frustum.js", - "/project/node_modules/three/src/math/Plane.js", - "/project/node_modules/three/src/math/Sphere.js", - "/project/node_modules/three/src/math/Interpolant.js", - "/project/node_modules/three/src/math/Box2.js", - "/project/node_modules/three/src/math/Line3.js", - "/project/node_modules/three/src/math/interpolants", - "/project/node_modules/three/src/math/interpolants/QuaternionLinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/LinearInterpolant.js", - "/project/node_modules/three/src/math/interpolants/DiscreteInterpolant.js", - "/project/node_modules/three/src/math/interpolants/CubicInterpolant.js", - "/project/node_modules/three/src/math/Vector4.js", - "/project/node_modules/three/src/math/Matrix4.js", - "/project/node_modules/three/src/math/Spherical.js", - "/project/node_modules/three/src/math/Triangle.js", - "/project/node_modules/three/src/audio", - "/project/node_modules/three/src/audio/AudioContext.js", - "/project/node_modules/three/src/audio/AudioAnalyser.js", - "/project/node_modules/three/src/audio/AudioListener.js", - "/project/node_modules/three/src/audio/PositionalAudio.js", - "/project/node_modules/three/src/audio/Audio.js", - "/project/node_modules/three/src/Three.Legacy.js", - "/project/node_modules/three/src/loaders", - "/project/node_modules/three/src/loaders/ImageLoader.js", - "/project/node_modules/three/src/loaders/FontLoader.js", - "/project/node_modules/three/src/loaders/AnimationLoader.js", - "/project/node_modules/three/src/loaders/Cache.js", - "/project/node_modules/three/src/loaders/MaterialLoader.js", - "/project/node_modules/three/src/loaders/TextureLoader.js", - "/project/node_modules/three/src/loaders/LoadingManager.js", - "/project/node_modules/three/src/loaders/ObjectLoader.js", - "/project/node_modules/three/src/loaders/XHRLoader.js", - "/project/node_modules/three/src/loaders/CubeTextureLoader.js", - "/project/node_modules/three/src/loaders/AudioLoader.js", - "/project/node_modules/three/src/loaders/BufferGeometryLoader.js", - "/project/node_modules/three/src/loaders/CompressedTextureLoader.js", - "/project/node_modules/three/src/loaders/JSONLoader.js", - "/project/node_modules/three/src/loaders/BinaryTextureLoader.js", - "/project/node_modules/three/src/loaders/Loader.js", - "/project/node_modules/three/src/lights", - "/project/node_modules/three/src/lights/DirectionalLight.js", - "/project/node_modules/three/src/lights/SpotLightShadow.js", - "/project/node_modules/three/src/lights/AmbientLight.js", - "/project/node_modules/three/src/lights/SpotLight.js", - "/project/node_modules/three/src/lights/HemisphereLight.js", - "/project/node_modules/three/src/lights/Light.js", - "/project/node_modules/three/src/lights/DirectionalLightShadow.js", - "/project/node_modules/three/src/lights/LightShadow.js", - "/project/node_modules/three/src/lights/PointLight.js", - "/project/node_modules/three/src/extras", - "/project/node_modules/three/src/extras/SceneUtils.js", - "/project/node_modules/three/src/extras/core", - "/project/node_modules/three/src/extras/core/Font.js", - "/project/node_modules/three/src/extras/core/Path.js", - "/project/node_modules/three/src/extras/core/CurvePath.js", - "/project/node_modules/three/src/extras/core/Curve.js", - "/project/node_modules/three/src/extras/core/Shape.js", - "/project/node_modules/three/src/extras/ShapeUtils.js", - "/project/node_modules/three/src/extras/objects", - "/project/node_modules/three/src/extras/objects/MorphBlendMesh.js", - "/project/node_modules/three/src/extras/objects/ImmediateRenderObject.js", - "/project/node_modules/three/src/extras/geometries", - "/project/node_modules/three/src/extras/geometries/TextGeometry.js", - "/project/node_modules/three/src/extras/geometries/WireframeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneGeometry.js", - "/project/node_modules/three/src/extras/geometries/DodecahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/ParametricGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxGeometry.js", - "/project/node_modules/three/src/extras/geometries/EdgesGeometry.js", - "/project/node_modules/three/src/extras/geometries/TetrahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/RingGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/LatheGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/SphereGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusGeometry.js", - "/project/node_modules/three/src/extras/geometries/IcosahedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/CircleGeometry.js", - "/project/node_modules/three/src/extras/geometries/ShapeGeometry.js", - "/project/node_modules/three/src/extras/geometries/PlaneBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/BoxBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderGeometry.js", - "/project/node_modules/three/src/extras/geometries/ExtrudeGeometry.js", - "/project/node_modules/three/src/extras/geometries/ConeGeometry.js", - "/project/node_modules/three/src/extras/geometries/TorusKnotGeometry.js", - "/project/node_modules/three/src/extras/geometries/TubeGeometry.js", - "/project/node_modules/three/src/extras/geometries/CylinderBufferGeometry.js", - "/project/node_modules/three/src/extras/geometries/PolyhedronGeometry.js", - "/project/node_modules/three/src/extras/geometries/OctahedronGeometry.js", - "/project/node_modules/three/src/extras/CurveUtils.js", - "/project/node_modules/three/src/extras/helpers", - "/project/node_modules/three/src/extras/helpers/WireframeHelper.js", - "/project/node_modules/three/src/extras/helpers/ArrowHelper.js", - "/project/node_modules/three/src/extras/helpers/SkeletonHelper.js", - "/project/node_modules/three/src/extras/helpers/PointLightHelper.js", - "/project/node_modules/three/src/extras/helpers/AxisHelper.js", - "/project/node_modules/three/src/extras/helpers/SpotLightHelper.js", - "/project/node_modules/three/src/extras/helpers/CameraHelper.js", - "/project/node_modules/three/src/extras/helpers/BoxHelper.js", - "/project/node_modules/three/src/extras/helpers/VertexNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/BoundingBoxHelper.js", - "/project/node_modules/three/src/extras/helpers/EdgesHelper.js", - "/project/node_modules/three/src/extras/helpers/FaceNormalsHelper.js", - "/project/node_modules/three/src/extras/helpers/GridHelper.js", - "/project/node_modules/three/src/extras/helpers/HemisphereLightHelper.js", - "/project/node_modules/three/src/extras/helpers/DirectionalLightHelper.js", - "/project/node_modules/three/src/extras/curves", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve.js", - "/project/node_modules/three/src/extras/curves/EllipseCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve3.js", - "/project/node_modules/three/src/extras/curves/ArcCurve.js", - "/project/node_modules/three/src/extras/curves/ClosedSplineCurve3.js", - "/project/node_modules/three/src/extras/curves/CubicBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve3.js", - "/project/node_modules/three/src/extras/curves/QuadraticBezierCurve.js", - "/project/node_modules/three/src/extras/curves/LineCurve.js", - "/project/node_modules/three/src/extras/curves/CatmullRomCurve3.js", - "/project/node_modules/three/src/extras/curves/SplineCurve.js", -}; - -pub const next = [_][]const u8{ - "next@11.1.0/app.js - 3424158524:2890943422", - "next@11.1.0/app.js - 3424158524:2890943422", - "next@11.1.0/dist/client/head-manager.js - 3424158524:2201168507", - "next@11.1.0/dist/client/head-manager.js - 3424158524:2201168507", - "next@11.1.0/dist/client/link.js - 3424158524:3978876338", - "next@11.1.0/dist/client/link.js - 3424158524:3978876338", - "next@11.1.0/dist/client/normalize-trailing-slash.js - 3424158524:3949960510", - "next@11.1.0/dist/client/normalize-trailing-slash.js - 3424158524:3949960510", - "next@11.1.0/dist/client/page-loader.js - 3424158524:3974401562", - "next@11.1.0/dist/client/request-idle-callback.js - 3424158524:2155089364", - "next@11.1.0/dist/client/request-idle-callback.js - 3424158524:2155089364", - "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608", - "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608", - "next@11.1.0/dist/client/route-loader.js - 3424158524:868049608", - "next@11.1.0/dist/client/router.js - 3424158524:60654157", - "next@11.1.0/dist/client/router.js - 3424158524:60654157", - "next@11.1.0/dist/client/router.js - 3424158524:60654157", - "next@11.1.0/dist/client/script.js - 3424158524:2971760940", - "next@11.1.0/dist/client/use-intersection.js - 3424158524:1893142411", - "next@11.1.0/dist/client/use-intersection.js - 3424158524:1893142411", - "next@11.1.0/dist/client/with-router.js - 3424158524:3574523301", - "next@11.1.0/dist/client/with-router.js - 3424158524:3574523301", - "next@11.1.0/dist/compiled/path-to-regexp/index.js - 3424158524:4292453228", - "next@11.1.0/dist/compiled/path-to-regexp/index.js - 3424158524:4292453228", - "next@11.1.0/dist/pages/_app.js - 3424158524:1831562171", - "next@11.1.0/dist/pages/_app.js - 3424158524:1831562171", - "next@11.1.0/dist/pages/_document.js - 3424158524:1843055786", - "next@11.1.0/dist/server/denormalize-page-path.js - 3424158524:2078268279", - "next@11.1.0/dist/server/denormalize-page-path.js - 3424158524:2078268279", - "next@11.1.0/dist/server/get-page-files.js - 3424158524:3103205117", - "next@11.1.0/dist/server/htmlescape.js - 3424158524:3619675719", - "next@11.1.0/dist/server/normalize-page-path.js - 3424158524:79382061", - "next@11.1.0/dist/server/utils.js - 3424158524:3170288217", - "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210", - "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210", - "next@11.1.0/dist/shared/lib/amp-context.js - 3424158524:2231212210", - "next@11.1.0/dist/shared/lib/amp.js - 3424158524:3972854680", - "next@11.1.0/dist/shared/lib/amp.js - 3424158524:3972854680", - "next@11.1.0/dist/shared/lib/constants.js - 3424158524:3766949957", - "next@11.1.0/dist/shared/lib/document-context.js - 3424158524:3503028665", - "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170", - "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170", - "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170", - "next@11.1.0/dist/shared/lib/head-manager-context.js - 3424158524:99574170", - "next@11.1.0/dist/shared/lib/head.js - 3424158524:1660462722", - "next@11.1.0/dist/shared/lib/head.js - 3424158524:1660462722", - "next@11.1.0/dist/shared/lib/i18n/detect-domain-locale.js - 3424158524:2360522531", - "next@11.1.0/dist/shared/lib/i18n/normalize-locale-path.js - 3424158524:2987178093", - "next@11.1.0/dist/shared/lib/i18n/normalize-locale-path.js - 3424158524:2987178093", - "next@11.1.0/dist/shared/lib/loadable-context.js - 3424158524:3504182001", - "next@11.1.0/dist/shared/lib/loadable-context.js - 3424158524:3504182001", - "next@11.1.0/dist/shared/lib/loadable.js - 3424158524:3055601316", - "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371", - "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371", - "next@11.1.0/dist/shared/lib/mitt.js - 3424158524:697603371", - "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782", - "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782", - "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782", - "next@11.1.0/dist/shared/lib/router-context.js - 3424158524:2677379782", - "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930", - "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930", - "next@11.1.0/dist/shared/lib/router/router.js - 3424158524:784078930", - "next@11.1.0/dist/shared/lib/router/utils/format-url.js - 3424158524:2249819031", - "next@11.1.0/dist/shared/lib/router/utils/format-url.js - 3424158524:2249819031", - "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198", - "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198", - "next@11.1.0/dist/shared/lib/router/utils/get-asset-path-from-route.js - 3424158524:1494341198", - "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346", - "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346", - "next@11.1.0/dist/shared/lib/router/utils/is-dynamic.js - 3424158524:3652061346", - "next@11.1.0/dist/shared/lib/router/utils/parse-relative-url.js - 3424158524:84921275", - "next@11.1.0/dist/shared/lib/router/utils/parse-relative-url.js - 3424158524:84921275", - "next@11.1.0/dist/shared/lib/router/utils/parse-url.js - 3424158524:2943870410", - "next@11.1.0/dist/shared/lib/router/utils/parse-url.js - 3424158524:2943870410", - "next@11.1.0/dist/shared/lib/router/utils/path-match.js - 3424158524:1335539408", - "next@11.1.0/dist/shared/lib/router/utils/path-match.js - 3424158524:1335539408", - "next@11.1.0/dist/shared/lib/router/utils/prepare-destination.js - 3424158524:2905198601", - "next@11.1.0/dist/shared/lib/router/utils/prepare-destination.js - 3424158524:2905198601", - "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157", - "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157", - "next@11.1.0/dist/shared/lib/router/utils/querystring.js - 3424158524:2585795157", - "next@11.1.0/dist/shared/lib/router/utils/resolve-rewrites.js - 3424158524:2049321565", - "next@11.1.0/dist/shared/lib/router/utils/resolve-rewrites.js - 3424158524:2049321565", - "next@11.1.0/dist/shared/lib/router/utils/route-matcher.js - 3424158524:3388378419", - "next@11.1.0/dist/shared/lib/router/utils/route-matcher.js - 3424158524:3388378419", - "next@11.1.0/dist/shared/lib/router/utils/route-regex.js - 3424158524:1570670727", - "next@11.1.0/dist/shared/lib/router/utils/route-regex.js - 3424158524:1570670727", - "next@11.1.0/dist/shared/lib/runtime-config.js - 3424158524:4205818429", - "next@11.1.0/dist/shared/lib/side-effect.js - 3424158524:3871282960", - "next@11.1.0/dist/shared/lib/side-effect.js - 3424158524:3871282960", - "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793", - "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793", - "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793", - "next@11.1.0/dist/shared/lib/utils.js - 3424158524:2498823793", - "next@11.1.0/document.js - 3424158524:761357561", - "next@11.1.0/head.js - 3424158524:4027675732", - "next@11.1.0/head.js - 3424158524:4027675732", - "next@11.1.0/link.js - 3424158524:3847679594", - "next@11.1.0/link.js - 3424158524:3847679594", - "next@11.1.0/router.js - 3424158524:2467530242", - "next@11.1.0/router.js - 3424158524:2467530242", - "object-assign@4.1.1/index.js - 1106322050:1257305923", - "object-assign@4.1.1/index.js - 1106322050:1257305923", - "react-dom@17.0.2/cjs/react-dom-server.browser.development.js - 2917057216:4251258747", - "react-dom@17.0.2/cjs/react-dom.development.js - 2917057216:2729826485", - "react-dom@17.0.2/index.js - 2917057216:4152798548", - "react-dom@17.0.2/server.browser.js - 2917057216:2336742101", - "react-is@17.0.2/cjs/react-is.development.js - 1177198225:1925584658", - "react-is@17.0.2/cjs/react-is.development.js - 1177198225:1925584658", - "react-is@17.0.2/index.js - 1177198225:3919220786", - "react-is@17.0.2/index.js - 1177198225:3919220786", - "react-is@17.0.2/index.js - 1177198225:3919220786", - "react-refresh@0.8.3/cjs/react-refresh-runtime.development.js - 1106322050:2742290347", - "react-refresh@0.8.3/runtime.js - 1106322050:1039122438", - "react@17.0.2/cjs/react-jsx-dev-runtime.development.js - 2465707714:1705570593", - "react@17.0.2/cjs/react-jsx-dev-runtime.development.js - 2465707714:1705570593", - "react@17.0.2/cjs/react.development.js - 2465707714:1390143369", - "react@17.0.2/cjs/react.development.js - 2465707714:1390143369", - "react@17.0.2/index.js - 2465707714:1063423392", - "react@17.0.2/index.js - 2465707714:1063423392", - "react@17.0.2/index.js - 2465707714:1063423392", - "react@17.0.2/index.js - 2465707714:1063423392", - "react@17.0.2/jsx-dev-runtime.js - 2465707714:3464951857", - "react@17.0.2/jsx-dev-runtime.js - 2465707714:3464951857", - "scheduler@0.20.2/cjs/scheduler-tracing.development.js - 2917057216:1128698082", - "scheduler@0.20.2/cjs/scheduler.development.js - 2917057216:4082470097", - "scheduler@0.20.2/index.js - 2917057216:3977196876", - "scheduler@0.20.2/tracing.js - 2917057216:2401030364", - "string-hash@1.1.3/index.js - 2958931479:1647663124", - "styled-jsx@4.0.0/dist/lib/stylesheet.js - 2917057216:205078822", - "styled-jsx@4.0.0/dist/server.js - 2917057216:2807236644", - "styled-jsx@4.0.0/dist/style.js - 2917057216:3820693621", - "styled-jsx@4.0.0/dist/stylesheet-registry.js - 2917057216:2283650446", - "styled-jsx@4.0.0/server.js - 2917057216:3921567966", - "use-subscription@1.5.1/cjs/use-subscription.development.js - 1836582978:3015515293", - "use-subscription@1.5.1/index.js - 1836582978:2982917928", -}; diff --git a/src/test/recover.zig b/src/test/recover.zig new file mode 100644 index 00000000000000..92f881c6faec58 --- /dev/null +++ b/src/test/recover.zig @@ -0,0 +1,131 @@ +// Copyright © 2024 Dimitris Dinodimos. + +//! Panic recover. +//! Regains control of the calling thread when the function panics or behaves +//! undefined. + +const std = @import("std"); +const builtin = @import("builtin"); + +const Context = if (builtin.os.tag == .windows) + std.os.windows.CONTEXT +else if (builtin.os.tag == .linux and builtin.abi == .musl) + musl.jmp_buf +else + std.c.ucontext_t; + +threadlocal var top_ctx: ?*const Context = null; + +/// Returns if there was no recover call in current thread. +/// Otherwise, does not return and execution continues from the current thread +/// recover call. +/// Call from root source file panic handler. +pub fn panicked() void { + if (top_ctx) |ctx| { + setContext(ctx); + } +} + +// comptime function that extends T by combining its error set with error.Panic +fn ExtErrType(T: type) type { + const E = error{Panic}; + const info = @typeInfo(T); + if (info != .error_union) { + return E!T; + } + return (info.error_union.error_set || E)!(info.error_union.payload); +} + +// comptime function that returns the return type of function `func` +fn ReturnType(func: anytype) type { + const ti = @typeInfo(@TypeOf(func)); + return ti.@"fn".return_type.?; +} + +pub fn callForTest( + test_func: *const fn () anyerror!void, +) anyerror!void { + const prev_ctx: ?*const Context = top_ctx; + var ctx: Context = std.mem.zeroes(Context); + getContext(&ctx); + if (top_ctx != prev_ctx) { + top_ctx = prev_ctx; + return error.Panic; + } + top_ctx = &ctx; + defer top_ctx = prev_ctx; + return @call(.auto, test_func, .{}); +} + +/// Calls `func` with `args`, guarding from runtime errors. +/// Returns `error.Panic` when recovers from runtime error. +/// Otherwise returns the return value of func. +pub fn call( + func: anytype, + args: anytype, +) ExtErrType(ReturnType(func)) { + const prev_ctx: ?*const Context = top_ctx; + var ctx: Context = std.mem.zeroes(Context); + getContext(&ctx); + if (top_ctx != prev_ctx) { + top_ctx = prev_ctx; + return error.Panic; + } + top_ctx = &ctx; + defer top_ctx = prev_ctx; + return @call(.auto, func, args); +} + +// windows +const CONTEXT = std.os.windows.CONTEXT; +const EXCEPTION_RECORD = std.os.windows.EXCEPTION_RECORD; +const WINAPI = std.os.windows.WINAPI; +extern "ntdll" fn RtlRestoreContext( + ContextRecord: *const CONTEXT, + ExceptionRecord: ?*const EXCEPTION_RECORD, +) callconv(WINAPI) noreturn; + +// darwin, bsd, gnu linux +extern "c" fn setcontext(ucp: *const std.c.ucontext_t) noreturn; + +// linux musl +const musl = struct { + const jmp_buf = @cImport(@cInclude("setjmp.h")).jmp_buf; + extern fn setjmp(env: *jmp_buf) c_int; + extern fn longjmp(env: *const jmp_buf, val: c_int) noreturn; +}; + +inline fn getContext(ctx: *Context) void { + if (builtin.os.tag == .windows) { + std.os.windows.ntdll.RtlCaptureContext(ctx); + } else if (builtin.os.tag == .linux and builtin.abi == .musl) { + _ = musl.setjmp(ctx); + } else { + _ = std.debug.getContext(ctx); + } +} + +inline fn setContext(ctx: *const Context) noreturn { + if (builtin.os.tag == .windows) { + RtlRestoreContext(ctx, null); + } else if (builtin.os.tag == .linux and builtin.abi == .musl) { + musl.longjmp(ctx, 1); + } else { + setcontext(ctx); + } +} + +/// Panic handler that if there is a recover call in current thread continues +/// from recover call. Otherwise calls the default panic. +/// Install at root source file as `pub const panic = @import("recover").panic;` +pub const panic: type = std.debug.FullPanic( + struct { + pub fn panic( + msg: []const u8, + first_trace_addr: ?usize, + ) noreturn { + panicked(); + std.debug.defaultPanic(msg, first_trace_addr); + } + }.panic, +); diff --git a/src/test/tester.zig b/src/test/tester.zig deleted file mode 100644 index 265accbe891d78..00000000000000 --- a/src/test/tester.zig +++ /dev/null @@ -1,157 +0,0 @@ -const std = @import("std"); - -const string = []const u8; - -const RED = "\x1b[31;1m"; -const GREEN = "\x1b[32;1m"; -const CYAN = "\x1b[36;1m"; -const WHITE = "\x1b[37;1m"; -const DIM = "\x1b[2m"; -const RESET = "\x1b[0m"; - -pub const Tester = struct { - pass: std.ArrayList(Expectation), - fail: std.ArrayList(Expectation), - allocator: std.mem.Allocator, - - pub fn t(allocator: std.mem.Allocator) Tester { - return Tester{ - .allocator = allocator, - .pass = std.ArrayList(Expectation).init(allocator), - .fail = std.ArrayList(Expectation).init(allocator), - }; - } - - pub const Expectation = struct { - expected: string, - result: string, - source: std.builtin.SourceLocation, - - pub fn init(expected: string, result: string, src: std.builtin.SourceLocation) Expectation { - return Expectation{ - .expected = expected, - .result = result, - .source = src, - }; - } - const PADDING = 0; - pub fn print(self: *const @This()) void { - const pad = &([_]u8{' '} ** PADDING); - var stderr = std.io.getStdErr(); - - stderr.writeAll(RESET) catch unreachable; - stderr.writeAll(pad) catch unreachable; - stderr.writeAll(DIM) catch unreachable; - std.fmt.format(stderr.writer(), "{s}:{d}:{d}", .{ self.source.file, self.source.line, self.source.column }) catch unreachable; - stderr.writeAll(RESET) catch unreachable; - stderr.writeAll("\n") catch unreachable; - - stderr.writeAll(pad) catch unreachable; - stderr.writeAll("Expected: ") catch unreachable; - stderr.writeAll(RESET) catch unreachable; - stderr.writeAll(GREEN) catch unreachable; - std.fmt.format(stderr.writer(), "\"{s}\"", .{self.expected}) catch unreachable; - stderr.writeAll(GREEN) catch unreachable; - stderr.writeAll(RESET) catch unreachable; - - stderr.writeAll("\n") catch unreachable; - stderr.writeAll(pad) catch unreachable; - stderr.writeAll("Received: ") catch unreachable; - stderr.writeAll(RESET) catch unreachable; - stderr.writeAll(RED) catch unreachable; - std.fmt.format(stderr.writer(), "\"{s}\"", .{self.result}) catch unreachable; - stderr.writeAll(RED) catch unreachable; - stderr.writeAll(RESET) catch unreachable; - stderr.writeAll("\n") catch unreachable; - } - const strings = @import("../string_immutable.zig"); - pub fn evaluate_outcome(self: *const @This()) Outcome { - if (strings.eql(self.expected, self.result)) { - return .pass; - } else { - return .fail; - } - } - }; - - pub const Outcome = enum { - pass, - fail, - }; - - pub inline fn expect(tester: *Tester, expected: string, result: string, src: std.builtin.SourceLocation) bool { - var expectation = Expectation.init(expected, result, src); - switch (expectation.evaluate_outcome()) { - .pass => { - tester.pass.append(expectation) catch unreachable; - return true; - }, - .fail => { - tester.fail.append(expectation) catch unreachable; - return false; - }, - } - } - - const ReportType = enum { - none, - pass, - fail, - some_fail, - - pub fn init(tester: *Tester) ReportType { - if (tester.fail.items.len == 0 and tester.pass.items.len == 0) { - return .none; - } else if (tester.fail.items.len == 0) { - return .pass; - } else if (tester.pass.items.len == 0) { - return .fail; - } else { - return .some_fail; - } - } - }; - - pub fn report(tester: *Tester, src: std.builtin.SourceLocation) void { - var stderr = std.io.getStdErr(); - - if (tester.fail.items.len > 0) { - std.fmt.format(stderr.writer(), "\n\n", .{}) catch unreachable; - } - - for (tester.fail.items) |item| { - item.print(); - std.fmt.format(stderr.writer(), "\n", .{}) catch unreachable; - } - - switch (ReportType.init(tester)) { - .none => { - std.log.info("No expectations.\n\n", .{}); - }, - .pass => { - std.fmt.format(stderr.writer(), "{s}All {d} expectations passed.{s}\n", .{ GREEN, tester.pass.items.len, GREEN }) catch unreachable; - std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; - std.testing.expect(true) catch std.debug.panic("Test failure", .{}); - }, - .fail => { - std.fmt.format(stderr.writer(), "{s}All {d} expectations failed.{s}\n\n", .{ RED, tester.fail.items.len, RED }) catch unreachable; - std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; - std.testing.expect(false) catch std.debug.panic("Test failure", .{}); - }, - .some_fail => { - std.fmt.format(stderr.writer(), "{s}{d} failed{s} and {s}{d} passed{s} of {d} expectations{s}\n\n", .{ - RED, - tester.fail.items.len, - RED ++ RESET, - GREEN, - tester.pass.items.len, - GREEN ++ RESET, - tester.fail.items.len + tester.pass.items.len, - RESET, - }) catch unreachable; - std.fmt.format(stderr.writer(), RESET, .{}) catch unreachable; - std.testing.expect(false) catch std.debug.panic("Test failure in {s}: {s}:{d}:{d}", .{ src.fn_name, src.file, src.line, src.column }); - }, - } - } -}; diff --git a/src/unit_test.zig b/src/unit_test.zig new file mode 100644 index 00000000000000..81a125aa39eb36 --- /dev/null +++ b/src/unit_test.zig @@ -0,0 +1,15 @@ +const std = @import("std"); +const bun = @import("root").bun; +const t = std.testing; + +test { + _ = @import("shell/braces.zig"); +} + +test "basic string usage" { + var s = bun.String.createUTF8("hi"); // it can create `WTF::String`s too + defer s.deref(); + try t.expect(s.tag != .Dead and s.tag != .Empty); + try t.expectEqual(s.length(), 2); + try t.expectEqualStrings(s.asUTF8().?, "hi"); +} diff --git a/test/internal/ban-words.test.ts b/test/internal/ban-words.test.ts index 229bdae02c2e2e..4697a7cf185ce8 100644 --- a/test/internal/ban-words.test.ts +++ b/test/internal/ban-words.test.ts @@ -6,7 +6,7 @@ const words: Record<string, { reason: string; limit?: number; regex?: boolean }> " != undefined": { reason: "This is by definition Undefined Behavior." }, " == undefined": { reason: "This is by definition Undefined Behavior." }, '@import("root").bun.': { reason: "Only import 'bun' once" }, - "std.debug.assert": { reason: "Use bun.assert instead", limit: 25 }, + "std.debug.assert": { reason: "Use bun.assert instead", limit: 26 }, "std.debug.dumpStackTrace": { reason: "Use bun.handleErrorReturnTrace or bun.crash_handler.dumpStackTrace instead" }, "std.debug.print": { reason: "Don't let this be committed", limit: 2 }, "std.mem.indexOfAny(u8": { reason: "Use bun.strings.indexOfAny", limit: 3 },