@itwin/rpcinterface-full-stack-tests 4.4.0-dev.16 → 4.4.0-dev.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/dist/_bea9.bundled-tests.js.map +1 -1
- package/lib/dist/bundled-tests.js +228 -194
- package/lib/dist/bundled-tests.js.map +1 -1
- package/lib/dist/core_frontend_lib_esm_ApproximateTerrainHeightsProps_js.bundled-tests.js.map +1 -1
- package/lib/dist/vendors-common_temp_node_modules_pnpm_loaders_gl_draco_3_1_6_node_modules_loaders_gl_draco_di-0642a6.bundled-tests.js.map +1 -1
- package/package.json +13 -13
|
@@ -255343,6 +255343,22 @@ class Sample {
|
|
|
255343
255343
|
}
|
|
255344
255344
|
}
|
|
255345
255345
|
}
|
|
255346
|
+
/** Create a point on the polar parametric curve r = cos(a * theta), aka "rose".
|
|
255347
|
+
* @param theta angle
|
|
255348
|
+
* @param a period multiplier. If odd, this is the petal count; if even, twice the number of petals.
|
|
255349
|
+
* @param z z-coordinate for output
|
|
255350
|
+
*/
|
|
255351
|
+
static createRosePoint3d(theta, a, z = 0) {
|
|
255352
|
+
const r = Math.cos(a * theta);
|
|
255353
|
+
return _geometry3d_Point3dVector3d__WEBPACK_IMPORTED_MODULE_1__.Point3d.create(r * Math.cos(theta), r * Math.sin(theta), z);
|
|
255354
|
+
}
|
|
255355
|
+
/** Create a point on the polar parametric curve r = cos(a * theta), aka "rose".
|
|
255356
|
+
* @param theta angle
|
|
255357
|
+
* @param a period multiplier. If odd, this is the petal count; if even, twice the number of petals.
|
|
255358
|
+
*/
|
|
255359
|
+
static createRosePoint2d(theta, a) {
|
|
255360
|
+
return _geometry3d_Point2dVector2d__WEBPACK_IMPORTED_MODULE_3__.Point2d.createFrom(Sample.createRosePoint3d(theta, a));
|
|
255361
|
+
}
|
|
255346
255362
|
/**
|
|
255347
255363
|
* Create a mesh surface from samples of a smooth function over [0,1]x[0,1].
|
|
255348
255364
|
* @param size grid size; the number of intervals on each side of the unit square domain.
|
|
@@ -259916,15 +259932,15 @@ var HalfEdgeMask;
|
|
|
259916
259932
|
* * A boundary edge with interior to one side, exterior to the other, will have EXTERIOR only on the outside.
|
|
259917
259933
|
* * An edge inserted "within a purely exterior face" can have EXTERIOR on both sides.
|
|
259918
259934
|
* * An interior edge (such as added during triangulation) will have no EXTERIOR bits.
|
|
259919
|
-
|
|
259920
|
-
|
|
259935
|
+
*/
|
|
259936
|
+
// Visualization can be found at geometry/internaldocs/Graph.md
|
|
259921
259937
|
HalfEdgeMask[HalfEdgeMask["EXTERIOR"] = 1] = "EXTERIOR";
|
|
259922
259938
|
/**
|
|
259923
259939
|
* Mask commonly set (on both sides) of original geometry edges that are transition from outside to inside.
|
|
259924
259940
|
* * At the moment of creating an edge from primary user boundary loop coordinates, the fact that an edge is BOUNDARY
|
|
259925
259941
|
* is often clear even though there is uncertainty about which side should be EXTERIOR.
|
|
259926
|
-
* * Visualization can be found at geometry/internaldocs/Graph.md
|
|
259927
259942
|
*/
|
|
259943
|
+
// Visualization can be found at geometry/internaldocs/Graph.md
|
|
259928
259944
|
HalfEdgeMask[HalfEdgeMask["BOUNDARY_EDGE"] = 2] = "BOUNDARY_EDGE";
|
|
259929
259945
|
/**
|
|
259930
259946
|
* Mask commonly set (on both sides) of original geometry edges, but NOT indicating that the edge is certainly a
|
|
@@ -261491,6 +261507,7 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
261491
261507
|
/* harmony export */ "HalfEdgeGraphSearch": () => (/* binding */ HalfEdgeGraphSearch),
|
|
261492
261508
|
/* harmony export */ "HalfEdgeMaskTester": () => (/* binding */ HalfEdgeMaskTester)
|
|
261493
261509
|
/* harmony export */ });
|
|
261510
|
+
/* harmony import */ var _geometry3d_Range__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../geometry3d/Range */ "../../core/geometry/lib/esm/geometry3d/Range.js");
|
|
261494
261511
|
/* harmony import */ var _Graph__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Graph */ "../../core/geometry/lib/esm/topology/Graph.js");
|
|
261495
261512
|
/* harmony import */ var _SignedDataSummary__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./SignedDataSummary */ "../../core/geometry/lib/esm/topology/SignedDataSummary.js");
|
|
261496
261513
|
/* harmony import */ var _XYParitySearchContext__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./XYParitySearchContext */ "../../core/geometry/lib/esm/topology/XYParitySearchContext.js");
|
|
@@ -261504,11 +261521,11 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
261504
261521
|
|
|
261505
261522
|
|
|
261506
261523
|
|
|
261507
|
-
|
|
261508
|
-
*/
|
|
261524
|
+
|
|
261525
|
+
/** Class to test match of half edge mask. */
|
|
261509
261526
|
class HalfEdgeMaskTester {
|
|
261510
261527
|
/**
|
|
261511
|
-
*
|
|
261528
|
+
* Constructor
|
|
261512
261529
|
* @param mask mask to test in `testEdge` function
|
|
261513
261530
|
* @param targetValue value to match for true return
|
|
261514
261531
|
*/
|
|
@@ -261516,47 +261533,27 @@ class HalfEdgeMaskTester {
|
|
|
261516
261533
|
this._targetMask = mask;
|
|
261517
261534
|
this._targetValue = targetValue;
|
|
261518
261535
|
}
|
|
261519
|
-
/** Return true if the value of the targetMask matches the targetValue */
|
|
261536
|
+
/** Return true if the value of the targetMask matches the targetValue. */
|
|
261520
261537
|
testEdge(edge) {
|
|
261521
261538
|
return edge.isMaskSet(this._targetMask) === this._targetValue;
|
|
261522
261539
|
}
|
|
261523
261540
|
}
|
|
261524
|
-
|
|
261541
|
+
/** Class for different types of searches for HalfEdgeGraph. */
|
|
261525
261542
|
class HalfEdgeGraphSearch {
|
|
261526
261543
|
/**
|
|
261527
|
-
*
|
|
261528
|
-
* *
|
|
261529
|
-
*/
|
|
261530
|
-
static pushAndMaskAllNodesInFace(faceSeed, mask, allNodeStack, onePerFaceStack) {
|
|
261531
|
-
onePerFaceStack.push(faceSeed);
|
|
261532
|
-
faceSeed.collectAroundFace((node) => {
|
|
261533
|
-
node.setMask(mask);
|
|
261534
|
-
allNodeStack.push(node);
|
|
261535
|
-
});
|
|
261536
|
-
}
|
|
261537
|
-
/**
|
|
261538
|
-
* Search an array of faceSeed nodes for the face with the most negative area.
|
|
261539
|
-
* @param oneCandidateNodePerFace array containing one node from each face to be considered.
|
|
261540
|
-
* @returns node on the minimum area face, or undefined if no such face (e.g., all faces have zero area).
|
|
261541
|
-
*/
|
|
261542
|
-
static findMinimumAreaFace(oneCandidateNodePerFace, faceAreaFunction) {
|
|
261543
|
-
const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);
|
|
261544
|
-
return summary.largestNegativeItem;
|
|
261545
|
-
}
|
|
261546
|
-
/**
|
|
261547
|
-
* static method for face area computation -- useful as function parameter in collect FaceAreaSummary.
|
|
261548
|
-
* * This simply calls `node.signedFaceArea ()`
|
|
261544
|
+
* Static method for face area computation -- useful as function parameter in `collectFaceAreaSummary`.
|
|
261545
|
+
* * This simply calls `node.signedFaceArea()`
|
|
261549
261546
|
* @param node instance for signedFaceArea call.
|
|
261550
261547
|
*/
|
|
261551
|
-
static signedFaceArea(node) {
|
|
261548
|
+
static signedFaceArea(node) {
|
|
261549
|
+
return node.signedFaceArea();
|
|
261550
|
+
}
|
|
261552
261551
|
/**
|
|
261553
|
-
*
|
|
261554
|
-
* Return a summary structure data about face (or other numeric quantity if the caller's areaFunction returns other value)
|
|
261555
|
-
* * The default areaFunction computes area of polygonal face.
|
|
261552
|
+
* Return a summary of face data (e.g., area) as computed by the callback on the faces of the graph.
|
|
261556
261553
|
* * Callers with curved edge graphs must supply their own area function.
|
|
261557
|
-
* @param source graph or array of nodes to examine
|
|
261558
|
-
* @param collectAllNodes flag to pass to the SignedDataSummary constructor to control collection of nodes.
|
|
261559
|
-
* @param areaFunction function to
|
|
261554
|
+
* @param source graph or array of nodes to examine.
|
|
261555
|
+
* @param collectAllNodes flag to pass to the `SignedDataSummary` constructor to control collection of nodes.
|
|
261556
|
+
* @param areaFunction function to obtain area (or other numeric value). Default computes polygonal face area.
|
|
261560
261557
|
*/
|
|
261561
261558
|
static collectFaceAreaSummary(source, collectAllNodes = false, areaFunction = (node) => HalfEdgeGraphSearch.signedFaceArea(node)) {
|
|
261562
261559
|
const result = new _SignedDataSummary__WEBPACK_IMPORTED_MODULE_0__.SignedDataSummary(collectAllNodes);
|
|
@@ -261572,10 +261569,19 @@ class HalfEdgeGraphSearch {
|
|
|
261572
261569
|
return result;
|
|
261573
261570
|
}
|
|
261574
261571
|
/**
|
|
261575
|
-
*
|
|
261576
|
-
*
|
|
261577
|
-
*
|
|
261578
|
-
|
|
261572
|
+
* Search the graph for the face with the most negative area.
|
|
261573
|
+
* @param oneCandidateNodePerFace graph or an array containing one node from each face to be considered.
|
|
261574
|
+
* @returns node on the negative area face with largest absolute area, or `undefined` if no negative area face.
|
|
261575
|
+
*/
|
|
261576
|
+
static findMinimumAreaFace(oneCandidateNodePerFace, faceAreaFunction) {
|
|
261577
|
+
const summary = HalfEdgeGraphSearch.collectFaceAreaSummary(oneCandidateNodePerFace, false, faceAreaFunction);
|
|
261578
|
+
return summary.largestNegativeItem;
|
|
261579
|
+
}
|
|
261580
|
+
/**
|
|
261581
|
+
* Test if the graph is triangulated.
|
|
261582
|
+
* * Return `false` if:
|
|
261583
|
+
* * number of positive area faces with more than 3 edges is larger than `numPositiveExceptionsAllowed`.
|
|
261584
|
+
* * graph has more than 1 negative area face when `allowMultipleNegativeAreaFaces` is `false`.
|
|
261579
261585
|
* * 2-edge faces are ignored.
|
|
261580
261586
|
*/
|
|
261581
261587
|
static isTriangulatedCCW(source, allowMultipleNegativeAreaFaces = true, numPositiveExceptionsAllowed = 0) {
|
|
@@ -261609,24 +261615,41 @@ class HalfEdgeGraphSearch {
|
|
|
261609
261615
|
return true;
|
|
261610
261616
|
}
|
|
261611
261617
|
/**
|
|
261612
|
-
*
|
|
261613
|
-
*
|
|
261614
|
-
*
|
|
261615
|
-
*
|
|
261616
|
-
*
|
|
261617
|
-
* * It is entirely clear on all faces that are an odd number of face-to-face steps away from the seed.
|
|
261618
|
-
* @param seedEdge first edge to search.
|
|
261619
|
-
* @param visitMask mask applied to all faces as visited.
|
|
261620
|
-
* @param parityMask mask to apply (a) to first face, (b) to faces with alternating parity during the search.
|
|
261618
|
+
* Process a face during graph traversal.
|
|
261619
|
+
* @param faceSeed a node in the face.
|
|
261620
|
+
* @param mask mask to set on each node of the face.
|
|
261621
|
+
* @param allNodeStack array appended with each node of the face.
|
|
261622
|
+
* @param onePerFaceStack array appended with `faceSeed`.
|
|
261621
261623
|
*/
|
|
261622
|
-
static
|
|
261624
|
+
static pushAndMaskAllNodesInFace(faceSeed, mask, allNodeStack, onePerFaceStack) {
|
|
261625
|
+
onePerFaceStack.push(faceSeed);
|
|
261626
|
+
faceSeed.collectAroundFace((node) => {
|
|
261627
|
+
node.setMask(mask);
|
|
261628
|
+
allNodeStack.push(node);
|
|
261629
|
+
});
|
|
261630
|
+
}
|
|
261631
|
+
/**
|
|
261632
|
+
* Traverse (via Depth First Search) to all accessible faces from the given seed.
|
|
261633
|
+
* @param faceSeed first node to start the traverse.
|
|
261634
|
+
* @param visitMask mask applied to all faces as visited.
|
|
261635
|
+
* @param parityEdgeTester function to test if an edge is adjacent to two faces of opposite parity, e.g., a boundary
|
|
261636
|
+
* edge that separates an "interior" face and an "exterior" face. If `parityEdgeTester` is not supplied and `parityMask`
|
|
261637
|
+
* is supplied, the default parity rule is to alternate parity state in a "bullseye" pattern starting at the seed face,
|
|
261638
|
+
* with each successive concentric ring of faces at constant topological distance from the seed face receiving the
|
|
261639
|
+
* opposite parity state of the previous ring.
|
|
261640
|
+
* @param parityMask mask to apply to the first face and faces that share the same parity as the first face, as
|
|
261641
|
+
* determined by the parity rule. If this is `NULL_MASK`, there is no record of parity. If (non-null) parity mask
|
|
261642
|
+
* is given, on return it is entirely set or entirely clear around each face.
|
|
261643
|
+
* @returns an array that contains one representative node in each face of the connected component.
|
|
261644
|
+
*/
|
|
261645
|
+
static parityFloodFromSeed(faceSeed, visitMask, parityEdgeTester, parityMask) {
|
|
261623
261646
|
const faces = [];
|
|
261624
|
-
if (
|
|
261625
|
-
return faces; // empty
|
|
261647
|
+
if (faceSeed.isMaskSet(visitMask))
|
|
261648
|
+
return faces; // empty array
|
|
261626
261649
|
const allMasks = parityMask | visitMask;
|
|
261627
261650
|
const stack = [];
|
|
261628
|
-
//
|
|
261629
|
-
HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(
|
|
261651
|
+
// the seed face is arbitrarily assigned the parity mask
|
|
261652
|
+
HalfEdgeGraphSearch.pushAndMaskAllNodesInFace(faceSeed, allMasks, stack, faces);
|
|
261630
261653
|
while (stack.length > 0) {
|
|
261631
261654
|
const p = stack.pop();
|
|
261632
261655
|
const mate = p.edgeMate;
|
|
@@ -261642,113 +261665,123 @@ class HalfEdgeGraphSearch {
|
|
|
261642
261665
|
return faces;
|
|
261643
261666
|
}
|
|
261644
261667
|
/**
|
|
261645
|
-
* *
|
|
261646
|
-
* *
|
|
261668
|
+
* * Correct the parity mask in the faces of a component.
|
|
261669
|
+
* * It is assumed that the parity mask is applied _consistently_ throughout the supplied faces, but maybe
|
|
261670
|
+
* not _correctly_.
|
|
261671
|
+
* * A consistently applied parity mask is "correct" if it is set on the negative area ("exterior") face of
|
|
261672
|
+
* a connected component.
|
|
261673
|
+
* * This method finds a face with negative area and toggles the mask throughout the input faces if this face
|
|
261674
|
+
* lacks the parity mask.
|
|
261647
261675
|
* * In a properly merged planar subdivision there should be only one true negative area face per component.
|
|
261648
|
-
* @param graph parent graph
|
|
261649
|
-
* @param parityMask mask which was previously set with alternating parity, but with an arbitrary start face.
|
|
261650
|
-
* @param faces array of faces to search.
|
|
261651
261676
|
*/
|
|
261652
|
-
static correctParityInSingleComponent(
|
|
261677
|
+
static correctParityInSingleComponent(parityMask, faces) {
|
|
261653
261678
|
const exteriorHalfEdge = HalfEdgeGraphSearch.findMinimumAreaFace(faces);
|
|
261654
261679
|
if (!exteriorHalfEdge) {
|
|
261680
|
+
// graph has all degenerate faces; do nothing
|
|
261655
261681
|
}
|
|
261656
|
-
else if (exteriorHalfEdge.isMaskSet(
|
|
261657
|
-
// all should be well
|
|
261682
|
+
else if (exteriorHalfEdge.isMaskSet(parityMask)) {
|
|
261683
|
+
// all should be well; nothing to do
|
|
261658
261684
|
}
|
|
261659
261685
|
else {
|
|
261660
|
-
// TOGGLE around the face (assuming all are consistent with the seed)
|
|
261661
261686
|
for (const faceSeed of faces) {
|
|
261662
|
-
if (faceSeed.isMaskSet(
|
|
261663
|
-
faceSeed.clearMaskAroundFace(
|
|
261687
|
+
if (faceSeed.isMaskSet(parityMask)) {
|
|
261688
|
+
faceSeed.clearMaskAroundFace(parityMask);
|
|
261664
261689
|
}
|
|
261665
261690
|
else {
|
|
261666
|
-
faceSeed.setMaskAroundFace(
|
|
261691
|
+
faceSeed.setMaskAroundFace(parityMask);
|
|
261667
261692
|
}
|
|
261668
261693
|
}
|
|
261669
261694
|
}
|
|
261670
261695
|
}
|
|
261671
|
-
/** Apply correctParityInSingleComponent to each array in components
|
|
261672
|
-
static correctParityInComponentArrays(
|
|
261673
|
-
if (
|
|
261696
|
+
/** Apply `correctParityInSingleComponent` to each array in components (quick exit if `parityMask` is `NULL_MASK`). */
|
|
261697
|
+
static correctParityInComponentArrays(parityMask, components) {
|
|
261698
|
+
if (parityMask === _Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.NULL_MASK)
|
|
261674
261699
|
return;
|
|
261675
261700
|
for (const facesInComponent of components)
|
|
261676
|
-
HalfEdgeGraphSearch.correctParityInSingleComponent(
|
|
261677
|
-
}
|
|
261678
|
-
/**
|
|
261679
|
-
* Collect
|
|
261680
|
-
* @param graph graph to inspect
|
|
261681
|
-
* @param parityEdgeTester (optional) function to test if an edge is
|
|
261682
|
-
*
|
|
261701
|
+
HalfEdgeGraphSearch.correctParityInSingleComponent(parityMask, facesInComponent);
|
|
261702
|
+
}
|
|
261703
|
+
/**
|
|
261704
|
+
* Collect connected components of the graph (via Depth First Search).
|
|
261705
|
+
* @param graph graph to inspect.
|
|
261706
|
+
* @param parityEdgeTester (optional) function to test if an edge is adjacent to two faces of opposite parity,
|
|
261707
|
+
* e.g., a boundary edge that separates an "interior" face and an "exterior" face. If `parityEdgeTester` is not
|
|
261708
|
+
* supplied and `parityMask` is supplied, the default parity rule is to alternate parity state in a "bullseye"
|
|
261709
|
+
* pattern starting at the seed face, with each successive concentric ring of faces at constant topological
|
|
261710
|
+
* distance from the seed face receiving the opposite parity state of the previous ring.
|
|
261711
|
+
* @param parityMask (optional) mask to apply to the first face and faces that share the same parity as the
|
|
261712
|
+
* first face, as determined by the parity rule. If this is `NULL_MASK`, there is no record of parity. If
|
|
261713
|
+
* (non-null) parity mask is given, on return it is entirely set or entirely clear around each face.
|
|
261714
|
+
* @returns the components of the graph, each component represented by an array of nodes, one node per face
|
|
261715
|
+
* of the component. In other words, entry [i][j] is a HalfEdge in the j_th face loop of the i_th component.
|
|
261683
261716
|
*/
|
|
261684
261717
|
static collectConnectedComponentsWithExteriorParityMasks(graph, parityEdgeTester, parityMask = _Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.NULL_MASK) {
|
|
261718
|
+
// Illustration of the algorithm can be found at geometry/internaldocs/Graph.md
|
|
261685
261719
|
const components = [];
|
|
261686
261720
|
const visitMask = _Graph__WEBPACK_IMPORTED_MODULE_1__.HalfEdgeMask.VISITED;
|
|
261687
261721
|
const allMasks = parityMask | visitMask;
|
|
261688
261722
|
graph.clearMask(allMasks);
|
|
261689
261723
|
for (const faceSeed of graph.allHalfEdges) {
|
|
261690
|
-
if (!faceSeed.isMaskSet(
|
|
261724
|
+
if (!faceSeed.isMaskSet(visitMask)) {
|
|
261691
261725
|
const newFaces = HalfEdgeGraphSearch.parityFloodFromSeed(faceSeed, visitMask, parityEdgeTester, parityMask);
|
|
261726
|
+
// parityFloodFromSeed does not return an empty array because it is called on an unvisited faceSeed
|
|
261692
261727
|
components.push(newFaces);
|
|
261693
261728
|
}
|
|
261694
261729
|
}
|
|
261695
|
-
HalfEdgeGraphSearch.correctParityInComponentArrays(
|
|
261730
|
+
HalfEdgeGraphSearch.correctParityInComponentArrays(parityMask, components);
|
|
261696
261731
|
return components;
|
|
261697
261732
|
}
|
|
261698
261733
|
/**
|
|
261699
|
-
* Test if (
|
|
261700
|
-
* @param seedNode any node on the face loop
|
|
261701
|
-
* @param
|
|
261702
|
-
* @param
|
|
261734
|
+
* Test if test point (xTest,yTest) is inside/outside a face or on an edge.
|
|
261735
|
+
* @param seedNode any node on the face loop.
|
|
261736
|
+
* @param xTest x coordinate of the test point.
|
|
261737
|
+
* @param yTest y coordinate of the test point.
|
|
261738
|
+
* @returns 0 if ON, 1 if IN, -1 if OUT.
|
|
261703
261739
|
*/
|
|
261704
|
-
static pointInOrOnFaceXY(seedNode,
|
|
261705
|
-
const context = new _XYParitySearchContext__WEBPACK_IMPORTED_MODULE_2__.XYParitySearchContext(
|
|
261706
|
-
// walk around looking for an accepted node to start the search (seedNode is usually ok
|
|
261740
|
+
static pointInOrOnFaceXY(seedNode, xTest, yTest) {
|
|
261741
|
+
const context = new _XYParitySearchContext__WEBPACK_IMPORTED_MODULE_2__.XYParitySearchContext(xTest, yTest);
|
|
261742
|
+
// walk around looking for an accepted node to start the search (seedNode is usually ok)
|
|
261707
261743
|
let nodeA = seedNode;
|
|
261708
261744
|
let nodeB = seedNode.faceSuccessor;
|
|
261709
261745
|
for (;; nodeA = nodeB) {
|
|
261710
261746
|
if (context.tryStartEdge(nodeA.x, nodeA.y, nodeB.x, nodeB.y))
|
|
261711
261747
|
break;
|
|
261712
261748
|
if (nodeB === seedNode) {
|
|
261713
|
-
//
|
|
261714
|
-
|
|
261749
|
+
// the test point and the face are all on line "y = yTest"
|
|
261750
|
+
const range = _geometry3d_Range__WEBPACK_IMPORTED_MODULE_3__.Range1d.createXX(nodeB.x, nodeB.faceSuccessor.x);
|
|
261751
|
+
return range.containsX(xTest) ? 0 : -1;
|
|
261715
261752
|
}
|
|
261716
261753
|
nodeB = nodeA.faceSuccessor;
|
|
261717
261754
|
}
|
|
261718
|
-
// nodeB is the real start node for search
|
|
261719
|
-
|
|
261720
|
-
let node = nodeB.faceSuccessor;
|
|
261755
|
+
// nodeB is the real start node for search, so stop when we revisit it. For each edge, accumulate parity and hits
|
|
261756
|
+
let nodeC = nodeB.faceSuccessor;
|
|
261721
261757
|
for (;;) {
|
|
261722
|
-
if (!context.advance(
|
|
261758
|
+
if (!context.advance(nodeC.x, nodeC.y)) {
|
|
261723
261759
|
return context.classifyCounts();
|
|
261724
261760
|
}
|
|
261725
|
-
if (
|
|
261761
|
+
if (nodeC === nodeB)
|
|
261726
261762
|
break;
|
|
261727
|
-
|
|
261763
|
+
nodeC = nodeC.faceSuccessor;
|
|
261728
261764
|
}
|
|
261729
261765
|
return context.classifyCounts();
|
|
261730
261766
|
}
|
|
261731
261767
|
/**
|
|
261732
|
-
*
|
|
261733
|
-
* *
|
|
261734
|
-
* * "Around the vertex" from nodeA means
|
|
261735
|
-
* * First look at nodeA.faceSuccessor;
|
|
261736
|
-
* * Then look at vertexPredecessor around that vertex loop.
|
|
261737
|
-
* * Each accepted node is passed to announceNode, and marked with the visit mask.
|
|
261738
|
-
* * The counter of the announceEdge function is zero for the first edge, then increases with each edge.
|
|
261768
|
+
* Collect boundary edges starting from `seed`.
|
|
261769
|
+
* * If `seed` is not a boundary node or is already visited, the function exists early.
|
|
261739
261770
|
* @param seed start node.
|
|
261740
|
-
* @param
|
|
261741
|
-
* @param
|
|
261771
|
+
* @param visitMask mask to set on processed nodes.
|
|
261772
|
+
* @param isBoundaryEdge function to test if an edge in a boundary edge.
|
|
261773
|
+
* @param announceEdgeInBoundary callback invoked on each edge in the boundary loop in order. The counter is zero
|
|
261774
|
+
* for the first edge, and incremented with each successive edge.
|
|
261742
261775
|
*/
|
|
261743
|
-
static collectExtendedBoundaryLoopFromSeed(seed, visitMask, isBoundaryEdge,
|
|
261776
|
+
static collectExtendedBoundaryLoopFromSeed(seed, visitMask, isBoundaryEdge, announceEdgeInBoundary) {
|
|
261744
261777
|
let counter = 0;
|
|
261745
261778
|
while (!seed.getMask(visitMask) && isBoundaryEdge(seed)) {
|
|
261746
|
-
|
|
261779
|
+
announceEdgeInBoundary(seed, counter++);
|
|
261747
261780
|
seed.setMask(visitMask);
|
|
261748
261781
|
const vertexBase = seed.faceSuccessor;
|
|
261749
261782
|
let candidateAroundVertex = vertexBase;
|
|
261750
261783
|
for (;;) {
|
|
261751
|
-
if (candidateAroundVertex.getMask(visitMask))
|
|
261784
|
+
if (candidateAroundVertex.getMask(visitMask)) // end of boundary loop
|
|
261752
261785
|
return;
|
|
261753
261786
|
if (isBoundaryEdge(candidateAroundVertex)) {
|
|
261754
261787
|
seed = candidateAroundVertex;
|
|
@@ -261756,23 +261789,22 @@ class HalfEdgeGraphSearch {
|
|
|
261756
261789
|
}
|
|
261757
261790
|
candidateAroundVertex = candidateAroundVertex.vertexPredecessor;
|
|
261758
261791
|
if (candidateAroundVertex === vertexBase)
|
|
261759
|
-
break;
|
|
261792
|
+
break; // prevent infinite loop in case exteriorMask is not set on the edge mate of the boundary edge
|
|
261760
261793
|
}
|
|
261761
261794
|
}
|
|
261762
261795
|
}
|
|
261763
261796
|
/**
|
|
261764
|
-
* Collect
|
|
261765
|
-
* *
|
|
261766
|
-
* *
|
|
261767
|
-
*
|
|
261768
|
-
*
|
|
261769
|
-
*
|
|
261770
|
-
*
|
|
261771
|
-
* @
|
|
261772
|
-
* @param isBoundaryNode
|
|
261773
|
-
* @param announceNode
|
|
261797
|
+
* Collect boundary edges in the graph.
|
|
261798
|
+
* * A boundary edge is defined by `exteriorMask` being set on only its "exterior" edge mate.
|
|
261799
|
+
* * Each boundary edge is identified in the output by its edge mate that lacks `exteriorMask`.
|
|
261800
|
+
* * Each inner array is ordered in the output so that its boundary edges form a connected path. If `exteriorMask`
|
|
261801
|
+
* is preset consistently around each "exterior" face, these paths are loops.
|
|
261802
|
+
* @param graph the graph to query
|
|
261803
|
+
* @param exteriorMask mask preset on exactly one side of boundary edges
|
|
261804
|
+
* @returns array of boundary loops, each loop an array of the unmasked mates of boundary edges
|
|
261774
261805
|
*/
|
|
261775
261806
|
static collectExtendedBoundaryLoopsInGraph(graph, exteriorMask) {
|
|
261807
|
+
// Illustration of the algorithm can be found at geometry/internaldocs/Graph.md
|
|
261776
261808
|
const loops = [];
|
|
261777
261809
|
const visitMask = graph.grabMask(true);
|
|
261778
261810
|
const isBoundaryEdge = (edge) => {
|
|
@@ -264257,10 +264289,10 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
264257
264289
|
/**
|
|
264258
264290
|
* Class to accumulate statistics about a stream of signed numbers with tag items.
|
|
264259
264291
|
* * All sums, counts, extrema, and item values are initialized to zero in the constructor.
|
|
264260
|
-
* * Each call to `announceItem
|
|
264292
|
+
* * Each call to `announceItem(item, value)` updates the various sums, counts, and extrema.
|
|
264261
264293
|
*/
|
|
264262
264294
|
class SignedDataSummary {
|
|
264263
|
-
/**
|
|
264295
|
+
/** Setup with zero sums and optional arrays. */
|
|
264264
264296
|
constructor(createArrays) {
|
|
264265
264297
|
this.positiveSum = this.negativeSum = 0.0;
|
|
264266
264298
|
this.numPositive = this.numNegative = this.numZero = 0.0;
|
|
@@ -264271,7 +264303,7 @@ class SignedDataSummary {
|
|
|
264271
264303
|
this.zeroItemArray = [];
|
|
264272
264304
|
}
|
|
264273
264305
|
}
|
|
264274
|
-
/**
|
|
264306
|
+
/** Update with an item and its data value. */
|
|
264275
264307
|
announceItem(item, data) {
|
|
264276
264308
|
if (data < 0) {
|
|
264277
264309
|
this.numNegative++;
|
|
@@ -265496,127 +265528,129 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
265496
265528
|
* @module Topology
|
|
265497
265529
|
*/
|
|
265498
265530
|
/**
|
|
265499
|
-
*
|
|
265531
|
+
* `XYParitySearchContext` is an internal class for callers that can feed points (without extracting to array structures)
|
|
265500
265532
|
* * Most will be via static methods which handle a specific data source.
|
|
265501
|
-
* * PolygonOps.classifyPointInPolygon
|
|
265502
|
-
* * HalfEdgeGraphSearch.pointInOrOnFaceXY
|
|
265533
|
+
* * PolygonOps.classifyPointInPolygon(x,y,points: XAndY[])
|
|
265534
|
+
* * HalfEdgeGraphSearch.pointInOrOnFaceXY(halfEdgeOnFace, x, y)
|
|
265503
265535
|
* Use pattern:
|
|
265504
|
-
* * Caller must be able walk around polygon producing x,y coordinates (possibly transformed from actual polygon)
|
|
265536
|
+
* * Caller must be able to walk around polygon producing x,y coordinates (possibly transformed from actual polygon).
|
|
265505
265537
|
* * Caller announce edges to tryStartEdge until finding one acceptable to the search.
|
|
265506
265538
|
* * Caller then passes additional points up to and including both x0,y0 and x1, y1 of the accepted start edge.
|
|
265507
265539
|
* Call sequence is:
|
|
265508
|
-
*
|
|
265509
|
-
*
|
|
265510
|
-
*
|
|
265511
|
-
*
|
|
265540
|
+
* * `context = new XYParitySearchContext`
|
|
265541
|
+
* * `repeat { acquire edge (x0,y0) (x1,y1) } until context.tryStartEdge(x0,y0,x1,y1);`
|
|
265542
|
+
* * `for each (x,y) beginning AFTER x1,y1 and ending with (x1,y1) context.advance (x,y)`
|
|
265543
|
+
* * `return context.classifyCounts();`
|
|
265512
265544
|
*/
|
|
265513
265545
|
class XYParitySearchContext {
|
|
265514
265546
|
/**
|
|
265515
265547
|
* Create a new searcher for specified test point.
|
|
265516
|
-
* @param xTest x coordinate of test point
|
|
265517
|
-
* @param yTest y coordinate of test point
|
|
265548
|
+
* @param xTest x coordinate of test point.
|
|
265549
|
+
* @param yTest y coordinate of test point.
|
|
265518
265550
|
*/
|
|
265519
265551
|
constructor(xTest, yTest) {
|
|
265520
265552
|
this.xTest = xTest;
|
|
265521
265553
|
this.yTest = yTest;
|
|
265522
|
-
this.u0 = this.v0 = this.u1 = this.v1 = 0; //
|
|
265554
|
+
this.u0 = this.v0 = this.u1 = this.v1 = 0; // not valid for search; caller must satisfy tryStartEdge
|
|
265523
265555
|
this.numLeftCrossing = this.numRightCrossing = 0;
|
|
265524
265556
|
this.numHit = 0;
|
|
265525
265557
|
}
|
|
265526
|
-
/**
|
|
265527
|
-
* test if x,y is a safe first coordinate to start the search.
|
|
265528
|
-
* * safe start must have non-zero y so that final point test (return to x0,y0) does not need look back for exact crossing logic.
|
|
265529
|
-
* @param x
|
|
265530
|
-
* @param y
|
|
265531
|
-
*/
|
|
265558
|
+
/** Test if parity processing can begin with this edge. */
|
|
265532
265559
|
tryStartEdge(x0, y0, x1, y1) {
|
|
265533
265560
|
if (y0 !== this.yTest) {
|
|
265534
265561
|
this.u0 = x0 - this.xTest;
|
|
265535
265562
|
this.v0 = y0 - this.yTest;
|
|
265536
265563
|
this.u1 = x1 - this.xTest;
|
|
265537
265564
|
this.v1 = y1 - this.yTest;
|
|
265538
|
-
return true;
|
|
265565
|
+
return true; // we won't need wraparound logic to process the final edge ending at (x0,y0)
|
|
265539
265566
|
}
|
|
265540
265567
|
return false;
|
|
265541
265568
|
}
|
|
265542
|
-
/**
|
|
265543
|
-
|
|
265544
|
-
|
|
265545
|
-
|
|
265546
|
-
|
|
265547
|
-
|
|
265548
|
-
|
|
265569
|
+
/** Update local coordinates: the current edge becomes the previous edge. */
|
|
265570
|
+
updateUV01(u2, v2) {
|
|
265571
|
+
this.u0 = this.u1;
|
|
265572
|
+
this.v0 = this.v1;
|
|
265573
|
+
this.u1 = u2;
|
|
265574
|
+
this.v1 = v2;
|
|
265575
|
+
return true;
|
|
265576
|
+
}
|
|
265577
|
+
/**
|
|
265578
|
+
* Process the current edge ending at (x2,y2).
|
|
265579
|
+
* * Accumulate left/right parity of the test point wrt to the polygon. These counts track the number of polygon crossings
|
|
265580
|
+
* of the left and right horizontal rays emanating from the test point. After all edges are processed, if either count is
|
|
265581
|
+
* odd/even, the test point is inside/outside the polygon (see [[classifyCounts]]).
|
|
265582
|
+
* * Check whether the test point lies on the edge.
|
|
265583
|
+
* @returns whether caller should continue processing with the next edge. In particular, `false` if we have an exact hit.
|
|
265584
|
+
*/
|
|
265585
|
+
advance(x2, y2) {
|
|
265586
|
+
// In this method we use local u,v coordinates obtained by translating the test point to the origin.
|
|
265587
|
+
// This simplifies our computations:
|
|
265588
|
+
// * left (right) parity is incremented if the current edge crosses the u-axis at u<0 (u>0)
|
|
265589
|
+
// * we have an exact hit if the current edge crosses the u-axis at u=0
|
|
265590
|
+
const u2 = x2 - this.xTest;
|
|
265591
|
+
const v2 = y2 - this.yTest;
|
|
265592
|
+
const p = v2 * this.v1;
|
|
265549
265593
|
if (p > 0) {
|
|
265550
|
-
//
|
|
265551
|
-
this.
|
|
265552
|
-
this.v0 = this.v1;
|
|
265553
|
-
this.u1 = u;
|
|
265554
|
-
this.v1 = v;
|
|
265555
|
-
return true;
|
|
265594
|
+
// Current edge does not cross u-axis.
|
|
265595
|
+
return this.updateUV01(u2, v2);
|
|
265556
265596
|
}
|
|
265557
265597
|
if (p < 0) {
|
|
265558
|
-
//
|
|
265559
|
-
//
|
|
265560
|
-
const
|
|
265561
|
-
const uCross = this.u1 +
|
|
265598
|
+
// Current edge crosses the u-axis at edge parameter 0 < lambda < 1 by the Intermediate Value Theorem.
|
|
265599
|
+
// Solve for lambda in 0 = v1 + lambda (v2 - v1), then use it to compute the u-value of the crossing.
|
|
265600
|
+
const lambda = -this.v1 / (v2 - this.v1);
|
|
265601
|
+
const uCross = this.u1 + lambda * (u2 - this.u1);
|
|
265562
265602
|
if (uCross === 0.0) {
|
|
265563
|
-
this.numHit++;
|
|
265603
|
+
this.numHit++; // Current edge crosses at the origin.
|
|
265564
265604
|
return false;
|
|
265565
265605
|
}
|
|
265566
265606
|
if (uCross > 0)
|
|
265567
265607
|
this.numRightCrossing++;
|
|
265568
265608
|
else
|
|
265569
265609
|
this.numLeftCrossing++;
|
|
265570
|
-
this.
|
|
265571
|
-
this.v0 = this.v1;
|
|
265572
|
-
this.u1 = u;
|
|
265573
|
-
this.v1 = v;
|
|
265574
|
-
return true;
|
|
265610
|
+
return this.updateUV01(u2, v2);
|
|
265575
265611
|
}
|
|
265576
|
-
//
|
|
265577
|
-
if (
|
|
265612
|
+
// At this point, at least one endpoint of the current edge lies on the u-axis.
|
|
265613
|
+
if (v2 === 0.0) {
|
|
265578
265614
|
if (this.v1 === 0.0) {
|
|
265579
|
-
|
|
265580
|
-
|
|
265581
|
-
this.numHit++;
|
|
265615
|
+
if (u2 * this.u1 <= 0.0) {
|
|
265616
|
+
this.numHit++; // Current edge lies on u-axis and contains the origin.
|
|
265582
265617
|
return false;
|
|
265583
265618
|
}
|
|
265584
|
-
//
|
|
265585
|
-
//
|
|
265586
|
-
this.u1 =
|
|
265587
|
-
this.v1 =
|
|
265619
|
+
// Current edge lies on the u-axis to one side of the origin.
|
|
265620
|
+
// This edge doesn't contribute to parity computations, so advance past it.
|
|
265621
|
+
this.u1 = u2;
|
|
265622
|
+
this.v1 = v2;
|
|
265588
265623
|
return true;
|
|
265589
265624
|
}
|
|
265590
|
-
|
|
265591
|
-
|
|
265592
|
-
|
|
265593
|
-
|
|
265594
|
-
|
|
265595
|
-
return
|
|
265625
|
+
if (u2 === 0.0) {
|
|
265626
|
+
this.numHit++; // Current edge ends at the origin.
|
|
265627
|
+
return false;
|
|
265628
|
+
}
|
|
265629
|
+
// Current edge ends on the u-axis away from the origin.
|
|
265630
|
+
return this.updateUV01(u2, v2);
|
|
265596
265631
|
}
|
|
265597
|
-
//
|
|
265598
|
-
|
|
265599
|
-
|
|
265600
|
-
|
|
265601
|
-
if (this.u1 > 0) {
|
|
265602
|
-
if (q < 0)
|
|
265603
|
-
this.numRightCrossing++;
|
|
265632
|
+
// At this point, the current edge starts at the u-axis.
|
|
265633
|
+
if (this.u1 === 0.0) {
|
|
265634
|
+
this.numHit++; // Current edge starts at the origin.
|
|
265635
|
+
return false;
|
|
265604
265636
|
}
|
|
265605
|
-
|
|
265606
|
-
|
|
265637
|
+
// At this point, the current edge starts on the u-axis away from the origin.
|
|
265638
|
+
const q = this.v0 * v2;
|
|
265639
|
+
if (q < 0) {
|
|
265640
|
+
// The current edge and the previous edge lie on opposite sides of the u-axis, so we have a parity change.
|
|
265641
|
+
if (this.u1 > 0)
|
|
265642
|
+
this.numRightCrossing++;
|
|
265643
|
+
else
|
|
265607
265644
|
this.numLeftCrossing++;
|
|
265608
265645
|
}
|
|
265609
|
-
|
|
265610
|
-
this.
|
|
265611
|
-
this.u1 = u;
|
|
265612
|
-
this.v1 = v;
|
|
265613
|
-
return true;
|
|
265646
|
+
// The current edge and the previous edge lie on the same sides of the u-axis, so no parity change.
|
|
265647
|
+
return this.updateUV01(u2, v2);
|
|
265614
265648
|
}
|
|
265615
265649
|
/**
|
|
265616
265650
|
* Return classification as ON, IN, or OUT according to hit and crossing counts.
|
|
265617
|
-
* * Any nonzero hit count is ON
|
|
265651
|
+
* * Any nonzero hit count is ON.
|
|
265618
265652
|
* * Otherwise IN if left crossing count is odd.
|
|
265619
|
-
* @return 0 if ON, 1 if IN, -1 if OUT
|
|
265653
|
+
* @return 0 if ON, 1 if IN, -1 if OUT.
|
|
265620
265654
|
*/
|
|
265621
265655
|
classifyCounts() {
|
|
265622
265656
|
if (this.numHit > 0)
|
|
@@ -286200,7 +286234,7 @@ class TestContext {
|
|
|
286200
286234
|
this.initializeRpcInterfaces({ title: this.settings.Backend.name, version: this.settings.Backend.version });
|
|
286201
286235
|
const iModelClient = new imodels_client_management_1.IModelsClient({ api: { baseUrl: `https://${process.env.IMJS_URL_PREFIX ?? ""}api.bentley.com/imodels` } });
|
|
286202
286236
|
await core_frontend_1.NoRenderApp.startup({
|
|
286203
|
-
applicationVersion: "4.4.0-dev.
|
|
286237
|
+
applicationVersion: "4.4.0-dev.18",
|
|
286204
286238
|
applicationId: this.settings.gprid,
|
|
286205
286239
|
authorizationClient: new frontend_1.TestFrontendAuthorizationClient(this.adminUserAccessToken),
|
|
286206
286240
|
hubAccess: new imodels_access_frontend_1.FrontendIModelsAccess(iModelClient),
|
|
@@ -305012,7 +305046,7 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
|
|
|
305012
305046
|
/***/ ((module) => {
|
|
305013
305047
|
|
|
305014
305048
|
"use strict";
|
|
305015
|
-
module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.4.0-dev.
|
|
305049
|
+
module.exports = JSON.parse('{"name":"@itwin/core-frontend","version":"4.4.0-dev.18","description":"iTwin.js frontend components","main":"lib/cjs/core-frontend.js","module":"lib/esm/core-frontend.js","typings":"lib/cjs/core-frontend","license":"MIT","scripts":{"build":"npm run -s copy:public && npm run -s build:cjs && npm run -s build:esm && npm run -s webpackWorkers && npm run -s copy:workers","build:cjs":"npm run -s copy:js:cjs && tsc 1>&2 --outDir lib/cjs","build:esm":"npm run -s copy:js:esm && tsc 1>&2 --module ES2020 --outDir lib/esm","clean":"rimraf lib .rush/temp/package-deps*.json","copy:public":"cpx \\"./src/public/**/*\\" ./lib/public","copy:js:cjs":"cpx \\"./src/**/*.js\\" ./lib/cjs","copy:js:esm":"cpx \\"./src/**/*.js\\" ./lib/esm","copy:workers":"cpx \\"./lib/workers/webpack/parse-imdl-worker.js\\" ./lib/public/scripts","docs":"betools docs --includes=../../generated-docs/extract --json=../../generated-docs/core/core-frontend/file.json --tsIndexFile=./core-frontend.ts --onlyJson --excludes=webgl/**/*,**/map/*.d.ts,**/tile/*.d.ts,**/*-css.ts","extract-api":"betools extract-api --entry=core-frontend && npm run extract-extension-api","extract-extension-api":"eslint -c extraction.eslint.config.js \\"./src/**/*.ts\\" 1>&2","lint":"eslint -f visualstudio \\"./src/**/*.ts\\" 1>&2","pseudolocalize":"betools pseudolocalize --englishDir ./src/public/locales/en --out ./public/locales/en-PSEUDO","test":"npm run -s webpackTests && certa -r chrome","cover":"npm -s test","test:debug":"certa -r chrome --debug","webpackTests":"webpack --config ./src/test/utils/webpack.config.js 1>&2 && npm run -s webpackTestWorker","webpackTestWorker":"webpack --config ./src/test/worker/webpack.config.js 1>&2 && cpx \\"./lib/test/test-worker.js\\" ./lib/test","webpackWorkers":"webpack --config ./src/workers/ImdlParser/webpack.config.js 1>&2"},"repository":{"type":"git","url":"https://github.com/iTwin/itwinjs-core.git","directory":"core/frontend"},"keywords":["Bentley","BIM","iModel","digital-twin","iTwin"],"author":{"name":"Bentley Systems, Inc.","url":"http://www.bentley.com"},"peerDependencies":{"@itwin/appui-abstract":"workspace:^4.4.0-dev.18","@itwin/core-bentley":"workspace:^4.4.0-dev.18","@itwin/core-common":"workspace:^4.4.0-dev.18","@itwin/core-geometry":"workspace:^4.4.0-dev.18","@itwin/core-orbitgt":"workspace:^4.4.0-dev.18","@itwin/core-quantity":"workspace:^4.4.0-dev.18"},"//devDependencies":["NOTE: All peerDependencies should also be listed as devDependencies since peerDependencies are not considered by npm install","NOTE: All tools used by scripts in this package must be listed as devDependencies"],"devDependencies":{"@itwin/appui-abstract":"workspace:*","@itwin/build-tools":"workspace:*","@itwin/core-bentley":"workspace:*","@itwin/core-common":"workspace:*","@itwin/core-geometry":"workspace:*","@itwin/core-orbitgt":"workspace:*","@itwin/core-quantity":"workspace:*","@itwin/certa":"workspace:*","@itwin/eslint-plugin":"4.0.0-dev.44","@types/chai":"4.3.1","@types/chai-as-promised":"^7","@types/mocha":"^10.0.6","@types/sinon":"^17.0.2","babel-loader":"~8.2.5","babel-plugin-istanbul":"~6.1.1","chai":"^4.3.10","chai-as-promised":"^7.1.1","cpx2":"^3.0.0","eslint":"^8.44.0","glob":"^7.1.2","mocha":"^10.2.0","nyc":"^15.1.0","rimraf":"^3.0.2","sinon":"^17.0.1","source-map-loader":"^4.0.0","typescript":"~5.0.2","typemoq":"^2.1.0","webpack":"^5.76.0"},"//dependencies":["NOTE: these dependencies should be only for things that DO NOT APPEAR IN THE API","NOTE: core-frontend should remain UI technology agnostic, so no react/angular dependencies are allowed"],"dependencies":{"@itwin/cloud-agnostic-core":"^2.1.0","@itwin/object-storage-core":"^2.2.2","@itwin/core-i18n":"workspace:*","@itwin/core-telemetry":"workspace:*","@itwin/webgl-compatibility":"workspace:*","@loaders.gl/core":"^3.1.6","@loaders.gl/draco":"^3.1.6","fuse.js":"^3.3.0","wms-capabilities":"0.4.0"},"nyc":{"extends":"./node_modules/@itwin/build-tools/.nycrc"}}');
|
|
305016
305050
|
|
|
305017
305051
|
/***/ }),
|
|
305018
305052
|
|