@itwin/core-common 3.2.0-dev.71 → 3.2.0-dev.75
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/cjs/ConcurrentQuery.d.ts.map +1 -1
- package/lib/cjs/ConcurrentQuery.js +2 -1
- package/lib/cjs/ConcurrentQuery.js.map +1 -1
- package/lib/cjs/HiddenLine.d.ts +12 -17
- package/lib/cjs/HiddenLine.d.ts.map +1 -1
- package/lib/cjs/HiddenLine.js +6 -2
- package/lib/cjs/HiddenLine.js.map +1 -1
- package/lib/cjs/ipc/IpcWebSocketTransport.d.ts.map +1 -1
- package/lib/cjs/ipc/IpcWebSocketTransport.js +3 -2
- package/lib/cjs/ipc/IpcWebSocketTransport.js.map +1 -1
- package/lib/cjs/rpc/core/RpcControl.d.ts.map +1 -1
- package/lib/cjs/rpc/core/RpcControl.js +3 -2
- package/lib/cjs/rpc/core/RpcControl.js.map +1 -1
- package/lib/cjs/rpc/web/RpcMultipart.d.ts +1 -0
- package/lib/cjs/rpc/web/RpcMultipart.d.ts.map +1 -1
- package/lib/cjs/rpc/web/RpcMultipart.js +2 -1
- package/lib/cjs/rpc/web/RpcMultipart.js.map +1 -1
- package/lib/cjs/rpc/web/WebAppRpcProtocol.d.ts.map +1 -1
- package/lib/cjs/rpc/web/WebAppRpcProtocol.js +2 -2
- package/lib/cjs/rpc/web/WebAppRpcProtocol.js.map +1 -1
- package/lib/cjs/rpc/web/WebAppRpcRequest.d.ts +1 -1
- package/lib/cjs/rpc/web/WebAppRpcRequest.d.ts.map +1 -1
- package/lib/cjs/rpc/web/WebAppRpcRequest.js +8 -8
- package/lib/cjs/rpc/web/WebAppRpcRequest.js.map +1 -1
- package/lib/cjs/rpc/web/multipart/RpcMultipartParser.d.ts +1 -0
- package/lib/cjs/rpc/web/multipart/RpcMultipartParser.d.ts.map +1 -1
- package/lib/cjs/rpc/web/multipart/RpcMultipartParser.js +4 -3
- package/lib/cjs/rpc/web/multipart/RpcMultipartParser.js.map +1 -1
- package/lib/cjs/tile/ElementGraphics.d.ts +8 -2
- package/lib/cjs/tile/ElementGraphics.d.ts.map +1 -1
- package/lib/cjs/tile/ElementGraphics.js.map +1 -1
- package/lib/cjs/tile/TileMetadata.d.ts +18 -13
- package/lib/cjs/tile/TileMetadata.d.ts.map +1 -1
- package/lib/cjs/tile/TileMetadata.js +164 -134
- package/lib/cjs/tile/TileMetadata.js.map +1 -1
- package/lib/esm/ConcurrentQuery.d.ts.map +1 -1
- package/lib/esm/ConcurrentQuery.js +1 -0
- package/lib/esm/ConcurrentQuery.js.map +1 -1
- package/lib/esm/HiddenLine.d.ts +12 -17
- package/lib/esm/HiddenLine.d.ts.map +1 -1
- package/lib/esm/HiddenLine.js +6 -2
- package/lib/esm/HiddenLine.js.map +1 -1
- package/lib/esm/ipc/IpcWebSocketTransport.d.ts.map +1 -1
- package/lib/esm/ipc/IpcWebSocketTransport.js +1 -0
- package/lib/esm/ipc/IpcWebSocketTransport.js.map +1 -1
- package/lib/esm/rpc/core/RpcControl.d.ts.map +1 -1
- package/lib/esm/rpc/core/RpcControl.js +1 -0
- package/lib/esm/rpc/core/RpcControl.js.map +1 -1
- package/lib/esm/rpc/web/RpcMultipart.d.ts +1 -0
- package/lib/esm/rpc/web/RpcMultipart.d.ts.map +1 -1
- package/lib/esm/rpc/web/RpcMultipart.js +1 -0
- package/lib/esm/rpc/web/RpcMultipart.js.map +1 -1
- package/lib/esm/rpc/web/WebAppRpcProtocol.d.ts.map +1 -1
- package/lib/esm/rpc/web/WebAppRpcProtocol.js +2 -2
- package/lib/esm/rpc/web/WebAppRpcProtocol.js.map +1 -1
- package/lib/esm/rpc/web/WebAppRpcRequest.d.ts +1 -1
- package/lib/esm/rpc/web/WebAppRpcRequest.d.ts.map +1 -1
- package/lib/esm/rpc/web/WebAppRpcRequest.js +5 -5
- package/lib/esm/rpc/web/WebAppRpcRequest.js.map +1 -1
- package/lib/esm/rpc/web/multipart/RpcMultipartParser.d.ts +1 -0
- package/lib/esm/rpc/web/multipart/RpcMultipartParser.d.ts.map +1 -1
- package/lib/esm/rpc/web/multipart/RpcMultipartParser.js +1 -0
- package/lib/esm/rpc/web/multipart/RpcMultipartParser.js.map +1 -1
- package/lib/esm/tile/ElementGraphics.d.ts +8 -2
- package/lib/esm/tile/ElementGraphics.d.ts.map +1 -1
- package/lib/esm/tile/ElementGraphics.js.map +1 -1
- package/lib/esm/tile/TileMetadata.d.ts +18 -13
- package/lib/esm/tile/TileMetadata.d.ts.map +1 -1
- package/lib/esm/tile/TileMetadata.js +163 -133
- package/lib/esm/tile/TileMetadata.js.map +1 -1
- package/package.json +8 -8
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module Tile
|
|
7
7
|
*/
|
|
8
|
-
import { assert, compareBooleansOrUndefined, compareNumbers, compareStringsOrUndefined, Id64, } from "@itwin/core-bentley";
|
|
8
|
+
import { assert, compareBooleans, compareBooleansOrUndefined, compareNumbers, compareStringsOrUndefined, Id64, } from "@itwin/core-bentley";
|
|
9
9
|
import { Range3d, Vector3d } from "@itwin/core-geometry";
|
|
10
10
|
import { BatchType } from "../FeatureTable";
|
|
11
11
|
import { CurrentImdlVersion, FeatureTableHeader, ImdlFlags, ImdlHeader } from "./IModelTileIO";
|
|
@@ -28,6 +28,7 @@ export var TileOptions;
|
|
|
28
28
|
function fromTreeIdAndContentId(treeId, contentId) {
|
|
29
29
|
const tree = treeFlagsAndFormatVersionFromId(treeId);
|
|
30
30
|
const contentFlags = contentFlagsFromId(contentId);
|
|
31
|
+
const edgeOptions = edgeOptionsFromTreeId(treeId);
|
|
31
32
|
return {
|
|
32
33
|
maximumMajorTileFormatVersion: tree.version,
|
|
33
34
|
enableInstancing: 0 !== (contentFlags & ContentFlags.AllowInstancing),
|
|
@@ -39,137 +40,143 @@ export var TileOptions;
|
|
|
39
40
|
useLargerTiles: 0 !== (tree.flags & TreeFlags.UseLargerTiles),
|
|
40
41
|
disableMagnification: false,
|
|
41
42
|
alwaysSubdivideIncompleteTiles: false,
|
|
42
|
-
enableIndexedEdges:
|
|
43
|
+
enableIndexedEdges: edgeOptions && edgeOptions.indexed,
|
|
44
|
+
generateAllPolyfaceEdges: edgeOptions && edgeOptions.smooth,
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
47
|
TileOptions.fromTreeIdAndContentId = fromTreeIdAndContentId;
|
|
46
48
|
})(TileOptions || (TileOptions = {}));
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return {
|
|
86
|
-
contentId: parsedContentId,
|
|
87
|
-
modelId,
|
|
88
|
-
options,
|
|
89
|
-
treeId: parsedTreeId,
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
function getTreeId(type, edges, sectionCut, animationId, expansion, enforceDisplayPriority) {
|
|
93
|
-
if (type === BatchType.Primary)
|
|
94
|
-
return {
|
|
95
|
-
type,
|
|
96
|
-
edges,
|
|
97
|
-
sectionCut,
|
|
98
|
-
animationId,
|
|
99
|
-
enforceDisplayPriority,
|
|
100
|
-
};
|
|
101
|
-
else
|
|
49
|
+
class Parser {
|
|
50
|
+
constructor(input) {
|
|
51
|
+
this.curPos = 0;
|
|
52
|
+
this.input = input;
|
|
53
|
+
}
|
|
54
|
+
parse(contentId) {
|
|
55
|
+
this.require(this.input.length > 0);
|
|
56
|
+
// Skip version and flags, they're handled by TileOptions.fromTreeIdAndContentId
|
|
57
|
+
while (this.curPos < this.input.length && this.cur() !== "-")
|
|
58
|
+
this.advance();
|
|
59
|
+
this.eat("-");
|
|
60
|
+
this.require(this.curPos < this.input.length);
|
|
61
|
+
const classifier = this.cur() === "C" ? this.parseClassifier() : undefined;
|
|
62
|
+
const animationId = this.parseAnimation();
|
|
63
|
+
const primary = classifier ? undefined : this.parsePrimary();
|
|
64
|
+
this.require((undefined === classifier) !== (undefined === primary));
|
|
65
|
+
const modelId = this.input.substr(this.curPos);
|
|
66
|
+
this.require(Id64.isId64(modelId));
|
|
67
|
+
const { flags: treeFlags } = treeFlagsAndFormatVersionFromId(this.input);
|
|
68
|
+
const options = TileOptions.fromTreeIdAndContentId(this.input, contentId);
|
|
69
|
+
let parsedContentId;
|
|
70
|
+
try {
|
|
71
|
+
parsedContentId = ContentIdProvider.create(true, options).specFromId(contentId);
|
|
72
|
+
}
|
|
73
|
+
catch (e) {
|
|
74
|
+
this.reject("Invalid content Id");
|
|
75
|
+
}
|
|
76
|
+
if (Object.keys(parsedContentId).some((key) => parsedContentId.hasOwnProperty(key) && typeof parsedContentId[key] === "number" && !Number.isFinite(parsedContentId[key])))
|
|
77
|
+
throw new Error("Invalid content Id");
|
|
78
|
+
let treeId;
|
|
79
|
+
if (classifier) {
|
|
80
|
+
treeId = { ...classifier, animationId };
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
assert(undefined !== primary);
|
|
84
|
+
const enforceDisplayPriority = (treeFlags & TreeFlags.EnforceDisplayPriority) !== 0 ? true : undefined;
|
|
85
|
+
treeId = { ...primary, animationId, type: BatchType.Primary, enforceDisplayPriority };
|
|
86
|
+
}
|
|
102
87
|
return {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
contentId: parsedContentId,
|
|
89
|
+
modelId,
|
|
90
|
+
options,
|
|
91
|
+
treeId,
|
|
106
92
|
};
|
|
107
|
-
}
|
|
108
|
-
function parsePrimary(idx, treeId, edges = EdgeType.None, sectionCut) {
|
|
109
|
-
// Edges
|
|
110
|
-
edges = EdgeType.NonIndexed;
|
|
111
|
-
if (idx < treeId.length) {
|
|
112
|
-
const noEdgesStr = "E:0_";
|
|
113
|
-
if (treeId.startsWith(noEdgesStr, idx))
|
|
114
|
-
edges = EdgeType.None;
|
|
115
|
-
else if (treeId.startsWith("E:2_", idx))
|
|
116
|
-
edges = EdgeType.Indexed;
|
|
117
|
-
if (EdgeType.NonIndexed !== edges)
|
|
118
|
-
idx += noEdgesStr.length;
|
|
119
|
-
}
|
|
120
|
-
// Section cut
|
|
121
|
-
if (idx + 1 < treeId.length && treeId[idx] === "S") {
|
|
122
|
-
idx++; // S
|
|
123
|
-
sectionCut = "";
|
|
124
|
-
while (idx < treeId.length && treeId[idx] !== "s") {
|
|
125
|
-
sectionCut += treeId[idx++];
|
|
126
|
-
}
|
|
127
|
-
if (idx === treeId.length)
|
|
128
|
-
throw new Error("Invalid tree Id");
|
|
129
|
-
idx++; // s
|
|
130
93
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
let type;
|
|
135
|
-
idx++; // C
|
|
136
|
-
if (idx + 1 < treeId.length && treeId[idx] === "P" && treeId[idx + 1] === ":") {
|
|
137
|
-
type = BatchType.PlanarClassifier;
|
|
138
|
-
idx += 2; // P:
|
|
94
|
+
cur() {
|
|
95
|
+
this.require(this.curPos < this.input.length);
|
|
96
|
+
return this.input[this.curPos];
|
|
139
97
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
98
|
+
advance() {
|
|
99
|
+
this.require(this.curPos < this.input.length);
|
|
100
|
+
++this.curPos;
|
|
143
101
|
}
|
|
144
|
-
|
|
145
|
-
|
|
102
|
+
eat(expectedChar) {
|
|
103
|
+
this.require(this.cur() === expectedChar);
|
|
104
|
+
this.advance();
|
|
146
105
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
while (idx < treeId.length && (treeId[idx] >= "0" && treeId[idx] <= "9" || treeId[idx] === ".")) {
|
|
150
|
-
expansionStr += treeId[idx++];
|
|
106
|
+
reject(message = "Invalid tree Id") {
|
|
107
|
+
throw new Error(message);
|
|
151
108
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
idx += 2;
|
|
163
|
-
// Parse animation id
|
|
164
|
-
animationId = "";
|
|
165
|
-
while (idx < treeId.length && treeId[idx] !== "_") {
|
|
166
|
-
animationId += treeId[idx++];
|
|
109
|
+
require(condition, message = "Invalid tree Id") {
|
|
110
|
+
if (!condition)
|
|
111
|
+
this.reject(message);
|
|
112
|
+
}
|
|
113
|
+
parseClassifier() {
|
|
114
|
+
this.eat("C");
|
|
115
|
+
let type = BatchType.VolumeClassifier;
|
|
116
|
+
if (this.cur() === "P") {
|
|
117
|
+
type = BatchType.PlanarClassifier;
|
|
118
|
+
this.advance();
|
|
167
119
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
120
|
+
this.eat(":");
|
|
121
|
+
// C: or CP: is always folowed by expansion then an underscore.
|
|
122
|
+
let expansionStr = "";
|
|
123
|
+
while (this.curPos < this.input.length && (this.cur() >= "0" && this.cur() <= "9" || this.cur() === ".")) {
|
|
124
|
+
expansionStr += this.cur();
|
|
125
|
+
this.advance();
|
|
126
|
+
}
|
|
127
|
+
this.eat("_");
|
|
128
|
+
const expansion = Number.parseFloat(expansionStr);
|
|
129
|
+
this.require(!Number.isNaN(expansion));
|
|
130
|
+
return { type, expansion };
|
|
131
|
+
}
|
|
132
|
+
parseAnimation() {
|
|
133
|
+
if (this.cur() !== "A")
|
|
134
|
+
return undefined;
|
|
135
|
+
this.eat("A");
|
|
136
|
+
this.eat(":");
|
|
137
|
+
const termPos = this.input.indexOf("_", this.curPos);
|
|
138
|
+
this.require(termPos > this.curPos);
|
|
139
|
+
const animationId = this.input.substring(this.curPos, termPos);
|
|
140
|
+
this.require(Id64.isId64(animationId));
|
|
141
|
+
this.curPos = termPos + 1; // Skip "_"
|
|
142
|
+
return animationId;
|
|
143
|
+
}
|
|
144
|
+
parsePrimary() {
|
|
145
|
+
const edges = this.parseEdges();
|
|
146
|
+
const sectionCut = this.parseSectionCut();
|
|
147
|
+
return { edges, sectionCut };
|
|
148
|
+
}
|
|
149
|
+
parseEdges() {
|
|
150
|
+
if ("E" !== this.cur())
|
|
151
|
+
return { indexed: false, smooth: false };
|
|
152
|
+
this.eat("E");
|
|
153
|
+
this.eat(":");
|
|
154
|
+
const typeStr = this.cur();
|
|
155
|
+
this.eat(typeStr);
|
|
156
|
+
this.eat("_");
|
|
157
|
+
switch (typeStr) {
|
|
158
|
+
case "0": return false;
|
|
159
|
+
case "2": return { indexed: true, smooth: false };
|
|
160
|
+
case "3": return { indexed: false, smooth: true };
|
|
161
|
+
case "4": return { indexed: true, smooth: true };
|
|
162
|
+
default: this.reject();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
parseSectionCut() {
|
|
166
|
+
if ("S" !== this.cur())
|
|
167
|
+
return undefined;
|
|
168
|
+
this.eat("S");
|
|
169
|
+
const termPos = this.input.indexOf("s", this.curPos);
|
|
170
|
+
this.require(termPos > this.curPos);
|
|
171
|
+
const sectionCut = this.input.substring(this.curPos, termPos);
|
|
172
|
+
this.curPos = termPos + 1; // Skip "_";
|
|
173
|
+
return sectionCut;
|
|
171
174
|
}
|
|
172
|
-
|
|
175
|
+
}
|
|
176
|
+
/** @internal */
|
|
177
|
+
export function parseTileTreeIdAndContentId(treeId, contentId) {
|
|
178
|
+
const parser = new Parser(treeId);
|
|
179
|
+
return parser.parse(contentId);
|
|
173
180
|
}
|
|
174
181
|
/** @internal */
|
|
175
182
|
export const defaultTileOptions = Object.freeze({
|
|
@@ -184,6 +191,7 @@ export const defaultTileOptions = Object.freeze({
|
|
|
184
191
|
disableMagnification: false,
|
|
185
192
|
alwaysSubdivideIncompleteTiles: false,
|
|
186
193
|
enableIndexedEdges: true,
|
|
194
|
+
generateAllPolyfaceEdges: true,
|
|
187
195
|
});
|
|
188
196
|
function contentFlagsFromId(id) {
|
|
189
197
|
if (0 === id.length || "-" !== id[0])
|
|
@@ -212,6 +220,18 @@ function treeFlagsAndFormatVersionFromId(id) {
|
|
|
212
220
|
}
|
|
213
221
|
throw new Error("Invalid tree Id");
|
|
214
222
|
}
|
|
223
|
+
function edgeOptionsFromTreeId(id) {
|
|
224
|
+
const pos = id.indexOf("E:");
|
|
225
|
+
if (pos <= 0)
|
|
226
|
+
return { indexed: false, smooth: false };
|
|
227
|
+
switch (id[pos + 2]) {
|
|
228
|
+
case "0": return { indexed: defaultTileOptions.enableIndexedEdges, smooth: defaultTileOptions.generateAllPolyfaceEdges };
|
|
229
|
+
case "2": return { indexed: true, smooth: false };
|
|
230
|
+
case "3": return { indexed: false, smooth: true };
|
|
231
|
+
case "4": return { indexed: true, smooth: true };
|
|
232
|
+
}
|
|
233
|
+
throw new Error("Invalid tree Id");
|
|
234
|
+
}
|
|
215
235
|
/** @internal */
|
|
216
236
|
export function getMaximumMajorTileFormatVersion(maxMajorVersion, formatVersion) {
|
|
217
237
|
// The `formatVersion` input is from the backend, telling us precisely the maximum major+minor version it can produce.
|
|
@@ -238,18 +258,19 @@ export var TreeFlags;
|
|
|
238
258
|
TreeFlags[TreeFlags["OptimizeBRepProcessing"] = 4] = "OptimizeBRepProcessing";
|
|
239
259
|
TreeFlags[TreeFlags["UseLargerTiles"] = 8] = "UseLargerTiles";
|
|
240
260
|
})(TreeFlags || (TreeFlags = {}));
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
(
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
261
|
+
function compareEdgeOptions(a, b) {
|
|
262
|
+
if (typeof a !== typeof b)
|
|
263
|
+
return a ? 1 : -1;
|
|
264
|
+
if (typeof a === "boolean") {
|
|
265
|
+
assert(typeof b === "boolean");
|
|
266
|
+
return compareBooleans(a, b);
|
|
267
|
+
}
|
|
268
|
+
assert(typeof b === "object");
|
|
269
|
+
let cmp = compareBooleans(a.indexed, b.indexed);
|
|
270
|
+
if (0 === cmp)
|
|
271
|
+
cmp = compareBooleans(a.smooth, b.smooth);
|
|
272
|
+
return cmp;
|
|
273
|
+
}
|
|
253
274
|
function animationIdToString(animationId) {
|
|
254
275
|
return `A:${animationId}_`;
|
|
255
276
|
}
|
|
@@ -268,7 +289,16 @@ export function iModelTileTreeIdToString(modelId, treeId, options) {
|
|
|
268
289
|
idStr = `${idStr}${animationIdToString(treeId.animationId)}`;
|
|
269
290
|
else if (treeId.enforceDisplayPriority) // animation and priority are currently mutually exclusive
|
|
270
291
|
flags |= TreeFlags.EnforceDisplayPriority;
|
|
271
|
-
|
|
292
|
+
let edges;
|
|
293
|
+
if (!treeId.edges) {
|
|
294
|
+
edges = "E:0_";
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
if (!treeId.edges.smooth)
|
|
298
|
+
edges = treeId.edges.indexed ? "E:2_" : "";
|
|
299
|
+
else
|
|
300
|
+
edges = treeId.edges.indexed ? "E:4_" : "E:3_";
|
|
301
|
+
}
|
|
272
302
|
const sectionCut = treeId.sectionCut ? `S${treeId.sectionCut}s` : "";
|
|
273
303
|
idStr = `${idStr}${edges}${sectionCut}`;
|
|
274
304
|
}
|
|
@@ -299,7 +329,7 @@ export function compareIModelTileTreeIds(lhs, rhs) {
|
|
|
299
329
|
// NB: The redundant checks on BatchType below are to satisfy compiler.
|
|
300
330
|
assert(lhs.type === rhs.type);
|
|
301
331
|
if (BatchType.Primary === lhs.type && BatchType.Primary === rhs.type) {
|
|
302
|
-
cmp =
|
|
332
|
+
cmp = compareEdgeOptions(lhs.edges, rhs.edges);
|
|
303
333
|
if (0 === cmp) {
|
|
304
334
|
cmp = compareBooleansOrUndefined(lhs.enforceDisplayPriority, rhs.enforceDisplayPriority);
|
|
305
335
|
if (0 === cmp)
|