mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-21 01:36:02 +08:00
[c][cpp][libgdx] Launch configs for debug-printer
This commit is contained in:
parent
21b9efc8c7
commit
4e3d2be023
22
spine-c/.vscode/launch.json
vendored
Normal file
22
spine-c/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "debug-printer (c)",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/debug-printer",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pro.json",
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pma.atlas",
|
||||||
|
"run"
|
||||||
|
],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}/build",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "lldb",
|
||||||
|
"preLaunchTask": "CMake: build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -3,14 +3,12 @@ set -e
|
|||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
for arg in "${@:-clean build}"; do
|
# Clean only if explicitly requested
|
||||||
case $arg in
|
if [ "$1" = "clean" ]; then
|
||||||
clean) rm -rf build ;;
|
rm -rf build
|
||||||
build)
|
fi
|
||||||
mkdir -p build && cd build
|
|
||||||
[ -f CMakeCache.txt ] || cmake .. -DCMAKE_BUILD_TYPE=Debug
|
# Always build
|
||||||
make -j$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)
|
mkdir -p build && cd build
|
||||||
cd ..
|
[ -f CMakeCache.txt ] || cmake .. -DCMAKE_BUILD_TYPE=Debug
|
||||||
;;
|
make -j$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)
|
||||||
esac
|
|
||||||
done
|
|
||||||
@ -288,21 +288,22 @@ spine_skeleton_data_result spine_skeleton_data_load_json(spine_atlas atlas, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set name from path if provided
|
// Set name from path if provided
|
||||||
if (path != nullptr) {
|
if (path != nullptr && data != nullptr) {
|
||||||
|
String pathStr(path);
|
||||||
|
|
||||||
// Extract filename without extension from path
|
// Extract filename without extension from path
|
||||||
const char *lastSlash = strrchr(path, '/');
|
int lastSlash = pathStr.lastIndexOf('/');
|
||||||
const char *lastBackslash = strrchr(path, '\\');
|
int lastBackslash = pathStr.lastIndexOf('\\');
|
||||||
const char *start = path;
|
int start = 0;
|
||||||
|
|
||||||
if (lastSlash != nullptr) start = lastSlash + 1;
|
if (lastSlash != -1) start = lastSlash + 1;
|
||||||
if (lastBackslash != nullptr && lastBackslash > start) start = lastBackslash + 1;
|
if (lastBackslash != -1 && lastBackslash > start) start = lastBackslash + 1;
|
||||||
|
|
||||||
const char *lastDot = strrchr(start, '.');
|
int lastDot = pathStr.lastIndexOf('.');
|
||||||
if (lastDot != nullptr) {
|
if (lastDot != -1 && lastDot > start) {
|
||||||
int length = lastDot - start;
|
data->setName(pathStr.substring(start, lastDot - start));
|
||||||
data->setName(String(start, length));
|
|
||||||
} else {
|
} else {
|
||||||
data->setName(String(start));
|
data->setName(pathStr.substring(start));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,21 +324,22 @@ spine_skeleton_data_result spine_skeleton_data_load_binary(spine_atlas atlas, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set name from path if provided
|
// Set name from path if provided
|
||||||
if (path != nullptr) {
|
if (path != nullptr && data != nullptr) {
|
||||||
|
String pathStr(path);
|
||||||
|
|
||||||
// Extract filename without extension from path
|
// Extract filename without extension from path
|
||||||
const char *lastSlash = strrchr(path, '/');
|
int lastSlash = pathStr.lastIndexOf('/');
|
||||||
const char *lastBackslash = strrchr(path, '\\');
|
int lastBackslash = pathStr.lastIndexOf('\\');
|
||||||
const char *start = path;
|
int start = 0;
|
||||||
|
|
||||||
if (lastSlash != nullptr) start = lastSlash + 1;
|
if (lastSlash != -1) start = lastSlash + 1;
|
||||||
if (lastBackslash != nullptr && lastBackslash > start) start = lastBackslash + 1;
|
if (lastBackslash != -1 && lastBackslash > start) start = lastBackslash + 1;
|
||||||
|
|
||||||
const char *lastDot = strrchr(start, '.');
|
int lastDot = pathStr.lastIndexOf('.');
|
||||||
if (lastDot != nullptr) {
|
if (lastDot != -1 && lastDot > start) {
|
||||||
int length = lastDot - start;
|
data->setName(pathStr.substring(start, lastDot - start));
|
||||||
data->setName(String(start, length));
|
|
||||||
} else {
|
} else {
|
||||||
data->setName(String(start));
|
data->setName(pathStr.substring(start));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -128,14 +128,16 @@ uint8_t *read_file(const char *path, int *length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc < 4) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: DebugPrinter <skeleton-path> <atlas-path> <animation-name>\n");
|
fprintf(stderr, "Usage: DebugPrinter <skeleton-path> <atlas-path> [animation-name]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spine_bone_set_y_down(false);
|
||||||
|
|
||||||
const char *skeletonPath = argv[1];
|
const char *skeletonPath = argv[1];
|
||||||
const char *atlasPath = argv[2];
|
const char *atlasPath = argv[2];
|
||||||
const char *animationName = argv[3];
|
const char *animationName = argc >= 4 ? argv[3] : NULL;
|
||||||
|
|
||||||
// Read atlas file
|
// Read atlas file
|
||||||
int atlasLength = 0;
|
int atlasLength = 0;
|
||||||
@ -210,24 +212,27 @@ int main(int argc, char *argv[]) {
|
|||||||
spine_animation_state_data stateData = spine_animation_state_data_create(skeletonData);
|
spine_animation_state_data stateData = spine_animation_state_data_create(skeletonData);
|
||||||
spine_animation_state state = spine_animation_state_create(stateData);
|
spine_animation_state state = spine_animation_state_create(stateData);
|
||||||
|
|
||||||
// Find and set animation
|
spine_skeleton_setup_pose(skeleton);
|
||||||
spine_animation animation = spine_skeleton_data_find_animation(skeletonData, animationName);
|
|
||||||
if (!animation) {
|
// Set animation or setup pose
|
||||||
fprintf(stderr, "Animation not found: %s\n", animationName);
|
if (animationName != NULL) {
|
||||||
spine_animation_state_dispose(state);
|
// Find and set animation
|
||||||
spine_animation_state_data_dispose(stateData);
|
spine_animation animation = spine_skeleton_data_find_animation(skeletonData, animationName);
|
||||||
spine_skeleton_dispose(skeleton);
|
if (!animation) {
|
||||||
spine_skeleton_data_result_dispose(result);
|
fprintf(stderr, "Animation not found: %s\n", animationName);
|
||||||
spine_atlas_dispose(atlas);
|
spine_animation_state_dispose(state);
|
||||||
return 1;
|
spine_animation_state_data_dispose(stateData);
|
||||||
|
spine_skeleton_dispose(skeleton);
|
||||||
|
spine_skeleton_data_result_dispose(result);
|
||||||
|
spine_atlas_dispose(atlas);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
spine_animation_state_set_animation_1(state, 0, animationName, 1);
|
||||||
|
// Update and apply
|
||||||
|
spine_animation_state_update(state, 0.016f);
|
||||||
|
spine_animation_state_apply(state, skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
spine_animation_state_set_animation_1(state, 0, animationName, 1);
|
|
||||||
|
|
||||||
// Update and apply
|
|
||||||
spine_animation_state_update(state, 0.016f);
|
|
||||||
spine_animation_state_apply(state, skeleton);
|
|
||||||
spine_skeleton_update(skeleton, 0.016f);
|
|
||||||
spine_skeleton_update_world_transform_1(skeleton, SPINE_PHYSICS_UPDATE);
|
spine_skeleton_update_world_transform_1(skeleton, SPINE_PHYSICS_UPDATE);
|
||||||
|
|
||||||
// Print skeleton state
|
// Print skeleton state
|
||||||
|
|||||||
22
spine-cpp/.vscode/launch.json
vendored
Normal file
22
spine-cpp/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "debug-printer (cpp)",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/debug-printer",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pro.json",
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pma.atlas",
|
||||||
|
"run"
|
||||||
|
],
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"cwd": "${workspaceFolder}/build",
|
||||||
|
"environment": [],
|
||||||
|
"externalConsole": false,
|
||||||
|
"MIMode": "lldb",
|
||||||
|
"preLaunchTask": "CMake: build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -22,5 +22,6 @@ export(
|
|||||||
|
|
||||||
# Optional tests
|
# Optional tests
|
||||||
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
add_subdirectory(tests)
|
add_executable(debug-printer ${CMAKE_CURRENT_SOURCE_DIR}/tests/DebugPrinter.cpp)
|
||||||
|
target_link_libraries(debug-printer spine-cpp)
|
||||||
endif()
|
endif()
|
||||||
@ -3,14 +3,12 @@ set -e
|
|||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
for arg in "${@:-clean build}"; do
|
# Clean only if explicitly requested
|
||||||
case $arg in
|
if [ "$1" = "clean" ]; then
|
||||||
clean) rm -rf build ;;
|
rm -rf build
|
||||||
build)
|
fi
|
||||||
mkdir -p build && cd build
|
|
||||||
[ -f CMakeCache.txt ] || cmake .. -DCMAKE_BUILD_TYPE=Debug
|
# Always build
|
||||||
make -j$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)
|
mkdir -p build && cd build
|
||||||
cd ..
|
[ -f CMakeCache.txt ] || cmake .. -DCMAKE_BUILD_TYPE=Debug
|
||||||
;;
|
make -j$(sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4)
|
||||||
esac
|
|
||||||
done
|
|
||||||
@ -1,4 +0,0 @@
|
|||||||
# Create DebugPrinter executable
|
|
||||||
add_executable(DebugPrinter ${CMAKE_CURRENT_SOURCE_DIR}/src/DebugPrinter.cpp)
|
|
||||||
target_link_libraries(DebugPrinter spine-cpp)
|
|
||||||
target_compile_features(DebugPrinter PRIVATE cxx_std_11)
|
|
||||||
@ -129,14 +129,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc < 4) {
|
if (argc < 3) {
|
||||||
fprintf(stderr, "Usage: DebugPrinter <skeleton-path> <atlas-path> <animation-name>\n");
|
fprintf(stderr, "Usage: DebugPrinter <skeleton-path> <atlas-path> [animation-name]\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bone::setYDown(false);
|
||||||
|
|
||||||
const char *skeletonPath = argv[1];
|
const char *skeletonPath = argv[1];
|
||||||
const char *atlasPath = argv[2];
|
const char *atlasPath = argv[2];
|
||||||
const char *animationName = argv[3];
|
const char *animationName = argc >= 4 ? argv[3] : nullptr;
|
||||||
|
|
||||||
// Load atlas with headless texture loader
|
// Load atlas with headless texture loader
|
||||||
HeadlessTextureLoader textureLoader;
|
HeadlessTextureLoader textureLoader;
|
||||||
@ -171,21 +173,24 @@ int main(int argc, char *argv[]) {
|
|||||||
AnimationStateData stateData(skeletonData);
|
AnimationStateData stateData(skeletonData);
|
||||||
AnimationState state(&stateData);
|
AnimationState state(&stateData);
|
||||||
|
|
||||||
// Find and set animation
|
skeleton.setupPose();
|
||||||
Animation *animation = skeletonData->findAnimation(animationName);
|
|
||||||
if (!animation) {
|
// Set animation or setup pose
|
||||||
fprintf(stderr, "Animation not found: %s\n", animationName);
|
if (animationName != nullptr) {
|
||||||
delete skeletonData;
|
// Find and set animation
|
||||||
delete atlas;
|
Animation *animation = skeletonData->findAnimation(animationName);
|
||||||
return 1;
|
if (!animation) {
|
||||||
|
fprintf(stderr, "Animation not found: %s\n", animationName);
|
||||||
|
delete skeletonData;
|
||||||
|
delete atlas;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
state.setAnimation(0, animation, true);
|
||||||
|
// Update and apply
|
||||||
|
state.update(0.016f);
|
||||||
|
state.apply(skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.setAnimation(0, animation, true);
|
|
||||||
|
|
||||||
// Update and apply
|
|
||||||
state.update(0.016f);
|
|
||||||
state.apply(skeleton);
|
|
||||||
skeleton.update(0.016f);
|
|
||||||
skeleton.updateWorldTransform(Physics_Update);
|
skeleton.updateWorldTransform(Physics_Update);
|
||||||
|
|
||||||
// Print skeleton state
|
// Print skeleton state
|
||||||
17
spine-libgdx/.vscode/launch.json
vendored
Normal file
17
spine-libgdx/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "debug-printer (java)",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "com.esotericsoftware.spine.DebugPrinter",
|
||||||
|
"projectName": "spine-libgdx-tests",
|
||||||
|
"args": [
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pro.json",
|
||||||
|
"${workspaceFolder}/../examples/spineboy/export/spineboy-pma.atlas",
|
||||||
|
"run"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
16
spine-libgdx/spine-libgdx-tests/.vscode/launch.json
vendored
Normal file
16
spine-libgdx/spine-libgdx-tests/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"type": "java",
|
||||||
|
"name": "DebugPrinter",
|
||||||
|
"request": "launch",
|
||||||
|
"mainClass": "com.esotericsoftware.spine.DebugPrinter",
|
||||||
|
"args": [
|
||||||
|
"../../spine-godot/example-v4-extension/assets/spineboy/spineboy-pro.spine-json",
|
||||||
|
"../../spine-godot/example-v4-extension/assets/spineboy/spineboy.atlas",
|
||||||
|
"idle"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@ -222,18 +222,22 @@ public class DebugPrinter implements ApplicationListener {
|
|||||||
AnimationStateData stateData = new AnimationStateData(skeletonData);
|
AnimationStateData stateData = new AnimationStateData(skeletonData);
|
||||||
AnimationState state = new AnimationState(stateData);
|
AnimationState state = new AnimationState(stateData);
|
||||||
|
|
||||||
// Find and set animation
|
skeleton.setupPose();
|
||||||
Animation animation = skeletonData.findAnimation(animationName);
|
|
||||||
if (animation == null) {
|
// Set animation or setup pose
|
||||||
System.err.println("Animation not found: " + animationName);
|
if (animationName != null) {
|
||||||
System.exit(1);
|
// Find and set animation
|
||||||
|
Animation animation = skeletonData.findAnimation(animationName);
|
||||||
|
if (animation == null) {
|
||||||
|
System.err.println("Animation not found: " + animationName);
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
state.setAnimation(0, animation, true);
|
||||||
|
// Update and apply
|
||||||
|
state.update(0.016f);
|
||||||
|
state.apply(skeleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.setAnimation(0, animation, true);
|
|
||||||
|
|
||||||
// Update and apply
|
|
||||||
state.update(0.016f);
|
|
||||||
state.apply(skeleton);
|
|
||||||
skeleton.update(0.016f);
|
skeleton.update(0.016f);
|
||||||
skeleton.updateWorldTransform(Physics.update);
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
@ -271,13 +275,14 @@ public class DebugPrinter implements ApplicationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void main (String[] args) {
|
public static void main (String[] args) {
|
||||||
if (args.length < 3) {
|
if (args.length < 2) {
|
||||||
System.err.println("Usage: DebugPrinter <skeleton-path> <atlas-path> <animation-name>");
|
System.err.println("Usage: DebugPrinter <skeleton-path> <atlas-path> [animation-name]");
|
||||||
System.exit(1);
|
System.exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
|
HeadlessApplicationConfiguration config = new HeadlessApplicationConfiguration();
|
||||||
config.updatesPerSecond = 60;
|
config.updatesPerSecond = 60;
|
||||||
new HeadlessApplication(new DebugPrinter(args[0], args[1], args[2]), config);
|
String animationName = args.length >= 3 ? args[2] : null;
|
||||||
|
new HeadlessApplication(new DebugPrinter(args[0], args[1], animationName), config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import com.badlogic.gdx.utils.Null;
|
|||||||
|
|
||||||
import com.esotericsoftware.spine.TransformConstraintData.FromProperty;
|
import com.esotericsoftware.spine.TransformConstraintData.FromProperty;
|
||||||
|
|
||||||
/** Stores the setup pose for a {@link Slider}. */
|
/** Stores the setup pose for a {@link Slider}. */
|
||||||
public class SliderData extends ConstraintData<Slider, SliderPose> {
|
public class SliderData extends ConstraintData<Slider, SliderPose> {
|
||||||
Animation animation;
|
Animation animation;
|
||||||
boolean additive, loop;
|
boolean additive, loop;
|
||||||
|
|||||||
210
spine-ts/spine-core/tests/DebugPrinter.ts
Executable file
210
spine-ts/spine-core/tests/DebugPrinter.ts
Executable file
@ -0,0 +1,210 @@
|
|||||||
|
#!/usr/bin/env npx tsx
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes License Agreement
|
||||||
|
* Last updated April 5, 2025. Replaces all prior versions.
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||||
|
*
|
||||||
|
* Integration of the Spine Runtimes into software or otherwise creating
|
||||||
|
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||||
|
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||||
|
* http://esotericsoftware.com/spine-editor-license
|
||||||
|
*
|
||||||
|
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||||
|
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||||
|
* "Products"), provided that each user of the Products must obtain their own
|
||||||
|
* Spine Editor license and redistribution of the Products in any form must
|
||||||
|
* include this license and copyright notice.
|
||||||
|
*
|
||||||
|
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||||
|
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
import { promises as fs } from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import {
|
||||||
|
AnimationState,
|
||||||
|
AnimationStateData,
|
||||||
|
AtlasAttachmentLoader,
|
||||||
|
Physics,
|
||||||
|
Skeleton,
|
||||||
|
SkeletonBinary,
|
||||||
|
SkeletonData,
|
||||||
|
SkeletonJson,
|
||||||
|
TextureAtlas
|
||||||
|
} from '../src/index.js';
|
||||||
|
|
||||||
|
// Printer class for hierarchical output
|
||||||
|
class Printer {
|
||||||
|
private indentLevel = 0;
|
||||||
|
private readonly INDENT = " ";
|
||||||
|
|
||||||
|
print(text: string): void {
|
||||||
|
const indent = this.INDENT.repeat(this.indentLevel);
|
||||||
|
console.log(indent + text);
|
||||||
|
}
|
||||||
|
|
||||||
|
indent(): void {
|
||||||
|
this.indentLevel++;
|
||||||
|
}
|
||||||
|
|
||||||
|
unindent(): void {
|
||||||
|
this.indentLevel--;
|
||||||
|
}
|
||||||
|
|
||||||
|
printSkeletonData(data: SkeletonData): void {
|
||||||
|
this.print("SkeletonData {");
|
||||||
|
this.indent();
|
||||||
|
|
||||||
|
this.print(`name: "${data.name || ""}"`);
|
||||||
|
this.print(`version: ${data.version ? `"${data.version}"` : "null"}`);
|
||||||
|
this.print(`hash: ${data.hash ? `"${data.hash}"` : "null"}`);
|
||||||
|
this.print(`x: ${this.formatFloat(data.x)}`);
|
||||||
|
this.print(`y: ${this.formatFloat(data.y)}`);
|
||||||
|
this.print(`width: ${this.formatFloat(data.width)}`);
|
||||||
|
this.print(`height: ${this.formatFloat(data.height)}`);
|
||||||
|
this.print(`referenceScale: ${this.formatFloat(data.referenceScale)}`);
|
||||||
|
this.print(`fps: ${this.formatFloat(data.fps || 0)}`);
|
||||||
|
this.print(`imagesPath: ${data.imagesPath ? `"${data.imagesPath}"` : "null"}`);
|
||||||
|
this.print(`audioPath: ${data.audioPath ? `"${data.audioPath}"` : "null"}`);
|
||||||
|
|
||||||
|
// TODO: Add bones, slots, skins, animations, etc. in future expansion
|
||||||
|
|
||||||
|
this.unindent();
|
||||||
|
this.print("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
printSkeleton(skeleton: Skeleton): void {
|
||||||
|
this.print("Skeleton {");
|
||||||
|
this.indent();
|
||||||
|
|
||||||
|
this.print(`x: ${this.formatFloat(skeleton.x)}`);
|
||||||
|
this.print(`y: ${this.formatFloat(skeleton.y)}`);
|
||||||
|
this.print(`scaleX: ${this.formatFloat(skeleton.scaleX)}`);
|
||||||
|
this.print(`scaleY: ${this.formatFloat(skeleton.scaleY)}`);
|
||||||
|
this.print(`time: ${this.formatFloat(skeleton.time)}`);
|
||||||
|
|
||||||
|
// TODO: Add runtime state (bones, slots, etc.) in future expansion
|
||||||
|
|
||||||
|
this.unindent();
|
||||||
|
this.print("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private formatFloat(value: number): string {
|
||||||
|
// Format to 6 decimal places, matching Java/C++ output
|
||||||
|
return value.toFixed(6).replace(',', '.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Main DebugPrinter class
|
||||||
|
class DebugPrinter {
|
||||||
|
static async main(args: string[]): Promise<void> {
|
||||||
|
if (args.length < 2) {
|
||||||
|
console.error("Usage: DebugPrinter <skeleton-path> <atlas-path> [animation-name]");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const skeletonPath = args[0];
|
||||||
|
const atlasPath = args[1];
|
||||||
|
const animationName = args.length >= 3 ? args[2] : null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load atlas
|
||||||
|
const atlasData = await fs.readFile(atlasPath, 'utf8');
|
||||||
|
const atlasDir = path.dirname(atlasPath);
|
||||||
|
const atlas = new TextureAtlas(atlasData);
|
||||||
|
|
||||||
|
// Load skeleton data
|
||||||
|
const skeletonData = await this.loadSkeletonData(skeletonPath, atlas);
|
||||||
|
|
||||||
|
// Print skeleton data
|
||||||
|
const printer = new Printer();
|
||||||
|
console.log("=== SKELETON DATA ===");
|
||||||
|
printer.printSkeletonData(skeletonData);
|
||||||
|
|
||||||
|
// Create skeleton and animation state
|
||||||
|
const skeleton = new Skeleton(skeletonData);
|
||||||
|
const stateData = new AnimationStateData(skeletonData);
|
||||||
|
const state = new AnimationState(stateData);
|
||||||
|
|
||||||
|
skeleton.setupPose();
|
||||||
|
|
||||||
|
// Set animation or setup pose
|
||||||
|
if (animationName) {
|
||||||
|
// Find and set animation
|
||||||
|
const animation = skeletonData.findAnimation(animationName);
|
||||||
|
if (!animation) {
|
||||||
|
console.error(`Animation not found: ${animationName}`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
state.setAnimation(0, animationName, true);
|
||||||
|
// Update and apply
|
||||||
|
state.update(0.016);
|
||||||
|
state.apply(skeleton);
|
||||||
|
}
|
||||||
|
|
||||||
|
skeleton.updateWorldTransform(Physics.update);
|
||||||
|
|
||||||
|
// Print skeleton state
|
||||||
|
console.log("\n=== SKELETON STATE ===");
|
||||||
|
printer.printSkeleton(skeleton);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error:", error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async loadSkeletonData(skeletonPath: string, atlas: TextureAtlas): Promise<SkeletonData> {
|
||||||
|
const attachmentLoader = new AtlasAttachmentLoader(atlas);
|
||||||
|
const ext = path.extname(skeletonPath).toLowerCase();
|
||||||
|
|
||||||
|
if (ext === '.json') {
|
||||||
|
const jsonData = await fs.readFile(skeletonPath, 'utf8');
|
||||||
|
const json = new SkeletonJson(attachmentLoader);
|
||||||
|
json.scale = 1;
|
||||||
|
const skeletonData = json.readSkeletonData(jsonData);
|
||||||
|
|
||||||
|
// Set name from filename if not already set
|
||||||
|
if (!skeletonData.name) {
|
||||||
|
const basename = path.basename(skeletonPath);
|
||||||
|
const nameWithoutExt = basename.substring(0, basename.lastIndexOf('.')) || basename;
|
||||||
|
skeletonData.name = nameWithoutExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return skeletonData;
|
||||||
|
} else if (ext === '.skel') {
|
||||||
|
const binaryData = await fs.readFile(skeletonPath);
|
||||||
|
const binary = new SkeletonBinary(attachmentLoader);
|
||||||
|
binary.scale = 1;
|
||||||
|
const skeletonData = binary.readSkeletonData(new Uint8Array(binaryData));
|
||||||
|
|
||||||
|
// Set name from filename if not already set
|
||||||
|
if (!skeletonData.name) {
|
||||||
|
const basename = path.basename(skeletonPath);
|
||||||
|
const nameWithoutExt = basename.substring(0, basename.lastIndexOf('.')) || basename;
|
||||||
|
skeletonData.name = nameWithoutExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return skeletonData;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unsupported skeleton file format: ${ext}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run if called directly
|
||||||
|
if (import.meta.url === `file://${process.argv[1]}`) {
|
||||||
|
DebugPrinter.main(process.argv.slice(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DebugPrinter;
|
||||||
@ -9,7 +9,8 @@
|
|||||||
"**/*.ts"
|
"**/*.ts"
|
||||||
],
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"dist/**/*.d.ts"
|
"dist/**/*.d.ts",
|
||||||
|
"tests/**/*.ts"
|
||||||
],
|
],
|
||||||
"references": []
|
"references": []
|
||||||
}
|
}
|
||||||
232
tests/compare-with-reference-impl.ts
Executable file
232
tests/compare-with-reference-impl.ts
Executable file
@ -0,0 +1,232 @@
|
|||||||
|
#!/usr/bin/env npx tsx
|
||||||
|
|
||||||
|
import { execSync } from 'child_process';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { promisify } from 'util';
|
||||||
|
|
||||||
|
const writeFile = promisify(fs.writeFile);
|
||||||
|
const mkdir = promisify(fs.mkdir);
|
||||||
|
|
||||||
|
// Parse command line arguments
|
||||||
|
const args = process.argv.slice(2);
|
||||||
|
if (args.length < 2) {
|
||||||
|
console.error('Usage: compare-with-reference-impl.ts <skeleton-path> <atlas-path> [animation-name]');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
const [skeletonPath, atlasPath, animationName] = args;
|
||||||
|
|
||||||
|
// Get absolute paths
|
||||||
|
const absoluteSkeletonPath = path.resolve(skeletonPath);
|
||||||
|
const absoluteAtlasPath = path.resolve(atlasPath);
|
||||||
|
|
||||||
|
// Script paths
|
||||||
|
const scriptDir = path.dirname(new URL(import.meta.url).pathname);
|
||||||
|
const rootDir = path.dirname(scriptDir);
|
||||||
|
const outputDir = path.join(scriptDir, 'output');
|
||||||
|
|
||||||
|
interface RuntimeConfig {
|
||||||
|
name: string;
|
||||||
|
buildCheck: () => boolean;
|
||||||
|
build: () => void;
|
||||||
|
run: () => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime configurations
|
||||||
|
const runtimes: RuntimeConfig[] = [
|
||||||
|
{
|
||||||
|
name: 'java',
|
||||||
|
buildCheck: () => {
|
||||||
|
const classPath = path.join(rootDir, 'spine-libgdx/spine-libgdx-tests/build/classes/java/main/com/esotericsoftware/spine/DebugPrinter.class');
|
||||||
|
return fs.existsSync(classPath);
|
||||||
|
},
|
||||||
|
build: () => {
|
||||||
|
console.log(' Building Java runtime...');
|
||||||
|
execSync('./gradlew :spine-libgdx-tests:build', {
|
||||||
|
cwd: path.join(rootDir, 'spine-libgdx'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
run: () => {
|
||||||
|
const args = animationName
|
||||||
|
? `${absoluteSkeletonPath} ${absoluteAtlasPath} ${animationName}`
|
||||||
|
: `${absoluteSkeletonPath} ${absoluteAtlasPath}`;
|
||||||
|
const output = execSync(
|
||||||
|
`./gradlew -q :spine-libgdx-tests:runDebugPrinter -Pargs="${args}"`,
|
||||||
|
{
|
||||||
|
cwd: path.join(rootDir, 'spine-libgdx'),
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// Find the start of actual output and return everything from there
|
||||||
|
const lines = output.split('\n');
|
||||||
|
const startIndex = lines.findIndex(line => line === '=== SKELETON DATA ===');
|
||||||
|
if (startIndex !== -1) {
|
||||||
|
return lines.slice(startIndex).join('\n').trim();
|
||||||
|
}
|
||||||
|
// Fallback to full output if marker not found
|
||||||
|
return output.trim();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'cpp',
|
||||||
|
buildCheck: () => {
|
||||||
|
const execPath = path.join(rootDir, 'spine-cpp/build/debug-printer');
|
||||||
|
return fs.existsSync(execPath);
|
||||||
|
},
|
||||||
|
build: () => {
|
||||||
|
console.log(' Building C++ runtime...');
|
||||||
|
execSync('./build.sh clean', {
|
||||||
|
cwd: path.join(rootDir, 'spine-cpp/'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
run: () => {
|
||||||
|
return execSync(
|
||||||
|
`./build/debug-printer "${absoluteSkeletonPath}" "${absoluteAtlasPath}" "${animationName}"`,
|
||||||
|
{
|
||||||
|
cwd: path.join(rootDir, 'spine-cpp'),
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
).trim();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'c',
|
||||||
|
buildCheck: () => {
|
||||||
|
const execPath = path.join(rootDir, 'spine-c/build/debug-printer');
|
||||||
|
return fs.existsSync(execPath);
|
||||||
|
},
|
||||||
|
build: () => {
|
||||||
|
console.log(' Building C runtime...');
|
||||||
|
execSync('./build.sh', {
|
||||||
|
cwd: path.join(rootDir, 'spine-c/'),
|
||||||
|
stdio: 'inherit'
|
||||||
|
});
|
||||||
|
},
|
||||||
|
run: () => {
|
||||||
|
return execSync(
|
||||||
|
`./build/debug-printer "${absoluteSkeletonPath}" "${absoluteAtlasPath}" "${animationName}"`,
|
||||||
|
{
|
||||||
|
cwd: path.join(rootDir, 'spine-c'),
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
).trim();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ts',
|
||||||
|
buildCheck: () => true, // No build needed
|
||||||
|
build: () => {}, // No build needed
|
||||||
|
run: () => {
|
||||||
|
return execSync(
|
||||||
|
`npx tsx tests/DebugPrinter.ts "${absoluteSkeletonPath}" "${absoluteAtlasPath}" "${animationName}"`,
|
||||||
|
{
|
||||||
|
cwd: path.join(rootDir, 'spine-ts/spine-core'),
|
||||||
|
encoding: 'utf8'
|
||||||
|
}
|
||||||
|
).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Ensure output directory exists
|
||||||
|
await mkdir(outputDir, { recursive: true });
|
||||||
|
|
||||||
|
console.log('Comparing DebugPrinter outputs for:');
|
||||||
|
console.log(` Skeleton: ${absoluteSkeletonPath}`);
|
||||||
|
console.log(` Atlas: ${absoluteAtlasPath}`);
|
||||||
|
console.log(` Animation: ${animationName}`);
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Run all runtimes and collect outputs
|
||||||
|
const outputs: Record<string, string> = {};
|
||||||
|
|
||||||
|
for (const runtime of runtimes) {
|
||||||
|
console.log(`Running ${runtime.name.toUpperCase()} DebugPrinter...`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Build if needed
|
||||||
|
if (!runtime.buildCheck()) {
|
||||||
|
runtime.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run and capture output
|
||||||
|
const output = runtime.run();
|
||||||
|
outputs[runtime.name] = output;
|
||||||
|
|
||||||
|
// Save output to file
|
||||||
|
await writeFile(path.join(outputDir, `${runtime.name}.txt`), output);
|
||||||
|
|
||||||
|
console.log(' Done.');
|
||||||
|
} catch (error) {
|
||||||
|
console.error(` Error: ${error instanceof Error ? error.message : JSON.stringify(error)}`);
|
||||||
|
outputs[runtime.name] = `Error: ${error instanceof Error ? error.message : JSON.stringify(error)}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
console.log('Comparing outputs...');
|
||||||
|
console.log('');
|
||||||
|
|
||||||
|
// Compare outputs
|
||||||
|
const reference = 'java';
|
||||||
|
let allMatch = true;
|
||||||
|
|
||||||
|
for (const runtime of runtimes) {
|
||||||
|
if (runtime.name !== reference) {
|
||||||
|
process.stdout.write(`Comparing ${reference} vs ${runtime.name}: `);
|
||||||
|
|
||||||
|
if (outputs[reference] === outputs[runtime.name]) {
|
||||||
|
console.log('✓ MATCH');
|
||||||
|
} else {
|
||||||
|
console.log('✗ DIFFER');
|
||||||
|
allMatch = false;
|
||||||
|
|
||||||
|
// Show first few differences
|
||||||
|
const refLines = outputs[reference].split('\n');
|
||||||
|
const runtimeLines = outputs[runtime.name].split('\n');
|
||||||
|
const maxLines = Math.max(refLines.length, runtimeLines.length);
|
||||||
|
let diffCount = 0;
|
||||||
|
|
||||||
|
console.log(' First differences:');
|
||||||
|
for (let i = 0; i < maxLines && diffCount < 5; i++) {
|
||||||
|
if (refLines[i] !== runtimeLines[i]) {
|
||||||
|
diffCount++;
|
||||||
|
console.log(` Line ${i + 1}:`);
|
||||||
|
if (refLines[i] !== undefined) {
|
||||||
|
console.log(` - ${refLines[i]}`);
|
||||||
|
}
|
||||||
|
if (runtimeLines[i] !== undefined) {
|
||||||
|
console.log(` + ${runtimeLines[i]}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (diffCount === 0 && refLines.length !== runtimeLines.length) {
|
||||||
|
console.log(` Different number of lines: ${refLines.length} vs ${runtimeLines.length}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save outputs for manual diff
|
||||||
|
console.log(` Full outputs saved to: ${outputDir}/`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('');
|
||||||
|
if (allMatch) {
|
||||||
|
console.log('✓ All outputs match!');
|
||||||
|
process.exit(0);
|
||||||
|
} else {
|
||||||
|
console.log(`✗ Outputs differ. Check the output files in ${outputDir}/`);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run main function
|
||||||
|
main().catch(error => {
|
||||||
|
console.error('Error:', error);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
573
tests/package-lock.json
generated
Normal file
573
tests/package-lock.json
generated
Normal file
@ -0,0 +1,573 @@
|
|||||||
|
{
|
||||||
|
"name": "spine-tests",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "spine-tests",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.0.0",
|
||||||
|
"tsx": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/aix-ppc64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"aix"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/android-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"android"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/darwin-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/freebsd-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"freebsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==",
|
||||||
|
"cpu": [
|
||||||
|
"arm"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ia32": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-loong64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==",
|
||||||
|
"cpu": [
|
||||||
|
"loong64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-mips64el": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==",
|
||||||
|
"cpu": [
|
||||||
|
"mips64el"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-ppc64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==",
|
||||||
|
"cpu": [
|
||||||
|
"ppc64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-riscv64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==",
|
||||||
|
"cpu": [
|
||||||
|
"riscv64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-s390x": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==",
|
||||||
|
"cpu": [
|
||||||
|
"s390x"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/linux-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"linux"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/netbsd-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"netbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openbsd-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openbsd"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/openharmony-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"openharmony"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/sunos-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"sunos"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-arm64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==",
|
||||||
|
"cpu": [
|
||||||
|
"arm64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-ia32": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==",
|
||||||
|
"cpu": [
|
||||||
|
"ia32"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@esbuild/win32-x64": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==",
|
||||||
|
"cpu": [
|
||||||
|
"x64"
|
||||||
|
],
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"win32"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "20.19.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.7.tgz",
|
||||||
|
"integrity": "sha512-1GM9z6BJOv86qkPvzh2i6VW5+VVrXxCLknfmTkWEqz+6DqosiY28XUWCTmBcJ0ACzKqx/iwdIREfo1fwExIlkA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~6.21.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/esbuild": {
|
||||||
|
"version": "0.25.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz",
|
||||||
|
"integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"esbuild": "bin/esbuild"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"@esbuild/aix-ppc64": "0.25.6",
|
||||||
|
"@esbuild/android-arm": "0.25.6",
|
||||||
|
"@esbuild/android-arm64": "0.25.6",
|
||||||
|
"@esbuild/android-x64": "0.25.6",
|
||||||
|
"@esbuild/darwin-arm64": "0.25.6",
|
||||||
|
"@esbuild/darwin-x64": "0.25.6",
|
||||||
|
"@esbuild/freebsd-arm64": "0.25.6",
|
||||||
|
"@esbuild/freebsd-x64": "0.25.6",
|
||||||
|
"@esbuild/linux-arm": "0.25.6",
|
||||||
|
"@esbuild/linux-arm64": "0.25.6",
|
||||||
|
"@esbuild/linux-ia32": "0.25.6",
|
||||||
|
"@esbuild/linux-loong64": "0.25.6",
|
||||||
|
"@esbuild/linux-mips64el": "0.25.6",
|
||||||
|
"@esbuild/linux-ppc64": "0.25.6",
|
||||||
|
"@esbuild/linux-riscv64": "0.25.6",
|
||||||
|
"@esbuild/linux-s390x": "0.25.6",
|
||||||
|
"@esbuild/linux-x64": "0.25.6",
|
||||||
|
"@esbuild/netbsd-arm64": "0.25.6",
|
||||||
|
"@esbuild/netbsd-x64": "0.25.6",
|
||||||
|
"@esbuild/openbsd-arm64": "0.25.6",
|
||||||
|
"@esbuild/openbsd-x64": "0.25.6",
|
||||||
|
"@esbuild/openharmony-arm64": "0.25.6",
|
||||||
|
"@esbuild/sunos-x64": "0.25.6",
|
||||||
|
"@esbuild/win32-arm64": "0.25.6",
|
||||||
|
"@esbuild/win32-ia32": "0.25.6",
|
||||||
|
"@esbuild/win32-x64": "0.25.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/fsevents": {
|
||||||
|
"version": "2.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||||
|
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"optional": true,
|
||||||
|
"os": [
|
||||||
|
"darwin"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/get-tsconfig": {
|
||||||
|
"version": "4.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
|
||||||
|
"integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"resolve-pkg-maps": "^1.0.0"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/resolve-pkg-maps": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tsx": {
|
||||||
|
"version": "4.20.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.3.tgz",
|
||||||
|
"integrity": "sha512-qjbnuR9Tr+FJOMBqJCW5ehvIo/buZq7vH7qD7JziU98h6l3qGy0a/yPFjwO+y0/T7GFpNgNAvEcPPVfyT8rrPQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"esbuild": "~0.25.0",
|
||||||
|
"get-tsconfig": "^4.7.5"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"tsx": "dist/cli.mjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18.0.0"
|
||||||
|
},
|
||||||
|
"optionalDependencies": {
|
||||||
|
"fsevents": "~2.3.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "6.21.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
tests/package.json
Normal file
12
tests/package.json
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "spine-tests",
|
||||||
|
"type": "module",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"compare": "tsx compare-with-reference-impl.ts"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.0.0",
|
||||||
|
"tsx": "^4.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
17
tests/tsconfig.json
Normal file
17
tests/tsconfig.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2022",
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"types": ["node"]
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"*.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user