@pilio/gemini-watermark-remover 1.0.20 → 1.0.21

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.
@@ -40,6 +40,18 @@ const VALIDATION_MIN_CONFIDENCE_FOR_ADAPTIVE_TRIAL = 0.25;
40
40
  const STANDARD_FAST_PATH_RESIDUAL_THRESHOLD = 0.22;
41
41
  const STANDARD_FAST_PATH_GRADIENT_THRESHOLD = 0.08;
42
42
  const FIXED_CORE_MAX_ACCEPTED_SPATIAL_RESIDUAL = 0.45;
43
+ const FIXED_CORE_STRONG_96_MAX_NEGATIVE_SPATIAL_RESIDUAL = 0.52;
44
+ const FIXED_CORE_STRONG_96_MIN_ORIGINAL_SPATIAL_SCORE = 0.95;
45
+ const FIXED_CORE_STRONG_96_MIN_ORIGINAL_GRADIENT_SCORE = 0.9;
46
+ const FIXED_CORE_STRONG_96_MAX_PROCESSED_GRADIENT_SCORE = 0.16;
47
+ const FIXED_CORE_STRONG_96_MIN_IMPROVEMENT = 0.45;
48
+ const FIXED_CORE_STRONG_96_MAX_TEXTURE = 0.05;
49
+ const FIXED_CORE_STRONG_96_MAX_NEAR_BLACK_INCREASE = 0.02;
50
+ const FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_ORIGINAL_SPATIAL_SCORE = 0.55;
51
+ const FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_ORIGINAL_GRADIENT_SCORE = 0.5;
52
+ const FIXED_CORE_STRONG_96_LOW_RESIDUAL_MAX_SPATIAL_SCORE = 0.08;
53
+ const FIXED_CORE_STRONG_96_LOW_RESIDUAL_MAX_GRADIENT_SCORE = 0.24;
54
+ const FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_IMPROVEMENT = 0.6;
43
55
  const STANDARD_EXPAND_CATALOG_MIN_ORIGINAL_GRADIENT = 0.12;
44
56
  const WEAK_ALPHA_PRIORITY_CLEAN_GRADIENT_THRESHOLD = 0.12;
45
57
  const STRONG_ORIGINAL_SIGNAL_SPATIAL_ADVANTAGE = 0.2;
@@ -81,6 +93,14 @@ const STANDARD_VISIBLE_CATALOG_MAX_SPATIAL_RESIDUAL = 0.35;
81
93
  const STANDARD_VISIBLE_CATALOG_MAX_GRADIENT_RESIDUAL = 0.18;
82
94
  const STANDARD_VISIBLE_CATALOG_MIN_IMPROVEMENT = 0.7;
83
95
  const STANDARD_VISIBLE_CATALOG_MAX_NEAR_BLACK_INCREASE = 0.05;
96
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_SPATIAL_SCORE = 0.9;
97
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_GRADIENT_SCORE = 0.7;
98
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_RESIDUAL = 0.16;
99
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_GRADIENT = 0.16;
100
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_IMPROVEMENT = 0.9;
101
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_GRADIENT_DROP = 0.6;
102
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_NEAR_BLACK_INCREASE = 0.01;
103
+ const STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_TEXTURE = 0.1;
84
104
  const STANDARD_HARD_REJECT_OVERRIDE_MIN_SPATIAL_SCORE = 0.9;
85
105
  const STANDARD_HARD_REJECT_OVERRIDE_MIN_GRADIENT_SCORE = 0.7;
86
106
  const STANDARD_HARD_REJECT_OVERRIDE_MAX_RESIDUAL = 0.08;
@@ -252,7 +272,7 @@ function buildStandardCandidateSeeds({
252
272
  config
253
273
  );
254
274
 
255
- seeds.push({
275
+ const baseSeed = {
256
276
  config: candidateConfig,
257
277
  position: candidatePosition,
258
278
  alphaMap,
@@ -270,11 +290,43 @@ function buildStandardCandidateSeeds({
270
290
  catalogEvidenceGate: catalogEntry.metadata.evidenceGate
271
291
  } : null
272
292
  )
273
- });
293
+ };
294
+ seeds.push(baseSeed);
295
+
296
+ if (shouldAddDarkPolaritySeed(candidateConfig)) {
297
+ seeds.push({
298
+ ...baseSeed,
299
+ alphaMap: createNegativeAlphaMap(alphaMap),
300
+ source: `${baseSeed.source}+dark-polarity`,
301
+ provenance: mergeCandidateProvenance(
302
+ baseSeed.provenance,
303
+ { darkPolarity: true }
304
+ )
305
+ });
306
+ }
274
307
  }
