@tscircuit/capacity-autorouter 0.0.57 → 0.0.59
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/dist/index.d.ts +28 -1
- package/dist/index.js +697 -12
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
package/dist/index.js
CHANGED
|
@@ -48,6 +48,12 @@ var BaseSolver = class {
|
|
|
48
48
|
failedSubSolvers;
|
|
49
49
|
timeToSolve;
|
|
50
50
|
stats = {};
|
|
51
|
+
/**
|
|
52
|
+
* For cached solvers
|
|
53
|
+
**/
|
|
54
|
+
cacheHit;
|
|
55
|
+
cacheKey;
|
|
56
|
+
cacheToSolveSpaceTransform;
|
|
51
57
|
/** DO NOT OVERRIDE! Override _step() instead */
|
|
52
58
|
step() {
|
|
53
59
|
if (this.solved) return;
|
|
@@ -8053,13 +8059,17 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
8053
8059
|
return [newNeighbor];
|
|
8054
8060
|
}
|
|
8055
8061
|
checkIfSolved(candidate) {
|
|
8056
|
-
|
|
8062
|
+
const minGapsToOtherConnectionsValid = candidate.minGaps.every(
|
|
8063
|
+
(minGap) => minGap >= this.obstacleMargin
|
|
8064
|
+
);
|
|
8065
|
+
const allPointsWithinBounds = candidate.polyLines.every((polyLine) => {
|
|
8057
8066
|
return polyLine.mPoints.every((mPoint) => {
|
|
8058
|
-
const padding = (mPoint.z1 !== mPoint.z2 ? this.viaDiameter / 2 :
|
|
8067
|
+
const padding = (mPoint.z1 !== mPoint.z2 ? this.viaDiameter / 2 : 0) * // Forgiveness outside bounds
|
|
8059
8068
|
0.9;
|
|
8060
8069
|
return withinBounds(mPoint, this.bounds, padding);
|
|
8061
8070
|
});
|
|
8062
8071
|
});
|
|
8072
|
+
return minGapsToOtherConnectionsValid && allPointsWithinBounds;
|
|
8063
8073
|
}
|
|
8064
8074
|
_step() {
|
|
8065
8075
|
if (this.phase === "setup") {
|
|
@@ -10259,6 +10269,7 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
10259
10269
|
tunedNodeCapacityMap;
|
|
10260
10270
|
MAX_CANDIDATES = 500;
|
|
10261
10271
|
iterationsSinceImprovement = 0;
|
|
10272
|
+
hyperParameters;
|
|
10262
10273
|
selectedCandidateIndex = null;
|
|
10263
10274
|
queuedOrExploredCandidatePointModificationHashes = /* @__PURE__ */ new Set();
|
|
10264
10275
|
constructorParams;
|
|
@@ -10267,6 +10278,10 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
10267
10278
|
this.constructorParams = params;
|
|
10268
10279
|
this.MUTABLE_HOPS = params.MUTABLE_HOPS ?? this.MUTABLE_HOPS;
|
|
10269
10280
|
this.MAX_ITERATIONS = 5e4;
|
|
10281
|
+
this.hyperParameters = {
|
|
10282
|
+
...params.hyperParameters,
|
|
10283
|
+
MAX_ITERATIONS_WITHOUT_IMPROVEMENT: 200
|
|
10284
|
+
};
|
|
10270
10285
|
this.nodeMap = params.nodeMap;
|
|
10271
10286
|
this.dedupedSegments = params.dedupedSegments;
|
|
10272
10287
|
if (params.dedupedSegmentMap) {
|
|
@@ -10429,16 +10444,21 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
10429
10444
|
});
|
|
10430
10445
|
return {
|
|
10431
10446
|
pointModifications,
|
|
10432
|
-
issues,
|
|
10433
10447
|
g,
|
|
10434
10448
|
h: 0,
|
|
10435
10449
|
f: g,
|
|
10436
10450
|
operationsPerformed: 0,
|
|
10437
|
-
candidateHash: createPointModificationsHash(pointModifications)
|
|
10451
|
+
candidateHash: createPointModificationsHash(pointModifications),
|
|
10438
10452
|
// candidateFullHash: createFullPointModificationsHash(
|
|
10439
10453
|
// this.unravelSection.segmentPointMap,
|
|
10440
10454
|
// pointModifications,
|
|
10441
10455
|
// ),
|
|
10456
|
+
// Ensure original candidate has issues calculated
|
|
10457
|
+
issues: getIssuesInSection(
|
|
10458
|
+
this.unravelSection,
|
|
10459
|
+
this.nodeMap,
|
|
10460
|
+
pointModifications
|
|
10461
|
+
)
|
|
10442
10462
|
};
|
|
10443
10463
|
}
|
|
10444
10464
|
get nextCandidate() {
|
|
@@ -10690,6 +10710,10 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
10690
10710
|
_step() {
|
|
10691
10711
|
const candidate = this.candidates.shift();
|
|
10692
10712
|
this.iterationsSinceImprovement++;
|
|
10713
|
+
if (this.iterationsSinceImprovement > this.hyperParameters.MAX_ITERATIONS_WITHOUT_IMPROVEMENT) {
|
|
10714
|
+
this.solved = true;
|
|
10715
|
+
return;
|
|
10716
|
+
}
|
|
10693
10717
|
if (!candidate) {
|
|
10694
10718
|
this.solved = true;
|
|
10695
10719
|
return;
|
|
@@ -10733,6 +10757,8 @@ var UnravelSectionSolver = class extends BaseSolver {
|
|
|
10733
10757
|
} else {
|
|
10734
10758
|
candidate = this.candidates[this.selectedCandidateIndex];
|
|
10735
10759
|
}
|
|
10760
|
+
} else if (this.solved) {
|
|
10761
|
+
candidate = this.bestCandidate;
|
|
10736
10762
|
} else {
|
|
10737
10763
|
candidate = this.lastProcessedCandidate || this.candidates[0];
|
|
10738
10764
|
}
|
|
@@ -10898,6 +10924,640 @@ New: (${modifiedPoint.x.toFixed(2)}, ${modifiedPoint.y.toFixed(2)}, ${modifiedPo
|
|
|
10898
10924
|
}
|
|
10899
10925
|
};
|
|
10900
10926
|
|
|
10927
|
+
// lib/solvers/UnravelSolver/CachedUnravelSectionSolver.ts
|
|
10928
|
+
import objectHash from "object-hash";
|
|
10929
|
+
|
|
10930
|
+
// lib/cache/InMemoryCache.ts
|
|
10931
|
+
var InMemoryCache = class {
|
|
10932
|
+
isSyncCache = true;
|
|
10933
|
+
cacheHits = 0;
|
|
10934
|
+
cacheMisses = 0;
|
|
10935
|
+
cache = /* @__PURE__ */ new Map();
|
|
10936
|
+
/**
|
|
10937
|
+
* Retrieves a cached solution synchronously based on the cache key.
|
|
10938
|
+
* Increments cache hit/miss counters.
|
|
10939
|
+
* @param cacheKey The key to look up in the cache.
|
|
10940
|
+
* @returns The cached solution if found, otherwise undefined.
|
|
10941
|
+
*/
|
|
10942
|
+
getCachedSolutionSync(cacheKey) {
|
|
10943
|
+
const cachedSolution = this.cache.get(cacheKey);
|
|
10944
|
+
if (cachedSolution !== void 0) {
|
|
10945
|
+
this.cacheHits++;
|
|
10946
|
+
return structuredClone(cachedSolution);
|
|
10947
|
+
} else {
|
|
10948
|
+
this.cacheMisses++;
|
|
10949
|
+
return void 0;
|
|
10950
|
+
}
|
|
10951
|
+
}
|
|
10952
|
+
/**
|
|
10953
|
+
* Retrieves a cached solution asynchronously. Wraps the synchronous method.
|
|
10954
|
+
* @param cacheKey The key to look up in the cache.
|
|
10955
|
+
* @returns A promise that resolves with the cached solution or undefined.
|
|
10956
|
+
*/
|
|
10957
|
+
async getCachedSolution(cacheKey) {
|
|
10958
|
+
return this.getCachedSolutionSync(cacheKey);
|
|
10959
|
+
}
|
|
10960
|
+
/**
|
|
10961
|
+
* Stores a solution in the cache synchronously.
|
|
10962
|
+
* Uses structured cloning to store a copy, preventing external modifications.
|
|
10963
|
+
* @param cacheKey The key under which to store the solution.
|
|
10964
|
+
* @param cachedSolution The solution data to cache.
|
|
10965
|
+
*/
|
|
10966
|
+
setCachedSolutionSync(cacheKey, cachedSolution) {
|
|
10967
|
+
this.cache.set(cacheKey, structuredClone(cachedSolution));
|
|
10968
|
+
}
|
|
10969
|
+
/**
|
|
10970
|
+
* Stores a solution in the cache asynchronously. Wraps the synchronous method.
|
|
10971
|
+
* @param cacheKey The key under which to store the solution.
|
|
10972
|
+
* @param cachedSolution The solution data to cache.
|
|
10973
|
+
* @returns A promise that resolves when the solution is cached.
|
|
10974
|
+
*/
|
|
10975
|
+
async setCachedSolution(cacheKey, cachedSolution) {
|
|
10976
|
+
this.setCachedSolutionSync(cacheKey, cachedSolution);
|
|
10977
|
+
}
|
|
10978
|
+
/**
|
|
10979
|
+
* Clears the entire cache and resets hit/miss counters.
|
|
10980
|
+
*/
|
|
10981
|
+
clearCache() {
|
|
10982
|
+
this.cache.clear();
|
|
10983
|
+
this.cacheHits = 0;
|
|
10984
|
+
this.cacheMisses = 0;
|
|
10985
|
+
}
|
|
10986
|
+
};
|
|
10987
|
+
|
|
10988
|
+
// lib/cache/LocalStorageCache.ts
|
|
10989
|
+
var CACHE_PREFIX = "tscircuit_autorouter_cache_";
|
|
10990
|
+
var LocalStorageCache = class {
|
|
10991
|
+
isSyncCache = true;
|
|
10992
|
+
cacheHits = 0;
|
|
10993
|
+
cacheMisses = 0;
|
|
10994
|
+
constructor() {
|
|
10995
|
+
if (typeof localStorage === "undefined") {
|
|
10996
|
+
console.warn(
|
|
10997
|
+
"LocalStorage is not available. LocalStorageCache will not function."
|
|
10998
|
+
);
|
|
10999
|
+
}
|
|
11000
|
+
}
|
|
11001
|
+
getKey(cacheKey) {
|
|
11002
|
+
return `${CACHE_PREFIX}${cacheKey}`;
|
|
11003
|
+
}
|
|
11004
|
+
/**
|
|
11005
|
+
* Retrieves a cached solution synchronously from localStorage.
|
|
11006
|
+
* Increments cache hit/miss counters.
|
|
11007
|
+
* @param cacheKey The key to look up in the cache.
|
|
11008
|
+
* @returns The cached solution if found and parsed correctly, otherwise undefined.
|
|
11009
|
+
*/
|
|
11010
|
+
getCachedSolutionSync(cacheKey) {
|
|
11011
|
+
if (typeof localStorage === "undefined") return void 0;
|
|
11012
|
+
const key = this.getKey(cacheKey);
|
|
11013
|
+
try {
|
|
11014
|
+
const cachedItem = localStorage.getItem(key);
|
|
11015
|
+
if (cachedItem !== null) {
|
|
11016
|
+
const solution = JSON.parse(cachedItem);
|
|
11017
|
+
this.cacheHits++;
|
|
11018
|
+
return solution;
|
|
11019
|
+
} else {
|
|
11020
|
+
this.cacheMisses++;
|
|
11021
|
+
return void 0;
|
|
11022
|
+
}
|
|
11023
|
+
} catch (error) {
|
|
11024
|
+
console.error(`Error getting cached solution sync for ${key}:`, error);
|
|
11025
|
+
this.cacheMisses++;
|
|
11026
|
+
return void 0;
|
|
11027
|
+
}
|
|
11028
|
+
}
|
|
11029
|
+
/**
|
|
11030
|
+
* Retrieves a cached solution asynchronously. Wraps the synchronous method.
|
|
11031
|
+
* @param cacheKey The key to look up in the cache.
|
|
11032
|
+
* @returns A promise that resolves with the cached solution or undefined.
|
|
11033
|
+
*/
|
|
11034
|
+
async getCachedSolution(cacheKey) {
|
|
11035
|
+
return this.getCachedSolutionSync(cacheKey);
|
|
11036
|
+
}
|
|
11037
|
+
/**
|
|
11038
|
+
* Stores a solution in localStorage synchronously.
|
|
11039
|
+
* The solution is JSON stringified before storing.
|
|
11040
|
+
* @param cacheKey The key under which to store the solution.
|
|
11041
|
+
* @param cachedSolution The solution data to cache.
|
|
11042
|
+
*/
|
|
11043
|
+
setCachedSolutionSync(cacheKey, cachedSolution) {
|
|
11044
|
+
if (typeof localStorage === "undefined") return;
|
|
11045
|
+
const key = this.getKey(cacheKey);
|
|
11046
|
+
try {
|
|
11047
|
+
const stringifiedSolution = JSON.stringify(cachedSolution);
|
|
11048
|
+
localStorage.setItem(key, stringifiedSolution);
|
|
11049
|
+
} catch (error) {
|
|
11050
|
+
console.error(`Error setting cached solution sync for ${key}:`, error);
|
|
11051
|
+
if (error instanceof DOMException && (error.name === "QuotaExceededError" || error.name === "NS_ERROR_DOM_QUOTA_REACHED")) {
|
|
11052
|
+
console.warn(
|
|
11053
|
+
`LocalStorage quota exceeded. Failed to cache solution for ${key}. Consider clearing the cache.`
|
|
11054
|
+
);
|
|
11055
|
+
}
|
|
11056
|
+
}
|
|
11057
|
+
}
|
|
11058
|
+
/**
|
|
11059
|
+
* Stores a solution in the cache asynchronously. Wraps the synchronous method.
|
|
11060
|
+
* @param cacheKey The key under which to store the solution.
|
|
11061
|
+
* @param cachedSolution The solution data to cache.
|
|
11062
|
+
* @returns A promise that resolves when the solution is cached.
|
|
11063
|
+
*/
|
|
11064
|
+
async setCachedSolution(cacheKey, cachedSolution) {
|
|
11065
|
+
this.setCachedSolutionSync(cacheKey, cachedSolution);
|
|
11066
|
+
}
|
|
11067
|
+
/**
|
|
11068
|
+
* Clears all cache entries created by this instance from localStorage
|
|
11069
|
+
* and resets hit/miss counters.
|
|
11070
|
+
*/
|
|
11071
|
+
clearCache() {
|
|
11072
|
+
if (typeof localStorage === "undefined") return;
|
|
11073
|
+
try {
|
|
11074
|
+
const keysToRemove = [];
|
|
11075
|
+
for (let i = 0; i < localStorage.length; i++) {
|
|
11076
|
+
const key = localStorage.key(i);
|
|
11077
|
+
if (key?.startsWith(CACHE_PREFIX)) {
|
|
11078
|
+
keysToRemove.push(key);
|
|
11079
|
+
}
|
|
11080
|
+
}
|
|
11081
|
+
keysToRemove.forEach((key) => localStorage.removeItem(key));
|
|
11082
|
+
console.log(
|
|
11083
|
+
`Cleared ${keysToRemove.length} items from LocalStorage cache.`
|
|
11084
|
+
);
|
|
11085
|
+
} catch (error) {
|
|
11086
|
+
console.error("Error clearing LocalStorage cache:", error);
|
|
11087
|
+
} finally {
|
|
11088
|
+
this.cacheHits = 0;
|
|
11089
|
+
this.cacheMisses = 0;
|
|
11090
|
+
}
|
|
11091
|
+
}
|
|
11092
|
+
};
|
|
11093
|
+
|
|
11094
|
+
// lib/cache/setupGlobalCaches.ts
|
|
11095
|
+
function getGlobalLocalStorageCache() {
|
|
11096
|
+
if (!globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE) {
|
|
11097
|
+
setupGlobalCaches();
|
|
11098
|
+
}
|
|
11099
|
+
return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE;
|
|
11100
|
+
}
|
|
11101
|
+
function setupGlobalCaches() {
|
|
11102
|
+
globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE ??= new LocalStorageCache();
|
|
11103
|
+
globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE ??= new InMemoryCache();
|
|
11104
|
+
}
|
|
11105
|
+
|
|
11106
|
+
// node_modules/transformation-matrix/src/applyToPoint.js
|
|
11107
|
+
function applyToPoint(matrix, point) {
|
|
11108
|
+
return Array.isArray(point) ? [
|
|
11109
|
+
matrix.a * point[0] + matrix.c * point[1] + matrix.e,
|
|
11110
|
+
matrix.b * point[0] + matrix.d * point[1] + matrix.f
|
|
11111
|
+
] : {
|
|
11112
|
+
x: matrix.a * point.x + matrix.c * point.y + matrix.e,
|
|
11113
|
+
y: matrix.b * point.x + matrix.d * point.y + matrix.f
|
|
11114
|
+
};
|
|
11115
|
+
}
|
|
11116
|
+
|
|
11117
|
+
// node_modules/transformation-matrix/src/translate.js
|
|
11118
|
+
function translate(tx, ty = 0) {
|
|
11119
|
+
return {
|
|
11120
|
+
a: 1,
|
|
11121
|
+
c: 0,
|
|
11122
|
+
e: tx,
|
|
11123
|
+
b: 0,
|
|
11124
|
+
d: 1,
|
|
11125
|
+
f: ty
|
|
11126
|
+
};
|
|
11127
|
+
}
|
|
11128
|
+
|
|
11129
|
+
// node_modules/transformation-matrix/src/rotate.js
|
|
11130
|
+
var { cos, sin, PI } = Math;
|
|
11131
|
+
|
|
11132
|
+
// node_modules/transformation-matrix/src/skew.js
|
|
11133
|
+
var { tan } = Math;
|
|
11134
|
+
|
|
11135
|
+
// node_modules/transformation-matrix/src/fromTransformAttribute.autogenerated.js
|
|
11136
|
+
function peg$subclass(child, parent) {
|
|
11137
|
+
function C() {
|
|
11138
|
+
this.constructor = child;
|
|
11139
|
+
}
|
|
11140
|
+
C.prototype = parent.prototype;
|
|
11141
|
+
child.prototype = new C();
|
|
11142
|
+
}
|
|
11143
|
+
function peg$SyntaxError(message, expected, found, location) {
|
|
11144
|
+
var self = Error.call(this, message);
|
|
11145
|
+
if (Object.setPrototypeOf) {
|
|
11146
|
+
Object.setPrototypeOf(self, peg$SyntaxError.prototype);
|
|
11147
|
+
}
|
|
11148
|
+
self.expected = expected;
|
|
11149
|
+
self.found = found;
|
|
11150
|
+
self.location = location;
|
|
11151
|
+
self.name = "SyntaxError";
|
|
11152
|
+
return self;
|
|
11153
|
+
}
|
|
11154
|
+
peg$subclass(peg$SyntaxError, Error);
|
|
11155
|
+
function peg$padEnd(str, targetLength, padString) {
|
|
11156
|
+
padString = padString || " ";
|
|
11157
|
+
if (str.length > targetLength) {
|
|
11158
|
+
return str;
|
|
11159
|
+
}
|
|
11160
|
+
targetLength -= str.length;
|
|
11161
|
+
padString += padString.repeat(targetLength);
|
|
11162
|
+
return str + padString.slice(0, targetLength);
|
|
11163
|
+
}
|
|
11164
|
+
peg$SyntaxError.prototype.format = function(sources) {
|
|
11165
|
+
var str = "Error: " + this.message;
|
|
11166
|
+
if (this.location) {
|
|
11167
|
+
var src = null;
|
|
11168
|
+
var k;
|
|
11169
|
+
for (k = 0; k < sources.length; k++) {
|
|
11170
|
+
if (sources[k].source === this.location.source) {
|
|
11171
|
+
src = sources[k].text.split(/\r\n|\n|\r/g);
|
|
11172
|
+
break;
|
|
11173
|
+
}
|
|
11174
|
+
}
|
|
11175
|
+
var s = this.location.start;
|
|
11176
|
+
var offset_s = this.location.source && typeof this.location.source.offset === "function" ? this.location.source.offset(s) : s;
|
|
11177
|
+
var loc = this.location.source + ":" + offset_s.line + ":" + offset_s.column;
|
|
11178
|
+
if (src) {
|
|
11179
|
+
var e = this.location.end;
|
|
11180
|
+
var filler = peg$padEnd("", offset_s.line.toString().length, " ");
|
|
11181
|
+
var line = src[s.line - 1];
|
|
11182
|
+
var last = s.line === e.line ? e.column : line.length + 1;
|
|
11183
|
+
var hatLen = last - s.column || 1;
|
|
11184
|
+
str += "\n --> " + loc + "\n" + filler + " |\n" + offset_s.line + " | " + line + "\n" + filler + " | " + peg$padEnd("", s.column - 1, " ") + peg$padEnd("", hatLen, "^");
|
|
11185
|
+
} else {
|
|
11186
|
+
str += "\n at " + loc;
|
|
11187
|
+
}
|
|
11188
|
+
}
|
|
11189
|
+
return str;
|
|
11190
|
+
};
|
|
11191
|
+
peg$SyntaxError.buildMessage = function(expected, found) {
|
|
11192
|
+
var DESCRIBE_EXPECTATION_FNS = {
|
|
11193
|
+
literal: function(expectation) {
|
|
11194
|
+
return '"' + literalEscape(expectation.text) + '"';
|
|
11195
|
+
},
|
|
11196
|
+
class: function(expectation) {
|
|
11197
|
+
var escapedParts = expectation.parts.map(function(part) {
|
|
11198
|
+
return Array.isArray(part) ? classEscape(part[0]) + "-" + classEscape(part[1]) : classEscape(part);
|
|
11199
|
+
});
|
|
11200
|
+
return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]";
|
|
11201
|
+
},
|
|
11202
|
+
any: function() {
|
|
11203
|
+
return "any character";
|
|
11204
|
+
},
|
|
11205
|
+
end: function() {
|
|
11206
|
+
return "end of input";
|
|
11207
|
+
},
|
|
11208
|
+
other: function(expectation) {
|
|
11209
|
+
return expectation.description;
|
|
11210
|
+
}
|
|
11211
|
+
};
|
|
11212
|
+
function hex(ch) {
|
|
11213
|
+
return ch.charCodeAt(0).toString(16).toUpperCase();
|
|
11214
|
+
}
|
|
11215
|
+
function literalEscape(s) {
|
|
11216
|
+
return s.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
|
|
11217
|
+
return "\\x0" + hex(ch);
|
|
11218
|
+
}).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
|
|
11219
|
+
return "\\x" + hex(ch);
|
|
11220
|
+
});
|
|
11221
|
+
}
|
|
11222
|
+
function classEscape(s) {
|
|
11223
|
+
return s.replace(/\\/g, "\\\\").replace(/\]/g, "\\]").replace(/\^/g, "\\^").replace(/-/g, "\\-").replace(/\0/g, "\\0").replace(/\t/g, "\\t").replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/[\x00-\x0F]/g, function(ch) {
|
|
11224
|
+
return "\\x0" + hex(ch);
|
|
11225
|
+
}).replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) {
|
|
11226
|
+
return "\\x" + hex(ch);
|
|
11227
|
+
});
|
|
11228
|
+
}
|
|
11229
|
+
function describeExpectation(expectation) {
|
|
11230
|
+
return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
|
|
11231
|
+
}
|
|
11232
|
+
function describeExpected(expected2) {
|
|
11233
|
+
var descriptions = expected2.map(describeExpectation);
|
|
11234
|
+
var i, j;
|
|
11235
|
+
descriptions.sort();
|
|
11236
|
+
if (descriptions.length > 0) {
|
|
11237
|
+
for (i = 1, j = 1; i < descriptions.length; i++) {
|
|
11238
|
+
if (descriptions[i - 1] !== descriptions[i]) {
|
|
11239
|
+
descriptions[j] = descriptions[i];
|
|
11240
|
+
j++;
|
|
11241
|
+
}
|
|
11242
|
+
}
|
|
11243
|
+
descriptions.length = j;
|
|
11244
|
+
}
|
|
11245
|
+
switch (descriptions.length) {
|
|
11246
|
+
case 1:
|
|
11247
|
+
return descriptions[0];
|
|
11248
|
+
case 2:
|
|
11249
|
+
return descriptions[0] + " or " + descriptions[1];
|
|
11250
|
+
default:
|
|
11251
|
+
return descriptions.slice(0, -1).join(", ") + ", or " + descriptions[descriptions.length - 1];
|
|
11252
|
+
}
|
|
11253
|
+
}
|
|
11254
|
+
function describeFound(found2) {
|
|
11255
|
+
return found2 ? '"' + literalEscape(found2) + '"' : "end of input";
|
|
11256
|
+
}
|
|
11257
|
+
return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
|
|
11258
|
+
};
|
|
11259
|
+
|
|
11260
|
+
// lib/solvers/UnravelSolver/CachedUnravelSectionSolver.ts
|
|
11261
|
+
var approximateCoordinate = (coord) => {
|
|
11262
|
+
return (Math.round(coord * 20) / 20).toFixed(2);
|
|
11263
|
+
};
|
|
11264
|
+
setupGlobalCaches();
|
|
11265
|
+
var CachedUnravelSectionSolver = class extends UnravelSectionSolver {
|
|
11266
|
+
cacheHit = false;
|
|
11267
|
+
cacheProvider;
|
|
11268
|
+
hasAttemptedToUseCache = false;
|
|
11269
|
+
constructor(params) {
|
|
11270
|
+
super(params);
|
|
11271
|
+
this.cacheProvider = params.cacheProvider === void 0 ? getGlobalLocalStorageCache() : params.cacheProvider;
|
|
11272
|
+
}
|
|
11273
|
+
_step() {
|
|
11274
|
+
if (!this.hasAttemptedToUseCache && this.cacheProvider) {
|
|
11275
|
+
if (this.attemptToUseCacheSync()) return;
|
|
11276
|
+
}
|
|
11277
|
+
super._step();
|
|
11278
|
+
if ((this.solved || this.failed) && this.cacheProvider) {
|
|
11279
|
+
this.saveToCacheSync();
|
|
11280
|
+
}
|
|
11281
|
+
}
|
|
11282
|
+
computeCacheKeyAndTransform() {
|
|
11283
|
+
const rootNode = this.nodeMap.get(this.rootNodeId);
|
|
11284
|
+
const realToCacheTransform = translate(
|
|
11285
|
+
-rootNode.center.x,
|
|
11286
|
+
-rootNode.center.y
|
|
11287
|
+
);
|
|
11288
|
+
const nodeIdMap = /* @__PURE__ */ new Map();
|
|
11289
|
+
const reverseNodeIdMap = /* @__PURE__ */ new Map();
|
|
11290
|
+
const segmentIdMap = /* @__PURE__ */ new Map();
|
|
11291
|
+
const reverseSegmentIdMap = /* @__PURE__ */ new Map();
|
|
11292
|
+
const segmentPointIdMap = /* @__PURE__ */ new Map();
|
|
11293
|
+
const reverseSegmentPointIdMap = /* @__PURE__ */ new Map();
|
|
11294
|
+
let nodeCounter = 0;
|
|
11295
|
+
let segmentCounter = 0;
|
|
11296
|
+
let spCounter = 0;
|
|
11297
|
+
const sortedNodeIds = [...this.unravelSection.allNodeIds].sort(
|
|
11298
|
+
(aNId, bNId) => {
|
|
11299
|
+
const n1 = this.nodeMap.get(aNId);
|
|
11300
|
+
const n2 = this.nodeMap.get(bNId);
|
|
11301
|
+
if (n1.center.x !== n2.center.x) {
|
|
11302
|
+
return n1.center.x - n2.center.x;
|
|
11303
|
+
}
|
|
11304
|
+
return n1.center.y - n2.center.y;
|
|
11305
|
+
}
|
|
11306
|
+
);
|
|
11307
|
+
for (const nodeId of sortedNodeIds) {
|
|
11308
|
+
const normId = `node_${nodeCounter++}`;
|
|
11309
|
+
nodeIdMap.set(nodeId, normId);
|
|
11310
|
+
reverseNodeIdMap.set(normId, nodeId);
|
|
11311
|
+
}
|
|
11312
|
+
const sortedSegmentPointIds = [
|
|
11313
|
+
...Array.from(this.unravelSection.segmentPointMap.entries()).sort(([, a], [, b]) => {
|
|
11314
|
+
if (a.x !== b.x) {
|
|
11315
|
+
return a.x - b.x;
|
|
11316
|
+
}
|
|
11317
|
+
return a.y - b.y;
|
|
11318
|
+
}).map(([id]) => id)
|
|
11319
|
+
].sort();
|
|
11320
|
+
for (const spId of sortedSegmentPointIds) {
|
|
11321
|
+
const normSpId = `sp_${spCounter++}`;
|
|
11322
|
+
segmentPointIdMap.set(spId, normSpId);
|
|
11323
|
+
reverseSegmentPointIdMap.set(normSpId, spId);
|
|
11324
|
+
const segmentId = this.unravelSection.segmentPointMap.get(spId).segmentId;
|
|
11325
|
+
if (!segmentIdMap.has(segmentId)) {
|
|
11326
|
+
const normSegId = `seg_${segmentCounter++}`;
|
|
11327
|
+
segmentIdMap.set(segmentId, normSegId);
|
|
11328
|
+
reverseSegmentIdMap.set(normSegId, segmentId);
|
|
11329
|
+
}
|
|
11330
|
+
}
|
|
11331
|
+
const normalizedNodes = {};
|
|
11332
|
+
for (const [nodeId, normNodeId] of nodeIdMap.entries()) {
|
|
11333
|
+
const node = this.nodeMap.get(nodeId);
|
|
11334
|
+
const transformedCenter = applyToPoint(realToCacheTransform, node.center);
|
|
11335
|
+
normalizedNodes[normNodeId] = {
|
|
11336
|
+
// ...node,
|
|
11337
|
+
width: node.width,
|
|
11338
|
+
// TODO: Scale width/height if transform includes scaling
|
|
11339
|
+
height: node.height,
|
|
11340
|
+
availableZ: node.availableZ,
|
|
11341
|
+
center: {
|
|
11342
|
+
x: approximateCoordinate(transformedCenter.x),
|
|
11343
|
+
y: approximateCoordinate(transformedCenter.y)
|
|
11344
|
+
}
|
|
11345
|
+
};
|
|
11346
|
+
}
|
|
11347
|
+
const normalizedSegmentPoints = {};
|
|
11348
|
+
for (const [spId, normSpId] of segmentPointIdMap.entries()) {
|
|
11349
|
+
const sp = this.unravelSection.segmentPointMap.get(spId);
|
|
11350
|
+
const transformedPoint = applyToPoint(realToCacheTransform, {
|
|
11351
|
+
x: sp.x,
|
|
11352
|
+
y: sp.y
|
|
11353
|
+
});
|
|
11354
|
+
normalizedSegmentPoints[normSpId] = {
|
|
11355
|
+
x: approximateCoordinate(transformedPoint.x),
|
|
11356
|
+
y: approximateCoordinate(transformedPoint.y),
|
|
11357
|
+
z: sp.z
|
|
11358
|
+
// Z is not transformed by 2D matrix
|
|
11359
|
+
// segmentId: segmentIdMap.get(sp.segmentId)!,
|
|
11360
|
+
// connectionName: sp.connectionName,
|
|
11361
|
+
};
|
|
11362
|
+
}
|
|
11363
|
+
const keyData = {
|
|
11364
|
+
hyperParameters: this.hyperParameters,
|
|
11365
|
+
normalizedNodes,
|
|
11366
|
+
normalizedSegmentPoints,
|
|
11367
|
+
mutableHops: this.MUTABLE_HOPS
|
|
11368
|
+
};
|
|
11369
|
+
const cacheKey = `unravelsec:${objectHash(keyData)}`;
|
|
11370
|
+
const cacheToSolveSpaceTransform = {
|
|
11371
|
+
realToCacheTransform,
|
|
11372
|
+
nodeIdMap,
|
|
11373
|
+
segmentIdMap,
|
|
11374
|
+
segmentPointIdMap,
|
|
11375
|
+
reverseNodeIdMap,
|
|
11376
|
+
reverseSegmentIdMap,
|
|
11377
|
+
reverseSegmentPointIdMap
|
|
11378
|
+
};
|
|
11379
|
+
this.cacheKey = cacheKey;
|
|
11380
|
+
this.cacheToSolveSpaceTransform = cacheToSolveSpaceTransform;
|
|
11381
|
+
return { cacheKey, cacheToSolveSpaceTransform };
|
|
11382
|
+
}
|
|
11383
|
+
applyCachedSolution(cachedSolution) {
|
|
11384
|
+
if (cachedSolution.success === false) {
|
|
11385
|
+
this.failed = true;
|
|
11386
|
+
return;
|
|
11387
|
+
}
|
|
11388
|
+
if (!this.cacheToSolveSpaceTransform) {
|
|
11389
|
+
console.error("Cache transform not available to apply cached solution.");
|
|
11390
|
+
return;
|
|
11391
|
+
}
|
|
11392
|
+
const {
|
|
11393
|
+
// realToCacheTransform, // Not needed to apply deltas
|
|
11394
|
+
reverseSegmentPointIdMap,
|
|
11395
|
+
reverseNodeIdMap
|
|
11396
|
+
// Needed if issues depend on node IDs
|
|
11397
|
+
} = this.cacheToSolveSpaceTransform;
|
|
11398
|
+
const pointModifications = /* @__PURE__ */ new Map();
|
|
11399
|
+
for (const [
|
|
11400
|
+
normSpId,
|
|
11401
|
+
normDelta
|
|
11402
|
+
// normDelta.dx and normDelta.dy are strings here
|
|
11403
|
+
] of cachedSolution.bestCandidatePointModificationsDelta) {
|
|
11404
|
+
const originalSpId = reverseSegmentPointIdMap.get(normSpId);
|
|
11405
|
+
if (!originalSpId) {
|
|
11406
|
+
console.warn(
|
|
11407
|
+
`Could not find original ID for normalized SP ID: ${normSpId} when applying cache.`
|
|
11408
|
+
);
|
|
11409
|
+
continue;
|
|
11410
|
+
}
|
|
11411
|
+
const originalSegmentPoint = this.unravelSection.segmentPointMap.get(originalSpId);
|
|
11412
|
+
if (!originalSegmentPoint) {
|
|
11413
|
+
console.warn(
|
|
11414
|
+
`Could not find original segment point for ID: ${originalSpId} when applying cache.`
|
|
11415
|
+
);
|
|
11416
|
+
continue;
|
|
11417
|
+
}
|
|
11418
|
+
const modifiedPoint = {};
|
|
11419
|
+
if (normDelta.dx !== void 0) {
|
|
11420
|
+
const dxNum = parseFloat(normDelta.dx);
|
|
11421
|
+
if (!Number.isNaN(dxNum)) {
|
|
11422
|
+
modifiedPoint.x = originalSegmentPoint.x + dxNum;
|
|
11423
|
+
} else {
|
|
11424
|
+
console.warn(`Failed to parse cached dx coordinate: ${normDelta.dx}`);
|
|
11425
|
+
}
|
|
11426
|
+
}
|
|
11427
|
+
if (normDelta.dy !== void 0) {
|
|
11428
|
+
const dyNum = parseFloat(normDelta.dy);
|
|
11429
|
+
if (!Number.isNaN(dyNum)) {
|
|
11430
|
+
modifiedPoint.y = originalSegmentPoint.y + dyNum;
|
|
11431
|
+
} else {
|
|
11432
|
+
console.warn(`Failed to parse cached dy coordinate: ${normDelta.dy}`);
|
|
11433
|
+
}
|
|
11434
|
+
}
|
|
11435
|
+
if (normDelta.dz !== void 0) {
|
|
11436
|
+
modifiedPoint.z = originalSegmentPoint.z + normDelta.dz;
|
|
11437
|
+
}
|
|
11438
|
+
if (Object.keys(modifiedPoint).length > 0) {
|
|
11439
|
+
pointModifications.set(originalSpId, modifiedPoint);
|
|
11440
|
+
}
|
|
11441
|
+
}
|
|
11442
|
+
const issues = getIssuesInSection(
|
|
11443
|
+
this.unravelSection,
|
|
11444
|
+
this.nodeMap,
|
|
11445
|
+
pointModifications
|
|
11446
|
+
);
|
|
11447
|
+
this.bestCandidate = {
|
|
11448
|
+
pointModifications,
|
|
11449
|
+
issues,
|
|
11450
|
+
f: cachedSolution.bestCandidateF,
|
|
11451
|
+
g: cachedSolution.bestCandidateF,
|
|
11452
|
+
// Assume g is the main component off for cached solution
|
|
11453
|
+
h: 0,
|
|
11454
|
+
// Heuristic is 0 when solution is loaded
|
|
11455
|
+
operationsPerformed: -1,
|
|
11456
|
+
// Indicate it's from cache, operation count unknown
|
|
11457
|
+
candidateHash: createPointModificationsHash(pointModifications)
|
|
11458
|
+
};
|
|
11459
|
+
this.cacheHit = true;
|
|
11460
|
+
this.solved = true;
|
|
11461
|
+
}
|
|
11462
|
+
attemptToUseCacheSync() {
|
|
11463
|
+
this.hasAttemptedToUseCache = true;
|
|
11464
|
+
if (!this.cacheProvider?.isSyncCache) {
|
|
11465
|
+
console.log(
|
|
11466
|
+
"Cache provider is not synchronous, skipping sync cache check."
|
|
11467
|
+
);
|
|
11468
|
+
return false;
|
|
11469
|
+
}
|
|
11470
|
+
if (!this.cacheKey) {
|
|
11471
|
+
this.computeCacheKeyAndTransform();
|
|
11472
|
+
}
|
|
11473
|
+
if (!this.cacheKey) {
|
|
11474
|
+
console.error("Failed to compute cache key.");
|
|
11475
|
+
return false;
|
|
11476
|
+
}
|
|
11477
|
+
try {
|
|
11478
|
+
const cachedSolution = this.cacheProvider.getCachedSolutionSync(
|
|
11479
|
+
this.cacheKey
|
|
11480
|
+
);
|
|
11481
|
+
if (cachedSolution) {
|
|
11482
|
+
this.applyCachedSolution(cachedSolution);
|
|
11483
|
+
return true;
|
|
11484
|
+
} else {
|
|
11485
|
+
}
|
|
11486
|
+
} catch (error) {
|
|
11487
|
+
console.error("Error attempting to use cache:", error);
|
|
11488
|
+
}
|
|
11489
|
+
return false;
|
|
11490
|
+
}
|
|
11491
|
+
saveToCacheSync() {
|
|
11492
|
+
if (this.failed) {
|
|
11493
|
+
this.cacheProvider?.setCachedSolutionSync(this.cacheKey, {
|
|
11494
|
+
success: false
|
|
11495
|
+
});
|
|
11496
|
+
return;
|
|
11497
|
+
}
|
|
11498
|
+
if (!this.bestCandidate) return;
|
|
11499
|
+
const {
|
|
11500
|
+
// realToCacheTransform, // Not needed to calculate deltas
|
|
11501
|
+
segmentPointIdMap
|
|
11502
|
+
} = this.cacheToSolveSpaceTransform;
|
|
11503
|
+
const normalizedDeltas = [];
|
|
11504
|
+
for (const [
|
|
11505
|
+
originalSpId,
|
|
11506
|
+
modifiedPoint
|
|
11507
|
+
// This contains the absolute modified coordinates {x?, y?, z?}
|
|
11508
|
+
] of this.bestCandidate.pointModifications.entries()) {
|
|
11509
|
+
const normSpId = segmentPointIdMap.get(originalSpId);
|
|
11510
|
+
if (!normSpId) {
|
|
11511
|
+
console.warn(
|
|
11512
|
+
`Could not find normalized ID for original SP ID: ${originalSpId} when saving to cache.`
|
|
11513
|
+
);
|
|
11514
|
+
continue;
|
|
11515
|
+
}
|
|
11516
|
+
const originalSegmentPoint = this.unravelSection.segmentPointMap.get(originalSpId);
|
|
11517
|
+
if (!originalSegmentPoint) {
|
|
11518
|
+
console.warn(
|
|
11519
|
+
`Could not find original segment point for ID: ${originalSpId} when saving cache.`
|
|
11520
|
+
);
|
|
11521
|
+
continue;
|
|
11522
|
+
}
|
|
11523
|
+
const normDelta = {};
|
|
11524
|
+
let hasDelta = false;
|
|
11525
|
+
if (modifiedPoint.x !== void 0) {
|
|
11526
|
+
const dx = modifiedPoint.x - originalSegmentPoint.x;
|
|
11527
|
+
const approxDx = approximateCoordinate(dx);
|
|
11528
|
+
if (parseFloat(approxDx) !== 0) {
|
|
11529
|
+
normDelta.dx = approxDx;
|
|
11530
|
+
hasDelta = true;
|
|
11531
|
+
}
|
|
11532
|
+
}
|
|
11533
|
+
if (modifiedPoint.y !== void 0) {
|
|
11534
|
+
const dy = modifiedPoint.y - originalSegmentPoint.y;
|
|
11535
|
+
const approxDy = approximateCoordinate(dy);
|
|
11536
|
+
if (parseFloat(approxDy) !== 0) {
|
|
11537
|
+
normDelta.dy = approxDy;
|
|
11538
|
+
hasDelta = true;
|
|
11539
|
+
}
|
|
11540
|
+
}
|
|
11541
|
+
if (modifiedPoint.z !== void 0) {
|
|
11542
|
+
const dz = modifiedPoint.z - originalSegmentPoint.z;
|
|
11543
|
+
if (dz !== 0) {
|
|
11544
|
+
normDelta.dz = dz;
|
|
11545
|
+
hasDelta = true;
|
|
11546
|
+
}
|
|
11547
|
+
}
|
|
11548
|
+
if (hasDelta) {
|
|
11549
|
+
normalizedDeltas.push([normSpId, normDelta]);
|
|
11550
|
+
}
|
|
11551
|
+
}
|
|
11552
|
+
const cachedSolution = {
|
|
11553
|
+
success: true,
|
|
11554
|
+
bestCandidatePointModificationsDelta: normalizedDeltas,
|
|
11555
|
+
bestCandidateF: this.bestCandidate.f
|
|
11556
|
+
};
|
|
11557
|
+
this.cacheProvider?.setCachedSolutionSync(this.cacheKey, cachedSolution);
|
|
11558
|
+
}
|
|
11559
|
+
};
|
|
11560
|
+
|
|
10901
11561
|
// lib/solvers/UnravelSolver/getDedupedSegments.ts
|
|
10902
11562
|
var getDedupedSegments = (assignedSegments) => {
|
|
10903
11563
|
const dedupedSegments = [];
|
|
@@ -11024,12 +11684,19 @@ var UnravelMultiSectionSolver = class extends BaseSolver {
|
|
|
11024
11684
|
attemptsToFixNode;
|
|
11025
11685
|
activeSubSolver = null;
|
|
11026
11686
|
segmentPointMap;
|
|
11687
|
+
cacheProvider = null;
|
|
11027
11688
|
constructor({
|
|
11028
11689
|
assignedSegments,
|
|
11029
11690
|
colorMap,
|
|
11030
|
-
nodes
|
|
11691
|
+
nodes,
|
|
11692
|
+
cacheProvider
|
|
11031
11693
|
}) {
|
|
11032
11694
|
super();
|
|
11695
|
+
this.stats.successfulOptimizations = 0;
|
|
11696
|
+
this.stats.failedOptimizations = 0;
|
|
11697
|
+
this.stats.cacheHits = 0;
|
|
11698
|
+
this.stats.cacheMisses = 0;
|
|
11699
|
+
this.cacheProvider = cacheProvider ?? null;
|
|
11033
11700
|
this.MAX_ITERATIONS = 1e6;
|
|
11034
11701
|
this.dedupedSegments = getDedupedSegments(assignedSegments);
|
|
11035
11702
|
this.dedupedSegmentMap = /* @__PURE__ */ new Map();
|
|
@@ -11112,7 +11779,7 @@ var UnravelMultiSectionSolver = class extends BaseSolver {
|
|
|
11112
11779
|
highestPfNodeId,
|
|
11113
11780
|
(this.attemptsToFixNode.get(highestPfNodeId) ?? 0) + 1
|
|
11114
11781
|
);
|
|
11115
|
-
this.activeSubSolver = new
|
|
11782
|
+
this.activeSubSolver = new CachedUnravelSectionSolver({
|
|
11116
11783
|
dedupedSegments: this.dedupedSegments,
|
|
11117
11784
|
dedupedSegmentMap: this.dedupedSegmentMap,
|
|
11118
11785
|
nodeMap: this.nodeMap,
|
|
@@ -11123,15 +11790,26 @@ var UnravelMultiSectionSolver = class extends BaseSolver {
|
|
|
11123
11790
|
MUTABLE_HOPS: this.MUTABLE_HOPS,
|
|
11124
11791
|
segmentPointMap: this.segmentPointMap,
|
|
11125
11792
|
nodeToSegmentPointMap: this.nodeToSegmentPointMap,
|
|
11126
|
-
segmentToSegmentPointMap: this.segmentToSegmentPointMap
|
|
11793
|
+
segmentToSegmentPointMap: this.segmentToSegmentPointMap,
|
|
11794
|
+
cacheProvider: this.cacheProvider
|
|
11127
11795
|
});
|
|
11128
11796
|
}
|
|
11129
11797
|
this.activeSubSolver.step();
|
|
11130
11798
|
const { bestCandidate, originalCandidate, lastProcessedCandidate } = this.activeSubSolver;
|
|
11131
|
-
|
|
11132
|
-
|
|
11799
|
+
if (this.activeSubSolver.failed) {
|
|
11800
|
+
this.stats.failedOptimizations += 1;
|
|
11801
|
+
this.activeSubSolver = null;
|
|
11802
|
+
return;
|
|
11803
|
+
}
|
|
11804
|
+
if (this.activeSubSolver.solved) {
|
|
11805
|
+
if (this.activeSubSolver.cacheHit) {
|
|
11806
|
+
this.stats.cacheHits += 1;
|
|
11807
|
+
} else {
|
|
11808
|
+
this.stats.cacheMisses += 1;
|
|
11809
|
+
}
|
|
11133
11810
|
const foundBetterSolution = bestCandidate && bestCandidate.g < originalCandidate.g;
|
|
11134
11811
|
if (foundBetterSolution) {
|
|
11812
|
+
this.stats.successfulOptimizations += 1;
|
|
11135
11813
|
for (const [
|
|
11136
11814
|
segmentPointId,
|
|
11137
11815
|
pointModification
|
|
@@ -11147,6 +11825,8 @@ var UnravelMultiSectionSolver = class extends BaseSolver {
|
|
|
11147
11825
|
this.computeNodePf(this.nodeMap.get(nodeId))
|
|
11148
11826
|
);
|
|
11149
11827
|
}
|
|
11828
|
+
} else {
|
|
11829
|
+
this.stats.failedOptimizations += 1;
|
|
11150
11830
|
}
|
|
11151
11831
|
this.activeSubSolver = null;
|
|
11152
11832
|
}
|
|
@@ -12074,7 +12754,7 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
12074
12754
|
this.nodeMap = new Map(
|
|
12075
12755
|
this.sectionNodes.map((n) => [n.capacityMeshNodeId, n])
|
|
12076
12756
|
);
|
|
12077
|
-
this.nodeEdgeMap = getNodeEdgeMap(this.sectionEdges);
|
|
12757
|
+
this.nodeEdgeMap = params.nodeEdgeMap ?? getNodeEdgeMap(this.sectionEdges);
|
|
12078
12758
|
this.colorMap = params.colorMap ?? {};
|
|
12079
12759
|
this.usedNodeCapacityMap = new Map(
|
|
12080
12760
|
this.sectionNodes.map((node) => [node.capacityMeshNodeId, 0])
|
|
@@ -12551,6 +13231,7 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12551
13231
|
this.simpleRouteJson = params.simpleRouteJson;
|
|
12552
13232
|
this.nodes = params.nodes;
|
|
12553
13233
|
this.edges = params.edges;
|
|
13234
|
+
this.nodeEdgeMap = getNodeEdgeMap(this.edges);
|
|
12554
13235
|
this.colorMap = params.colorMap ?? {};
|
|
12555
13236
|
this.nodeMap = new Map(
|
|
12556
13237
|
this.nodes.map((node) => [node.capacityMeshNodeId, node])
|
|
@@ -12635,7 +13316,8 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
12635
13316
|
sectionEdges: section.sectionEdges,
|
|
12636
13317
|
sectionNodes: section.sectionNodes,
|
|
12637
13318
|
colorMap: this.colorMap,
|
|
12638
|
-
centerNodeId: section.centerNodeId
|
|
13319
|
+
centerNodeId: section.centerNodeId,
|
|
13320
|
+
nodeEdgeMap: this.nodeEdgeMap
|
|
12639
13321
|
});
|
|
12640
13322
|
this.activeSubSolver = this.sectionSolver;
|
|
12641
13323
|
this.nodeOptimizationAttemptCountMap.set(
|
|
@@ -15089,6 +15771,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
15089
15771
|
}
|
|
15090
15772
|
this.connMap = getConnectivityMapFromSimpleRouteJson(srj);
|
|
15091
15773
|
this.colorMap = getColorMap(srj, this.connMap);
|
|
15774
|
+
this.cacheProvider = opts.cacheProvider ?? null;
|
|
15092
15775
|
this.startTimeOfPhase = {};
|
|
15093
15776
|
this.endTimeOfPhase = {};
|
|
15094
15777
|
this.timeSpentOnPhase = {};
|
|
@@ -15119,6 +15802,7 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
15119
15802
|
connMap;
|
|
15120
15803
|
srjWithPointPairs;
|
|
15121
15804
|
capacityNodes = null;
|
|
15805
|
+
cacheProvider = null;
|
|
15122
15806
|
pipelineDef = [
|
|
15123
15807
|
definePipelineStep(
|
|
15124
15808
|
"netToPointPairsSolver",
|
|
@@ -15266,7 +15950,8 @@ var AutoroutingPipelineSolver = class extends BaseSolver {
|
|
|
15266
15950
|
{
|
|
15267
15951
|
assignedSegments: cms.segmentToPointSolver?.solvedSegments || [],
|
|
15268
15952
|
colorMap: cms.colorMap,
|
|
15269
|
-
nodes: cms.capacityNodes
|
|
15953
|
+
nodes: cms.capacityNodes,
|
|
15954
|
+
cacheProvider: this.cacheProvider
|
|
15270
15955
|
}
|
|
15271
15956
|
]
|
|
15272
15957
|
),
|