From 24000091e9b981e0963e99bddf85c4f5e972d47a Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Thu, 15 Jan 2026 09:43:50 +0000 Subject: [PATCH 1/2] Revert "Revert "Check max complexity before bool process"" --- .../web-ifc/geometry/IfcGeometryProcessor.cpp | 37 + .../web-ifc/geometry/IfcGeometryProcessor.h | 1 + .../boolean-utils/shared-position.h | 917 +++++------------- .../geometry/operations/geometryutils.h | 96 +- yarn.lock | 454 +++------ 5 files changed, 424 insertions(+), 1081 deletions(-) diff --git a/src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp b/src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp index 0c921937e..eea928d57 100644 --- a/src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp +++ b/src/cpp/web-ifc/geometry/IfcGeometryProcessor.cpp @@ -215,6 +215,10 @@ namespace webifc::geometry std::vector geomVector = {geom}; // Wrap 'geom' in a vector fusedVoids = BoolProcess(std::vector{fusedVoids}, geomVector, "UNION", _settings); } + if (fusedVoids.numFaces > _settings._CSG_MAX_NUM_FACES) { + spdlog::warn("High number of faces ({}) in voids for element {}, skipping further CSG operations", fusedVoids.numFaces, expressID); + break; + } } joinedVoidGeoms.push_back(fusedVoids); @@ -339,6 +343,39 @@ namespace webifc::geometry return mesh; } + size_t numFacesGeoms = 0; + for (auto& geom : flatFirstMeshes) { + numFacesGeoms += geom.numFaces; + } + for (auto& geom : flatSecondMeshes) { + numFacesGeoms += geom.numFaces; + } + + if (numFacesGeoms > _settings._CSG_MAX_NUM_FACES) { + spdlog::warn("High number of faces in CSG operand ({}), skipping further CSG operations", numFacesGeoms); + + // Flatten the first operand (transformed and normalized, like in the normal path) + auto flatFirstMeshes = flatten(firstMesh, _expressIDToGeometry, normalizeMat); + + // Merge into a single geometry (equivalent to the first operand without boolean) + IfcGeometry resultMesh; + for (const auto& g : flatFirstMeshes) { + resultMesh.MergeGeometry(g); + } + + _expressIDToGeometry[expressID] = resultMesh; + mesh.hasGeometry = true; + mesh.transformation = glm::translate(origin); + + if (!mesh.hasColor && firstMesh.hasColor) { + mesh.hasColor = true; + mesh.color = firstMesh.color; + } + + // No need to set mesh = firstMesh; we're building a flat geometry here for consistency + return mesh; + } + IfcGeometry resultMesh = BoolProcess(flatFirstMeshes, flatSecondMeshes, std::string(op), _settings); _expressIDToGeometry[expressID] = resultMesh; diff --git a/src/cpp/web-ifc/geometry/IfcGeometryProcessor.h b/src/cpp/web-ifc/geometry/IfcGeometryProcessor.h index 1ef76932b..7d5a7a45e 100644 --- a/src/cpp/web-ifc/geometry/IfcGeometryProcessor.h +++ b/src/cpp/web-ifc/geometry/IfcGeometryProcessor.h @@ -34,6 +34,7 @@ namespace webifc::geometry double TOLERANCE_INSIDE_OUTSIDE_PERIMETER = 1.0E-10; double TOLERANCE_BOUNDING_BOX = 1.0E-02; uint16_t _BOOLEAN_UNION_THRESHOLD = 150; + uint16_t _CSG_MAX_NUM_FACES = 20000; }; class booleanManager diff --git a/src/cpp/web-ifc/geometry/operations/boolean-utils/shared-position.h b/src/cpp/web-ifc/geometry/operations/boolean-utils/shared-position.h index 32719ecce..2f2f24460 100644 --- a/src/cpp/web-ifc/geometry/operations/boolean-utils/shared-position.h +++ b/src/cpp/web-ifc/geometry/operations/boolean-utils/shared-position.h @@ -1,18 +1,14 @@ #pragma once - #include #include #include #include #include - #include - #pragma warning(push) #pragma warning(disable : 4267) #include #pragma warning(pop) - #include "geometry.h" #include "aabb.h" #include "bvh.h" @@ -23,35 +19,37 @@ #include "obj-exporter.h" #include "is-inside-mesh.h" #include "is-inside-boundary.h" - #define GLM_ENABLE_EXPERIMENTAL #include - using Vec2 = glm::dvec2; using Vec3 = glm::dvec3; - +namespace std { + template <> + struct hash { + size_t operator()(const glm::ivec3& v) const { + size_t h1 = std::hash()(v.x); + size_t h2 = std::hash()(v.y); + size_t h3 = std::hash()(v.z); + return h1 ^ (h2 << 1) ^ (h3 << 2); // Simple combine + } + }; +} namespace fuzzybools { - //============================================================================================ - struct PlaneBasis { Vec3 origin; - Vec3 up; Vec3 left; Vec3 right; - - Vec2 project(const Vec3 &pt) + Vec2 project(const Vec3& pt) { auto relative = pt - origin; return Vec2(glm::dot(relative, left), glm::dot(relative, right)); } }; - //============================================================================================ - struct ReferencePlane { size_t planeID; @@ -59,21 +57,18 @@ namespace fuzzybools size_t lineID; Vec2 location; }; - //============================================================================================ - struct ReferenceLine { size_t lineID; size_t pointID; double location; }; - //============================================================================================ //============================================================================================ /* - The vector direction is not necessarily a unit vector! It is the vector pointing - from the start of the line (identified with origin) to the end. Thus, + The vector direction is not necessarily a unit vector! It is the vector pointing + from the start of the line (identified with origin) to the end. Thus, end = origin + direction */ struct Line @@ -82,23 +77,18 @@ namespace fuzzybools size_t globalID; Vec3 origin; Vec3 direction; - //============================================================================================ - Line() { static size_t idcounter = 0; idcounter++; globalID = idcounter; } - //============================================================================================ - /* Does point a lie on the line defined by vectors origin and direction? - */ - bool IsPointOnLine(const Vec3 &a) const + bool IsPointOnLine(const Vec3& a) const { /* Vector d is the unit vector pointing along the line from origin towards @@ -107,7 +97,7 @@ namespace fuzzybools Vec3 d = glm::normalize(direction); Vec3 v = a - origin; /* - Drop a perpendicular from point a to the line. The quantity t + Drop a perpendicular from point a to the line. The quantity t is the distance from origin along the line to the foot of the perpendicular, denoted by p. */ @@ -119,43 +109,35 @@ namespace fuzzybools */ return glm::distance(p, a) < tolerancePointOnLine; } - //============================================================================================ - /* The original version of GetPosOnline seemed to assume that direction is a unit vector. This version normalises direction first. */ - - double GetPosOnLine(const Vec3 &pos) const + double GetPosOnLine(const Vec3& pos) const { Vec3 unitDirection = glm::normalize(direction); return glm::dot(pos - origin, unitDirection); } - Vec3 GetPosOnLine(const double dist) const { Vec3 unitDirection = glm::normalize(direction); return origin + dist * unitDirection; } - //============================================================================================ - - bool IsCollinear(const Line &other) const + bool IsCollinear(const Line& other) const { Vec3 unitDirection = glm::normalize(direction); Vec3 unitOtherDirection = glm::normalize(other.direction); return (equals(unitOtherDirection, unitDirection, toleranceCollinear) || equals(unitOtherDirection, -unitDirection, toleranceCollinear)); - // return (equals(other.direction, direction, toleranceCollinear) || equals(other.direction, -direction, toleranceCollinear)); + // return (equals(other.direction, direction, toleranceCollinear) || equals(other.direction, -direction, toleranceCollinear)); } - //============================================================================================ - /* - The original version of IsEqualTo compared dir and direction. This version compares + The original version of IsEqualTo compared dir and direction. This version compares normalised copies of dir and direction. */ - bool IsEqualTo(const Vec3 &pos, const Vec3 &dir) const + bool IsEqualTo(const Vec3& pos, const Vec3& dir) const { // check dir Vec3 unitDir = glm::normalize(dir); @@ -164,87 +146,79 @@ namespace fuzzybools { return false; } - // check pos if (!IsPointOnLine(pos)) { return false; } - return true; } - //============================================================================================ - void AddPointToLine(double dist, size_t id) { // check existing - for (auto &p : points) + for (auto& p : points) { if (p.second == id) return; } - // add new point points.push_back(std::make_pair(dist, id)); - // re-sort all std::sort( points.begin(), points.end(), - [&](const std::pair &left, const std::pair &right) + [&](const std::pair& left, const std::pair& right) { return left.first < right.first; }); } - //============================================================================================ - auto GetSegments() const { const auto makeSegments = [&](int i) - { - return std::make_pair(points[i - 1].second, points[i].second); - }; - + { + return std::make_pair(points[i - 1].second, points[i].second); + }; return std::views::iota(size_t(1), points.size()) | std::views::transform(makeSegments); } - + //============================================================================================ + bool ContainsPos(double pos, double tol = tolerancePointOnLine) const + { + if (points.empty()) return false; + for (size_t i = 1; i < points.size(); ++i) { + double minv = points[i - 1].first; + double maxv = points[i].first; + if (pos >= minv - tol && pos <= maxv + tol) return true; + } + return false; + } std::vector> points; - std::vector planes; }; - //============================================================================================ //============================================================================================ - struct Point { size_t id; size_t globalID; Vec3 location3D; - Point() { static size_t idcounter = 0; idcounter++; globalID = idcounter; } - //============================================================================================ - - bool operator==(const Vec3 &pt) + bool operator==(const Vec3& pt) { return equals(location3D, pt, toleranceVectorEquality); } - std::vector lines; std::vector planes; }; - //============================================================================================ //============================================================================================ - struct Plane { int refPlane = -1; @@ -252,64 +226,48 @@ namespace fuzzybools size_t globalID; double distance; Vec3 normal; - std::vector lines; AABB aabb; - //============================================================================================ - - void AddPoint(const Vec3 &pt) + void AddPoint(const Vec3& pt) { aabb.merge(pt); } - //============================================================================================ - Plane() { static size_t idcounter = 0; idcounter++; globalID = idcounter; } - //============================================================================================ - double round(double input) { input = std::fabs(input) < EPS_BIG ? 0.0 : input; input = std::fabs(input) < (1.0 - EPS_BIG) ? input : input > 0.0 ? 1.0 - : -1.0; + : -1.0; return input; } - //============================================================================================ - Vec3 round(Vec3 in) { in.x = round(in.x); in.y = round(in.y); in.z = round(in.z); - return in; } - //============================================================================================ - Vec3 GetDirection(Vec3 a, Vec3 b) { auto dir = b - a; return glm::normalize(dir); } - //============================================================================================ - - std::pair AddLine(const Point &a, const Point &b) + std::pair AddLine(const Point& a, const Point& b) { Vec3 pos = a.location3D; Vec3 dir = GetDirection(pos, b.location3D); - auto lineId = AddLine(pos, dir); - if (!lines[lineId.first].IsPointOnLine(a.location3D)) { if (messages) @@ -324,7 +282,6 @@ namespace fuzzybools printf("bad point in AddLine\n"); } } - if (!aabb.contains(a.location3D)) { if (messages) @@ -339,70 +296,52 @@ namespace fuzzybools printf("bad points in AddLine\n"); } } - lines[lineId.first].AddPointToLine(lines[lineId.first].GetPosOnLine(a.location3D), a.id); lines[lineId.first].AddPointToLine(lines[lineId.first].GetPosOnLine(b.location3D), b.id); - return lineId; } - //============================================================================================ - - std::pair AddLine(const Vec3 &pos, const Vec3 &dir) + std::pair AddLine(const Vec3& pos, const Vec3& dir) { - for (auto &line : lines) + for (auto& line : lines) { if (line.IsEqualTo(pos, dir)) { - return {line.id, false}; + return { line.id, false }; } } - Line l; l.id = lines.size(); l.origin = pos; - // l.direction = dir; Vec3 temp = glm::normalize(dir); l.direction = temp; - lines.push_back(l); - - return {l.id, true}; + return { l.id, true }; } - //============================================================================================ - void RemoveLastLine() { lines.pop_back(); } - //============================================================================================ - - bool IsEqualTo(const Vec3 &n, double d) + bool IsEqualTo(const Vec3& n, double d) { return (equals(normal, n, toleranceVectorEquality) && equals(distance, d, TOLERANCE_SCALAR_EQUALITY)); } - //============================================================================================ - - glm::dvec2 GetPosOnPlane(const glm::dvec3 &pos) + glm::dvec2 GetPosOnPlane(const glm::dvec3& pos) { return {}; } - //============================================================================================ - - bool HasOverlap(const std::pair &A, const std::pair &B) + bool HasOverlap(const std::pair& A, const std::pair& B) { return (A.first == B.first || A.first == B.second || A.second == B.first || A.second == B.second); } - //============================================================================================ - - void PutPointOnLines(Point &p) + void PutPointOnLines(Point& p) { - for (auto &l : lines) + for (auto& l : lines) { if (l.IsPointOnLine(p.location3D)) { @@ -414,89 +353,67 @@ namespace fuzzybools } } } - //============================================================================================ - /* Normal is assumed to be normalised. */ - bool IsPointOnPlane(const glm::dvec3 &pos) + bool IsPointOnPlane(const glm::dvec3& pos) { double d = glm::dot(normal, pos); double posLength = pos.length(); - // return equals(distance, d, toleranceVectorEquality * posLength); + // return equals(distance, d, toleranceVectorEquality * posLength); return equals(distance, d, toleranceVectorEquality); } - //============================================================================================ - PlaneBasis MakeBasis() { glm::dvec3 origin = normal * distance; glm::dvec3 up = normal; - glm::dvec3 worldUp = glm::dvec3(0, 1, 0); glm::dvec3 worldRight = glm::dvec3(1, 0, 0); - bool normalIsUp = equals(up, worldUp, EPS_SMALL) || equals(-up, worldUp, EPS_SMALL); glm::dvec3 left = normalIsUp ? glm::cross(up, worldRight) : glm::cross(up, worldUp); glm::dvec3 right = glm::cross(left, up); - PlaneBasis basis; - basis.origin = origin; basis.up = glm::normalize(up); basis.left = glm::normalize(left); basis.right = glm::normalize(right); - return basis; } }; - //============================================================================================ //============================================================================================ - struct Triangle { size_t id; - size_t a; size_t b; size_t c; - //============================================================================================ - void Flip() { auto temp = a; a = b; b = temp; } - //============================================================================================ - bool HasPoint(size_t p) { return a == p || b == p || c == p; } - //============================================================================================ - - bool IsNeighbour(Triangle &t) + bool IsNeighbour(Triangle& t) { return HasPoint(t.a) || HasPoint(t.b) || HasPoint(t.c); } - //============================================================================================ - - bool SamePoints(Triangle &other) + bool SamePoints(Triangle& other) { return other.HasPoint(a) && other.HasPoint(b) && other.HasPoint(c); } - //============================================================================================ - - size_t GetNotShared(Triangle &other) + size_t GetNotShared(Triangle& other) { if (!other.HasPoint(a)) { @@ -510,14 +427,11 @@ namespace fuzzybools { return c; } - // throw std::exception("Missing common point in GetNotShared"); } }; - //============================================================================================ //============================================================================================ - struct SegmentSet { std::vector> segments; @@ -525,12 +439,9 @@ namespace fuzzybools std::map, size_t> segmentCounts; std::vector irrelevantFaces; std::vector irrelevantFaces_toTest; - std::map>> planeSegments; std::map, size_t>> planeSegmentCounts; - //============================================================================================ - void AddSegment(size_t planeId, size_t a, size_t b) { if (a == b) @@ -541,73 +452,55 @@ namespace fuzzybools } return; } - auto seg = a < b ? std::make_pair(a, b) : std::make_pair(b, a); - segments.emplace_back(seg); segmentCounts[seg]++; - planeSegments[planeId].emplace_back(seg); planeSegmentCounts[planeId][seg]++; } - //============================================================================================ - void AddFace(size_t planeId, size_t a, size_t b, size_t c) { AddSegment(planeId, a, b); AddSegment(planeId, b, c); AddSegment(planeId, c, a); - Triangle t; t.id = triangles.size(); t.a = a; t.b = b; t.c = c; - triangles.push_back(t); } - //============================================================================================ - std::vector GetTrianglesWithPoint(size_t p) { std::vector returnTriangles; - - for (auto &t : triangles) + for (auto& t : triangles) { if (t.HasPoint(p)) { returnTriangles.push_back(t.id); } } - return returnTriangles; } - //============================================================================================ - std::vector GetTrianglesWithEdge(size_t a, size_t b) { std::vector returnTriangles; - - for (auto &t : triangles) + for (auto& t : triangles) { if (t.HasPoint(a) && t.HasPoint(b)) { returnTriangles.push_back(t.id); } } - return returnTriangles; } - //============================================================================================ - - std::vector, std::vector>> GetNeighbourTriangles(Triangle &triangle) + std::vector, std::vector>> GetNeighbourTriangles(Triangle& triangle) { std::vector, std::vector>> returnTriangles; - { auto tris = GetTrianglesWithEdge(triangle.a, triangle.b); returnTriangles.emplace_back(std::make_pair(triangle.a, triangle.b), tris); @@ -620,32 +513,26 @@ namespace fuzzybools auto tris = GetTrianglesWithEdge(triangle.c, triangle.a); returnTriangles.emplace_back(std::make_pair(triangle.c, triangle.a), tris); } - return returnTriangles; } - bool IsManifold() { std::vector> contours; - - for (auto &[pair, count] : segmentCounts) + for (auto& [pair, count] : segmentCounts) { if (count != 2) { contours.push_back(pair); } } - return contours.empty(); } - std::map>> GetContourSegments() { std::map>> contours; - - for (auto &[plane, segmentCounts] : planeSegmentCounts) + for (auto& [plane, segmentCounts] : planeSegmentCounts) { - for (auto &[pair, count] : segmentCounts) + for (auto& [pair, count] : segmentCounts) { if (count == 1) { @@ -653,61 +540,44 @@ namespace fuzzybools } } } - return contours; } }; /////////////////////////////////////////////////// - //============================================================================================ //============================================================================================ - struct SharedPosition { std::vector points; std::vector planes; - SegmentSet A; SegmentSet B; - // TODO: design flaw - const Geometry *_linkedA; - const Geometry *_linkedB; - + const Geometry* _linkedA; + const Geometry* _linkedB; Geometry relevantA; Geometry relevantB; - BVH relevantBVHA; BVH relevantBVHB; - //============================================================================================ - - // assumes all triangleIds are connected to base with an edge and are flipped correctly - size_t FindUppermostTriangleId(Triangle &base, const std::vector &triangleIds) + // assumes all triangleIds are connected to base with an edge and are flipped correctly + size_t FindUppermostTriangleId(Triangle& base, const std::vector& triangleIds) { if (triangleIds.size() == 1) { return triangleIds[0]; } - auto baseNorm = GetNormal(base); - size_t maxDotId = -1; double maxDot = -DBL_MAX; - for (auto id : triangleIds) { if (id == base.id) continue; - auto triNorm = GetNormal(A.triangles[id]); - auto other = A.triangles[id].GetNotShared(base); - auto above = CalcTriPt(base, other); - auto dot = (glm::dot(baseNorm, triNorm) + 1.0) / 2.0; // range dot from 0 to 1, positive for above, negative for below - if (above == TriangleVsPoint::BELOW) { dot = dot - 1.0; @@ -716,25 +586,20 @@ namespace fuzzybools { dot = 1.0 - dot; } - if (dot > maxDot) { maxDot = dot; maxDotId = id; } } - return maxDotId; } - //============================================================================================ - size_t GetPointWithMaxY() { double max = -DBL_MAX; size_t pointID = 0; - - for (auto &p : points) + for (auto& p : points) { if (p.location3D.y > max) { @@ -742,44 +607,34 @@ namespace fuzzybools pointID = p.id; } } - return pointID; } - //============================================================================================ - enum class TriangleVsPoint { ABOVE, BELOW, ON }; - //============================================================================================ - - TriangleVsPoint CalcTriPt(Triangle &T, size_t point) + TriangleVsPoint CalcTriPt(Triangle& T, size_t point) { auto norm = GetNormal(T); - auto dpt3d = points[point].location3D - points[T.a].location3D; auto dot = glm::dot(norm, dpt3d); - if (std::fabs(dot) < EPS_BIG) return TriangleVsPoint::ON; if (dot > 0.0) return TriangleVsPoint::ABOVE; return TriangleVsPoint::BELOW; } - //============================================================================================ - // simplify, see FindUppermostTriangleId - bool ShouldFlip(Triangle &T, Triangle &neighbour) + bool ShouldFlip(Triangle& T, Triangle& neighbour) { /* for each n in N, orient n by formula: if triangle T and N are vertices ABCDEF with BCDE as the shared edge, consider three cases: - E is above T, then A is above n if dot(normal(T), E) > 0 => dot(normal(n), A) > 0, else flip n E is below T, then A is below n @@ -789,19 +644,15 @@ namespace fuzzybools */ auto normT = GetNormal(T); auto normNB = GetNormal(neighbour); - if (T.SamePoints(neighbour)) { // same tri, different winding, flip if not the same normal return glm::dot(normT, normNB) < 1.0 - EPS_BIG; } - auto A = T.GetNotShared(neighbour); auto E = neighbour.GetNotShared(T); - TriangleVsPoint EvsT = CalcTriPt(T, E); - TriangleVsPoint AvsN = CalcTriPt(neighbour, E); - + TriangleVsPoint AvsN = CalcTriPt(neighbour, A); if (EvsT == TriangleVsPoint::ABOVE && AvsN != TriangleVsPoint::ABOVE) { return true; @@ -820,95 +671,95 @@ namespace fuzzybools return false; } } - //============================================================================================ - - Vec3 GetNormal(Triangle &tri) + Vec3 GetNormal(Triangle& tri) { Vec3 temp(-1.0, -1.0, -1.0); Vec3 norm = glm::normalize(temp); computeSafeNormal(points[tri.a].location3D, points[tri.b].location3D, points[tri.c].location3D, norm, EPS_SMALL); return norm; } - //============================================================================================ - - SegmentSet &GetSegSetA() + SegmentSet& GetSegSetA() { return A; } - //============================================================================================ - - size_t AddPoint(const Vec3 &newPoint) - { - for (auto &pt : points) - { - if (pt == newPoint) - { - return pt.id; + std::unordered_map> pointHashMap; // Maps quantized key to list of point IDs + // Optimized AddPoint: + size_t AddPoint(const Vec3& newPoint) { + // Quantize the point based on tolerance + double invTol = 1.0 / toleranceVectorEquality; + glm::ivec3 primaryKey( + static_cast(std::floor(newPoint.x * invTol)), + static_cast(std::floor(newPoint.y * invTol)), + static_cast(std::floor(newPoint.z * invTol)) + ); + // Check primary and neighboring cells with radius 2 + const int RADIUS = 2; + for (int dx = -RADIUS; dx <= RADIUS; ++dx) { + for (int dy = -RADIUS; dy <= RADIUS; ++dy) { + for (int dz = -RADIUS; dz <= RADIUS; ++dz) { + glm::ivec3 neighKey = primaryKey + glm::ivec3(dx, dy, dz); + auto it = pointHashMap.find(neighKey); + if (it != pointHashMap.end()) { + for (size_t existingId : it->second) { + if (equals(points[existingId].location3D, newPoint, toleranceVectorEquality)) { + return existingId; // Match found + } + } + } + } } } - + // No match: add new point Point p; p.id = points.size(); p.location3D = newPoint; - points.push_back(p); - + // Insert into primary cell's list + pointHashMap[primaryKey].push_back(p.id); return p.id; } - + //============================================================================================ - - size_t AddPlane(const Vec3 &normal, double d, uint32_t refId) + size_t AddPlane(const Vec3& normal, double d, uint32_t refId) { - for (auto &plane : planes) + for (auto& plane : planes) { if (plane.refPlane == refId || plane.IsEqualTo(normal, d)) { return plane.id; } } - Plane p; p.id = planes.size(); p.refPlane = refId; p.normal = glm::normalize(normal); p.distance = d; planes.push_back(p); - return p.id; } - //============================================================================================ - - void Construct(const Geometry &A, const Geometry &B, bool isUnion) + void Construct(const Geometry& A, const Geometry& B, bool isUnion) { auto boxA = A.GetAABB(); auto boxB = B.GetAABB(); - AddGeometry(A, B, boxB, true, isUnion, 0); AddGeometry(B, A, boxA, false, isUnion, A.planes.size()); - _linkedA = &A; _linkedB = &B; } - //============================================================================================ - - void AddGeometry(const Geometry &geom, const Geometry &secondGeom, const AABB &relevantBounds, bool isA, bool isUnion, uint32_t offsetPlane) + void AddGeometry(const Geometry& geom, const Geometry& secondGeom, const AABB& relevantBounds, bool isA, bool isUnion, uint32_t offsetPlane) { #ifdef CSG_DEBUG_OUTPUT Geometry relevant; #endif - for (size_t i = 0; i < geom.numFaces; i++) { Face f = geom.GetFace(i); - auto faceBox = geom.GetFaceBox(i); - if (!faceBox.intersects(relevantBounds)) { if (isA) @@ -919,23 +770,18 @@ namespace fuzzybools { B.irrelevantFaces.push_back(i); } - continue; } - bool contact = false; - for (size_t j = 0; j < secondGeom.numFaces; j++) { auto faceBox2 = secondGeom.GetFaceBox(j); - if (faceBox.intersects(faceBox2)) { contact = true; break; } } - if (!contact) { if (isA) @@ -949,38 +795,31 @@ namespace fuzzybools B.irrelevantFaces_toTest.push_back(i); } } - continue; } - if (isA) { #ifdef CSG_DEBUG_OUTPUT -// DumpGeometry(geom, L"Initial_A.obj"); + // DumpGeometry(geom, L"Initial_A.obj"); #endif } else { #ifdef CSG_DEBUG_OUTPUT -// DumpGeometry(geom, L"Initial_B.obj"); + // DumpGeometry(geom, L"Initial_B.obj"); #endif } - auto a = geom.GetPoint(f.i0); auto b = geom.GetPoint(f.i1); auto c = geom.GetPoint(f.i2); - #ifdef CSG_DEBUG_OUTPUT -// relevant.AddFace(a, b, c, -1); + // relevant.AddFace(a, b, c, -1); #endif - Vec3 norm; if (computeSafeNormal(a, b, c, norm, EPS_SMALL)) { double rs = glm::dot(geom.planes[f.pId].normal, norm); - size_t planeId = -1; - if (rs < 0) { planeId = AddPlane(-geom.planes[f.pId].normal, -geom.planes[f.pId].distance, f.pId + offsetPlane); @@ -989,15 +828,12 @@ namespace fuzzybools { planeId = AddPlane(geom.planes[f.pId].normal, geom.planes[f.pId].distance, f.pId + offsetPlane); } - auto ia = AddPoint(a); auto ib = AddPoint(b); auto ic = AddPoint(c); - double da = glm::dot(norm, a); double db = glm::dot(norm, b); double dc = glm::dot(norm, c); - if (!planes[planeId].IsPointOnPlane(a)) { if (messages) @@ -1034,7 +870,6 @@ namespace fuzzybools planes[planeId].AddPoint(a); planes[planeId].AddPoint(b); planes[planeId].AddPoint(c); - if (isA) { A.AddFace(planeId, ia, ib, ic); @@ -1054,7 +889,6 @@ namespace fuzzybools } } } - if (isA) { relevantBVHA = MakeBVH(relevantA); @@ -1063,49 +897,40 @@ namespace fuzzybools { relevantBVHB = MakeBVH(relevantB); } - #ifdef CSG_DEBUG_OUTPUT // if (isA) // { - // DumpGeometry(relevant, L"relevantA.obj"); + // DumpGeometry(relevant, L"relevantA.obj"); // } // else // { - // DumpGeometry(relevant, L"relevantB.obj"); + // DumpGeometry(relevant, L"relevantB.obj"); // } #endif } - //============================================================================================ - - std::vector GetPointsOnPlane(Plane &p) + std::vector GetPointsOnPlane(Plane& p) { auto cp = planeToPoints[p.id]; std::sort(cp.begin(), cp.end()); cp.erase(std::unique(cp.begin(), cp.end()), cp.end()); return cp; } - //============================================================================================ - // pair of lineID, distance - std::vector> BuildSegments(const std::vector &a, const std::vector &b) const + std::vector> BuildSegments(const std::vector& a, const std::vector& b) const { if (a.size() == 0 || b.size() == 0) { return {}; } - // we need to figure out the overlap between the two lists of intersections // we can be clever here and try to conclude that the first point must be the start of a segment and the next point would end that segment // however, we would really shoot ourselves in the foot as any coplanar results are missing from these two sets // let's just make some segments that span both intersection lists, and eat the overhead - double min = std::max(a[0], b[0]); double max = std::min(a[a.size() - 1], b[b.size() - 1]); - std::vector points; - for (size_t i = 0; i < a.size(); i++) { double val = a[i]; @@ -1114,7 +939,6 @@ namespace fuzzybools points.push_back(val); } } - for (size_t i = 0; i < b.size(); i++) { double val = b[i]; @@ -1123,92 +947,35 @@ namespace fuzzybools points.push_back(val); } } - const auto double_less = +[](double left, double right) - { return left < right; }; + { return left < right; }; std::sort(points.begin(), points.end(), double_less); - std::vector> result; result.reserve(points.size() * 2); - for (size_t i = 1; i < points.size(); i++) { result.emplace_back(points[i - 1], points[i]); } - // Remove redundant lines result.erase(std::unique(result.begin(), result.end()), result.end()); - return result; } - //============================================================================================ - - std::vector> GetNonIntersectingSegments(Line &l) + std::vector> GetNonIntersectingSegments(Line& l) { - std::vector> pointsInOrder; - - for (auto segment : l.GetSegments()) - { - if (!l.IsPointOnLine(points[segment.first].location3D)) - { - if (messages) - { - printf("point not on line in GetNonIntersectingSegments\n"); - } - if (messages) - { - printf("points[segment.first].location3D = (%12.8f, %12.8f, %12.8f)\n", points[segment.first].location3D.x, points[segment.first].location3D.y, points[segment.first].location3D.z); - } - if (messages) - { - printf("l.origin = (%12.8f, %12.8f, %12.8f)\n", l.origin.x, l.origin.y, l.origin.z); - } - if (messages) - { - printf("l.direction = (%12.8f, %12.8f, %12.8f)\n", l.direction.x, l.direction.y, l.direction.z); - } - } - - if (!l.IsPointOnLine(points[segment.second].location3D)) - { - if (messages) - { - printf("point not on line in GetNonIntersectingSegments\n"); - } - if (messages) - { - printf("points[segment.second].location3D = (%12.8f, %12.8f, %12.8f)\n", points[segment.second].location3D.x, points[segment.second].location3D.y, points[segment.second].location3D.z); - } - if (messages) - { - printf("l.origin = (%12.8f, %12.8f, %12.8f)\n", l.origin.x, l.origin.y, l.origin.z); - } - if (messages) - { - printf("l.direction = (%12.8f, %12.8f, %12.8f)\n", l.direction.x, l.direction.y, l.direction.z); - } - } - - pointsInOrder.emplace_back(segment.first, l.GetPosOnLine(points[segment.first].location3D)); - pointsInOrder.emplace_back(segment.second, l.GetPosOnLine(points[segment.second].location3D)); - } - + std::vector> pointsInOrder = l.points; std::sort( - pointsInOrder.begin(), pointsInOrder.end(), [&](const std::pair &left, const std::pair &right) - { return left.second > right.second; }); - + pointsInOrder.begin(), pointsInOrder.end(), [&](const std::pair& left, const std::pair& right) + { return left.first < right.first; }); std::vector> segmentsWithoutIntersections; - if (pointsInOrder.empty()) return {}; - - size_t cur = pointsInOrder[0].first; + size_t cur = pointsInOrder[0].second; for (size_t i = 1; i < pointsInOrder.size(); i++) { // this fills gaps, but we don't care about that in this stage // gaps filled will be removed during inside/outside checking - size_t next = pointsInOrder[i].first; + size_t next = pointsInOrder[i].second; if (cur != next) { segmentsWithoutIntersections.emplace_back(cur, next); @@ -1217,47 +984,35 @@ namespace fuzzybools } return segmentsWithoutIntersections; } - //============================================================================================ - - void TriangulatePlane(Geometry &geom, Plane &p) + void TriangulatePlane(Geometry& geom, Plane& p) { - // grab all points on the plane auto pointsOnPlane = GetPointsOnPlane(p); - // temporarily project all points for triangulation // NOTE: these points should not be used as output, only as placeholder for triangulation! - auto basis = p.MakeBasis(); - std::unordered_map pointToProjectedPoint; pointToProjectedPoint.reserve(pointsOnPlane.size()); - std::unordered_map projectedPointToPoint; projectedPointToPoint.reserve(pointsOnPlane.size()); - std::vector projectedPoints; projectedPoints.reserve(pointsOnPlane.size()); - - for (auto &pointId : pointsOnPlane) + for (auto& pointId : pointsOnPlane) { pointToProjectedPoint[pointId] = projectedPoints.size(); projectedPointToPoint[projectedPoints.size()] = pointId; projectedPoints.push_back(basis.project(points[pointId].location3D)); } - std::set> edges; std::set> defaultEdges; static int i = 0; i++; - - for (auto &line : p.lines) + for (auto& line : p.lines) { // these segments might intersect internally, lets resolve that so we get a valid chain auto segments = GetNonIntersectingSegments(line); - - for (auto &segment : segments) + for (auto& segment : segments) { if (pointToProjectedPoint.count(segment.first) == 0) { @@ -1266,7 +1021,6 @@ namespace fuzzybools { printf("unknown point in list, repairing in TriangulateLine\n"); } - pointToProjectedPoint[segment.first] = projectedPoints.size(); projectedPointToPoint[projectedPoints.size()] = segment.first; projectedPoints.push_back(basis.project(points[segment.first].location3D)); @@ -1278,220 +1032,164 @@ namespace fuzzybools { printf("unknown point in list, repairing in TriangulateLine\n"); } - pointToProjectedPoint[segment.second] = projectedPoints.size(); projectedPointToPoint[projectedPoints.size()] = segment.second; projectedPoints.push_back(basis.project(points[segment.second].location3D)); } - auto projectedIndexA = pointToProjectedPoint[segment.first]; auto projectedIndexB = pointToProjectedPoint[segment.second]; - if (projectedIndexA != projectedIndexB) { defaultEdges.insert(segment); - edges.insert(std::make_pair(projectedIndexA, projectedIndexB)); + edges.insert(std::make_pair(std::min(projectedIndexA, projectedIndexB), std::max(projectedIndexA, projectedIndexB))); } } } - #ifdef CSG_DEBUG_OUTPUT // std::vector> edgesPrinted; - // for (auto &e : edges) // { - // edgesPrinted.push_back({projectedPoints[e.first], projectedPoints[e.second]}); + // edgesPrinted.push_back({projectedPoints[e.first], projectedPoints[e.second]}); // } - // DumpSVGLines(edgesPrinted, L"poly.html"); #endif - CDT::Triangulation cdt(CDT::VertexInsertionOrder::AsProvided); std::vector cdt_edges; cdt_edges.reserve(edges.size()); - std::vector> cdt_verts; cdt_verts.reserve(projectedPoints.size()); - - for (auto &point : projectedPoints) + for (auto& point : projectedPoints) { cdt_verts.emplace_back(CDT::V2d::make(point.x, point.y)); } - - for (auto &edge : edges) + for (auto& edge : edges) { cdt_edges.emplace_back((uint32_t)edge.first, (uint32_t)edge.second); } - auto mapping = CDT::RemoveDuplicatesAndRemapEdges(cdt_verts, cdt_edges).mapping; - cdt.insertVertices(cdt_verts); cdt.insertEdges(cdt_edges); - cdt.eraseSuperTriangle(); - auto triangles = cdt.triangles; - // auto contourLoop = FindLargestEdgeLoop(projectedPoints, edges); - #ifdef CSG_DEBUG_OUTPUT // std::vector> edges3DTriangles; // std::set> edgesTriangles; // std::set> finalEdgesTriangles; #endif - - for (auto &tri : triangles) + for (auto& tri : triangles) { #ifdef CSG_DEBUG_OUTPUT // edgesTriangles.insert(std::make_pair(tri.vertices[0], tri.vertices[1])); // edgesTriangles.insert(std::make_pair(tri.vertices[1], tri.vertices[2])); // edgesTriangles.insert(std::make_pair(tri.vertices[0], tri.vertices[2])); #endif - size_t pointIdA = projectedPointToPoint[mapping[tri.vertices[0]]]; size_t pointIdB = projectedPointToPoint[mapping[tri.vertices[1]]]; size_t pointIdC = projectedPointToPoint[mapping[tri.vertices[2]]]; - auto ptA = points[pointIdA].location3D; auto ptB = points[pointIdB].location3D; auto ptC = points[pointIdC].location3D; - glm::dvec3 v1 = glm::normalize(ptA - ptB); glm::dvec3 v2 = glm::normalize(ptA - ptC); glm::dvec3 v3 = glm::normalize(ptB - ptC); double rs1 = glm::dot(v1, v2); double rs2 = glm::dot(v2, v3); double rs3 = glm::dot(v1, v3); - if (std::abs(rs1) > 1 - toleranceThinTriangle || std::abs(rs2) > 1 - toleranceThinTriangle || std::abs(rs3) > 1 - toleranceThinTriangle) { continue; } - auto pt2DA = projectedPoints[mapping[tri.vertices[0]]]; auto pt2DB = projectedPoints[mapping[tri.vertices[1]]]; auto pt2DC = projectedPoints[mapping[tri.vertices[2]]]; - auto triCenter = (ptA + ptB + ptC) / 3.0; - Vec raydir = computeNormal(ptA, ptB, ptC); - auto posA = isInsideMesh(triCenter, glm::dvec3(0), relevantA, relevantBVHA, raydir); auto posB = isInsideMesh(triCenter, glm::dvec3(0), relevantB, relevantBVHB, raydir); - if (posA.loc != MeshLocation::BOUNDARY && posB.loc != MeshLocation::BOUNDARY) { continue; } - // If the 2D triangle is not inside the boundaries of the projected boundary of the face it requires further verification // It can't be discarded because inside/outside could fail when boundaries have internal partitions // Therefore new tests are required to verify that the triangle is on the boundary of A or B - glm::dvec2 t1 = projectedPoints[tri.vertices[0]]; glm::dvec2 t2 = projectedPoints[tri.vertices[1]]; glm::dvec2 t3 = projectedPoints[tri.vertices[2]]; - bool inside2d = isInsideBoundary(t1, t2, t3, edges, projectedPoints); - if (!inside2d) { - auto postA = isInsideMesh(triCenter, glm::dvec3(0), relevantA, relevantBVHA, raydir); auto postB = isInsideMesh(triCenter, glm::dvec3(0), relevantB, relevantBVHB, raydir); - if (postA.loc != MeshLocation::BOUNDARY && postB.loc != MeshLocation::BOUNDARY) { continue; } - auto ptt = glm::mix(triCenter, ptA, triangleEvaluationFactor); - postA = isInsideMesh(ptt, glm::dvec3(0), relevantA, relevantBVHA, raydir); postB = isInsideMesh(ptt, glm::dvec3(0), relevantB, relevantBVHB, raydir); - if (postA.loc != MeshLocation::BOUNDARY && postB.loc != MeshLocation::BOUNDARY) { continue; } - ptt = glm::mix(triCenter, ptB, triangleEvaluationFactor); - postA = isInsideMesh(ptt, glm::dvec3(0), relevantA, relevantBVHA, raydir); postB = isInsideMesh(ptt, glm::dvec3(0), relevantB, relevantBVHB, raydir); - if (postA.loc != MeshLocation::BOUNDARY && postB.loc != MeshLocation::BOUNDARY) { continue; } - ptt = glm::mix(triCenter, ptC, triangleEvaluationFactor); - postA = isInsideMesh(ptt, glm::dvec3(0), relevantA, relevantBVHA, raydir); postB = isInsideMesh(ptt, glm::dvec3(0), relevantB, relevantBVHB, raydir); - if (postA.loc != MeshLocation::BOUNDARY && postB.loc != MeshLocation::BOUNDARY) { continue; } } - // although CDT is great, it spits out too many or too little tris, we fix it manually // if (!IsPointInsideLoop(projectedPoints, contourLoop, triCenter)) //{ - // printf("removing point outside loop\n"); - // continue; + // printf("removing point outside loop\n"); + // continue; //} - // TODO: why is this swapped? winding doesnt matter much, but still geom.AddFace(ptB, ptA, ptC, p.refPlane); - #ifdef CSG_DEBUG_OUTPUT // edges3DTriangles.push_back({ glm::dvec2(ptA.z+ ptA.x/2, ptA.y+ ptA.x/2), glm::dvec2(ptB.z+ ptB.x/2, ptB.y+ ptB.x/2) }); // edges3DTriangles.push_back({ glm::dvec2(ptA.z+ ptA.x/2, ptA.y+ ptA.x/2), glm::dvec2(ptC.z+ ptC.x/2, ptC.y+ ptC.x/2) }); // edges3DTriangles.push_back({ glm::dvec2(ptB.z+ ptB.x/2, ptB.y+ ptB.x/2), glm::dvec2(ptC.z+ ptC.x/2, ptC.y+ ptC.x/2) }); // DumpSVGLines(edges3DTriangles, L"edges_tri.html"); #endif - #ifdef CSG_DEBUG_OUTPUT // finalEdgesTriangles.insert(std::make_pair(tri.vertices[0], tri.vertices[1])); // finalEdgesTriangles.insert(std::make_pair(tri.vertices[1], tri.vertices[2])); // finalEdgesTriangles.insert(std::make_pair(tri.vertices[0], tri.vertices[2])); #endif } - #ifdef CSG_DEBUG_OUTPUT // std::vector> edgesPrinted2; - // for (auto& e : edgesTriangles) // { - // edgesPrinted2.push_back({ projectedPoints[e.first], projectedPoints[e.second] }); + // edgesPrinted2.push_back({ projectedPoints[e.first], projectedPoints[e.second] }); // } - // DumpSVGLines(edgesPrinted2, L"poly_triangulation.html"); - // std::vector> finalEdgesPrinted; - // for (auto& e : finalEdgesTriangles) // { - // finalEdgesPrinted.push_back({ projectedPoints[e.first], projectedPoints[e.second] }); + // finalEdgesPrinted.push_back({ projectedPoints[e.first], projectedPoints[e.second] }); // } - // DumpSVGLines(finalEdgesPrinted, L"final_poly_triangulation.html"); #endif } //============================================================================================ - std::unordered_map> planeToLines; - //============================================================================================ - std::unordered_map> planeToPoints; - //============================================================================================ - void AddRefPlaneToPoint(size_t point, size_t plane) { ReferencePlane ref; @@ -1501,19 +1199,15 @@ namespace fuzzybools planeToPoints[plane].push_back(point); } }; - //============================================================================================ - - inline void AddSegments(Plane &p, SharedPosition &sp, Line &templine, const std::vector> &segments) + inline void AddSegments(Plane& p, SharedPosition& sp, Line& templine, const std::vector>& segments) { // NOTE: this is a design flaw, the addline may return a line that is // EQUIVALENT BUT NOT IDENTICAL // hence line distances mentioned in "segments" DO apply to templine // but not necessary (but possibly) to isectLineId auto isectLineId = p.AddLine(templine.origin, templine.direction); - - auto &isectLine = p.lines[isectLineId.first]; - + auto& isectLine = p.lines[isectLineId.first]; if (!p.IsPointOnPlane(isectLine.origin) || !p.IsPointOnPlane(isectLine.origin + isectLine.direction * 100.)) { if (messages) @@ -1521,11 +1215,9 @@ namespace fuzzybools printf("Bad isect line in AddSegments\n"); } } - - for (auto &seg : segments) + for (auto& seg : segments) { auto pos = templine.GetPosOnLine(seg.first); - if (!p.aabb.contains(pos)) { if (messages) @@ -1533,10 +1225,8 @@ namespace fuzzybools printf("making pos outside in AddSegments]\n"); } } - size_t ptA = sp.AddPoint(pos); size_t ptB = sp.AddPoint(templine.GetPosOnLine(seg.second)); - if (!p.aabb.contains(sp.points[ptA].location3D)) { if (messages) @@ -1551,13 +1241,10 @@ namespace fuzzybools printf("bad points in AddS.segments\n"); } } - - // if (ptA != ptB) { isectLine.AddPointToLine(isectLine.GetPosOnLine(sp.points[ptA].location3D), ptA); isectLine.AddPointToLine(isectLine.GetPosOnLine(sp.points[ptB].location3D), ptB); } - if (!p.IsPointOnPlane(sp.points[ptA].location3D)) { if (messages) @@ -1572,167 +1259,84 @@ namespace fuzzybools printf("bad point in AddSegments\n"); } } - sp.AddRefPlaneToPoint(ptA, p.id); sp.AddRefPlaneToPoint(ptB, p.id); } } - //============================================================================================ - - inline std::vector ComputeInitialIntersections(Plane &p, SharedPosition &sp, const Line &lineA) + inline std::vector ComputeInitialIntersections(Plane& p, SharedPosition& sp, const Line& lineA) { - double size = 1.0E+08; // TODO: this is bad - - for (auto &point : sp.points) - { - const auto d2 = glm::distance2(lineA.origin, point.location3D); - size = std::max(size, d2); - } - - size = std::sqrt(size); - - auto Astart = lineA.origin + lineA.direction * (size * 2); - auto Aend = lineA.origin - lineA.direction * (size * 2); - std::vector distances; distances.reserve(p.lines.size()); - // line B is expected to have the segments already filled, line A is not - for (auto &line : p.lines) + for (auto& line : p.lines) { // skip collinear if (lineA.IsCollinear(line)) continue; - - for (const auto &seg : line.GetSegments()) + Vec3 relative = lineA.origin - line.origin; + Vec3 cr = glm::cross(lineA.direction, line.direction); + double denom = glm::dot(cr, p.normal); + if (std::fabs(denom) < EPS_SMALL) + continue; + double t = -glm::dot(glm::cross(relative, line.direction), p.normal) / denom; + Vec3 point = lineA.origin + t * lineA.direction; + if (!line.IsPointOnLine(point)) + continue; + double distB = line.GetPosOnLine(point); + if (!line.ContainsPos(distB)) + continue; + if (!p.IsPointOnPlane(point)) { - auto result = LineLineIntersection( - Astart, - Aend, - sp.points[seg.first].location3D, - sp.points[seg.second].location3D); - - if (result.distance < _TOLERANCE_PLANE_INTERSECTION) + if (messages) { - if (!p.aabb.contains(sp.points[seg.first].location3D)) - { - if (messages) - { - printf("bad points in ComputeInitialIntersections\n"); - } - } - if (!p.aabb.contains(sp.points[seg.second].location3D)) - { - if (messages) - { - printf("bad points in ComputeInitialIntersections\n"); - } - } - - // intersection, mark index of line B and distance on line A - distances.emplace_back(lineA.GetPosOnLine(result.point2)); - auto pt = lineA.GetPosOnLine(distances[distances.size() - 1]); - - if (!p.aabb.contains(result.point2)) - { - if (messages) - { - printf("bad points in ComputeInitialIntersections\n"); - } - } - - if (!equals(pt, result.point2, _TOLERANCE_PLANE_INTERSECTION)) - { - if (messages) - { - printf("BAD POINT in ComputeInitialIntersections\n"); - } - } + printf("bad point in ComputeInitialIntersections\n"); } } + double distA = lineA.GetPosOnLine(point); + distances.emplace_back(distA); } - const auto double_less = +[](double left, double right) - { return left < right; }; + { return left < right; }; std::sort(distances.begin(), distances.end(), double_less); - distances.erase(std::unique(distances.begin(), distances.end()), distances.end()); - return distances; } - //============================================================================================ - - inline void AddLineLineIntersections(Plane &p, SharedPosition &sp, Line &lineA, Line &lineB) + inline void AddLineLineIntersections(Plane& p, SharedPosition& sp, Line& lineA, Line& lineB) { - for (auto segA : lineA.GetSegments()) - { - for (auto segB : lineB.GetSegments()) - { - // check isect A vs B - if (!p.HasOverlap(segA, segB)) - { - // no overlap, possibility of intersection - auto result = LineLineIntersection( - sp.points[segA.first].location3D, - sp.points[segA.second].location3D, - sp.points[segB.first].location3D, - sp.points[segB.second].location3D); - - if (result.distance < SCALED_EPS_BIG) - { - // intersection! Take center and insert - if (!p.aabb.contains(result.point1)) - { - if (messages) - { - printf("bad points in AddLineLineIntersections\n"); - } - continue; - } - - size_t point = sp.AddPoint((result.point1)); - - lineA.AddPointToLine(lineA.GetPosOnLine(sp.points[point].location3D), point); - lineB.AddPointToLine(lineB.GetPosOnLine(sp.points[point].location3D), point); - - // point falls on intersection of two lines, so is part of those lines and all planes of those lines - { - ReferenceLine ref; - ref.pointID = point; - ref.lineID = lineA.id; - ref.location = lineA.GetPosOnLine(result.point1); - sp.points[point].lines.push_back(ref); - - // TODO: FIX THIS POINT MIGHT NOT BE ON THE PLANE ACTUALLY - - for (auto &plane : lineA.planes) - { - sp.AddRefPlaneToPoint(point, plane.planeID); - } - } - { - ReferenceLine ref; - ref.pointID = point; - ref.lineID = lineB.id; - ref.location = lineB.GetPosOnLine(result.point2); - sp.points[point].lines.push_back(ref); - - for (auto &plane : lineB.planes) - { - sp.AddRefPlaneToPoint(point, plane.planeID); - } - } - } - } - } - } + if (lineA.IsCollinear(lineB)) + return; + Vec3 relative = lineA.origin - lineB.origin; + Vec3 cr = glm::cross(lineA.direction, lineB.direction); + double denom = glm::dot(cr, p.normal); + if (std::fabs(denom) < EPS_SMALL) + return; + double t = -glm::dot(glm::cross(relative, lineB.direction), p.normal) / denom; + Vec3 point = lineA.origin + t * lineA.direction; + if (!lineA.IsPointOnLine(point) || !lineB.IsPointOnLine(point)) + return; + double distA = lineA.GetPosOnLine(point); + double distB = lineB.GetPosOnLine(point); + if (!lineA.ContainsPos(distA) || !lineB.ContainsPos(distB)) + return; + size_t point_id = sp.AddPoint(point); + lineA.AddPointToLine(distA, point_id); + lineB.AddPointToLine(distB, point_id); + ReferenceLine refA; + refA.pointID = point_id; + refA.lineID = lineA.id; + refA.location = distA; + sp.points[point_id].lines.push_back(refA); + ReferenceLine refB; + refB.pointID = point_id; + refB.lineID = lineB.id; + refB.location = distB; + sp.points[point_id].lines.push_back(refB); + sp.AddRefPlaneToPoint(point_id, p.id); } - //============================================================================================ - - inline void AddLineLineIsects(Plane &p, SharedPosition &sp) + inline void AddLineLineIsects(Plane& p, SharedPosition& sp) { for (size_t lineAIndex = 0; lineAIndex < p.lines.size(); lineAIndex++) { @@ -1742,65 +1346,50 @@ namespace fuzzybools } } } - //============================================================================================ - - inline Geometry Normalize(const Geometry &A, const Geometry &B, SharedPosition &sp, bool UNION) + inline Geometry Normalize(const Geometry& A, const Geometry& B, SharedPosition& sp, bool UNION) { - // construct all contours, derive lines auto contoursA = sp.A.GetContourSegments(); - - for (auto &[planeId, contours] : contoursA) + for (auto& [planeId, contours] : contoursA) { std::vector> edges; - - Plane &p = sp.planes[planeId]; - + Plane& p = sp.planes[planeId]; #ifdef CSG_DEBUG_OUTPUT // auto basis = p.MakeBasis(); - // for (auto& segment : contours) // { - // edges.push_back({ basis.project(sp.points[segment.first].location3D), basis.project(sp.points[segment.second].location3D) }); + // edges.push_back({ basis.project(sp.points[segment.first].location3D), basis.project(sp.points[segment.second].location3D) }); // } // DumpSVGLines(edges, L"contour_A.html"); #endif - - for (auto &segment : contours) + for (auto& segment : contours) { auto lineId = sp.planes[planeId].AddLine(sp.points[segment.first], sp.points[segment.second]); } } - auto contoursB = sp.B.GetContourSegments(); - - for (auto &[planeId, contours] : contoursB) + for (auto& [planeId, contours] : contoursB) { std::vector> edges; - - Plane &p = sp.planes[planeId]; - + Plane& p = sp.planes[planeId]; #ifdef CSG_DEBUG_OUTPUT // auto basis = p.MakeBasis(); - // for (auto& segment : contours) // { - // edges.push_back({ basis.project(sp.points[segment.first].location3D), basis.project(sp.points[segment.second].location3D) }); + // edges.push_back({ basis.project(sp.points[segment.first].location3D), basis.project(sp.points[segment.second].location3D) }); // } // DumpSVGLines(edges, L"contour_B.html"); #endif - - for (auto &segment : contours) + for (auto& segment : contours) { auto lineId = sp.planes[planeId].AddLine(sp.points[segment.first], sp.points[segment.second]); } } - // put all points on lines/planes - for (auto &p : sp.points) + for (auto& p : sp.points) { - for (auto &plane : sp.planes) + for (auto& plane : sp.planes) { if (plane.IsPointOnPlane(p.location3D)) { @@ -1809,43 +1398,31 @@ namespace fuzzybools } } } - - for (auto &plane : sp.planes) - { - AddLineLineIsects(plane, sp); - } - // intersect planes for (size_t planeAIndex = 0; planeAIndex < sp.planes.size(); planeAIndex++) { - for (size_t planeBIndex = 0; planeBIndex < sp.planes.size(); planeBIndex++) + for (size_t planeBIndex = planeAIndex + 1; planeBIndex < sp.planes.size(); planeBIndex++) { - auto &planeA = sp.planes[planeAIndex]; - auto &planeB = sp.planes[planeBIndex]; - + auto& planeA = sp.planes[planeAIndex]; + auto& planeB = sp.planes[planeBIndex]; if (!planeA.aabb.intersects(planeB.aabb)) { continue; } - // plane intersect results in new lines // new lines result in new line intersects // new line intersects result in new points - if (std::fabs(glm::dot(planeA.normal, planeB.normal)) > 1.0 - EPS_BIG) { // parallel planes, don't care continue; } - // calculate plane intersection line auto result = PlanePlaneIsect(planeA.normal, planeA.distance, planeB.normal, planeB.distance); - // TODO: invalid temp line object Line intersectionLine; intersectionLine.origin = result.pos; intersectionLine.direction = result.dir; - if (!planeA.IsPointOnPlane(intersectionLine.origin) || !planeA.IsPointOnPlane(intersectionLine.origin + intersectionLine.direction * 1000.)) { if (messages) @@ -1860,14 +1437,11 @@ namespace fuzzybools printf("Bad isect line in Normalize\n"); } } - // get all intersection points with the shared line and both planes auto isectA = ComputeInitialIntersections(planeA, sp, intersectionLine); auto isectB = ComputeInitialIntersections(planeB, sp, intersectionLine); - // from these, figure out the shared segments on the current line produced by these two planes auto segments = sp.BuildSegments(isectA, isectB); - if (segments.empty()) { // nothing resulted from this plane-plane intersection @@ -1880,15 +1454,13 @@ namespace fuzzybools } } } - - for (auto &plane : sp.planes) + for (auto& plane : sp.planes) { AddLineLineIsects(plane, sp); } - - for (auto &p : sp.points) + for (auto& p : sp.points) { - for (auto &plane : sp.planes) + for (auto& plane : sp.planes) { if (plane.IsPointOnPlane(p.location3D)) { @@ -1896,53 +1468,42 @@ namespace fuzzybools } } } - // from the inserted geometries, all lines planes and points are now merged into a single set of shared planes lines and points // from this starting point, we can triangulate all planes and obtain the triangulation of the intersected set of geometries // this mesh itself is not a boolean result, but rather a merging of all operands - Geometry geom; - for (auto &plane : sp.planes) + for (auto& plane : sp.planes) { - #ifdef CSG_DEBUG_OUTPUT // std::vector> edges; - // auto basis = plane.MakeBasis(); - // for (auto& line : plane.lines) { - // // Get line parameters - // auto origin = line.origin; // 3D point (glm::dvec3) - // auto direction = line.direction; // 3D vector (glm::dvec3) - - // // Convert each distance to a 3D point along the line - // std::vector lineSegments; - // for (auto distance : line.points) { - // glm::dvec3 point3D = origin + glm::dvec3(direction.x * distance.first, direction.y * distance.first, direction.z * distance.first); // 3D calculation - // glm::dvec2 point2D = basis.project(point3D); // Project to 2D - // lineSegments.push_back(point2D); - // } - - // // Create edges between consecutive points - // for (size_t i = 0; i < lineSegments.size() - 1; ++i) { - // edges.push_back({ - // lineSegments[i], - // lineSegments[i + 1] - // }); - // } + // // Get line parameters + // auto origin = line.origin; // 3D point (glm::dvec3) + // auto direction = line.direction; // 3D vector (glm::dvec3) + // // Convert each distance to a 3D point along the line + // std::vector lineSegments; + // for (auto distance : line.points) { + // glm::dvec3 point3D = origin + glm::dvec3(direction.x * distance.first, direction.y * distance.first, direction.z * distance.first); // 3D calculation + // glm::dvec2 point2D = basis.project(point3D); // Project to 2D + // lineSegments.push_back(point2D); + // } + // // Create edges between consecutive points + // for (size_t i = 0; i < lineSegments.size() - 1; ++i) { + // edges.push_back({ + // lineSegments[i], + // lineSegments[i + 1] + // }); + // } // } - // DumpSVGLines(edges, L"contour.html"); #endif - sp.TriangulatePlane(geom, plane); - #ifdef CSG_DEBUG_OUTPUT // DumpGeometry(geom, L"triangulated.obj"); #endif } - - for (auto &plane : A.planes) + for (auto& plane : A.planes) { SimplePlane p; p.normal = plane.normal; @@ -1950,8 +1511,7 @@ namespace fuzzybools geom.planes.push_back(p); geom.hasPlanes = true; } - - for (auto &plane : B.planes) + for (auto& plane : B.planes) { SimplePlane p; p.normal = plane.normal; @@ -1959,60 +1519,45 @@ namespace fuzzybools geom.planes.push_back(p); geom.hasPlanes = true; } - uint32_t offsetA = A.planes.size(); - // re-add irrelevant faces that should be tested - for (auto &faceIndex : sp.A.irrelevantFaces_toTest) + for (auto& faceIndex : sp.A.irrelevantFaces_toTest) { - const Face &f = sp._linkedA->GetFace(faceIndex); - + const Face& f = sp._linkedA->GetFace(faceIndex); auto a = sp._linkedA->GetPoint(f.i0); auto b = sp._linkedA->GetPoint(f.i1); auto c = sp._linkedA->GetPoint(f.i2); - geom.AddFace(a, b, c, f.pId); } - - for (auto &faceIndex : sp.B.irrelevantFaces_toTest) + for (auto& faceIndex : sp.B.irrelevantFaces_toTest) { - const Face &f = sp._linkedB->GetFace(faceIndex); - + const Face& f = sp._linkedB->GetFace(faceIndex); auto a = sp._linkedB->GetPoint(f.i0); auto b = sp._linkedB->GetPoint(f.i1); auto c = sp._linkedB->GetPoint(f.i2); - geom.AddFace(a, b, c, f.pId + offsetA); } - geom.data = geom.numFaces; - // re-add irrelevant faces - for (auto &faceIndex : sp.A.irrelevantFaces) + for (auto& faceIndex : sp.A.irrelevantFaces) { - const Face &f = sp._linkedA->GetFace(faceIndex); - + const Face& f = sp._linkedA->GetFace(faceIndex); auto a = sp._linkedA->GetPoint(f.i0); auto b = sp._linkedA->GetPoint(f.i1); auto c = sp._linkedA->GetPoint(f.i2); - geom.AddFace(a, b, c, f.pId); } - if (UNION) { - for (auto &faceIndex : sp.B.irrelevantFaces) + for (auto& faceIndex : sp.B.irrelevantFaces) { - const Face &f = sp._linkedB->GetFace(faceIndex); - + const Face& f = sp._linkedB->GetFace(faceIndex); auto a = sp._linkedB->GetPoint(f.i0); auto b = sp._linkedB->GetPoint(f.i1); auto c = sp._linkedB->GetPoint(f.i2); - geom.AddFace(a, b, c, f.pId + offsetA); } } - return geom; } -} +} \ No newline at end of file diff --git a/src/cpp/web-ifc/geometry/operations/geometryutils.h b/src/cpp/web-ifc/geometry/operations/geometryutils.h index 31c371e90..5b33ce449 100644 --- a/src/cpp/web-ifc/geometry/operations/geometryutils.h +++ b/src/cpp/web-ifc/geometry/operations/geometryutils.h @@ -16,6 +16,7 @@ #include #include #include +#include #include "../representation/geometry.h" #include "../representation/IfcGeometry.h" #include @@ -117,76 +118,61 @@ namespace webifc::geometry return bimGeometry::computeSafeNormal(v1, v2, v3, normal, eps); } - inline bool GetBasisFromCoplanarPoints(std::vector &points, glm::dvec3 &v1, glm::dvec3 &v2, glm::dvec3 &v3) + inline bool GetBasisFromCoplanarPoints( + const std::vector& points, + glm::dvec3& v1, + glm::dvec3& v2, + glm::dvec3& v3 + ) { + if (points.size() < 3) { + // Need at least three points to define a plane (basis) + return false; + } + v1 = points[0]; - for (auto &p : points) - { - if (v1 != p) - { - v2 = p; + // --- 1. Find the second distinct point (v2) --- + bool v2_found = false; + for (size_t i = 1; i < points.size(); ++i) { + if (glm::distance2(v1, points[i]) > EPS_SMALL * EPS_SMALL) { + v2 = points[i]; + v2_found = true; break; } } - - glm::dvec3 normal; - // multiple tries to find the best match - for (double i = 0; i < 4; i++) - { - double EPS = EPS_SMALL; - if (i == 0) - { - EPS = 100; - } - if (i == 1) - { - EPS = 1; - } - if (i == 2) - { - EPS = 0.01; - } - if (i == 3) - { - EPS = 1e-03; - } - for (auto &p : points) - { - if (computeSafeNormal(v1, v2, p, normal, EPS)) - { - v3 = p; - return true; - } - } + if (!v2_found) { + // All points are identical + return false; } - double d1 = 0; + // --- 2. Search for the third non-collinear point (v3) --- + glm::dvec3 v1v2 = v2 - v1; - for (auto &p : points) - { - double d2 = glm::distance(v1, p); - if (d1 < d2) - { - d1 = d2; - v2 = p; + // Use a robust check for collinearity: check the area of the triangle (v1, v2, p) + for (size_t i = 1; i < points.size(); ++i) { + const glm::dvec3& p = points[i]; + + // Skip v1 and v2, though the check below should handle them correctly + if (glm::distance2(v1, p) < EPS_SMALL * EPS_SMALL || glm::distance2(v2, p) < EPS_SMALL * EPS_SMALL) { + continue; } - } - d1 = 0; - for (auto &p : points) - { - double d2 = glm::distance(v1, p); - double d3 = glm::distance(v2, p); - if (d1 < d2 + d3) - { - d1 = d2 + d3; + glm::dvec3 v1p = p - v1; + + // Check if the cross product is significant (meaning the points are not collinear) + glm::dvec3 cross_product = glm::cross(v1v2, v1p); + + // Use a small, fixed tolerance (e.g., 1e-12) for the square of the cross product magnitude. + if (glm::length2(cross_product) > 1e-12) { v3 = p; + return true; } } - // multiple tries to find the best match - return computeSafeNormal(v1, v2, v3, normal, 1e-08); + // --- 3. Fallback: No three non-collinear points found --- + // All points are either identical or collinear. + return false; } inline void TriangulateBounds(IfcGeometry& geometry, std::vector& bounds, uint32_t expressID) diff --git a/yarn.lock b/yarn.lock index 07da5c611..b032a3b3f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz" integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg== -"@babel/core@^7.23.9", "@babel/core@^7.27.4": +"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.0 || ^8.0.0-0", "@babel/core@^7.11.0 || ^8.0.0-beta.1", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@>=7.0.0-beta.0 <8": version "7.28.6" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz" integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw== @@ -290,158 +290,11 @@ resolved "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz" integrity sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow== -"@emnapi/core@^1.4.3": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.8.1.tgz#fd9efe721a616288345ffee17a1f26ac5dd01349" - integrity sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg== - dependencies: - "@emnapi/wasi-threads" "1.1.0" - tslib "^2.4.0" - -"@emnapi/runtime@^1.4.3": - version "1.8.1" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.8.1.tgz#550fa7e3c0d49c5fb175a116e8cd70614f9a22a5" - integrity sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf" - integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ== - dependencies: - tslib "^2.4.0" - -"@esbuild/aix-ppc64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz#521cbd968dcf362094034947f76fa1b18d2d403c" - integrity sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw== - -"@esbuild/android-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz#61ea550962d8aa12a9b33194394e007657a6df57" - integrity sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA== - -"@esbuild/android-arm@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.27.2.tgz#554887821e009dd6d853f972fde6c5143f1de142" - integrity sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA== - -"@esbuild/android-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.27.2.tgz#a7ce9d0721825fc578f9292a76d9e53334480ba2" - integrity sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A== - -"@esbuild/darwin-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz" - integrity sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg== - -"@esbuild/darwin-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz#e741fa6b1abb0cd0364126ba34ca17fd5e7bf509" - integrity sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA== - -"@esbuild/freebsd-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz#2b64e7116865ca172d4ce034114c21f3c93e397c" - integrity sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g== - -"@esbuild/freebsd-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz#e5252551e66f499e4934efb611812f3820e990bb" - integrity sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA== - -"@esbuild/linux-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz#dc4acf235531cd6984f5d6c3b13dbfb7ddb303cb" - integrity sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw== - -"@esbuild/linux-arm@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz#56a900e39240d7d5d1d273bc053daa295c92e322" - integrity sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw== - -"@esbuild/linux-ia32@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz#d4a36d473360f6870efcd19d52bbfff59a2ed1cc" - integrity sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w== - -"@esbuild/linux-loong64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz#fcf0ab8c3eaaf45891d0195d4961cb18b579716a" - integrity sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg== - -"@esbuild/linux-mips64el@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz#598b67d34048bb7ee1901cb12e2a0a434c381c10" - integrity sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw== - -"@esbuild/linux-ppc64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz#3846c5df6b2016dab9bc95dde26c40f11e43b4c0" - integrity sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ== - -"@esbuild/linux-riscv64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz#173d4475b37c8d2c3e1707e068c174bb3f53d07d" - integrity sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA== - -"@esbuild/linux-s390x@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz#f7a4790105edcab8a5a31df26fbfac1aa3dacfab" - integrity sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w== - "@esbuild/linux-x64@0.27.2": version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz#2ecc1284b1904aeb41e54c9ddc7fcd349b18f650" + resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz" integrity sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA== -"@esbuild/netbsd-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz#e2863c2cd1501845995cb11adf26f7fe4be527b0" - integrity sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw== - -"@esbuild/netbsd-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz#93f7609e2885d1c0b5a1417885fba8d1fcc41272" - integrity sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA== - -"@esbuild/openbsd-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz#a1985604a203cdc325fd47542e106fafd698f02e" - integrity sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA== - -"@esbuild/openbsd-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz#8209e46c42f1ffbe6e4ef77a32e1f47d404ad42a" - integrity sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg== - -"@esbuild/openharmony-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz#8fade4441893d9cc44cbd7dcf3776f508ab6fb2f" - integrity sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag== - -"@esbuild/sunos-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz#980d4b9703a16f0f07016632424fc6d9a789dfc2" - integrity sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg== - -"@esbuild/win32-arm64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz#1c09a3633c949ead3d808ba37276883e71f6111a" - integrity sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg== - -"@esbuild/win32-ia32@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz#1b1e3a63ad4bef82200fef4e369e0fff7009eee5" - integrity sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ== - -"@esbuild/win32-x64@0.27.2": - version "0.27.2" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz#9e585ab6086bef994c6e8a5b3a0481219ada862b" - integrity sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ== - "@gerrit0/mini-shiki@^3.17.0": version "3.21.0" resolved "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.21.0.tgz" @@ -684,7 +537,7 @@ jest-haste-map "30.2.0" slash "^3.0.0" -"@jest/transform@30.2.0": +"@jest/transform@^29.0.0 || ^30.0.0", "@jest/transform@30.2.0": version "30.2.0" resolved "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz" integrity sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA== @@ -705,7 +558,7 @@ slash "^3.0.0" write-file-atomic "^5.0.1" -"@jest/types@30.2.0": +"@jest/types@^29.0.0 || ^30.0.0", "@jest/types@30.2.0": version "30.2.0" resolved "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz" integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg== @@ -744,14 +597,6 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": version "0.3.31" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" @@ -760,6 +605,14 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@koa/cors@^5.0.0": version "5.0.0" resolved "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz" @@ -767,15 +620,6 @@ dependencies: vary "^1.1.2" -"@napi-rs/wasm-runtime@^0.2.11": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" - integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== - dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@tybys/wasm-util" "^0.10.0" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -784,7 +628,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": +"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -829,7 +673,7 @@ dependencies: "@shikijs/types" "3.21.0" -"@shikijs/types@3.21.0", "@shikijs/types@^3.21.0": +"@shikijs/types@^3.21.0", "@shikijs/types@3.21.0": version "3.21.0" resolved "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz" integrity sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA== @@ -891,13 +735,6 @@ resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz" integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA== -"@tybys/wasm-util@^0.10.0": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" - integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== - dependencies: - tslib "^2.4.0" - "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -967,7 +804,7 @@ "@types/node@*": version "25.0.8" - resolved "https://registry.yarnpkg.com/@types/node/-/node-25.0.8.tgz#e54e00f94fe1db2497b3e42d292b8376a2678c8d" + resolved "https://registry.npmjs.org/@types/node/-/node-25.0.8.tgz" integrity sha512-powIePYMmC3ibL0UJ2i2s0WIbq6cg6UyVFQxSCpaPxxzAaziRfimGivjdF943sSGV6RADVbk0Nvlm5P/FB44Zg== dependencies: undici-types "~7.16.0" @@ -1022,116 +859,21 @@ resolved "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz" integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== -"@unrs/resolver-binding-android-arm-eabi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz#9f5b04503088e6a354295e8ea8fe3cb99e43af81" - integrity sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw== - -"@unrs/resolver-binding-android-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz#7414885431bd7178b989aedc4d25cccb3865bc9f" - integrity sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g== - -"@unrs/resolver-binding-darwin-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz" - integrity sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g== - -"@unrs/resolver-binding-darwin-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz#fd4d81257b13f4d1a083890a6a17c00de571f0dc" - integrity sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ== - -"@unrs/resolver-binding-freebsd-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz#d2513084d0f37c407757e22f32bd924a78cfd99b" - integrity sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz#844d2605d057488d77fab09705f2866b86164e0a" - integrity sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz#204892995cefb6bd1d017d52d097193bc61ddad3" - integrity sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw== - -"@unrs/resolver-binding-linux-arm64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz#023eb0c3aac46066a10be7a3f362e7b34f3bdf9d" - integrity sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ== - -"@unrs/resolver-binding-linux-arm64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz#9e6f9abb06424e3140a60ac996139786f5d99be0" - integrity sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz#b111417f17c9d1b02efbec8e08398f0c5527bb44" - integrity sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz#92ffbf02748af3e99873945c9a8a5ead01d508a9" - integrity sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ== - -"@unrs/resolver-binding-linux-riscv64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz#0bec6f1258fc390e6b305e9ff44256cb207de165" - integrity sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew== - -"@unrs/resolver-binding-linux-s390x-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz#577843a084c5952f5906770633ccfb89dac9bc94" - integrity sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg== - "@unrs/resolver-binding-linux-x64-gnu@1.11.1": version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz#36fb318eebdd690f6da32ac5e0499a76fa881935" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz" integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w== "@unrs/resolver-binding-linux-x64-musl@1.11.1": version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz#bfb9af75f783f98f6a22c4244214efe4df1853d6" + resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz" integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== -"@unrs/resolver-binding-wasm32-wasi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" - integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== - dependencies: - "@napi-rs/wasm-runtime" "^0.2.11" - -"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" - integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== - -"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" - integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== - -"@unrs/resolver-binding-win32-x64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" - integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== - "@webgpu/types@*": version "0.1.69" - resolved "https://registry.yarnpkg.com/@webgpu/types/-/types-0.1.69.tgz#6b849bf370a1f29c78bd3aeba8e84c1150b237f2" + resolved "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz" integrity sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ== -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - accepts@^1.3.5, accepts@~1.3.4: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" @@ -1260,7 +1002,7 @@ arrify@^3.0.0: resolved "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz" integrity sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw== -babel-jest@30.2.0: +"babel-jest@^29.0.0 || ^30.0.0", babel-jest@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz" integrity sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw== @@ -1364,7 +1106,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0: +browserslist@^4.24.0, "browserslist@>= 4.21.0": version "4.28.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz" integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== @@ -1659,20 +1401,13 @@ current-module-paths@^1.1.1: resolved "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.3.tgz" integrity sha512-7AH+ZTRKikdK4s1RmY0l6067UD/NZc7p3zZVZxvmnH80G31kr0y0W0E6ibYM4IS01MEm8DiC5FnTcgcgkbFHoA== -debug@*, debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: +debug@*, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@4: version "4.4.3" resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: ms "^2.1.3" -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - debug@^3.1.0: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" @@ -1680,6 +1415,13 @@ debug@^3.1.0: dependencies: ms "^2.1.1" +debug@2.6.9: + version "2.6.9" + resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + dedent@^1.6.0: version "1.7.1" resolved "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz" @@ -1857,16 +1599,16 @@ escape-html@^1.0.3, escape-html@~1.0.3: resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" - integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== - escape-string-regexp@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== +escape-string-regexp@5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" @@ -1897,7 +1639,7 @@ exit-x@^0.2.2: resolved "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz" integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ== -expect@30.2.0, expect@^30.0.0: +expect@^30.0.0, expect@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz" integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw== @@ -1920,7 +1662,7 @@ fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.8" -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: +fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -1982,11 +1724,6 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== -fsevents@^2.3.3: - version "2.3.3" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - function-bind@^1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" @@ -2248,7 +1985,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@~2.0.3, inherits@~2.0.4: +inherits@~2.0.3, inherits@~2.0.4, inherits@2, inherits@2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2589,7 +2326,7 @@ jest-resolve-dependencies@30.2.0: jest-regex-util "30.0.1" jest-snapshot "30.2.0" -jest-resolve@30.2.0: +jest-resolve@*, jest-resolve@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz" integrity sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A== @@ -2686,7 +2423,7 @@ jest-snapshot@30.2.0: semver "^7.7.2" synckit "^0.11.8" -jest-util@30.2.0: +"jest-util@^29.0.0 || ^30.0.0", jest-util@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz" integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA== @@ -2735,7 +2472,7 @@ jest-worker@30.2.0: merge-stream "^2.0.0" supports-color "^8.1.1" -jest@^30.0.3: +"jest@^29.0.0 || ^30.0.0", jest@^30.0.3: version "30.2.0" resolved "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz" integrity sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A== @@ -2783,6 +2520,14 @@ jsonparse@^1.2.0: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + junk@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz" @@ -2839,7 +2584,7 @@ koa-etag@^4.0.0: dependencies: etag "^1.8.1" -koa-is-json@1, koa-is-json@^1.0.0: +koa-is-json@^1.0.0, koa-is-json@1: version "1.0.0" resolved "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz" integrity sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw== @@ -3244,16 +2989,16 @@ micromatch@^4.0.5, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - "mime-db@>= 1.43.0 < 2": version "1.54.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.1.18, mime-types@~2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" @@ -3308,16 +3053,16 @@ morgan@^1.6.1: on-finished "~2.3.0" on-headers "~1.1.0" -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + napi-postinstall@^0.3.0: version "0.3.4" resolved "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz" @@ -3499,7 +3244,7 @@ path-exists@^4.0.0: resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@1.0.1, path-is-absolute@^1.0.0: +path-is-absolute@^1.0.0, path-is-absolute@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== @@ -3562,7 +3307,7 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pretty-format@30.2.0, pretty-format@^30.0.0: +pretty-format@^30.0.0, pretty-format@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz" integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA== @@ -3681,7 +3426,17 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: +safe-buffer@~5.1.0: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.1.2: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -3710,7 +3465,22 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3, semver@^7.5.4, semver@^7.7.2, semver@^7.7.3: +semver@^7.5.3: + version "7.7.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + +semver@^7.5.4: + version "7.7.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + +semver@^7.7.2: + version "7.7.3" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" + integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== + +semver@^7.7.3: version "7.7.3" resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== @@ -3728,16 +3498,16 @@ serve-index-75lb@^2.0.1: mime-types "~2.1.18" parseurl "~1.3.2" +setprototypeof@~1.2.0, setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.2.0, setprototypeof@~1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -3835,7 +3605,7 @@ stack-utils@^2.0.6: dependencies: escape-string-regexp "^2.0.0" -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: +statuses@^1.5.0, "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== @@ -3850,10 +3620,10 @@ stream-log-stats@^3.0.2: resolved "https://registry.npmjs.org/stream-log-stats/-/stream-log-stats-3.0.2.tgz" integrity sha512-393j7aeF9iRdHvyANqEQU82UQmpw2CTxgsT83caefh+lOxavVLbVrw8Mr4zjXeZLh2+xeHZMKfVx4T0rJ/EchA== dependencies: - JSONStream "^1.3.5" ansi-escape-sequences "^5.1.2" byte-size "^6.2.0" common-log-format "^1.0.0" + JSONStream "^1.3.5" lodash.throttle "^4.1.1" stream-via "^1.0.4" table-layout "~1.0.0" @@ -3876,6 +3646,13 @@ streaming-json-stringify@3: json-stringify-safe "5" readable-stream "2" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + string-length@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -3893,7 +3670,16 @@ string-length@^4.0.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3911,13 +3697,6 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -4024,7 +3803,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.1, toidentifier@~1.0.1: +toidentifier@~1.0.1, toidentifier@1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -4044,7 +3823,7 @@ ts-jest@^29.3.2: type-fest "^4.41.0" yargs-parser "^21.1.1" -ts-node@^10.9.2: +ts-node@^10.9.2, ts-node@>=9.0.0: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -4063,11 +3842,6 @@ ts-node@^10.9.2: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^2.4.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - tsscmp@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz" @@ -4107,7 +3881,7 @@ typedoc@^0.28.3: minimatch "^9.0.5" yaml "^2.8.1" -typescript@^5.8.3: +typescript@^5.8.3, typescript@>=2.7, "typescript@>=4.3 <6", "typescript@5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x": version "5.9.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== From 0187bad4568f1cb49487298fecef6e2b387ebd1f Mon Sep 17 00:00:00 2001 From: Tom Beach Date: Fri, 23 Jan 2026 09:28:12 +0000 Subject: [PATCH 2/2] Fix --- yarn.lock | 272 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 163 insertions(+), 109 deletions(-) diff --git a/yarn.lock b/yarn.lock index e74785cb2..4aab824a8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,7 +24,7 @@ resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz" integrity sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg== -"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.0 || ^8.0.0-0", "@babel/core@^7.11.0 || ^8.0.0-beta.1", "@babel/core@^7.23.9", "@babel/core@^7.27.4", "@babel/core@>=7.0.0-beta.0 <8": +"@babel/core@^7.23.9", "@babel/core@^7.27.4": version "7.28.6" resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz" integrity sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw== @@ -397,6 +397,51 @@ resolved "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz" integrity sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA== +"@esbuild/netbsd-arm64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz#e2863c2cd1501845995cb11adf26f7fe4be527b0" + integrity sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw== + +"@esbuild/netbsd-x64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz#93f7609e2885d1c0b5a1417885fba8d1fcc41272" + integrity sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA== + +"@esbuild/openbsd-arm64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz#a1985604a203cdc325fd47542e106fafd698f02e" + integrity sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA== + +"@esbuild/openbsd-x64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz#8209e46c42f1ffbe6e4ef77a32e1f47d404ad42a" + integrity sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg== + +"@esbuild/openharmony-arm64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz#8fade4441893d9cc44cbd7dcf3776f508ab6fb2f" + integrity sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag== + +"@esbuild/sunos-x64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz#980d4b9703a16f0f07016632424fc6d9a789dfc2" + integrity sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg== + +"@esbuild/win32-arm64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz#1c09a3633c949ead3d808ba37276883e71f6111a" + integrity sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg== + +"@esbuild/win32-ia32@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz#1b1e3a63ad4bef82200fef4e369e0fff7009eee5" + integrity sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ== + +"@esbuild/win32-x64@0.27.2": + version "0.27.2" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz#9e585ab6086bef994c6e8a5b3a0481219ada862b" + integrity sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ== + "@gerrit0/mini-shiki@^3.17.0": version "3.21.0" resolved "https://registry.npmjs.org/@gerrit0/mini-shiki/-/mini-shiki-3.21.0.tgz" @@ -639,7 +684,7 @@ jest-haste-map "30.2.0" slash "^3.0.0" -"@jest/transform@^29.0.0 || ^30.0.0", "@jest/transform@30.2.0": +"@jest/transform@30.2.0": version "30.2.0" resolved "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz" integrity sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA== @@ -660,7 +705,7 @@ slash "^3.0.0" write-file-atomic "^5.0.1" -"@jest/types@^29.0.0 || ^30.0.0", "@jest/types@30.2.0": +"@jest/types@30.2.0": version "30.2.0" resolved "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz" integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg== @@ -699,14 +744,6 @@ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz" integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": - version "0.3.31" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@jridgewell/trace-mapping@0.3.9": version "0.3.9" resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz" @@ -715,6 +752,14 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + "@koa/cors@^5.0.0": version "5.0.0" resolved "https://registry.npmjs.org/@koa/cors/-/cors-5.0.0.tgz" @@ -722,6 +767,15 @@ dependencies: vary "^1.1.2" +"@napi-rs/wasm-runtime@^0.2.11": + version "0.2.12" + resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" + integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== + dependencies: + "@emnapi/core" "^1.4.3" + "@emnapi/runtime" "^1.4.3" + "@tybys/wasm-util" "^0.10.0" + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" @@ -730,7 +784,7 @@ "@nodelib/fs.stat" "2.0.5" run-parallel "^1.1.9" -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": version "2.0.5" resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== @@ -775,7 +829,7 @@ dependencies: "@shikijs/types" "3.21.0" -"@shikijs/types@^3.21.0", "@shikijs/types@3.21.0": +"@shikijs/types@3.21.0", "@shikijs/types@^3.21.0": version "3.21.0" resolved "https://registry.npmjs.org/@shikijs/types/-/types-3.21.0.tgz" integrity sha512-zGrWOxZ0/+0ovPY7PvBU2gIS9tmhSUUt30jAcNV0Bq0gb2S98gwfjIs1vxlmH5zM7/4YxLamT6ChlqqAJmPPjA== @@ -837,6 +891,13 @@ resolved "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz" integrity sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA== +"@tybys/wasm-util@^0.10.0": + version "0.10.1" + resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" + integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== + dependencies: + tslib "^2.4.0" + "@types/babel__core@^7.20.5": version "7.20.5" resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz" @@ -1036,11 +1097,41 @@ resolved "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz" integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== +"@unrs/resolver-binding-wasm32-wasi@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" + integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== + dependencies: + "@napi-rs/wasm-runtime" "^0.2.11" + +"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" + integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== + +"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" + integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== + +"@unrs/resolver-binding-win32-x64-msvc@1.11.1": + version "1.11.1" + resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" + integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== + "@webgpu/types@*": version "0.1.69" resolved "https://registry.npmjs.org/@webgpu/types/-/types-0.1.69.tgz" integrity sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ== +JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + accepts@^1.3.5, accepts@~1.3.4: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" @@ -1169,7 +1260,7 @@ arrify@^3.0.0: resolved "https://registry.npmjs.org/arrify/-/arrify-3.0.0.tgz" integrity sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw== -"babel-jest@^29.0.0 || ^30.0.0", babel-jest@30.2.0: +babel-jest@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-30.2.0.tgz" integrity sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw== @@ -1273,7 +1364,7 @@ braces@^3.0.3: dependencies: fill-range "^7.1.1" -browserslist@^4.24.0, "browserslist@>= 4.21.0": +browserslist@^4.24.0: version "4.28.1" resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz" integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== @@ -1568,20 +1659,13 @@ current-module-paths@^1.1.1: resolved "https://registry.npmjs.org/current-module-paths/-/current-module-paths-1.1.3.tgz" integrity sha512-7AH+ZTRKikdK4s1RmY0l6067UD/NZc7p3zZVZxvmnH80G31kr0y0W0E6ibYM4IS01MEm8DiC5FnTcgcgkbFHoA== -debug@*, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@4: +debug@*, debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: version "4.4.3" resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== dependencies: ms "^2.1.3" -debug@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - debug@2.6.9: version "2.6.9" resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" @@ -1589,6 +1673,13 @@ debug@2.6.9: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + dedent@^1.6.0: version "1.7.1" resolved "https://registry.npmjs.org/dedent/-/dedent-1.7.1.tgz" @@ -1766,16 +1857,16 @@ escape-html@^1.0.3, escape-html@~1.0.3: resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - escape-string-regexp@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + esprima@^4.0.0: version "4.0.1" resolved "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz" @@ -1806,7 +1897,7 @@ exit-x@^0.2.2: resolved "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz" integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ== -expect@^30.0.0, expect@30.2.0: +expect@30.2.0, expect@^30.0.0: version "30.2.0" resolved "https://registry.npmjs.org/expect/-/expect-30.2.0.tgz" integrity sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw== @@ -1829,7 +1920,7 @@ fast-glob@^3.3.0: merge2 "^1.3.0" micromatch "^4.0.8" -fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x: +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== @@ -2157,7 +2248,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@~2.0.3, inherits@~2.0.4, inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -2498,7 +2589,7 @@ jest-resolve-dependencies@30.2.0: jest-regex-util "30.0.1" jest-snapshot "30.2.0" -jest-resolve@*, jest-resolve@30.2.0: +jest-resolve@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.2.0.tgz" integrity sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A== @@ -2595,7 +2686,7 @@ jest-snapshot@30.2.0: semver "^7.7.2" synckit "^0.11.8" -"jest-util@^29.0.0 || ^30.0.0", jest-util@30.2.0: +jest-util@30.2.0: version "30.2.0" resolved "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz" integrity sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA== @@ -2644,7 +2735,7 @@ jest-worker@30.2.0: merge-stream "^2.0.0" supports-color "^8.1.1" -"jest@^29.0.0 || ^30.0.0", jest@^30.0.3: +jest@^30.0.3: version "30.2.0" resolved "https://registry.npmjs.org/jest/-/jest-30.2.0.tgz" integrity sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A== @@ -2692,14 +2783,6 @@ jsonparse@^1.2.0: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - junk@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/junk/-/junk-4.0.1.tgz" @@ -2756,7 +2839,7 @@ koa-etag@^4.0.0: dependencies: etag "^1.8.1" -koa-is-json@^1.0.0, koa-is-json@1: +koa-is-json@1, koa-is-json@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/koa-is-json/-/koa-is-json-1.0.0.tgz" integrity sha512-+97CtHAlWDx0ndt0J8y3P12EWLwTLMXIfMnYDev3wOTwH/RpBGMlfn4bDXlMEg1u73K6XRE9BbUp+5ZAYoRYWw== @@ -3161,16 +3244,16 @@ micromatch@^4.0.5, micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== +"mime-db@>= 1.43.0 < 2": + version "1.54.0" + resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" + integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== + mime-types@^2.1.18, mime-types@~2.1.18, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" @@ -3225,16 +3308,16 @@ morgan@^1.6.1: on-finished "~2.3.0" on-headers "~1.1.0" -ms@^2.1.1, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== +ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + napi-postinstall@^0.3.0: version "0.3.4" resolved "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz" @@ -3416,7 +3499,7 @@ path-exists@^4.0.0: resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== -path-is-absolute@^1.0.0, path-is-absolute@1.0.1: +path-is-absolute@1.0.1, path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== @@ -3479,7 +3562,7 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pretty-format@^30.0.0, pretty-format@30.2.0: +pretty-format@30.2.0, pretty-format@^30.0.0: version "30.2.0" resolved "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz" integrity sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA== @@ -3598,17 +3681,7 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -safe-buffer@~5.1.0: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.1.2: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -3637,22 +3710,7 @@ semver@^6.3.1: resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.5.3: - version "7.7.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - -semver@^7.5.4: - version "7.7.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - -semver@^7.7.2: - version "7.7.3" - resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - -semver@^7.7.3: +semver@^7.5.3, semver@^7.5.4, semver@^7.7.2, semver@^7.7.3: version "7.7.3" resolved "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz" integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== @@ -3670,16 +3728,16 @@ serve-index-75lb@^2.0.1: mime-types "~2.1.18" parseurl "~1.3.2" -setprototypeof@~1.2.0, setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== +setprototypeof@1.2.0, setprototypeof@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -3777,7 +3835,7 @@ stack-utils@^2.0.6: dependencies: escape-string-regexp "^2.0.0" -statuses@^1.5.0, "statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2": +"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@^1.5.0: version "1.5.0" resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== @@ -3792,10 +3850,10 @@ stream-log-stats@^3.0.2: resolved "https://registry.npmjs.org/stream-log-stats/-/stream-log-stats-3.0.2.tgz" integrity sha512-393j7aeF9iRdHvyANqEQU82UQmpw2CTxgsT83caefh+lOxavVLbVrw8Mr4zjXeZLh2+xeHZMKfVx4T0rJ/EchA== dependencies: + JSONStream "^1.3.5" ansi-escape-sequences "^5.1.2" byte-size "^6.2.0" common-log-format "^1.0.0" - JSONStream "^1.3.5" lodash.throttle "^4.1.1" stream-via "^1.0.4" table-layout "~1.0.0" @@ -3818,13 +3876,6 @@ streaming-json-stringify@3: json-stringify-safe "5" readable-stream "2" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - string-length@^4.0.2: version "4.0.2" resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz" @@ -3842,16 +3893,7 @@ string-length@^4.0.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.2.3: +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -3869,6 +3911,13 @@ string-width@^5.0.1, string-width@^5.1.2: emoji-regex "^9.2.2" strip-ansi "^7.0.1" +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + "strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" @@ -3975,7 +4024,7 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@~1.0.1, toidentifier@1.0.1: +toidentifier@1.0.1, toidentifier@~1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== @@ -3995,7 +4044,7 @@ ts-jest@^29.3.2: type-fest "^4.41.0" yargs-parser "^21.1.1" -ts-node@^10.9.2, ts-node@>=9.0.0: +ts-node@^10.9.2: version "10.9.2" resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz" integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ== @@ -4014,6 +4063,11 @@ ts-node@^10.9.2, ts-node@>=9.0.0: v8-compile-cache-lib "^3.0.1" yn "3.1.1" +tslib@^2.4.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + tsscmp@1.0.6: version "1.0.6" resolved "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz" @@ -4053,7 +4107,7 @@ typedoc@^0.28.3: minimatch "^9.0.5" yaml "^2.8.1" -typescript@^5.8.3, typescript@>=2.7, "typescript@>=4.3 <6", "typescript@5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x": +typescript@^5.8.3: version "5.9.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz" integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==