275
-
276
- return seeds;
277
- }
308
+
309
+ return seeds;
310
+ }
311
+
312
+ function shouldAddDarkPolaritySeed(config) {
313
+ return config?.logoSize === 96 &&
314
+ config.marginRight === 192 &&
315
+ config.marginBottom === 192;
316
+ }
317
+
318
+ const negativeAlphaMapCache = new WeakMap();
319
+
320
+ function createNegativeAlphaMap(alphaMap) {
321
+ const cached = negativeAlphaMapCache.get(alphaMap);
322
+ if (cached) return cached;
323
+ const negative = new Float32Array(alphaMap.length);
324
+ for (let index = 0; index < alphaMap.length; index++) {
325
+ negative[index] = -alphaMap[index];
326
+ }
327
+ negativeAlphaMapCache.set(alphaMap, negative);
328
+ return negative;
329
+ }
278
330
 
279
331
  function inferDecisionTier(candidate, { directMatch = false } = {}) {
280
332
  if (!candidate) return 'insufficient';
@@ -334,6 +386,10 @@ function resolveAlphaMapForConfig(config, {
334
386
  if (config.alphaVariant && config.logoSize === 96 && alpha96Variants) {
335
387
  return alpha96Variants[config.alphaVariant] ?? null;
336
388
  }
389
+ if (config.alphaVariant && typeof getAlphaMap === 'function') {
390
+ const variantAlpha = getAlphaMap(`${config.logoSize}-${config.alphaVariant}`);
391
+ if (variantAlpha) return variantAlpha;
392
+ }
337
393
  return typeof resolveAlphaMap === 'function'
338
394
  ? resolveAlphaMap(config.logoSize)
339
395
  : resolveAlphaMapForSize(config.logoSize, {
@@ -381,7 +437,54 @@ function isStrictFixedCoreCandidate(candidate) {
381
437
  const processedSpatial = Number(candidate.processedSpatialScore);
382
438
  if (!Number.isFinite(processedSpatial)) return false;
383
439
 
384
- return Math.abs(processedSpatial) <= FIXED_CORE_MAX_ACCEPTED_SPATIAL_RESIDUAL;
440
+ if (Math.abs(processedSpatial) <= FIXED_CORE_MAX_ACCEPTED_SPATIAL_RESIDUAL) {
441
+ return true;
442
+ }
443
+
444
+ const originalSpatial = Number(candidate.originalSpatialScore);
445
+ const originalGradient = Number(candidate.originalGradientScore);
446
+ const processedGradient = Number(candidate.processedGradientScore);
447
+ const improvement = Number(candidate.improvement);
448
+ const texturePenalty = Number(candidate.texturePenalty);
449
+ const nearBlackIncrease = Number(candidate.nearBlackIncrease);
450
+ if (
451
+ !Number.isFinite(originalSpatial) ||
452
+ !Number.isFinite(originalGradient) ||
453
+ !Number.isFinite(processedGradient) ||
454
+ !Number.isFinite(improvement) ||
455
+ !Number.isFinite(texturePenalty) ||
456
+ !Number.isFinite(nearBlackIncrease)
457
+ ) {
458
+ return false;
459
+ }
460
+
461
+ const isStrongStandard96 =
462
+ candidate.config?.logoSize === 96 &&
463
+ isStandardCandidateSource(candidate) &&
464
+ candidate.provenance?.localShift !== true &&
465
+ candidate.provenance?.sizeJitter !== true &&
466
+ candidate.provenance?.previewAnchor !== true;
467
+ if (!isStrongStandard96 || candidate.hardReject === true) return false;
468
+
469
+ const boundedNegativeOvershoot =
470
+ processedSpatial < 0 &&
471
+ Math.abs(processedSpatial) <= FIXED_CORE_STRONG_96_MAX_NEGATIVE_SPATIAL_RESIDUAL &&
472
+ originalSpatial >= FIXED_CORE_STRONG_96_MIN_ORIGINAL_SPATIAL_SCORE &&
473
+ originalGradient >= FIXED_CORE_STRONG_96_MIN_ORIGINAL_GRADIENT_SCORE &&
474
+ processedGradient <= FIXED_CORE_STRONG_96_MAX_PROCESSED_GRADIENT_SCORE &&
475
+ improvement >= FIXED_CORE_STRONG_96_MIN_IMPROVEMENT &&
476
+ texturePenalty <= FIXED_CORE_STRONG_96_MAX_TEXTURE &&
477
+ nearBlackIncrease <= FIXED_CORE_STRONG_96_MAX_NEAR_BLACK_INCREASE;
478
+ const strongLowResidualFullAnchor =
479
+ Math.abs(processedSpatial) <= FIXED_CORE_STRONG_96_LOW_RESIDUAL_MAX_SPATIAL_SCORE &&
480
+ processedGradient <= FIXED_CORE_STRONG_96_LOW_RESIDUAL_MAX_GRADIENT_SCORE &&
481
+ originalSpatial >= FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_ORIGINAL_SPATIAL_SCORE &&
482
+ originalGradient >= FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_ORIGINAL_GRADIENT_SCORE &&
483
+ improvement >= FIXED_CORE_STRONG_96_LOW_RESIDUAL_MIN_IMPROVEMENT &&
484
+ texturePenalty <= FIXED_CORE_STRONG_96_MAX_TEXTURE &&
485
+ nearBlackIncrease <= FIXED_CORE_STRONG_96_MAX_NEAR_BLACK_INCREASE;
486
+
487
+ return boundedNegativeOvershoot || strongLowResidualFullAnchor;
385
488
  }
386
489
 
387
490
  function isCleanWeakAlphaPriorityCandidate(candidate) {
@@ -683,13 +786,36 @@ export function evaluateRestorationCandidate({
683
786
  processedScores.gradientScore <= STANDARD_VISIBLE_CATALOG_MAX_GRADIENT_RESIDUAL &&
684
787
  improvement >= STANDARD_VISIBLE_CATALOG_MIN_IMPROVEMENT &&
685
788
  nearBlackIncrease <= STANDARD_VISIBLE_CATALOG_MAX_NEAR_BLACK_INCREASE;
789
+ const newMarginAlphaHardRejectAllowed =
790
+ textureAssessment.hardReject === true &&
791
+ isNewMarginAlphaVariantTrial({ config, provenance }) &&
792
+ alphaGain === 1 &&
793
+ originalScores.spatialScore >= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_SPATIAL_SCORE &&
794
+ originalScores.gradientScore >= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_GRADIENT_SCORE &&
795
+ Math.abs(processedScores.spatialScore) <= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_RESIDUAL &&
796
+ processedScores.gradientScore <= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_GRADIENT &&
797
+ improvement >= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_IMPROVEMENT &&
798
+ gradientDrop >= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MIN_GRADIENT_DROP &&
799
+ nearBlackIncrease <= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_NEAR_BLACK_INCREASE &&
800
+ texturePenalty <= STANDARD_NEW_MARGIN_ALPHA_OVERRIDE_MAX_TEXTURE;
686
801
  const originalEvidenceAllowed =
687
802
  !isStandardCandidateSource({ source }) ||
688
803
  originalScores.spatialScore >= STANDARD_VALIDATION_MIN_ORIGINAL_SPATIAL_SCORE ||
689
804
  originalScores.gradientScore >= STANDARD_VALIDATION_MIN_ORIGINAL_GRADIENT_SCORE;
805
+ const catalogEvidenceGate = provenance?.catalogEvidenceGate ?? null;
806
+ const catalogEvidenceAllowed =
807
+ catalogEvidenceGate !== 'medium' ||
808
+ originalScores.spatialScore >= 0.15 ||
809
+ originalScores.gradientScore >= 0.08;
690
810
  const accepted =
691
811
  originalEvidenceAllowed &&
692
- (hardRejectAllowed || conservativeCatalogHardRejectAllowed || visibleCatalogHardRejectAllowed) &&
812
+ catalogEvidenceAllowed &&
813
+ (
814
+ hardRejectAllowed ||
815
+ conservativeCatalogHardRejectAllowed ||
816
+ visibleCatalogHardRejectAllowed ||
817
+ newMarginAlphaHardRejectAllowed
818
+ ) &&
693
819
  nearBlackIncreaseAllowed &&
694
820
  improvement >= VALIDATION_MIN_IMPROVEMENT &&
695
821
  (
@@ -712,8 +838,12 @@ export function evaluateRestorationCandidate({
712
838
  processedGradient: processedScores.gradientScore,
713
839
  suppressionGain: improvement
714
840
  });
841
+ const hardRejectBypassed =
842
+ conservativeCatalogHardRejectAllowed ||
843
+ visibleCatalogHardRejectAllowed ||
844
+ newMarginAlphaHardRejectAllowed;
715
845
  const damage = scoreDamage({
716
- hardReject: textureAssessment.hardReject,
846
+ hardReject: textureAssessment.hardReject === true && !hardRejectBypassed,
717
847
  nearBlackIncrease,
718
848
  texturePenalty
719
849
  });
@@ -772,19 +902,55 @@ export function evaluateRestorationCandidate({
772
902
  }
773
903
 
774
904
  function pickBestValidatedCandidate(candidates) {
775
- const accepted = candidates.filter((candidate) => candidate?.accepted);
776
- if (accepted.length === 0) return null;
905
+ const accepted = candidates.filter((candidate) => candidate?.accepted);
906
+ if (accepted.length === 0) return null;
777
907
 
778
908
  accepted.sort((a, b) => {
779
909
  if (a.validationCost !== b.validationCost) {
780
910
  return a.validationCost - b.validationCost;
781
911
  }
782
912
 
783
- return b.improvement - a.improvement;
784
- });
785
-
786
- return accepted[0];
787
- }
913
+ return b.improvement - a.improvement;
914
+ });
915
+
916
+ const validationBest = accepted[0];
917
+ const preservedStrongCanonical96 = accepted.find((candidate) => (
918
+ shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(candidate, validationBest)
919
+ ));
920
+ return preservedStrongCanonical96 ?? validationBest;
921
+ }
922
+
923
+ function pickAggressiveStrongLocatedCandidate(candidates) {
924
+ const located = candidates
925
+ .filter((candidate) => (
926
+ candidate &&
927
+ isAggressiveLocatedCandidate(candidate)
928
+ ))
929
+ .sort((left, right) => {
930
+ const rightSignal =
931
+ Number(right.originalSpatialScore) +
932
+ Math.max(0, Number(right.originalGradientScore)) * 0.75;
933
+ const leftSignal =
934
+ Number(left.originalSpatialScore) +
935
+ Math.max(0, Number(left.originalGradientScore)) * 0.75;
936
+ if (rightSignal !== leftSignal) return rightSignal - leftSignal;
937
+ return Number(left.validationCost ?? Infinity) - Number(right.validationCost ?? Infinity);
938
+ });
939
+ return located[0] ?? null;
940
+ }
941
+
942
+ function isAggressiveLocatedCandidate(candidate) {
943
+ const spatialScore = Number(candidate.originalSpatialScore);
944
+ const gradientScore = Number(candidate.originalGradientScore);
945
+ if (!Number.isFinite(spatialScore) || !Number.isFinite(gradientScore)) return false;
946
+
947
+ const highConfidence = spatialScore >= 0.75 && gradientScore >= 0.5;
948
+ const clearShape = spatialScore >= 0.38 && gradientScore >= -0.06;
949
+ const lowContrastShape = spatialScore >= 0.24 && gradientScore >= 0.02;
950
+ const visibleGradient = spatialScore >= 0.12 && gradientScore >= 0.28;
951
+
952
+ return highConfidence || clearShape || lowContrastShape || visibleGradient;
953
+ }
788
954
 
789
955
  function createCandidateRegionImageData({
790
956
  originalImageData,
@@ -872,6 +1038,12 @@ export function pickBetterCandidate(currentBest, candidate, minCostDelta = 0.005
872
1038
  if (shouldPreserveCatalogOriginalSignal(currentBest, candidate)) {
873
1039
  return currentBest;
874
1040
  }
1041
+ if (shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(currentBest, candidate)) {
1042
+ return currentBest;
1043
+ }
1044
+ if (shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(candidate, currentBest)) {
1045
+ return candidate;
1046
+ }
875
1047
  if (shouldPreferCatalogOriginalSignal(candidate, currentBest)) {
876
1048
  return candidate;
877
1049
  }
@@ -965,7 +1137,11 @@ function isCatalogVariantCandidate(candidate) {
965
1137
 
966
1138
  function isCurrentLargeMarginCatalogCandidate(candidate) {
967
1139
  return isCatalogVariantCandidate(candidate) &&
968
- candidate?.config?.logoSize === 48 &&
1140
+ isCurrentLargeMarginCandidate(candidate);
1141
+ }
1142
+
1143
+ function isCurrentLargeMarginCandidate(candidate) {
1144
+ return candidate?.config?.logoSize === 48 &&
969
1145
  candidate.config.marginRight === 96 &&
970
1146
  candidate.config.marginBottom === 96;
971
1147
  }
@@ -975,7 +1151,7 @@ function isPreviewAnchorCandidate(candidate) {
975
1151
  }
976
1152
 
977
1153
  function shouldPreferCatalogOriginalSignal(candidate, currentBest) {
978
- if (!isCurrentLargeMarginCatalogCandidate(candidate)) return false;
1154
+ if (!isCurrentLargeMarginCandidate(candidate)) return false;
979
1155
  if (currentBest?.provenance?.localShift === true || currentBest?.provenance?.sizeJitter === true) {
980
1156
  return false;
981
1157
  }
@@ -986,13 +1162,11 @@ function shouldPreferCatalogOriginalSignal(candidate, currentBest) {
986
1162
 
987
1163
  return candidateReliable &&
988
1164
  currentReliable &&
989
- isPreviewAnchorCandidate(currentBest) &&
990
1165
  hasMuchStrongerOriginalSignal(candidate, currentBest);
991
1166
  }
992
1167
 
993
1168
  function shouldPreserveCatalogOriginalSignal(currentBest, candidate) {
994
- if (!isCurrentLargeMarginCatalogCandidate(currentBest)) return false;
995
- if (!isPreviewAnchorCandidate(candidate)) return false;
1169
+ if (!isCurrentLargeMarginCandidate(currentBest)) return false;
996
1170
 
997
1171
  const currentReliable = hasReliableCandidateOriginalSignal(currentBest);
998
1172
  const candidateReliable = hasReliableCandidateOriginalSignal(candidate);
@@ -1003,6 +1177,67 @@ function shouldPreserveCatalogOriginalSignal(currentBest, candidate) {
1003
1177
  hasMuchStrongerOriginalSignal(currentBest, candidate);
1004
1178
  }
1005
1179
 
1180
+ function isCanonicalDefault96Candidate(candidate) {
1181
+ return isStandardCandidateSource(candidate) &&
1182
+ candidate?.provenance?.catalogVariant !== true &&
1183
+ candidate?.provenance?.localShift !== true &&
1184
+ candidate?.provenance?.sizeJitter !== true &&
1185
+ candidate?.provenance?.previewAnchor !== true &&
1186
+ candidate?.config?.logoSize === 96 &&
1187
+ candidate.config.marginRight === 64 &&
1188
+ candidate.config.marginBottom === 64;
1189
+ }
1190
+
1191
+ function isDefault96GeometryCandidate(candidate) {
1192
+ return isStandardCandidateSource(candidate) &&
1193
+ candidate?.provenance?.localShift !== true &&
1194
+ candidate?.provenance?.sizeJitter !== true &&
1195
+ candidate?.provenance?.previewAnchor !== true &&
1196
+ candidate?.config?.logoSize === 96 &&
1197
+ candidate.config.marginRight === 64 &&
1198
+ candidate.config.marginBottom === 64;
1199
+ }
1200
+
1201
+ function shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(currentBest, candidate) {
1202
+ if (!isCanonicalDefault96Candidate(currentBest)) return false;
1203
+ if (!isCurrentLargeMarginCatalogCandidate(candidate)) return false;
1204
+
1205
+ const currentSpatial = Number(currentBest.originalSpatialScore);
1206
+ const currentGradient = Number(currentBest.originalGradientScore);
1207
+ const currentProcessedSpatial = Number(currentBest.processedSpatialScore);
1208
+ const currentProcessedGradient = Number(currentBest.processedGradientScore);
1209
+ const candidateSpatial = Number(candidate.originalSpatialScore);
1210
+ const candidateGradient = Number(candidate.originalGradientScore);
1211
+ if (
1212
+ !Number.isFinite(currentSpatial) ||
1213
+ !Number.isFinite(currentGradient) ||
1214
+ !Number.isFinite(currentProcessedSpatial) ||
1215
+ !Number.isFinite(currentProcessedGradient) ||
1216
+ !Number.isFinite(candidateSpatial) ||
1217
+ !Number.isFinite(candidateGradient)
1218
+ ) {
1219
+ return false;
1220
+ }
1221
+
1222
+ const currentAlreadyCleared = currentBest.residual?.cleared === true;
1223
+ const currentStrongLowResidual =
1224
+ currentSpatial >= 0.55 &&
1225
+ currentGradient >= 0.5 &&
1226
+ Math.abs(currentProcessedSpatial) <= 0.08 &&
1227
+ currentProcessedGradient <= 0.24;
1228
+ const candidateHasWeakOriginalSignal =
1229
+ candidateGradient < STANDARD_VALIDATION_MIN_ORIGINAL_GRADIENT_SCORE ||
1230
+ (
1231
+ candidateSpatial <= currentSpatial - 0.2 &&
1232
+ candidateGradient <= currentGradient - 0.3
1233
+ );
1234
+
1235
+ return currentSpatial >= 0.4 &&
1236
+ currentGradient >= 0.2 &&
1237
+ (currentAlreadyCleared || currentStrongLowResidual) &&
1238
+ candidateHasWeakOriginalSignal;
1239
+ }
1240
+
1006
1241
  function hasWeakDriftEvidence(candidate) {
1007
1242
  const candidateSpatial = Number(candidate?.originalSpatialScore);
1008
1243
  const candidateGradient = Number(candidate?.originalGradientScore);
@@ -1600,9 +1835,38 @@ function searchStrongStandardTrialAlphaGain({
1600
1835
  };
1601
1836
  }
1602
1837
 
1838
+ function searchFixedCoreStrongStandardAlphaGain({
1839
+ originalImageData,
1840
+ baseCandidate,
1841
+ alphaGainCandidates
1842
+ }) {
1843
+ if (!isCanonicalDefault96Candidate(baseCandidate)) return null;
1844
+ if (!hasReliableCandidateOriginalSignal(baseCandidate)) return null;
1845
+
1846
+ let bestCandidate = null;
1847
+ const baselineNearBlackRatio = calculateNearBlackRatio(originalImageData, baseCandidate.position);
1848
+ for (const candidateGain of alphaGainCandidates) {
1849
+ if (!Number.isFinite(candidateGain) || candidateGain <= 0 || candidateGain === 1) continue;
1850
+ const candidate = evaluateRestorationCandidate({
1851
+ originalImageData,
1852
+ alphaMap: baseCandidate.alphaMap,
1853
+ position: baseCandidate.position,
1854
+ source: `${baseCandidate.source}+gain`,
1855
+ config: baseCandidate.config,
1856
+ baselineNearBlackRatio,
1857
+ alphaGain: candidateGain,
1858
+ provenance: baseCandidate.provenance,
1859
+ includeImageData: false
1860
+ });
1861
+ if (!candidate?.accepted || !isStrictFixedCoreCandidate(candidate)) continue;
1862
+ bestCandidate = pickBetterCandidate(bestCandidate, candidate, 0.002);
1863
+ }
1864
+
1865
+ return bestCandidate;
1866
+ }
1867
+
1603
1868
  function isNewMarginAlphaVariantTrial(candidate) {
1604
- return isCatalogVariantCandidate(candidate) &&
1605
- candidate?.config?.logoSize === 96 &&
1869
+ return candidate?.config?.logoSize === 96 &&
1606
1870
  candidate.config.marginRight === 192 &&
1607
1871
  candidate.config.marginBottom === 192 &&
1608
1872
  candidate.config.alphaVariant === '20260520';
@@ -1864,8 +2128,13 @@ function resolveStandardAnchorSelection({
1864
2128
  alphaPriorityGains
1865
2129
  });
1866
2130
 
2131
+ const shouldSearchCatalogRescue =
2132
+ standardSelection.standardTrial &&
2133
+ !standardSelection.standardTrial.accepted &&
2134
+ shouldEscalateSearch(standardSelection.standardTrial);
1867
2135
  const shouldExpandStandardCatalog =
1868
2136
  forceCatalogVariants ||
2137
+ shouldSearchCatalogRescue ||
1869
2138
  !standardSelection.hasReliableStandardMatch &&
1870
2139
  (
1871
2140
  !standardSelection.standardTrial ||
@@ -2153,6 +2422,7 @@ export function selectInitialCandidate({
2153
2422
  getAlphaMap,
2154
2423
  allowAdaptiveSearch,
2155
2424
  allowAutomaticSearch = true,
2425
+ allowAggressiveStrongLocated = false,
2156
2426
  alphaGainCandidates,
2157
2427
  alphaPriorityGains = [1],
2158
2428
  alpha96Variants = null
@@ -2397,8 +2667,24 @@ export function selectInitialCandidate({
2397
2667
  }
2398
2668
 
2399
2669
  if (!baseCandidate) {
2400
- const validatedCandidate = pickBestValidatedCandidate([standardTrial, adaptiveTrial]);
2670
+ const validatedCandidate = pickBestValidatedCandidate([
2671
+ ...standardTrials,
2672
+ adaptiveTrial
2673
+ ]);
2401
2674
  if (!validatedCandidate) {
2675
+ const aggressiveLocatedCandidate = allowAggressiveStrongLocated
2676
+ ? pickAggressiveStrongLocatedCandidate([
2677
+ ...standardTrials,
2678
+ adaptiveTrial
2679
+ ])
2680
+ : null;
2681
+ if (aggressiveLocatedCandidate) {
2682
+ baseCandidate = {
2683
+ ...aggressiveLocatedCandidate,
2684
+ source: `${aggressiveLocatedCandidate.source}+aggressive-located`
2685
+ };
2686
+ baseDecisionTier = 'direct-match';
2687
+ } else {
2402
2688
  const fixedCoreLocalGeometryCandidate = !allowAutomaticSearch
2403
2689
  ? searchFixedCoreLocalGeometryCandidate({
2404
2690
  originalImageData,
@@ -2425,6 +2711,7 @@ export function selectInitialCandidate({
2425
2711
  decisionTier: 'insufficient'
2426
2712
  };
2427
2713
  }
2714
+ }
2428
2715
  } else {
2429
2716
  baseCandidate = {
2430
2717
  ...validatedCandidate,
@@ -2439,32 +2726,88 @@ export function selectInitialCandidate({
2439
2726
  baseDecisionTier = hasReliableStandardMatch ? 'direct-match' : 'validated-match';
2440
2727
  }
2441
2728
 
2729
+ if (!allowAutomaticSearch && isCurrentLargeMarginCatalogCandidate(baseCandidate)) {
2730
+ const initialCanonical96Candidate = (
2731
+ config?.logoSize === 96 &&
2732
+ config.marginRight === 64 &&
2733
+ config.marginBottom === 64 &&
2734
+ fallbackAlphaMap
2735
+ )
2736
+ ? evaluateRestorationCandidate({
2737
+ originalImageData,
2738
+ alphaMap: fallbackAlphaMap,
2739
+ position,
2740
+ source: 'standard',
2741
+ config,
2742
+ baselineNearBlackRatio: calculateNearBlackRatio(originalImageData, position),
2743
+ alphaGain: 1,
2744
+ provenance: null,
2745
+ includeImageData: false
2746
+ })
2747
+ : null;
2748
+ const fixedCoreCanonical96Candidate = searchFixedCoreStrongStandardAlphaGain({
2749
+ originalImageData,
2750
+ baseCandidate: initialCanonical96Candidate,
2751
+ alphaGainCandidates
2752
+ });
2753
+ if (shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(fixedCoreCanonical96Candidate, baseCandidate)) {
2754
+ baseCandidate = fixedCoreCanonical96Candidate;
2755
+ baseDecisionTier = 'direct-match';
2756
+ }
2757
+ }
2758
+
2442
2759
  if (!allowAutomaticSearch && !isStrictFixedCoreCandidate(baseCandidate)) {
2443
- const bestEffortCandidate = searchBestEffortCurrentLargeMarginWeakAlpha({
2760
+ const fixedCoreStrongAlphaGainCandidate = searchFixedCoreStrongStandardAlphaGain({
2444
2761
  originalImageData,
2445
- standardTrials,
2762
+ baseCandidate,
2446
2763
  alphaGainCandidates
2447
2764
  });
2448
- if (bestEffortCandidate) {
2449
- baseCandidate = bestEffortCandidate;
2765
+ if (fixedCoreStrongAlphaGainCandidate) {
2766
+ baseCandidate = fixedCoreStrongAlphaGainCandidate;
2450
2767
  baseDecisionTier = 'direct-match';
2451
2768
  } else {
2452
- const fixedCoreLocalGeometryCandidate = searchFixedCoreLocalGeometryCandidate({
2769
+ const bestEffortCandidate = searchBestEffortCurrentLargeMarginWeakAlpha({
2453
2770
  originalImageData,
2454
- candidateSeeds: standardCandidateSeeds,
2455
- resolveAlphaMap,
2771
+ standardTrials,
2456
2772
  alphaGainCandidates
2457
2773
  });
2458
- baseCandidate = fixedCoreLocalGeometryCandidate;
2459
- baseDecisionTier = fixedCoreLocalGeometryCandidate ? 'direct-match' : 'insufficient';
2774
+ if (bestEffortCandidate) {
2775
+ baseCandidate = bestEffortCandidate;
2776
+ baseDecisionTier = 'direct-match';
2777
+ } else {
2778
+ const fixedCoreLocalGeometryCandidate = searchFixedCoreLocalGeometryCandidate({
2779
+ originalImageData,
2780
+ candidateSeeds: standardCandidateSeeds,
2781
+ resolveAlphaMap,
2782
+ alphaGainCandidates
2783
+ });
2784
+ baseCandidate = fixedCoreLocalGeometryCandidate;
2785
+ baseDecisionTier = fixedCoreLocalGeometryCandidate ? 'direct-match' : 'insufficient';
2786
+ }
2460
2787
  }
2461
2788
  }
2462
2789
 
2463
2790
  if (!baseCandidate) {
2464
2791
  const validatedCandidate = allowAutomaticSearch
2465
- ? pickBestValidatedCandidate([standardTrial, adaptiveTrial])
2792
+ ? pickBestValidatedCandidate([
2793
+ ...standardTrials,
2794
+ adaptiveTrial
2795
+ ])
2466
2796
  : null;
2467
2797
  if (!validatedCandidate) {
2798
+ const aggressiveLocatedCandidate = allowAggressiveStrongLocated
2799
+ ? pickAggressiveStrongLocatedCandidate([
2800
+ ...standardTrials,
2801
+ adaptiveTrial
2802
+ ])
2803
+ : null;
2804
+ if (aggressiveLocatedCandidate) {
2805
+ baseCandidate = {
2806
+ ...aggressiveLocatedCandidate,
2807
+ source: `${aggressiveLocatedCandidate.source}+aggressive-located`
2808
+ };
2809
+ baseDecisionTier = 'direct-match';
2810
+ } else {
2468
2811
  const fixedCoreLocalGeometryCandidate = !allowAutomaticSearch
2469
2812
  ? searchFixedCoreLocalGeometryCandidate({
2470
2813
  originalImageData,
@@ -2491,6 +2834,7 @@ export function selectInitialCandidate({
2491
2834
  decisionTier: 'insufficient'
2492
2835
  };
2493
2836
  }
2837
+ }
2494
2838
  } else {
2495
2839
  baseCandidate = {
2496
2840
  ...validatedCandidate,
@@ -2500,6 +2844,51 @@ export function selectInitialCandidate({
2500
2844
  }
2501
2845
  }
2502
2846
 
2847
+ if (isCurrentLargeMarginCatalogCandidate(baseCandidate)) {
2848
+ const initialCanonical96Seed = (
2849
+ config?.logoSize === 96 &&
2850
+ config.marginRight === 64 &&
2851
+ config.marginBottom === 64 &&
2852
+ fallbackAlphaMap
2853
+ )
2854
+ ? evaluateRestorationCandidate({
2855
+ originalImageData,
2856
+ alphaMap: fallbackAlphaMap,
2857
+ position,
2858
+ source: 'standard',
2859
+ config,
2860
+ baselineNearBlackRatio: calculateNearBlackRatio(originalImageData, position),
2861
+ alphaGain: 1,
2862
+ provenance: null,
2863
+ includeImageData: false
2864
+ })
2865
+ : null;
2866
+ const rawCanonical96Seed =
2867
+ standardTrials.find((candidate) => isCanonicalDefault96Candidate(candidate)) ??
2868
+ (isCanonicalDefault96Candidate(standardTrial) ? standardTrial : null) ??
2869
+ standardTrials.find((candidate) => isDefault96GeometryCandidate(candidate)) ??
2870
+ (isDefault96GeometryCandidate(standardTrial) ? standardTrial : null) ??
2871
+ initialCanonical96Seed;
2872
+ const canonical96Seed = rawCanonical96Seed && !isCanonicalDefault96Candidate(rawCanonical96Seed)
2873
+ ? {
2874
+ ...rawCanonical96Seed,
2875
+ source: 'standard',
2876
+ provenance: null
2877
+ }
2878
+ : rawCanonical96Seed;
2879
+ const strictCanonical96Candidate = isStrictFixedCoreCandidate(canonical96Seed)
2880
+ ? canonical96Seed
2881
+ : searchFixedCoreStrongStandardAlphaGain({
2882
+ originalImageData,
2883
+ baseCandidate: canonical96Seed,
2884
+ alphaGainCandidates
2885
+ });
2886
+ if (shouldPreserveStrongCanonical96AgainstWeakCurrentLargeMargin(strictCanonical96Candidate, baseCandidate)) {
2887
+ baseCandidate = strictCanonical96Candidate;
2888
+ baseDecisionTier = 'direct-match';
2889
+ }
2890
+ }
2891
+
2503
2892
  const {
2504
2893
  selectedTrial,
2505
2894
  source,