@bitstack/ng-boundary 14.0.6-alpha.5 → 14.0.7-alpha.0

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.
@@ -93,6 +93,10 @@ export class BsBoundary {
93
93
  if (this.orientation === 'portraitLockRotation') {
94
94
  return false;
95
95
  }
96
+ // fluid: 不區分橫直向,以寬度為基準
97
+ if (this.orientation === 'fluid') {
98
+ return false;
99
+ }
96
100
  // landscape: 鎖定橫向
97
101
  if (this.orientation === 'landscape') {
98
102
  return true;
@@ -138,8 +142,8 @@ export class BsBoundary {
138
142
  this.orientationChange.emit(true);
139
143
  return;
140
144
  }
141
- // portrait 或 portraitLockRotation: 鎖定為直向
142
- if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation') {
145
+ // portrait、portraitLockRotationfluid: 鎖定為直向
146
+ if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation' || this.orientation === 'fluid') {
143
147
  this.boundaryContext.setIsLandscape(false);
144
148
  this.orientationChange.emit(false);
145
149
  return;
@@ -239,6 +243,18 @@ export class BsBoundary {
239
243
  [vw100, vh100] = [vh100, vw100];
240
244
  }
241
245
  // ========================================
246
+ // Fluid 模式:不參考寬高比,直接使用螢幕尺寸
247
+ // ========================================
248
+ if (this.orientation === 'fluid') {
249
+ const boundaryWidth = vw100;
250
+ const boundaryHeight = vh100;
251
+ const px2vwRatio = vw100 / designWidth;
252
+ hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);
253
+ hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);
254
+ hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);
255
+ return;
256
+ }
257
+ // ========================================
242
258
  // Step 3: 計算比例和邊界最大值
243
259
  // ========================================
244
260
  const landscapeRatio = designWidth / designHeight;
@@ -272,7 +288,7 @@ export class BsBoundary {
272
288
  }
273
289
  }
274
290
  BsBoundary.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, deps: [], target: i0.ɵɵFactoryTarget.Component });
275
- BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
291
+ BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.fluid": "orientation === \"fluid\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
276
292
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, decorators: [{
277
293
  type: Component,
278
294
  args: [{ selector: 'bs-boundary', standalone: true, providers: [BsBoundaryContextService], host: {
@@ -281,9 +297,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
281
297
  '[class.portrait]': '!isLandscape && orientation === "portrait"',
282
298
  '[class.landscape-lock-rotation]': 'orientation === "landscapeLockRotation"',
283
299
  '[class.portrait-lock-rotation]': 'orientation === "portraitLockRotation"',
300
+ '[class.fluid]': 'orientation === "fluid"',
284
301
  '[class.actual-portrait]': 'actualIsPortrait',
285
302
  '[class.actual-landscape]': '!actualIsPortrait'
286
- }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
303
+ }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
287
304
  }], propDecorators: { isFixedCenter: [{
288
305
  type: Input
289
306
  }], pointerEventsNone: [{
@@ -299,4 +316,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
299
316
  }], orientationChange: [{
300
317
  type: Output
301
318
  }] } });
302
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnMtYm91bmRhcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9iaXRzdGFjay1uZy1ib3VuZGFyeS9zcmMvbGliL2JzLWJvdW5kYXJ5LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvYml0c3RhY2stbmctYm91bmRhcnkvc3JjL2xpYi90ZW1wbGF0ZS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFFSCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUVMLE1BQU0sR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFakUsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sK0JBQStCLENBQUM7O0FBR3ZFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBaUJILE1BQU0sT0FBTyxVQUFVO0lBaEJ2QjtRQWtCSSwrREFBK0Q7UUFDL0QsbUJBQW1CO1FBQ25CLCtEQUErRDtRQUUvRDs7O1dBR0c7UUFDTSxrQkFBYSxHQUFhLEtBQUssQ0FBQztRQUV6Qzs7O1dBR0c7UUFDTSxzQkFBaUIsR0FBYSxLQUFLLENBQUM7UUFFN0M7Ozs7Ozs7O1dBUUc7UUFDTSxnQkFBVyxHQUFzQixNQUFNLENBQUM7UUFtQmpEOzs7O1dBSUc7UUFDTyxzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBRTFELCtEQUErRDtRQUMvRCx1QkFBdUI7UUFDdkIsK0RBQStEO1FBRXZELHVCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hELG9CQUFlLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDbkQsZUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFV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QkFNRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBV0csV0FBVztzQkFBbkIsS0FBSztnQkFLRyxZQUFZO3NCQUFwQixLQUFLO2dCQU1HLFdBQVc7c0JBQW5CLEtBQUs7Z0JBTUcsWUFBWTtzQkFBcEIsS0FBSztnQkFPSSxpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0JyZWFrcG9pbnRPYnNlcnZlcn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2xheW91dCc7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGluamVjdCxcbiAgICBJbnB1dCwgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZyb21FdmVudCwgU3ViamVjdCwgdGFrZVVudGlsfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtCc0JvdW5kYXJ5Q29udGV4dFNlcnZpY2V9IGZyb20gJy4vYnMtYm91bmRhcnktY29udGV4dC5zZXJ2aWNlJztcbmltcG9ydCB7VE9yaWVudGF0aW9uTW9kZX0gZnJvbSAnLi9tb2RlbCc7XG5cbi8qKlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCc0JvdW5kYXJ5IENvbXBvbmVudCAtIEFXRCDoh6rpganmh4npgornlYzlrrnlmahcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICpcbiAqIOWKn+iDveiqquaYju+8mlxuICogMS4g5o+Q5L6b6Z+/5oeJ5byP6YKK55WM5a655Zmo77yM6Ieq5YuV6YGp5oeJ5LiN5ZCM6Kit5YKZ5bC65a+4XG4gKiAyLiDmlK/mj7QgNSDnqK7mlrnlkJHmqKHlvI/vvJphdXRvLCBwb3J0cmFpdCwgbGFuZHNjYXBlLCBwb3J0cmFpdExvY2tSb3RhdGlvbiwgbGFuZHNjYXBlTG9ja1JvdGF0aW9uXG4gKiAzLiDkvb/nlKggQ1NTIOiuiuaVuOWvpuePvuWLleaFi+ioiOeul++8jOaUr+aPtCBweDJ2dygpIOWHveaVuFxuICogNC4g55u45a65IENocm9tZSA3NCvvvIzkvb/nlKggSmF2YVNjcmlwdCDoqIjnrpfpgornlYzlsLrlr7hcbiAqXG4gKiDkvb/nlKjnr4TkvovvvJpcbiAqIGBgYGh0bWxcbiAqIDxicy1ib3VuZGFyeSBbb3JpZW50YXRpb25dPVwiJ2F1dG8nXCIgW2lzRml4ZWRDZW50ZXJdPVwidHJ1ZVwiPlxuICogICA8ZGl2IGNsYXNzPVwiY29udGVudFwiPi4uLjwvZGl2PlxuICogPC9icy1ib3VuZGFyeT5cbiAqIGBgYFxuICpcbiAqIENTUyDorormlbjoqK3lrprvvJpcbiAqIGBgYHNjc3NcbiAqIGJzLWJvdW5kYXJ5IHtcbiAqICAgLS1kZXNpZ24td2lkdGg6IDM3NTsgICAvLyDoqK3oqIjnqL/lr6zluqZcbiAqICAgLS1kZXNpZ24taGVpZ2h0OiA2Njc7ICAvLyDoqK3oqIjnqL/pq5jluqZcbiAqIH1cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2JzLWJvdW5kYXJ5JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGVtcGxhdGUuaHRtbCcsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzdHlsZVVybHM6IFsnLi9zdHlsZXMuc2NzcyddLFxuICAgIHByb3ZpZGVyczogW0JzQm91bmRhcnlDb250ZXh0U2VydmljZV0sXG4gICAgaG9zdDoge1xuICAgICAgICAnW2NsYXNzLmF1dG9dJzogJ29yaWVudGF0aW9uID09PSBcImF1dG9cIicsXG4gICAgICAgICdbY2xhc3MubGFuZHNjYXBlXSc6ICdpc0xhbmRzY2FwZSAmJiBvcmllbnRhdGlvbiA9PT0gXCJsYW5kc2NhcGVcIicsXG4gICAgICAgICdbY2xhc3MucG9ydHJhaXRdJzogJyFpc0xhbmRzY2FwZSAmJiBvcmllbnRhdGlvbiA9PT0gXCJwb3J0cmFpdFwiJyxcbiAgICAgICAgJ1tjbGFzcy5sYW5kc2NhcGUtbG9jay1yb3RhdGlvbl0nOiAnb3JpZW50YXRpb24gPT09IFwibGFuZHNjYXBlTG9ja1JvdGF0aW9uXCInLFxuICAgICAgICAnW2NsYXNzLnBvcnRyYWl0LWxvY2stcm90YXRpb25dJzogJ29yaWVudGF0aW9uID09PSBcInBvcnRyYWl0TG9ja1JvdGF0aW9uXCInLFxuICAgICAgICAnW2NsYXNzLmFjdHVhbC1wb3J0cmFpdF0nOiAnYWN0dWFsSXNQb3J0cmFpdCcsXG4gICAgICAgICdbY2xhc3MuYWN0dWFsLWxhbmRzY2FwZV0nOiAnIWFjdHVhbElzUG9ydHJhaXQnXG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBCc0JvdW5kYXJ5IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gSW5wdXRzICYgT3V0cHV0c1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICog5piv5ZCm5bCH5YWn5a655Zu65a6a5Zyo6KaW56qX5Lit5aSuXG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKSBpc0ZpeGVkQ2VudGVyPzogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICog5piv5ZCm56aB55So5oyH5qiZ5LqL5Lu2XG4gICAgICogQGRlZmF1bHQgZmFsc2VcbiAgICAgKi9cbiAgICBASW5wdXQoKSBwb2ludGVyRXZlbnRzTm9uZT86IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIOaWueWQkeaooeW8j1xuICAgICAqIC0gYXV0bzog6Ieq5YuV5qqi5ris5pa55ZCRXG4gICAgICogLSBwb3J0cmFpdDog6Y6W5a6a55u05ZCRXG4gICAgICogLSBsYW5kc2NhcGU6IOmOluWumuapq+WQkVxuICAgICAqIC0gcG9ydHJhaXRMb2NrUm90YXRpb246IOW8t+WItuebtOWQke+8iOapq+WQkeioreWCmeaZguaXi+i9iSAtOTDCsO+8iVxuICAgICAqIC0gbGFuZHNjYXBlTG9ja1JvdGF0aW9uOiDlvLfliLbmqavlkJHvvIjnm7TlkJHoqK3lgpnmmYLml4vovYkgOTDCsO+8iVxuICAgICAqIEBkZWZhdWx0ICdhdXRvJ1xuICAgICAqL1xuICAgIEBJbnB1dCgpIG9yaWVudGF0aW9uPzogVE9yaWVudGF0aW9uTW9kZSA9ICdhdXRvJztcblxuICAgIC8qKlxuICAgICAqIOWQkeWFp+WxpOWuueWZqOi9ieeZvOeahOiHquioguaoo+W8j1xuICAgICAqL1xuICAgIEBJbnB1dCgpIGZvcndhcmRTdHlsZT86IFJlY29yZDxzdHJpbmcsIHN0cmluZz47XG5cbiAgICAvKipcbiAgICAgKiDoqK3oqIjnqL/lr6zluqbvvIjllq7kvY3vvJpweO+8iVxuICAgICAqIOW/heWhq+WPg+aVuFxuICAgICAqL1xuICAgIEBJbnB1dCgpIGRlc2lnbldpZHRoITogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICog6Kit6KiI56i/6auY5bqm77yI5Zau5L2N77yacHjvvIlcbiAgICAgKiDlv4Xloavlj4PmlbhcbiAgICAgKi9cbiAgICBASW5wdXQoKSBkZXNpZ25IZWlnaHQhOiBudW1iZXI7XG5cbiAgICAvKipcbiAgICAgKiDmlrnlkJHororljJbkuovku7ZcbiAgICAgKiBAZW1pdHMgdHJ1ZTogbGFuZHNjYXBl77yI5qmr5bGP77yJXG4gICAgICogQGVtaXRzIGZhbHNlOiBwb3J0cmFpdO+8iOebtOWxj++8iVxuICAgICAqL1xuICAgIEBPdXRwdXQoKSBvcmllbnRhdGlvbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFByaXZhdGUgRGVwZW5kZW5jaWVzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICBwcml2YXRlIGJyZWFrcG9pbnRPYnNlcnZlciA9IGluamVjdChCcmVha3BvaW50T2JzZXJ2ZXIpO1xuICAgIHByaXZhdGUgYm91bmRhcnlDb250ZXh0ID0gaW5qZWN0KEJzQm91bmRhcnlDb250ZXh0U2VydmljZSk7XG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuICAgIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gUHVibGljIFByb3BlcnRpZXNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIOWvpumam+ioreWCmeaWueWQke+8iOWfuuaWvOimluWPo+WwuuWvuO+8iVxuICAgICAqIHRydWU6IOebtOWQkSAoaGVpZ2h0ID4gd2lkdGgpXG4gICAgICogZmFsc2U6IOapq+WQkSAod2lkdGggPj0gaGVpZ2h0KVxuICAgICAqL1xuICAgIGFjdHVhbElzUG9ydHJhaXQgPSBmYWxzZTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIEdldHRlcnNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIOWIpOaWt+eVtuWJjeaYr+WQpueCuuapq+WQkeaooeW8j1xuICAgICAqIOagueaTmiBvcmllbnRhdGlvbiDoqK3lrprlkozlr6bpmpvoqK3lgpnmlrnlkJHliKTmlrdcbiAgICAgKi9cbiAgICBnZXQgaXNMYW5kc2NhcGUoKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGxhbmRzY2FwZUxvY2tSb3RhdGlvbjog5by35Yi25qmr5bGP5qih5byPXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcG9ydHJhaXRMb2NrUm90YXRpb246IOW8t+WItuebtOWxj+aooeW8j1xuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3BvcnRyYWl0TG9ja1JvdGF0aW9uJykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGxhbmRzY2FwZTog6Y6W5a6a5qmr5ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlJykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgLy8gcG9ydHJhaXQ6IOmOluWumuebtOWQkVxuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3BvcnRyYWl0Jykge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIC8vIGF1dG86IOiHquWLleaqoua4rFxuICAgICAgICByZXR1cm4gdGhpcy5ib3VuZGFyeUNvbnRleHQuZ2V0SXNMYW5kc2NhcGUoKTtcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBMaWZlY3ljbGUgSG9va3NcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZUFjdHVhbE9yaWVudGF0aW9uKCk7XG4gICAgICAgIHRoaXMuc2V0dXBCcmVha3BvaW50T2JzZXJ2ZXIoKTtcbiAgICAgICAgdGhpcy5zZXR1cFJlc2l6ZU9ic2VydmVyKCk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICAvLyDkvb/nlKggQElucHV0IOWPg+aVuO+8jOWPr+S7peeri+WNs+ioiOeul++8iOeEoemcgOetieW+hSBDU1PvvIlcbiAgICAgICAgdGhpcy51cGRhdGVCb3VuZGFyeUNhbGN1bGF0aW9ucygpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIE9ic2VydmVycyBTZXR1cCAtIOebo+iBveWZqOioreWumlxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICog6Kit5a6a5pa55ZCR6K6K5YyW55uj5o6nXG4gICAgICpcbiAgICAgKiDlt6XkvZzljp/nkIbvvJpcbiAgICAgKiAtIGxvY2sg5qih5byP77yIcG9ydHJhaXQvbGFuZHNjYXBl77yJ77ya55u05o6l6Kit5a6a5Zu65a6a5pa55ZCR77yM5LiN55uj6IG96K6K5YyWXG4gICAgICogLSBsb2NrUm90YXRpb24g5qih5byP77ya6Kit5a6a5Zu65a6a5pa55ZCR77yM5L2G6ZyA55uj6IG95a+m6Zqb6Kit5YKZ5pa55ZCR5Lul6Ke455m85peL6L2JXG4gICAgICogLSBhdXRvIOaooeW8j++8muS9v+eUqCBCcmVha3BvaW50T2JzZXJ2ZXIg55uj6IG96Kit5YKZ5pa55ZCR6K6K5YyWXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZXR1cEJyZWFrcG9pbnRPYnNlcnZlcigpIHtcbiAgICAgICAgLy8gbGFuZHNjYXBlIOaIliBsYW5kc2NhcGVMb2NrUm90YXRpb246IOmOluWumueCuuapq+WQkVxuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ2xhbmRzY2FwZScgfHwgdGhpcy5vcmllbnRhdGlvbiA9PT0gJ2xhbmRzY2FwZUxvY2tSb3RhdGlvbicpIHtcbiAgICAgICAgICAgIHRoaXMuYm91bmRhcnlDb250ZXh0LnNldElzTGFuZHNjYXBlKHRydWUpO1xuICAgICAgICAgICAgdGhpcy5vcmllbnRhdGlvbkNoYW5nZS5lbWl0KHRydWUpO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gcG9ydHJhaXQg5oiWIHBvcnRyYWl0TG9ja1JvdGF0aW9uOiDpjpblrprngrrnm7TlkJFcbiAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICdwb3J0cmFpdCcgfHwgdGhpcy5vcmllbnRhdGlvbiA9PT0gJ3BvcnRyYWl0TG9ja1JvdGF0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5ib3VuZGFyeUNvbnRleHQuc2V0SXNMYW5kc2NhcGUoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5vcmllbnRhdGlvbkNoYW5nZS5lbWl0KGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGF1dG8g5qih5byP77ya55uj6IG95a+m6Zqb55qE6Kit5YKZ5pa55ZCR77yI55So5pa8IG9yaWVudGF0aW9uQ2hhbmdlIOS6i+S7tu+8iVxuICAgICAgICB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlclxuICAgICAgICAgICAgLm9ic2VydmUoJyhvcmllbnRhdGlvbjogbGFuZHNjYXBlKScpXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ib3VuZGFyeUNvbnRleHQuc2V0SXNMYW5kc2NhcGUocmVzdWx0Lm1hdGNoZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub3JpZW50YXRpb25DaGFuZ2UuZW1pdChyZXN1bHQubWF0Y2hlcyk7XG4gICAgICAgICAgICAgICAgLy8g5pa55ZCR6K6K5YyW5pmC6YeN5paw6KiI566X6YKK55WMXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVCb3VuZGFyeUNhbGN1bGF0aW9ucygpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog6Kit5a6a6KaW56qX5aSn5bCP6K6K5YyW55uj5o6nXG4gICAgICpcbiAgICAgKiDlip/og73vvJpcbiAgICAgKiAtIOebo+iBvSB3aW5kb3cgcmVzaXplIOS6i+S7tlxuICAgICAqIC0g5pu05paw5a+m6Zqb6Kit5YKZ5pa55ZCRXG4gICAgICogLSDph43mlrDoqIjnrpfpgornlYzlsLrlr7hcbiAgICAgKi9cbiAgICBwcml2YXRlIHNldHVwUmVzaXplT2JzZXJ2ZXIoKSB7XG4gICAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgLy8gZGVib3VuY2VUaW1lKDE1MCksIC8vIOWPr+mBuO+8mumYsuaKluWEquWMluaAp+iDvVxuICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVBY3R1YWxPcmllbnRhdGlvbigpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQm91bmRhcnlDYWxjdWxhdGlvbnMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIENhbGN1bGF0aW9uIE1ldGhvZHMgLSDoqIjnrpfmlrnms5VcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIOabtOaWsOWvpumam+ioreWCmeaWueWQke+8iOWfuuaWvOimluWPo+WwuuWvuO+8iVxuICAgICAqXG4gICAgICog5bel5L2c5Y6f55CG77yaXG4gICAgICogLSDlj6rlnKggbG9ja1JvdGF0aW9uIOaooeW8j+S4i+mcgOimgeaqoua4rOWvpumam+aWueWQkVxuICAgICAqIC0g6YCa6YGO5q+U6LyDIHdpbmRvdy5pbm5lckhlaWdodCDlkowgd2luZG93LmlubmVyV2lkdGgg5Yik5pa3XG4gICAgICogLSDntZDmnpznlKjmlrzop7jnmbwgQ1NTIOaXi+i9ieiuiuaPm1xuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlQWN0dWFsT3JpZW50YXRpb24oKSB7XG4gICAgICAgIC8vIOWPquacieWcqCBsb2NrUm90YXRpb24g5qih5byP5LiL5omN6ZyA6KaB5qqi5ris5a+m6Zqb5pa55ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uICE9PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJyAmJiB0aGlzLm9yaWVudGF0aW9uICE9PSAncG9ydHJhaXRMb2NrUm90YXRpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmFjdHVhbElzUG9ydHJhaXQgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOaqoua4rOWvpumam+imluWPo+aWueWQke+8mumrmOW6piA+IOWvrOW6piA9IOebtOWQkVxuICAgICAgICB0aGlzLmFjdHVhbElzUG9ydHJhaXQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDmm7TmlrDpgornlYzoqIjnrpfvvIjmlK/mj7QgQ2hyb21lIDc077yM5L2/55SoIEphdmFTY3JpcHQg5qih5pOsIG1pbiDlh73mlbjvvIlcbiAgICAgKlxuICAgICAqIOW3peS9nOWOn+eQhu+8mlxuICAgICAqIDEuIOW+niBASW5wdXQg5Y+D5pW46K6A5Y+W6Kit6KiI5bC65a+4XG4gICAgICogMi4g6K6A5Y+W6KaW5Y+j5bC65a+477yIdncxMDAsIHZoMTAw77yJXG4gICAgICogMy4g6JmV55CGIGxvY2tSb3RhdGlvbiDmqKHlvI/nmoToppblj6PlsLrlr7jkuqTmj5tcbiAgICAgKiA0LiDoqIjnrpfpgornlYzmnIDlpKflgLzlkozlr6bpmpvpgornlYzlsLrlr7hcbiAgICAgKiA1LiDoqIjnrpcgcHgydncg6L2J5o+b5q+U5L6LXG4gICAgICogNi4g6Kit5a6aIENTUyDorormlbjkvpvmqKPlvI/kvb/nlKhcbiAgICAgKlxuICAgICAqIOioreWumueahCBDU1Mg6K6K5pW477yaXG4gICAgICogLSAtLWRlc2lnbi13aWR0aDog6Kit6KiI56i/5a+s5bqmXG4gICAgICogLSAtLWRlc2lnbi1oZWlnaHQ6IOioreioiOeov+mrmOW6plxuICAgICAqIC0gLS1ib3VuZGFyeS13aWR0aDog5a+m6Zqb6YKK55WM5a+s5bqm77yIcHjvvIlcbiAgICAgKiAtIC0tYm91bmRhcnktaGVpZ2h0OiDlr6bpmpvpgornlYzpq5jluqbvvIhweO+8iVxuICAgICAqIC0gLS1weDJ2dy1yYXRpbzogcHgg6L2JIHZ3IOeahOavlOS+i+S/guaVuFxuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlQm91bmRhcnlDYWxjdWxhdGlvbnMoKSB7XG4gICAgICAgIGNvbnN0IGhvc3RFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBTdGVwIDE6IOiugOWPluioreioiOWwuuWvuOS4puioreWumiBDU1Mg6K6K5pW4XG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgY29uc3QgZGVzaWduV2lkdGggPSB0aGlzLmRlc2lnbldpZHRoO1xuICAgICAgICBjb25zdCBkZXNpZ25IZWlnaHQgPSB0aGlzLmRlc2lnbkhlaWdodDtcblxuICAgICAgICAvLyDoqK3lrpogQ1NTIOiuiuaVuO+8jOS+m+aoo+W8j+S9v+eUqO+8iOS+i+WmgiBweDJ2dygpIOWHveaVuO+8iVxuICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1kZXNpZ24td2lkdGgnLCBgJHtkZXNpZ25XaWR0aH1gKTtcbiAgICAgICAgaG9zdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tZGVzaWduLWhlaWdodCcsIGAke2Rlc2lnbkhlaWdodH1gKTtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgMjog6K6A5Y+W6KaW5Y+j5bC65a+477yI55u05o6l5L2/55SoIHdpbmRvdy5pbm5lciog56K65L+d5LiA6Ie05oCn77yJXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgbGV0IHZ3MTAwID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgICAgIGxldCB2aDEwMCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgMjog6JmV55CGIGxvY2tSb3RhdGlvbiDmqKHlvI/nmoToppblj6PlsLrlr7jkuqTmj5tcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBsYW5kc2NhcGVMb2NrUm90YXRpb24gKyDlr6bpmpvnm7TlkJHvvJrkuqTmj5voppblj6PlsLrlr7hcbiAgICAgICAgLy8g5Y6f5Zug77ya5peL6L2J5b6M77yM5YWn5a6555qE5a+s5bqm5bCN5oeJ6Kit5YKZ55qE6auY5bqm77yM5YWn5a6555qE6auY5bqm5bCN5oeJ6Kit5YKZ55qE5a+s5bqmXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJyAmJiB0aGlzLmFjdHVhbElzUG9ydHJhaXQpIHtcbiAgICAgICAgICAgIFt2dzEwMCwgdmgxMDBdID0gW3ZoMTAwLCB2dzEwMF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb3J0cmFpdExvY2tSb3RhdGlvbiArIOWvpumam+apq+WQke+8muS6pOaPm+imluWPo+WwuuWvuFxuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3BvcnRyYWl0TG9ja1JvdGF0aW9uJyAmJiAhdGhpcy5hY3R1YWxJc1BvcnRyYWl0KSB7XG4gICAgICAgICAgICBbdncxMDAsIHZoMTAwXSA9IFt2aDEwMCwgdncxMDBdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBTdGVwIDM6IOioiOeul+avlOS+i+WSjOmCiueVjOacgOWkp+WAvFxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIGNvbnN0IGxhbmRzY2FwZVJhdGlvID0gZGVzaWduV2lkdGggLyBkZXNpZ25IZWlnaHQ7XG4gICAgICAgIGNvbnN0IHBvcnRyYWl0UmF0aW8gPSBkZXNpZ25IZWlnaHQgLyBkZXNpZ25XaWR0aDtcblxuICAgICAgICAvLyDmoLnmk5rmlrnlkJHmqKHlvI/oqIjnrpfpgornlYzmnIDlpKflgLxcbiAgICAgICAgY29uc3QgaXNMYW5kc2NhcGUgPSB0aGlzLmlzTGFuZHNjYXBlO1xuICAgICAgICBjb25zdCBib3VuZGFyeU1heFdpZHRoID0gaXNMYW5kc2NhcGVcbiAgICAgICAgICAgID8gdmgxMDAgKiBwb3J0cmFpdFJhdGlvICAvLyDmqavlkJHvvJrpq5jluqYgKiDpq5jlr6zmr5RcbiAgICAgICAgICAgIDogdmgxMDAgKiBsYW5kc2NhcGVSYXRpbzsgLy8g55u05ZCR77ya6auY5bqmICog5a+s6auY5q+UXG4gICAgICAgIGNvbnN0IGJvdW5kYXJ5TWF4SGVpZ2h0ID0gaXNMYW5kc2NhcGVcbiAgICAgICAgICAgID8gdncxMDAgKiBsYW5kc2NhcGVSYXRpbyAgLy8g5qmr5ZCR77ya5a+s5bqmICog5a+s6auY5q+UXG4gICAgICAgICAgICA6IHZ3MTAwICogcG9ydHJhaXRSYXRpbzsgIC8vIOebtOWQke+8muWvrOW6piAqIOmrmOWvrOavlFxuXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgLy8gU3RlcCA0OiDoqIjnrpflr6bpmpvpgornlYzlsLrlr7jvvIjkvb/nlKggTWF0aC5taW4g5qih5pOsIENTUyBtaW4oKe+8iVxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIENocm9tZSA3OSDmiY3mlK/mj7QgQ1NTIG1pbigpIOWHveaVuO+8jOaJgOS7peWcqCBKYXZhU2NyaXB0IOS4reioiOeul1xuICAgICAgICBjb25zdCBib3VuZGFyeVdpZHRoID0gTWF0aC5taW4odncxMDAsIGJvdW5kYXJ5TWF4V2lkdGgpO1xuICAgICAgICBjb25zdCBib3VuZGFyeUhlaWdodCA9IE1hdGgubWluKHZoMTAwLCBib3VuZGFyeU1heEhlaWdodCk7XG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBTdGVwIDU6IOioiOeulyBweDJ2dyDovYnmj5vmr5TkvotcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyDmqavlkJHmqKHlvI/kvb/nlKggZGVzaWduLWhlaWdodCDkvZzngrrln7rmupbvvIznm7TlkJHmqKHlvI/kvb/nlKggZGVzaWduLXdpZHRoIOS9nOeCuuWfuua6llxuICAgICAgICBjb25zdCBkZXNpZ25CYXNlV2lkdGggPSBpc0xhbmRzY2FwZSA/IGRlc2lnbkhlaWdodCA6IGRlc2lnbldpZHRoO1xuICAgICAgICBjb25zdCBweDJ2d1JhdGlvID0gYm91bmRhcnlXaWR0aCAvIGRlc2lnbkJhc2VXaWR0aDtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgNjog6Kit5a6aIENTUyDorormlbhcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1ib3VuZGFyeS13aWR0aCcsIGAke2JvdW5kYXJ5V2lkdGh9cHhgKTtcbiAgICAgICAgaG9zdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tYm91bmRhcnktaGVpZ2h0JywgYCR7Ym91bmRhcnlIZWlnaHR9cHhgKTtcbiAgICAgICAgaG9zdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tcHgydnctcmF0aW8nLCBgJHtweDJ2d1JhdGlvfWApO1xuICAgIH1cbn1cbiIsIjxkaXZcbiAgY2xhc3M9XCJib3VuZGFyeS13cmFwcGVyXCJcbiAgW2NsYXNzLmZpeGVkLWNlbnRlcl09XCJpc0ZpeGVkQ2VudGVyXCJcbiAgW2NsYXNzLnBvaW50ZXJFdmVudHNOb25lXT1cInBvaW50ZXJFdmVudHNOb25lXCJcbiAgW3N0eWxlXT1cImZvcndhcmRTdHlsZVwiXG4+XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuPC9kaXY+XG4iXX0=
319
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnMtYm91bmRhcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9iaXRzdGFjay1uZy1ib3VuZGFyeS9zcmMvbGliL2JzLWJvdW5kYXJ5LnRzIiwiLi4vLi4vLi4vLi4vcHJvamVjdHMvYml0c3RhY2stbmctYm91bmRhcnkvc3JjL2xpYi90ZW1wbGF0ZS5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFFSCxTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUVMLE1BQU0sR0FDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFFakUsT0FBTyxFQUFDLHdCQUF3QixFQUFDLE1BQU0sK0JBQStCLENBQUM7O0FBR3ZFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBa0JILE1BQU0sT0FBTyxVQUFVO0lBakJ2QjtRQW1CSSwrREFBK0Q7UUFDL0QsbUJBQW1CO1FBQ25CLCtEQUErRDtRQUUvRDs7O1dBR0c7UUFDTSxrQkFBYSxHQUFhLEtBQUssQ0FBQztRQUV6Qzs7O1dBR0c7UUFDTSxzQkFBaUIsR0FBYSxLQUFLLENBQUM7UUFFN0M7Ozs7Ozs7O1dBUUc7UUFDTSxnQkFBVyxHQUFzQixNQUFNLENBQUM7UUFtQmpEOzs7O1dBSUc7UUFDTyxzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBRTFELCtEQUErRDtRQUMvRCx1QkFBdUI7UUFDdkIsK0RBQStEO1FBRXZELHVCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2hELG9CQUFlLEdBQUcsTUFBTSxDQUFDLHdCQUF3QixDQUFDLENBQUM7UUFDbkQsZUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFV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QUFHLGFBQWEsSUFBSSxDQUFDLENBQUM7UUFDeEUsV0FBVyxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxjQUFjLElBQUksQ0FBQyxDQUFDO1FBQzFFLFdBQVcsQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLGVBQWUsRUFBRSxHQUFHLFVBQVUsRUFBRSxDQUFDLENBQUM7SUFDcEUsQ0FBQzs7dUdBcFRRLFVBQVU7MkZBQVYsVUFBVSxreUJBWlIsQ0FBQyx3QkFBd0IsQ0FBQywwQkMvQ3pDLHlNQVFBOzJGRG1EYSxVQUFVO2tCQWpCdEIsU0FBUzsrQkFDSSxhQUFhLGNBRVgsSUFBSSxhQUVMLENBQUMsd0JBQXdCLENBQUMsUUFDL0I7d0JBQ0YsY0FBYyxFQUFFLHdCQUF3Qjt3QkFDeEMsbUJBQW1CLEVBQUUsNENBQTRDO3dCQUNqRSxrQkFBa0IsRUFBRSw0Q0FBNEM7d0JBQ2hFLGlDQUFpQyxFQUFFLHlDQUF5Qzt3QkFDNUUsZ0NBQWdDLEVBQUUsd0NBQXdDO3dCQUMxRSxlQUFlLEVBQUUseUJBQXlCO3dCQUMxQyx5QkFBeUIsRUFBRSxrQkFBa0I7d0JBQzdDLDBCQUEwQixFQUFFLG1CQUFtQjtxQkFDbEQ7OEJBWVEsYUFBYTtzQkFBckIsS0FBSztnQkFNRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBV0csV0FBVztzQkFBbkIsS0FBSztnQkFLRyxZQUFZO3NCQUFwQixLQUFLO2dCQU1HLFdBQVc7c0JBQW5CLEtBQUs7Z0JBTUcsWUFBWTtzQkFBcEIsS0FBSztnQkFPSSxpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0JyZWFrcG9pbnRPYnNlcnZlcn0gZnJvbSAnQGFuZ3VsYXIvY2RrL2xheW91dCc7XG5pbXBvcnQge1xuICAgIEFmdGVyVmlld0luaXQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGluamVjdCxcbiAgICBJbnB1dCwgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWUsIGZyb21FdmVudCwgU3ViamVjdCwgdGFrZVVudGlsfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHtCc0JvdW5kYXJ5Q29udGV4dFNlcnZpY2V9IGZyb20gJy4vYnMtYm91bmRhcnktY29udGV4dC5zZXJ2aWNlJztcbmltcG9ydCB7VE9yaWVudGF0aW9uTW9kZX0gZnJvbSAnLi9tb2RlbCc7XG5cbi8qKlxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gKiBCc0JvdW5kYXJ5IENvbXBvbmVudCAtIEFXRCDoh6rpganmh4npgornlYzlrrnlmahcbiAqID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICpcbiAqIOWKn+iDveiqquaYju+8mlxuICogMS4g5o+Q5L6b6Z+/5oeJ5byP6YKK55WM5a655Zmo77yM6Ieq5YuV6YGp5oeJ5LiN5ZCM6Kit5YKZ5bC65a+4XG4gKiAyLiDmlK/mj7QgNSDnqK7mlrnlkJHmqKHlvI/vvJphdXRvLCBwb3J0cmFpdCwgbGFuZHNjYXBlLCBwb3J0cmFpdExvY2tSb3RhdGlvbiwgbGFuZHNjYXBlTG9ja1JvdGF0aW9uXG4gKiAzLiDkvb/nlKggQ1NTIOiuiuaVuOWvpuePvuWLleaFi+ioiOeul++8jOaUr+aPtCBweDJ2dygpIOWHveaVuFxuICogNC4g55u45a65IENocm9tZSA3NCvvvIzkvb/nlKggSmF2YVNjcmlwdCDoqIjnrpfpgornlYzlsLrlr7hcbiAqXG4gKiDkvb/nlKjnr4TkvovvvJpcbiAqIGBgYGh0bWxcbiAqIDxicy1ib3VuZGFyeSBbb3JpZW50YXRpb25dPVwiJ2F1dG8nXCIgW2lzRml4ZWRDZW50ZXJdPVwidHJ1ZVwiPlxuICogICA8ZGl2IGNsYXNzPVwiY29udGVudFwiPi4uLjwvZGl2PlxuICogPC9icy1ib3VuZGFyeT5cbiAqIGBgYFxuICpcbiAqIENTUyDorormlbjoqK3lrprvvJpcbiAqIGBgYHNjc3NcbiAqIGJzLWJvdW5kYXJ5IHtcbiAqICAgLS1kZXNpZ24td2lkdGg6IDM3NTsgICAvLyDoqK3oqIjnqL/lr6zluqZcbiAqICAgLS1kZXNpZ24taGVpZ2h0OiA2Njc7ICAvLyDoqK3oqIjnqL/pq5jluqZcbiAqIH1cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2JzLWJvdW5kYXJ5JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vdGVtcGxhdGUuaHRtbCcsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBzdHlsZVVybHM6IFsnLi9zdHlsZXMuc2NzcyddLFxuICAgIHByb3ZpZGVyczogW0JzQm91bmRhcnlDb250ZXh0U2VydmljZV0sXG4gICAgaG9zdDoge1xuICAgICAgICAnW2NsYXNzLmF1dG9dJzogJ29yaWVudGF0aW9uID09PSBcImF1dG9cIicsXG4gICAgICAgICdbY2xhc3MubGFuZHNjYXBlXSc6ICdpc0xhbmRzY2FwZSAmJiBvcmllbnRhdGlvbiA9PT0gXCJsYW5kc2NhcGVcIicsXG4gICAgICAgICdbY2xhc3MucG9ydHJhaXRdJzogJyFpc0xhbmRzY2FwZSAmJiBvcmllbnRhdGlvbiA9PT0gXCJwb3J0cmFpdFwiJyxcbiAgICAgICAgJ1tjbGFzcy5sYW5kc2NhcGUtbG9jay1yb3RhdGlvbl0nOiAnb3JpZW50YXRpb24gPT09IFwibGFuZHNjYXBlTG9ja1JvdGF0aW9uXCInLFxuICAgICAgICAnW2NsYXNzLnBvcnRyYWl0LWxvY2stcm90YXRpb25dJzogJ29yaWVudGF0aW9uID09PSBcInBvcnRyYWl0TG9ja1JvdGF0aW9uXCInLFxuICAgICAgICAnW2NsYXNzLmZsdWlkXSc6ICdvcmllbnRhdGlvbiA9PT0gXCJmbHVpZFwiJyxcbiAgICAgICAgJ1tjbGFzcy5hY3R1YWwtcG9ydHJhaXRdJzogJ2FjdHVhbElzUG9ydHJhaXQnLFxuICAgICAgICAnW2NsYXNzLmFjdHVhbC1sYW5kc2NhcGVdJzogJyFhY3R1YWxJc1BvcnRyYWl0J1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgQnNCb3VuZGFyeSBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIElucHV0cyAmIE91dHB1dHNcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIOaYr+WQpuWwh+WFp+WuueWbuuWumuWcqOimlueql+S4reWkrlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KCkgaXNGaXhlZENlbnRlcj86IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKlxuICAgICAqIOaYr+WQpuemgeeUqOaMh+aomeS6i+S7tlxuICAgICAqIEBkZWZhdWx0IGZhbHNlXG4gICAgICovXG4gICAgQElucHV0KCkgcG9pbnRlckV2ZW50c05vbmU/OiBib29sZWFuID0gZmFsc2U7XG5cbiAgICAvKipcbiAgICAgKiDmlrnlkJHmqKHlvI9cbiAgICAgKiAtIGF1dG86IOiHquWLleaqoua4rOaWueWQkVxuICAgICAqIC0gcG9ydHJhaXQ6IOmOluWumuebtOWQkVxuICAgICAqIC0gbGFuZHNjYXBlOiDpjpblrprmqavlkJFcbiAgICAgKiAtIHBvcnRyYWl0TG9ja1JvdGF0aW9uOiDlvLfliLbnm7TlkJHvvIjmqavlkJHoqK3lgpnmmYLml4vovYkgLTkwwrDvvIlcbiAgICAgKiAtIGxhbmRzY2FwZUxvY2tSb3RhdGlvbjog5by35Yi25qmr5ZCR77yI55u05ZCR6Kit5YKZ5pmC5peL6L2JIDkwwrDvvIlcbiAgICAgKiBAZGVmYXVsdCAnYXV0bydcbiAgICAgKi9cbiAgICBASW5wdXQoKSBvcmllbnRhdGlvbj86IFRPcmllbnRhdGlvbk1vZGUgPSAnYXV0byc7XG5cbiAgICAvKipcbiAgICAgKiDlkJHlhaflsaTlrrnlmajovYnnmbznmoToh6roqILmqKPlvI9cbiAgICAgKi9cbiAgICBASW5wdXQoKSBmb3J3YXJkU3R5bGU/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gICAgLyoqXG4gICAgICog6Kit6KiI56i/5a+s5bqm77yI5Zau5L2N77yacHjvvIlcbiAgICAgKiDlv4Xloavlj4PmlbhcbiAgICAgKi9cbiAgICBASW5wdXQoKSBkZXNpZ25XaWR0aCE6IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIOioreioiOeov+mrmOW6pu+8iOWWruS9je+8mnB477yJXG4gICAgICog5b+F5aGr5Y+D5pW4XG4gICAgICovXG4gICAgQElucHV0KCkgZGVzaWduSGVpZ2h0ITogbnVtYmVyO1xuXG4gICAgLyoqXG4gICAgICog5pa55ZCR6K6K5YyW5LqL5Lu2XG4gICAgICogQGVtaXRzIHRydWU6IGxhbmRzY2FwZe+8iOapq+Wxj++8iVxuICAgICAqIEBlbWl0cyBmYWxzZTogcG9ydHJhaXTvvIjnm7TlsY/vvIlcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgb3JpZW50YXRpb25DaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBQcml2YXRlIERlcGVuZGVuY2llc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgcHJpdmF0ZSBicmVha3BvaW50T2JzZXJ2ZXIgPSBpbmplY3QoQnJlYWtwb2ludE9ic2VydmVyKTtcbiAgICBwcml2YXRlIGJvdW5kYXJ5Q29udGV4dCA9IGluamVjdChCc0JvdW5kYXJ5Q29udGV4dFNlcnZpY2UpO1xuICAgIHByaXZhdGUgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIFB1YmxpYyBQcm9wZXJ0aWVzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiDlr6bpmpvoqK3lgpnmlrnlkJHvvIjln7rmlrzoppblj6PlsLrlr7jvvIlcbiAgICAgKiB0cnVlOiDnm7TlkJEgKGhlaWdodCA+IHdpZHRoKVxuICAgICAqIGZhbHNlOiDmqavlkJEgKHdpZHRoID49IGhlaWdodClcbiAgICAgKi9cbiAgICBhY3R1YWxJc1BvcnRyYWl0ID0gZmFsc2U7XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyBHZXR0ZXJzXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiDliKTmlrfnlbbliY3mmK/lkKbngrrmqavlkJHmqKHlvI9cbiAgICAgKiDmoLnmk5ogb3JpZW50YXRpb24g6Kit5a6a5ZKM5a+m6Zqb6Kit5YKZ5pa55ZCR5Yik5pa3XG4gICAgICovXG4gICAgZ2V0IGlzTGFuZHNjYXBlKCk6IGJvb2xlYW4ge1xuICAgICAgICAvLyBsYW5kc2NhcGVMb2NrUm90YXRpb246IOW8t+WItuapq+Wxj+aooeW8j1xuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ2xhbmRzY2FwZUxvY2tSb3RhdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIC8vIHBvcnRyYWl0TG9ja1JvdGF0aW9uOiDlvLfliLbnm7TlsY/mqKHlvI9cbiAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICdwb3J0cmFpdExvY2tSb3RhdGlvbicpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBmbHVpZDog5LiN5Y2A5YiG5qmr55u05ZCR77yM5Lul5a+s5bqm54K65Z+65rqWXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnZmx1aWQnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gbGFuZHNjYXBlOiDpjpblrprmqavlkJFcbiAgICAgICAgaWYgKHRoaXMub3JpZW50YXRpb24gPT09ICdsYW5kc2NhcGUnKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICAvLyBwb3J0cmFpdDog6Y6W5a6a55u05ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAncG9ydHJhaXQnKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgLy8gYXV0bzog6Ieq5YuV5qqi5risXG4gICAgICAgIHJldHVybiB0aGlzLmJvdW5kYXJ5Q29udGV4dC5nZXRJc0xhbmRzY2FwZSgpO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIExpZmVjeWNsZSBIb29rc1xuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudXBkYXRlQWN0dWFsT3JpZW50YXRpb24oKTtcbiAgICAgICAgdGhpcy5zZXR1cEJyZWFrcG9pbnRPYnNlcnZlcigpO1xuICAgICAgICB0aGlzLnNldHVwUmVzaXplT2JzZXJ2ZXIoKTtcbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIC8vIOS9v+eUqCBASW5wdXQg5Y+D5pW477yM5Y+v5Lul56uL5Y2z6KiI566X77yI54Sh6ZyA562J5b6FIENTU++8iVxuICAgICAgICB0aGlzLnVwZGF0ZUJvdW5kYXJ5Q2FsY3VsYXRpb25zKCk7XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gT2JzZXJ2ZXJzIFNldHVwIC0g55uj6IG95Zmo6Kit5a6aXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiDoqK3lrprmlrnlkJHororljJbnm6PmjqdcbiAgICAgKlxuICAgICAqIOW3peS9nOWOn+eQhu+8mlxuICAgICAqIC0gbG9jayDmqKHlvI/vvIhwb3J0cmFpdC9sYW5kc2NhcGXvvInvvJrnm7TmjqXoqK3lrprlm7rlrprmlrnlkJHvvIzkuI3nm6Pogb3ororljJZcbiAgICAgKiAtIGxvY2tSb3RhdGlvbiDmqKHlvI/vvJroqK3lrprlm7rlrprmlrnlkJHvvIzkvYbpnIDnm6Pogb3lr6bpmpvoqK3lgpnmlrnlkJHku6Xop7jnmbzml4vovYlcbiAgICAgKiAtIGF1dG8g5qih5byP77ya5L2/55SoIEJyZWFrcG9pbnRPYnNlcnZlciDnm6Pogb3oqK3lgpnmlrnlkJHororljJZcbiAgICAgKi9cbiAgICBwcml2YXRlIHNldHVwQnJlYWtwb2ludE9ic2VydmVyKCkge1xuICAgICAgICAvLyBsYW5kc2NhcGUg5oiWIGxhbmRzY2FwZUxvY2tSb3RhdGlvbjog6Y6W5a6a54K65qmr5ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlJyB8fCB0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJykge1xuICAgICAgICAgICAgdGhpcy5ib3VuZGFyeUNvbnRleHQuc2V0SXNMYW5kc2NhcGUodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLm9yaWVudGF0aW9uQ2hhbmdlLmVtaXQodHJ1ZSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb3J0cmFpdOOAgXBvcnRyYWl0TG9ja1JvdGF0aW9uIOaIliBmbHVpZDog6Y6W5a6a54K655u05ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAncG9ydHJhaXQnIHx8IHRoaXMub3JpZW50YXRpb24gPT09ICdwb3J0cmFpdExvY2tSb3RhdGlvbicgfHwgdGhpcy5vcmllbnRhdGlvbiA9PT0gJ2ZsdWlkJykge1xuICAgICAgICAgICAgdGhpcy5ib3VuZGFyeUNvbnRleHQuc2V0SXNMYW5kc2NhcGUoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5vcmllbnRhdGlvbkNoYW5nZS5lbWl0KGZhbHNlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGF1dG8g5qih5byP77ya55uj6IG95a+m6Zqb55qE6Kit5YKZ5pa55ZCR77yI55So5pa8IG9yaWVudGF0aW9uQ2hhbmdlIOS6i+S7tu+8iVxuICAgICAgICB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlclxuICAgICAgICAgICAgLm9ic2VydmUoJyhvcmllbnRhdGlvbjogbGFuZHNjYXBlKScpXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5ib3VuZGFyeUNvbnRleHQuc2V0SXNMYW5kc2NhcGUocmVzdWx0Lm1hdGNoZXMpO1xuICAgICAgICAgICAgICAgIHRoaXMub3JpZW50YXRpb25DaGFuZ2UuZW1pdChyZXN1bHQubWF0Y2hlcyk7XG4gICAgICAgICAgICAgICAgLy8g5pa55ZCR6K6K5YyW5pmC6YeN5paw6KiI566X6YKK55WMXG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVCb3VuZGFyeUNhbGN1bGF0aW9ucygpO1xuICAgICAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICog6Kit5a6a6KaW56qX5aSn5bCP6K6K5YyW55uj5o6nXG4gICAgICpcbiAgICAgKiDlip/og73vvJpcbiAgICAgKiAtIOebo+iBvSB3aW5kb3cgcmVzaXplIOS6i+S7tlxuICAgICAqIC0g5pu05paw5a+m6Zqb6Kit5YKZ5pa55ZCRXG4gICAgICogLSDph43mlrDoqIjnrpfpgornlYzlsLrlr7hcbiAgICAgKi9cbiAgICBwcml2YXRlIHNldHVwUmVzaXplT2JzZXJ2ZXIoKSB7XG4gICAgICAgIGZyb21FdmVudCh3aW5kb3csICdyZXNpemUnKVxuICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgLy8gZGVib3VuY2VUaW1lKDE1MCksIC8vIOWPr+mBuO+8mumYsuaKluWEquWMluaAp+iDvVxuICAgICAgICAgICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVBY3R1YWxPcmllbnRhdGlvbigpO1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlQm91bmRhcnlDYWxjdWxhdGlvbnMoKTtcbiAgICAgICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIENhbGN1bGF0aW9uIE1ldGhvZHMgLSDoqIjnrpfmlrnms5VcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIC8qKlxuICAgICAqIOabtOaWsOWvpumam+ioreWCmeaWueWQke+8iOWfuuaWvOimluWPo+WwuuWvuO+8iVxuICAgICAqXG4gICAgICog5bel5L2c5Y6f55CG77yaXG4gICAgICogLSDlj6rlnKggbG9ja1JvdGF0aW9uIOaooeW8j+S4i+mcgOimgeaqoua4rOWvpumam+aWueWQkVxuICAgICAqIC0g6YCa6YGO5q+U6LyDIHdpbmRvdy5pbm5lckhlaWdodCDlkowgd2luZG93LmlubmVyV2lkdGgg5Yik5pa3XG4gICAgICogLSDntZDmnpznlKjmlrzop7jnmbwgQ1NTIOaXi+i9ieiuiuaPm1xuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlQWN0dWFsT3JpZW50YXRpb24oKSB7XG4gICAgICAgIC8vIOWPquacieWcqCBsb2NrUm90YXRpb24g5qih5byP5LiL5omN6ZyA6KaB5qqi5ris5a+m6Zqb5pa55ZCRXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uICE9PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJyAmJiB0aGlzLm9yaWVudGF0aW9uICE9PSAncG9ydHJhaXRMb2NrUm90YXRpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmFjdHVhbElzUG9ydHJhaXQgPSBmYWxzZTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOaqoua4rOWvpumam+imluWPo+aWueWQke+8mumrmOW6piA+IOWvrOW6piA9IOebtOWQkVxuICAgICAgICB0aGlzLmFjdHVhbElzUG9ydHJhaXQgPSB3aW5kb3cuaW5uZXJIZWlnaHQgPiB3aW5kb3cuaW5uZXJXaWR0aDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiDmm7TmlrDpgornlYzoqIjnrpfvvIjmlK/mj7QgQ2hyb21lIDc077yM5L2/55SoIEphdmFTY3JpcHQg5qih5pOsIG1pbiDlh73mlbjvvIlcbiAgICAgKlxuICAgICAqIOW3peS9nOWOn+eQhu+8mlxuICAgICAqIDEuIOW+niBASW5wdXQg5Y+D5pW46K6A5Y+W6Kit6KiI5bC65a+4XG4gICAgICogMi4g6K6A5Y+W6KaW5Y+j5bC65a+477yIdncxMDAsIHZoMTAw77yJXG4gICAgICogMy4g6JmV55CGIGxvY2tSb3RhdGlvbiDmqKHlvI/nmoToppblj6PlsLrlr7jkuqTmj5tcbiAgICAgKiA0LiDoqIjnrpfpgornlYzmnIDlpKflgLzlkozlr6bpmpvpgornlYzlsLrlr7hcbiAgICAgKiA1LiDoqIjnrpcgcHgydncg6L2J5o+b5q+U5L6LXG4gICAgICogNi4g6Kit5a6aIENTUyDorormlbjkvpvmqKPlvI/kvb/nlKhcbiAgICAgKlxuICAgICAqIOioreWumueahCBDU1Mg6K6K5pW477yaXG4gICAgICogLSAtLWRlc2lnbi13aWR0aDog6Kit6KiI56i/5a+s5bqmXG4gICAgICogLSAtLWRlc2lnbi1oZWlnaHQ6IOioreioiOeov+mrmOW6plxuICAgICAqIC0gLS1ib3VuZGFyeS13aWR0aDog5a+m6Zqb6YKK55WM5a+s5bqm77yIcHjvvIlcbiAgICAgKiAtIC0tYm91bmRhcnktaGVpZ2h0OiDlr6bpmpvpgornlYzpq5jluqbvvIhweO+8iVxuICAgICAqIC0gLS1weDJ2dy1yYXRpbzogcHgg6L2JIHZ3IOeahOavlOS+i+S/guaVuFxuICAgICAqL1xuICAgIHByaXZhdGUgdXBkYXRlQm91bmRhcnlDYWxjdWxhdGlvbnMoKSB7XG4gICAgICAgIGNvbnN0IGhvc3RFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBTdGVwIDE6IOiugOWPluioreioiOWwuuWvuOS4puioreWumiBDU1Mg6K6K5pW4XG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgY29uc3QgZGVzaWduV2lkdGggPSB0aGlzLmRlc2lnbldpZHRoO1xuICAgICAgICBjb25zdCBkZXNpZ25IZWlnaHQgPSB0aGlzLmRlc2lnbkhlaWdodDtcblxuICAgICAgICAvLyDoqK3lrpogQ1NTIOiuiuaVuO+8jOS+m+aoo+W8j+S9v+eUqO+8iOS+i+WmgiBweDJ2dygpIOWHveaVuO+8iVxuICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1kZXNpZ24td2lkdGgnLCBgJHtkZXNpZ25XaWR0aH1gKTtcbiAgICAgICAgaG9zdEVsZW1lbnQuc3R5bGUuc2V0UHJvcGVydHkoJy0tZGVzaWduLWhlaWdodCcsIGAke2Rlc2lnbkhlaWdodH1gKTtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgMjog6K6A5Y+W6KaW5Y+j5bC65a+477yI55u05o6l5L2/55SoIHdpbmRvdy5pbm5lciog56K65L+d5LiA6Ie05oCn77yJXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgbGV0IHZ3MTAwID0gd2luZG93LmlubmVyV2lkdGg7XG4gICAgICAgIGxldCB2aDEwMCA9IHdpbmRvdy5pbm5lckhlaWdodDtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgMjog6JmV55CGIGxvY2tSb3RhdGlvbiDmqKHlvI/nmoToppblj6PlsLrlr7jkuqTmj5tcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBsYW5kc2NhcGVMb2NrUm90YXRpb24gKyDlr6bpmpvnm7TlkJHvvJrkuqTmj5voppblj6PlsLrlr7hcbiAgICAgICAgLy8g5Y6f5Zug77ya5peL6L2J5b6M77yM5YWn5a6555qE5a+s5bqm5bCN5oeJ6Kit5YKZ55qE6auY5bqm77yM5YWn5a6555qE6auY5bqm5bCN5oeJ6Kit5YKZ55qE5a+s5bqmXG4gICAgICAgIGlmICh0aGlzLm9yaWVudGF0aW9uID09PSAnbGFuZHNjYXBlTG9ja1JvdGF0aW9uJyAmJiB0aGlzLmFjdHVhbElzUG9ydHJhaXQpIHtcbiAgICAgICAgICAgIFt2dzEwMCwgdmgxMDBdID0gW3ZoMTAwLCB2dzEwMF07XG4gICAgICAgIH1cblxuICAgICAgICAvLyBwb3J0cmFpdExvY2tSb3RhdGlvbiArIOWvpumam+apq+WQke+8muS6pOaPm+imluWPo+WwuuWvuFxuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ3BvcnRyYWl0TG9ja1JvdGF0aW9uJyAmJiAhdGhpcy5hY3R1YWxJc1BvcnRyYWl0KSB7XG4gICAgICAgICAgICBbdncxMDAsIHZoMTAwXSA9IFt2aDEwMCwgdncxMDBdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBGbHVpZCDmqKHlvI/vvJrkuI3lj4PogIPlr6zpq5jmr5TvvIznm7TmjqXkvb/nlKjonqLluZXlsLrlr7hcbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICBpZiAodGhpcy5vcmllbnRhdGlvbiA9PT0gJ2ZsdWlkJykge1xuICAgICAgICAgICAgY29uc3QgYm91bmRhcnlXaWR0aCA9IHZ3MTAwO1xuICAgICAgICAgICAgY29uc3QgYm91bmRhcnlIZWlnaHQgPSB2aDEwMDtcbiAgICAgICAgICAgIGNvbnN0IHB4MnZ3UmF0aW8gPSB2dzEwMCAvIGRlc2lnbldpZHRoO1xuXG4gICAgICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1ib3VuZGFyeS13aWR0aCcsIGAke2JvdW5kYXJ5V2lkdGh9cHhgKTtcbiAgICAgICAgICAgIGhvc3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWJvdW5kYXJ5LWhlaWdodCcsIGAke2JvdW5kYXJ5SGVpZ2h0fXB4YCk7XG4gICAgICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1weDJ2dy1yYXRpbycsIGAke3B4MnZ3UmF0aW99YCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgMzog6KiI566X5q+U5L6L5ZKM6YKK55WM5pyA5aSn5YC8XG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgY29uc3QgbGFuZHNjYXBlUmF0aW8gPSBkZXNpZ25XaWR0aCAvIGRlc2lnbkhlaWdodDtcbiAgICAgICAgY29uc3QgcG9ydHJhaXRSYXRpbyA9IGRlc2lnbkhlaWdodCAvIGRlc2lnbldpZHRoO1xuXG4gICAgICAgIC8vIOagueaTmuaWueWQkeaooeW8j+ioiOeul+mCiueVjOacgOWkp+WAvFxuICAgICAgICBjb25zdCBpc0xhbmRzY2FwZSA9IHRoaXMuaXNMYW5kc2NhcGU7XG4gICAgICAgIGNvbnN0IGJvdW5kYXJ5TWF4V2lkdGggPSBpc0xhbmRzY2FwZVxuICAgICAgICAgICAgPyB2aDEwMCAqIHBvcnRyYWl0UmF0aW8gIC8vIOapq+WQke+8mumrmOW6piAqIOmrmOWvrOavlFxuICAgICAgICAgICAgOiB2aDEwMCAqIGxhbmRzY2FwZVJhdGlvOyAvLyDnm7TlkJHvvJrpq5jluqYgKiDlr6zpq5jmr5RcbiAgICAgICAgY29uc3QgYm91bmRhcnlNYXhIZWlnaHQgPSBpc0xhbmRzY2FwZVxuICAgICAgICAgICAgPyB2dzEwMCAqIGxhbmRzY2FwZVJhdGlvICAvLyDmqavlkJHvvJrlr6zluqYgKiDlr6zpq5jmr5RcbiAgICAgICAgICAgIDogdncxMDAgKiBwb3J0cmFpdFJhdGlvOyAgLy8g55u05ZCR77ya5a+s5bqmICog6auY5a+s5q+UXG5cbiAgICAgICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgICAgICAvLyBTdGVwIDQ6IOioiOeul+Wvpumam+mCiueVjOWwuuWvuO+8iOS9v+eUqCBNYXRoLm1pbiDmqKHmk6wgQ1NTIG1pbigp77yJXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgLy8gQ2hyb21lIDc5IOaJjeaUr+aPtCBDU1MgbWluKCkg5Ye95pW477yM5omA5Lul5ZyoIEphdmFTY3JpcHQg5Lit6KiI566XXG4gICAgICAgIGNvbnN0IGJvdW5kYXJ5V2lkdGggPSBNYXRoLm1pbih2dzEwMCwgYm91bmRhcnlNYXhXaWR0aCk7XG4gICAgICAgIGNvbnN0IGJvdW5kYXJ5SGVpZ2h0ID0gTWF0aC5taW4odmgxMDAsIGJvdW5kYXJ5TWF4SGVpZ2h0KTtcblxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIFN0ZXAgNTog6KiI566XIHB4MnZ3IOi9ieaPm+avlOS+i1xuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIC8vIOapq+WQkeaooeW8j+S9v+eUqCBkZXNpZ24taGVpZ2h0IOS9nOeCuuWfuua6lu+8jOebtOWQkeaooeW8j+S9v+eUqCBkZXNpZ24td2lkdGgg5L2c54K65Z+65rqWXG4gICAgICAgIGNvbnN0IGRlc2lnbkJhc2VXaWR0aCA9IGlzTGFuZHNjYXBlID8gZGVzaWduSGVpZ2h0IDogZGVzaWduV2lkdGg7XG4gICAgICAgIGNvbnN0IHB4MnZ3UmF0aW8gPSBib3VuZGFyeVdpZHRoIC8gZGVzaWduQmFzZVdpZHRoO1xuXG4gICAgICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAgICAgLy8gU3RlcCA2OiDoqK3lrpogQ1NTIOiuiuaVuFxuICAgICAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgICAgIGhvc3RFbGVtZW50LnN0eWxlLnNldFByb3BlcnR5KCctLWJvdW5kYXJ5LXdpZHRoJywgYCR7Ym91bmRhcnlXaWR0aH1weGApO1xuICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1ib3VuZGFyeS1oZWlnaHQnLCBgJHtib3VuZGFyeUhlaWdodH1weGApO1xuICAgICAgICBob3N0RWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgnLS1weDJ2dy1yYXRpbycsIGAke3B4MnZ3UmF0aW99YCk7XG4gICAgfVxufVxuIiwiPGRpdlxuICBjbGFzcz1cImJvdW5kYXJ5LXdyYXBwZXJcIlxuICBbY2xhc3MuZml4ZWQtY2VudGVyXT1cImlzRml4ZWRDZW50ZXJcIlxuICBbY2xhc3MucG9pbnRlckV2ZW50c05vbmVdPVwicG9pbnRlckV2ZW50c05vbmVcIlxuICBbc3R5bGVdPVwiZm9yd2FyZFN0eWxlXCJcbj5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG48L2Rpdj5cbiJdfQ==
@@ -1,2 +1,2 @@
1
1
  export {};
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9iaXRzdGFjay1uZy1ib3VuZGFyeS9zcmMvbGliL21vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSBUT3JpZW50YXRpb25Nb2RlID0gJ2F1dG8nIHwgJ3BvcnRyYWl0JyB8ICdsYW5kc2NhcGUnIHwgJ2xhbmRzY2FwZUxvY2tSb3RhdGlvbicgfCAncG9ydHJhaXRMb2NrUm90YXRpb24nO1xuIl19
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9iaXRzdGFjay1uZy1ib3VuZGFyeS9zcmMvbGliL21vZGVsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgdHlwZSBUT3JpZW50YXRpb25Nb2RlID0gJ2F1dG8nIHwgJ3BvcnRyYWl0JyB8ICdsYW5kc2NhcGUnIHwgJ2xhbmRzY2FwZUxvY2tSb3RhdGlvbicgfCAncG9ydHJhaXRMb2NrUm90YXRpb24nIHwgJ2ZsdWlkJztcbiJdfQ==
@@ -111,6 +111,10 @@ class BsBoundary {
111
111
  if (this.orientation === 'portraitLockRotation') {
112
112
  return false;
113
113
  }
114
+ // fluid: 不區分橫直向,以寬度為基準
115
+ if (this.orientation === 'fluid') {
116
+ return false;
117
+ }
114
118
  // landscape: 鎖定橫向
115
119
  if (this.orientation === 'landscape') {
116
120
  return true;
@@ -156,8 +160,8 @@ class BsBoundary {
156
160
  this.orientationChange.emit(true);
157
161
  return;
158
162
  }
159
- // portrait 或 portraitLockRotation: 鎖定為直向
160
- if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation') {
163
+ // portrait、portraitLockRotationfluid: 鎖定為直向
164
+ if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation' || this.orientation === 'fluid') {
161
165
  this.boundaryContext.setIsLandscape(false);
162
166
  this.orientationChange.emit(false);
163
167
  return;
@@ -257,6 +261,18 @@ class BsBoundary {
257
261
  [vw100, vh100] = [vh100, vw100];
258
262
  }
259
263
  // ========================================
264
+ // Fluid 模式:不參考寬高比,直接使用螢幕尺寸
265
+ // ========================================
266
+ if (this.orientation === 'fluid') {
267
+ const boundaryWidth = vw100;
268
+ const boundaryHeight = vh100;
269
+ const px2vwRatio = vw100 / designWidth;
270
+ hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);
271
+ hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);
272
+ hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);
273
+ return;
274
+ }
275
+ // ========================================
260
276
  // Step 3: 計算比例和邊界最大值
261
277
  // ========================================
262
278
  const landscapeRatio = designWidth / designHeight;
@@ -290,7 +306,7 @@ class BsBoundary {
290
306
  }
291
307
  }
292
308
  BsBoundary.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, deps: [], target: i0.ɵɵFactoryTarget.Component });
293
- BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
309
+ BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.fluid": "orientation === \"fluid\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
294
310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, decorators: [{
295
311
  type: Component,
296
312
  args: [{ selector: 'bs-boundary', standalone: true, providers: [BsBoundaryContextService], host: {
@@ -299,9 +315,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
299
315
  '[class.portrait]': '!isLandscape && orientation === "portrait"',
300
316
  '[class.landscape-lock-rotation]': 'orientation === "landscapeLockRotation"',
301
317
  '[class.portrait-lock-rotation]': 'orientation === "portraitLockRotation"',
318
+ '[class.fluid]': 'orientation === "fluid"',
302
319
  '[class.actual-portrait]': 'actualIsPortrait',
303
320
  '[class.actual-landscape]': '!actualIsPortrait'
304
- }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
321
+ }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
305
322
  }], propDecorators: { isFixedCenter: [{
306
323
  type: Input
307
324
  }], pointerEventsNone: [{
@@ -1 +1 @@
1
- {"version":3,"file":"bitstack-ng-boundary.mjs","sources":["../../../projects/bitstack-ng-boundary/src/lib/bs-boundary-context.service.ts","../../../projects/bitstack-ng-boundary/src/lib/bs-boundary.ts","../../../projects/bitstack-ng-boundary/src/lib/template.html","../../../projects/bitstack-ng-boundary/src/public-api.ts","../../../projects/bitstack-ng-boundary/src/bitstack-ng-boundary.ts"],"sourcesContent":["import {Injectable} from '@angular/core';\nimport {BehaviorSubject} from 'rxjs';\n\n@Injectable()\nexport class BsBoundaryContextService {\n private _isLandscape = new BehaviorSubject<boolean>(false);\n\n readonly isLandscape$ = this._isLandscape.asObservable();\n\n setIsLandscape(value: boolean): void {\n this._isLandscape.next(value);\n }\n\n getIsLandscape(): boolean {\n return this._isLandscape.value;\n }\n}\n","import {BreakpointObserver} from '@angular/cdk/layout';\nimport {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input, OnDestroy,\n OnInit,\n Output,\n} from '@angular/core';\nimport {debounceTime, fromEvent, Subject, takeUntil} from 'rxjs';\n\nimport {BsBoundaryContextService} from './bs-boundary-context.service';\nimport {TOrientationMode} from './model';\n\n/**\n * ============================================================\n * BsBoundary Component - AWD 自適應邊界容器\n * ============================================================\n *\n * 功能說明:\n * 1. 提供響應式邊界容器,自動適應不同設備尺寸\n * 2. 支援 5 種方向模式:auto, portrait, landscape, portraitLockRotation, landscapeLockRotation\n * 3. 使用 CSS 變數實現動態計算,支援 px2vw() 函數\n * 4. 相容 Chrome 74+,使用 JavaScript 計算邊界尺寸\n *\n * 使用範例:\n * ```html\n * <bs-boundary [orientation]=\"'auto'\" [isFixedCenter]=\"true\">\n * <div class=\"content\">...</div>\n * </bs-boundary>\n * ```\n *\n * CSS 變數設定:\n * ```scss\n * bs-boundary {\n * --design-width: 375; // 設計稿寬度\n * --design-height: 667; // 設計稿高度\n * }\n * ```\n */\n@Component({\n selector: 'bs-boundary',\n templateUrl: './template.html',\n standalone: true,\n styleUrls: ['./styles.scss'],\n providers: [BsBoundaryContextService],\n host: {\n '[class.auto]': 'orientation === \"auto\"',\n '[class.landscape]': 'isLandscape && orientation === \"landscape\"',\n '[class.portrait]': '!isLandscape && orientation === \"portrait\"',\n '[class.landscape-lock-rotation]': 'orientation === \"landscapeLockRotation\"',\n '[class.portrait-lock-rotation]': 'orientation === \"portraitLockRotation\"',\n '[class.actual-portrait]': 'actualIsPortrait',\n '[class.actual-landscape]': '!actualIsPortrait'\n }\n})\nexport class BsBoundary implements OnInit, AfterViewInit, OnDestroy {\n\n // ============================================================\n // Inputs & Outputs\n // ============================================================\n\n /**\n * 是否將內容固定在視窗中央\n * @default false\n */\n @Input() isFixedCenter?: boolean = false;\n\n /**\n * 是否禁用指標事件\n * @default false\n */\n @Input() pointerEventsNone?: boolean = false;\n\n /**\n * 方向模式\n * - auto: 自動檢測方向\n * - portrait: 鎖定直向\n * - landscape: 鎖定橫向\n * - portraitLockRotation: 強制直向(橫向設備時旋轉 -90°)\n * - landscapeLockRotation: 強制橫向(直向設備時旋轉 90°)\n * @default 'auto'\n */\n @Input() orientation?: TOrientationMode = 'auto';\n\n /**\n * 向內層容器轉發的自訂樣式\n */\n @Input() forwardStyle?: Record<string, string>;\n\n /**\n * 設計稿寬度(單位:px)\n * 必填參數\n */\n @Input() designWidth!: number;\n\n /**\n * 設計稿高度(單位:px)\n * 必填參數\n */\n @Input() designHeight!: number;\n\n /**\n * 方向變化事件\n * @emits true: landscape(橫屏)\n * @emits false: portrait(直屏)\n */\n @Output() orientationChange = new EventEmitter<boolean>();\n\n // ============================================================\n // Private Dependencies\n // ============================================================\n\n private breakpointObserver = inject(BreakpointObserver);\n private boundaryContext = inject(BsBoundaryContextService);\n private elementRef = inject(ElementRef);\n private destroy$ = new Subject<void>();\n\n // ============================================================\n // Public Properties\n // ============================================================\n\n /**\n * 實際設備方向(基於視口尺寸)\n * true: 直向 (height > width)\n * false: 橫向 (width >= height)\n */\n actualIsPortrait = false;\n\n // ============================================================\n // Getters\n // ============================================================\n\n /**\n * 判斷當前是否為橫向模式\n * 根據 orientation 設定和實際設備方向判斷\n */\n get isLandscape(): boolean {\n // landscapeLockRotation: 強制橫屏模式\n if (this.orientation === 'landscapeLockRotation') {\n return true;\n }\n // portraitLockRotation: 強制直屏模式\n if (this.orientation === 'portraitLockRotation') {\n return false;\n }\n // landscape: 鎖定橫向\n if (this.orientation === 'landscape') {\n return true;\n }\n // portrait: 鎖定直向\n if (this.orientation === 'portrait') {\n return false;\n }\n // auto: 自動檢測\n return this.boundaryContext.getIsLandscape();\n }\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n ngOnInit(): void {\n this.updateActualOrientation();\n this.setupBreakpointObserver();\n this.setupResizeObserver();\n }\n\n ngAfterViewInit(): void {\n // 使用 @Input 參數,可以立即計算(無需等待 CSS)\n this.updateBoundaryCalculations();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ============================================================\n // Observers Setup - 監聽器設定\n // ============================================================\n\n /**\n * 設定方向變化監控\n *\n * 工作原理:\n * - lock 模式(portrait/landscape):直接設定固定方向,不監聽變化\n * - lockRotation 模式:設定固定方向,但需監聽實際設備方向以觸發旋轉\n * - auto 模式:使用 BreakpointObserver 監聽設備方向變化\n */\n private setupBreakpointObserver() {\n // landscape 或 landscapeLockRotation: 鎖定為橫向\n if (this.orientation === 'landscape' || this.orientation === 'landscapeLockRotation') {\n this.boundaryContext.setIsLandscape(true);\n this.orientationChange.emit(true);\n return;\n }\n\n // portrait 或 portraitLockRotation: 鎖定為直向\n if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation') {\n this.boundaryContext.setIsLandscape(false);\n this.orientationChange.emit(false);\n return;\n }\n\n // auto 模式:監聽實際的設備方向(用於 orientationChange 事件)\n this.breakpointObserver\n .observe('(orientation: landscape)')\n .pipe(takeUntil(this.destroy$))\n .subscribe(result => {\n this.boundaryContext.setIsLandscape(result.matches);\n this.orientationChange.emit(result.matches);\n // 方向變化時重新計算邊界\n this.updateBoundaryCalculations();\n });\n }\n\n /**\n * 設定視窗大小變化監控\n *\n * 功能:\n * - 監聽 window resize 事件\n * - 更新實際設備方向\n * - 重新計算邊界尺寸\n */\n private setupResizeObserver() {\n fromEvent(window, 'resize')\n .pipe(\n // debounceTime(150), // 可選:防抖優化性能\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.updateActualOrientation();\n this.updateBoundaryCalculations();\n });\n }\n\n // ============================================================\n // Calculation Methods - 計算方法\n // ============================================================\n\n /**\n * 更新實際設備方向(基於視口尺寸)\n *\n * 工作原理:\n * - 只在 lockRotation 模式下需要檢測實際方向\n * - 通過比較 window.innerHeight 和 window.innerWidth 判斷\n * - 結果用於觸發 CSS 旋轉變換\n */\n private updateActualOrientation() {\n // 只有在 lockRotation 模式下才需要檢測實際方向\n if (this.orientation !== 'landscapeLockRotation' && this.orientation !== 'portraitLockRotation') {\n this.actualIsPortrait = false;\n return;\n }\n\n // 檢測實際視口方向:高度 > 寬度 = 直向\n this.actualIsPortrait = window.innerHeight > window.innerWidth;\n }\n\n /**\n * 更新邊界計算(支援 Chrome 74,使用 JavaScript 模擬 min 函數)\n *\n * 工作原理:\n * 1. 從 @Input 參數讀取設計尺寸\n * 2. 讀取視口尺寸(vw100, vh100)\n * 3. 處理 lockRotation 模式的視口尺寸交換\n * 4. 計算邊界最大值和實際邊界尺寸\n * 5. 計算 px2vw 轉換比例\n * 6. 設定 CSS 變數供樣式使用\n *\n * 設定的 CSS 變數:\n * - --design-width: 設計稿寬度\n * - --design-height: 設計稿高度\n * - --boundary-width: 實際邊界寬度(px)\n * - --boundary-height: 實際邊界高度(px)\n * - --px2vw-ratio: px 轉 vw 的比例係數\n */\n private updateBoundaryCalculations() {\n const hostElement = this.elementRef.nativeElement as HTMLElement;\n\n // ========================================\n // Step 1: 讀取設計尺寸並設定 CSS 變數\n // ========================================\n const designWidth = this.designWidth;\n const designHeight = this.designHeight;\n\n // 設定 CSS 變數,供樣式使用(例如 px2vw() 函數)\n hostElement.style.setProperty('--design-width', `${designWidth}`);\n hostElement.style.setProperty('--design-height', `${designHeight}`);\n\n // ========================================\n // Step 2: 讀取視口尺寸(直接使用 window.inner* 確保一致性)\n // ========================================\n let vw100 = window.innerWidth;\n let vh100 = window.innerHeight;\n\n // ========================================\n // Step 2: 處理 lockRotation 模式的視口尺寸交換\n // ========================================\n // landscapeLockRotation + 實際直向:交換視口尺寸\n // 原因:旋轉後,內容的寬度對應設備的高度,內容的高度對應設備的寬度\n if (this.orientation === 'landscapeLockRotation' && this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // portraitLockRotation + 實際橫向:交換視口尺寸\n if (this.orientation === 'portraitLockRotation' && !this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // ========================================\n // Step 3: 計算比例和邊界最大值\n // ========================================\n const landscapeRatio = designWidth / designHeight;\n const portraitRatio = designHeight / designWidth;\n\n // 根據方向模式計算邊界最大值\n const isLandscape = this.isLandscape;\n const boundaryMaxWidth = isLandscape\n ? vh100 * portraitRatio // 橫向:高度 * 高寬比\n : vh100 * landscapeRatio; // 直向:高度 * 寬高比\n const boundaryMaxHeight = isLandscape\n ? vw100 * landscapeRatio // 橫向:寬度 * 寬高比\n : vw100 * portraitRatio; // 直向:寬度 * 高寬比\n\n // ========================================\n // Step 4: 計算實際邊界尺寸(使用 Math.min 模擬 CSS min())\n // ========================================\n // Chrome 79 才支援 CSS min() 函數,所以在 JavaScript 中計算\n const boundaryWidth = Math.min(vw100, boundaryMaxWidth);\n const boundaryHeight = Math.min(vh100, boundaryMaxHeight);\n\n // ========================================\n // Step 5: 計算 px2vw 轉換比例\n // ========================================\n // 橫向模式使用 design-height 作為基準,直向模式使用 design-width 作為基準\n const designBaseWidth = isLandscape ? designHeight : designWidth;\n const px2vwRatio = boundaryWidth / designBaseWidth;\n\n // ========================================\n // Step 6: 設定 CSS 變數\n // ========================================\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n }\n}\n","<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n","/*\n * Public API Surface of @bitstack/ng-boundary\n */\n\nexport * from './lib/bs-boundary';\nexport * from './lib/bs-boundary-context.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitstack-ng-boundary.mjs","sources":["../../../projects/bitstack-ng-boundary/src/lib/bs-boundary-context.service.ts","../../../projects/bitstack-ng-boundary/src/lib/bs-boundary.ts","../../../projects/bitstack-ng-boundary/src/lib/template.html","../../../projects/bitstack-ng-boundary/src/public-api.ts","../../../projects/bitstack-ng-boundary/src/bitstack-ng-boundary.ts"],"sourcesContent":["import {Injectable} from '@angular/core';\nimport {BehaviorSubject} from 'rxjs';\n\n@Injectable()\nexport class BsBoundaryContextService {\n private _isLandscape = new BehaviorSubject<boolean>(false);\n\n readonly isLandscape$ = this._isLandscape.asObservable();\n\n setIsLandscape(value: boolean): void {\n this._isLandscape.next(value);\n }\n\n getIsLandscape(): boolean {\n return this._isLandscape.value;\n }\n}\n","import {BreakpointObserver} from '@angular/cdk/layout';\nimport {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input, OnDestroy,\n OnInit,\n Output,\n} from '@angular/core';\nimport {debounceTime, fromEvent, Subject, takeUntil} from 'rxjs';\n\nimport {BsBoundaryContextService} from './bs-boundary-context.service';\nimport {TOrientationMode} from './model';\n\n/**\n * ============================================================\n * BsBoundary Component - AWD 自適應邊界容器\n * ============================================================\n *\n * 功能說明:\n * 1. 提供響應式邊界容器,自動適應不同設備尺寸\n * 2. 支援 5 種方向模式:auto, portrait, landscape, portraitLockRotation, landscapeLockRotation\n * 3. 使用 CSS 變數實現動態計算,支援 px2vw() 函數\n * 4. 相容 Chrome 74+,使用 JavaScript 計算邊界尺寸\n *\n * 使用範例:\n * ```html\n * <bs-boundary [orientation]=\"'auto'\" [isFixedCenter]=\"true\">\n * <div class=\"content\">...</div>\n * </bs-boundary>\n * ```\n *\n * CSS 變數設定:\n * ```scss\n * bs-boundary {\n * --design-width: 375; // 設計稿寬度\n * --design-height: 667; // 設計稿高度\n * }\n * ```\n */\n@Component({\n selector: 'bs-boundary',\n templateUrl: './template.html',\n standalone: true,\n styleUrls: ['./styles.scss'],\n providers: [BsBoundaryContextService],\n host: {\n '[class.auto]': 'orientation === \"auto\"',\n '[class.landscape]': 'isLandscape && orientation === \"landscape\"',\n '[class.portrait]': '!isLandscape && orientation === \"portrait\"',\n '[class.landscape-lock-rotation]': 'orientation === \"landscapeLockRotation\"',\n '[class.portrait-lock-rotation]': 'orientation === \"portraitLockRotation\"',\n '[class.fluid]': 'orientation === \"fluid\"',\n '[class.actual-portrait]': 'actualIsPortrait',\n '[class.actual-landscape]': '!actualIsPortrait'\n }\n})\nexport class BsBoundary implements OnInit, AfterViewInit, OnDestroy {\n\n // ============================================================\n // Inputs & Outputs\n // ============================================================\n\n /**\n * 是否將內容固定在視窗中央\n * @default false\n */\n @Input() isFixedCenter?: boolean = false;\n\n /**\n * 是否禁用指標事件\n * @default false\n */\n @Input() pointerEventsNone?: boolean = false;\n\n /**\n * 方向模式\n * - auto: 自動檢測方向\n * - portrait: 鎖定直向\n * - landscape: 鎖定橫向\n * - portraitLockRotation: 強制直向(橫向設備時旋轉 -90°)\n * - landscapeLockRotation: 強制橫向(直向設備時旋轉 90°)\n * @default 'auto'\n */\n @Input() orientation?: TOrientationMode = 'auto';\n\n /**\n * 向內層容器轉發的自訂樣式\n */\n @Input() forwardStyle?: Record<string, string>;\n\n /**\n * 設計稿寬度(單位:px)\n * 必填參數\n */\n @Input() designWidth!: number;\n\n /**\n * 設計稿高度(單位:px)\n * 必填參數\n */\n @Input() designHeight!: number;\n\n /**\n * 方向變化事件\n * @emits true: landscape(橫屏)\n * @emits false: portrait(直屏)\n */\n @Output() orientationChange = new EventEmitter<boolean>();\n\n // ============================================================\n // Private Dependencies\n // ============================================================\n\n private breakpointObserver = inject(BreakpointObserver);\n private boundaryContext = inject(BsBoundaryContextService);\n private elementRef = inject(ElementRef);\n private destroy$ = new Subject<void>();\n\n // ============================================================\n // Public Properties\n // ============================================================\n\n /**\n * 實際設備方向(基於視口尺寸)\n * true: 直向 (height > width)\n * false: 橫向 (width >= height)\n */\n actualIsPortrait = false;\n\n // ============================================================\n // Getters\n // ============================================================\n\n /**\n * 判斷當前是否為橫向模式\n * 根據 orientation 設定和實際設備方向判斷\n */\n get isLandscape(): boolean {\n // landscapeLockRotation: 強制橫屏模式\n if (this.orientation === 'landscapeLockRotation') {\n return true;\n }\n // portraitLockRotation: 強制直屏模式\n if (this.orientation === 'portraitLockRotation') {\n return false;\n }\n // fluid: 不區分橫直向,以寬度為基準\n if (this.orientation === 'fluid') {\n return false;\n }\n // landscape: 鎖定橫向\n if (this.orientation === 'landscape') {\n return true;\n }\n // portrait: 鎖定直向\n if (this.orientation === 'portrait') {\n return false;\n }\n // auto: 自動檢測\n return this.boundaryContext.getIsLandscape();\n }\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n ngOnInit(): void {\n this.updateActualOrientation();\n this.setupBreakpointObserver();\n this.setupResizeObserver();\n }\n\n ngAfterViewInit(): void {\n // 使用 @Input 參數,可以立即計算(無需等待 CSS)\n this.updateBoundaryCalculations();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ============================================================\n // Observers Setup - 監聽器設定\n // ============================================================\n\n /**\n * 設定方向變化監控\n *\n * 工作原理:\n * - lock 模式(portrait/landscape):直接設定固定方向,不監聽變化\n * - lockRotation 模式:設定固定方向,但需監聽實際設備方向以觸發旋轉\n * - auto 模式:使用 BreakpointObserver 監聽設備方向變化\n */\n private setupBreakpointObserver() {\n // landscape 或 landscapeLockRotation: 鎖定為橫向\n if (this.orientation === 'landscape' || this.orientation === 'landscapeLockRotation') {\n this.boundaryContext.setIsLandscape(true);\n this.orientationChange.emit(true);\n return;\n }\n\n // portrait、portraitLockRotation 或 fluid: 鎖定為直向\n if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation' || this.orientation === 'fluid') {\n this.boundaryContext.setIsLandscape(false);\n this.orientationChange.emit(false);\n return;\n }\n\n // auto 模式:監聽實際的設備方向(用於 orientationChange 事件)\n this.breakpointObserver\n .observe('(orientation: landscape)')\n .pipe(takeUntil(this.destroy$))\n .subscribe(result => {\n this.boundaryContext.setIsLandscape(result.matches);\n this.orientationChange.emit(result.matches);\n // 方向變化時重新計算邊界\n this.updateBoundaryCalculations();\n });\n }\n\n /**\n * 設定視窗大小變化監控\n *\n * 功能:\n * - 監聽 window resize 事件\n * - 更新實際設備方向\n * - 重新計算邊界尺寸\n */\n private setupResizeObserver() {\n fromEvent(window, 'resize')\n .pipe(\n // debounceTime(150), // 可選:防抖優化性能\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.updateActualOrientation();\n this.updateBoundaryCalculations();\n });\n }\n\n // ============================================================\n // Calculation Methods - 計算方法\n // ============================================================\n\n /**\n * 更新實際設備方向(基於視口尺寸)\n *\n * 工作原理:\n * - 只在 lockRotation 模式下需要檢測實際方向\n * - 通過比較 window.innerHeight 和 window.innerWidth 判斷\n * - 結果用於觸發 CSS 旋轉變換\n */\n private updateActualOrientation() {\n // 只有在 lockRotation 模式下才需要檢測實際方向\n if (this.orientation !== 'landscapeLockRotation' && this.orientation !== 'portraitLockRotation') {\n this.actualIsPortrait = false;\n return;\n }\n\n // 檢測實際視口方向:高度 > 寬度 = 直向\n this.actualIsPortrait = window.innerHeight > window.innerWidth;\n }\n\n /**\n * 更新邊界計算(支援 Chrome 74,使用 JavaScript 模擬 min 函數)\n *\n * 工作原理:\n * 1. 從 @Input 參數讀取設計尺寸\n * 2. 讀取視口尺寸(vw100, vh100)\n * 3. 處理 lockRotation 模式的視口尺寸交換\n * 4. 計算邊界最大值和實際邊界尺寸\n * 5. 計算 px2vw 轉換比例\n * 6. 設定 CSS 變數供樣式使用\n *\n * 設定的 CSS 變數:\n * - --design-width: 設計稿寬度\n * - --design-height: 設計稿高度\n * - --boundary-width: 實際邊界寬度(px)\n * - --boundary-height: 實際邊界高度(px)\n * - --px2vw-ratio: px 轉 vw 的比例係數\n */\n private updateBoundaryCalculations() {\n const hostElement = this.elementRef.nativeElement as HTMLElement;\n\n // ========================================\n // Step 1: 讀取設計尺寸並設定 CSS 變數\n // ========================================\n const designWidth = this.designWidth;\n const designHeight = this.designHeight;\n\n // 設定 CSS 變數,供樣式使用(例如 px2vw() 函數)\n hostElement.style.setProperty('--design-width', `${designWidth}`);\n hostElement.style.setProperty('--design-height', `${designHeight}`);\n\n // ========================================\n // Step 2: 讀取視口尺寸(直接使用 window.inner* 確保一致性)\n // ========================================\n let vw100 = window.innerWidth;\n let vh100 = window.innerHeight;\n\n // ========================================\n // Step 2: 處理 lockRotation 模式的視口尺寸交換\n // ========================================\n // landscapeLockRotation + 實際直向:交換視口尺寸\n // 原因:旋轉後,內容的寬度對應設備的高度,內容的高度對應設備的寬度\n if (this.orientation === 'landscapeLockRotation' && this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // portraitLockRotation + 實際橫向:交換視口尺寸\n if (this.orientation === 'portraitLockRotation' && !this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // ========================================\n // Fluid 模式:不參考寬高比,直接使用螢幕尺寸\n // ========================================\n if (this.orientation === 'fluid') {\n const boundaryWidth = vw100;\n const boundaryHeight = vh100;\n const px2vwRatio = vw100 / designWidth;\n\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n return;\n }\n\n // ========================================\n // Step 3: 計算比例和邊界最大值\n // ========================================\n const landscapeRatio = designWidth / designHeight;\n const portraitRatio = designHeight / designWidth;\n\n // 根據方向模式計算邊界最大值\n const isLandscape = this.isLandscape;\n const boundaryMaxWidth = isLandscape\n ? vh100 * portraitRatio // 橫向:高度 * 高寬比\n : vh100 * landscapeRatio; // 直向:高度 * 寬高比\n const boundaryMaxHeight = isLandscape\n ? vw100 * landscapeRatio // 橫向:寬度 * 寬高比\n : vw100 * portraitRatio; // 直向:寬度 * 高寬比\n\n // ========================================\n // Step 4: 計算實際邊界尺寸(使用 Math.min 模擬 CSS min())\n // ========================================\n // Chrome 79 才支援 CSS min() 函數,所以在 JavaScript 中計算\n const boundaryWidth = Math.min(vw100, boundaryMaxWidth);\n const boundaryHeight = Math.min(vh100, boundaryMaxHeight);\n\n // ========================================\n // Step 5: 計算 px2vw 轉換比例\n // ========================================\n // 橫向模式使用 design-height 作為基準,直向模式使用 design-width 作為基準\n const designBaseWidth = isLandscape ? designHeight : designWidth;\n const px2vwRatio = boundaryWidth / designBaseWidth;\n\n // ========================================\n // Step 6: 設定 CSS 變數\n // ========================================\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n }\n}\n","<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n","/*\n * Public API Surface of @bitstack/ng-boundary\n */\n\nexport * from './lib/bs-boundary';\nexport * from './lib/bs-boundary-context.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;MAIa,wBAAwB,CAAA;AADrC,IAAA,WAAA,GAAA;QAEY,IAAA,CAAA,YAAY,GAAG,IAAI,eAAe,CAAU,KAAK,CAAC,CAAC;QAElD,IAAA,CAAA,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;KAS5D;AAPG,IAAA,cAAc,CAAC,KAAc,EAAA;AACzB,QAAA,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;KACjC;IAED,cAAc,GAAA;AACV,QAAA,OAAO,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;KAClC;;qHAXQ,wBAAwB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;yHAAxB,wBAAwB,EAAA,CAAA,CAAA;2FAAxB,wBAAwB,EAAA,UAAA,EAAA,CAAA;kBADpC,UAAU;;;ACaX;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;MAkBU,UAAU,CAAA;AAjBvB,IAAA,WAAA,GAAA;;;;AAuBI;;;AAGG;AACM,QAAA,IAAa,CAAA,aAAA,GAAa,KAAK,CAAC;AAEzC;;;AAGG;AACM,QAAA,IAAiB,CAAA,iBAAA,GAAa,KAAK,CAAC;AAE7C;;;;;;;;AAQG;AACM,QAAA,IAAW,CAAA,WAAA,GAAsB,MAAM,CAAC;AAmBjD;;;;AAIG;AACO,QAAA,IAAA,CAAA,iBAAiB,GAAG,IAAI,YAAY,EAAW,CAAC;;;;AAMlD,QAAA,IAAA,CAAA,kBAAkB,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAChD,QAAA,IAAA,CAAA,eAAe,GAAG,MAAM,CAAC,wBAAwB,CAAC,CAAC;AACnD,QAAA,IAAA,CAAA,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;AAChC,QAAA,IAAA,CAAA,QAAQ,GAAG,IAAI,OAAO,EAAQ,CAAC;;;;AAMvC;;;;AAIG;AACH,QAAA,IAAgB,CAAA,gBAAA,GAAG,KAAK,CAAC;KA8O5B;;;;AAxOG;;;AAGG;AACH,IAAA,IAAI,WAAW,GAAA;;AAEX,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,uBAAuB,EAAE;AAC9C,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;;AAED,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,sBAAsB,EAAE;AAC7C,YAAA,OAAO,KAAK,CAAC;AAChB,SAAA;;AAED,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE;AAC9B,YAAA,OAAO,KAAK,CAAC;AAChB,SAAA;;AAED,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,EAAE;AAClC,YAAA,OAAO,IAAI,CAAC;AACf,SAAA;;AAED,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,UAAU,EAAE;AACjC,YAAA,OAAO,KAAK,CAAC;AAChB,SAAA;;AAED,QAAA,OAAO,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;KAChD;;;;IAMD,QAAQ,GAAA;QACJ,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAC/B,IAAI,CAAC,mBAAmB,EAAE,CAAC;KAC9B;IAED,eAAe,GAAA;;QAEX,IAAI,CAAC,0BAA0B,EAAE,CAAC;KACrC;IAED,WAAW,GAAA;AACP,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;AACrB,QAAA,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;KAC5B;;;;AAMD;;;;;;;AAOG;IACK,uBAAuB,GAAA;;QAE3B,IAAI,IAAI,CAAC,WAAW,KAAK,WAAW,IAAI,IAAI,CAAC,WAAW,KAAK,uBAAuB,EAAE;AAClF,YAAA,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;AAC1C,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClC,OAAO;AACV,SAAA;;AAGD,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,UAAU,IAAI,IAAI,CAAC,WAAW,KAAK,sBAAsB,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE;AAChH,YAAA,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAC3C,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnC,OAAO;AACV,SAAA;;AAGD,QAAA,IAAI,CAAC,kBAAkB;aAClB,OAAO,CAAC,0BAA0B,CAAC;AACnC,aAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC9B,SAAS,CAAC,MAAM,IAAG;YAChB,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACpD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;;YAE5C,IAAI,CAAC,0BAA0B,EAAE,CAAC;AACtC,SAAC,CAAC,CAAC;KACV;AAED;;;;;;;AAOG;IACK,mBAAmB,GAAA;AACvB,QAAA,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC;aACtB,IAAI;;AAED,QAAA,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAC3B;aACA,SAAS,CAAC,MAAK;YACZ,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAC/B,IAAI,CAAC,0BAA0B,EAAE,CAAC;AACtC,SAAC,CAAC,CAAC;KACV;;;;AAMD;;;;;;;AAOG;IACK,uBAAuB,GAAA;;QAE3B,IAAI,IAAI,CAAC,WAAW,KAAK,uBAAuB,IAAI,IAAI,CAAC,WAAW,KAAK,sBAAsB,EAAE;AAC7F,YAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;YAC9B,OAAO;AACV,SAAA;;QAGD,IAAI,CAAC,gBAAgB,GAAG,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC,UAAU,CAAC;KAClE;AAED;;;;;;;;;;;;;;;;;AAiBG;IACK,0BAA0B,GAAA;AAC9B,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,CAAC,aAA4B,CAAC;;;;AAKjE,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;AACrC,QAAA,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;;QAGvC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAG,EAAA,WAAW,CAAE,CAAA,CAAC,CAAC;QAClE,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,CAAG,EAAA,YAAY,CAAE,CAAA,CAAC,CAAC;;;;AAKpE,QAAA,IAAI,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC;AAC9B,QAAA,IAAI,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC;;;;;;QAO/B,IAAI,IAAI,CAAC,WAAW,KAAK,uBAAuB,IAAI,IAAI,CAAC,gBAAgB,EAAE;YACvE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACnC,SAAA;;QAGD,IAAI,IAAI,CAAC,WAAW,KAAK,sBAAsB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;YACvE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AACnC,SAAA;;;;AAKD,QAAA,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,EAAE;YAC9B,MAAM,aAAa,GAAG,KAAK,CAAC;YAC5B,MAAM,cAAc,GAAG,KAAK,CAAC;AAC7B,YAAA,MAAM,UAAU,GAAG,KAAK,GAAG,WAAW,CAAC;YAEvC,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAG,EAAA,aAAa,CAAI,EAAA,CAAA,CAAC,CAAC;YACxE,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAG,EAAA,cAAc,CAAI,EAAA,CAAA,CAAC,CAAC;YAC1E,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,CAAG,EAAA,UAAU,CAAE,CAAA,CAAC,CAAC;YAChE,OAAO;AACV,SAAA;;;;AAKD,QAAA,MAAM,cAAc,GAAG,WAAW,GAAG,YAAY,CAAC;AAClD,QAAA,MAAM,aAAa,GAAG,YAAY,GAAG,WAAW,CAAC;;AAGjD,QAAA,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACrC,MAAM,gBAAgB,GAAG,WAAW;AAChC,cAAE,KAAK,GAAG,aAAa;AACvB,cAAE,KAAK,GAAG,cAAc,CAAC;QAC7B,MAAM,iBAAiB,GAAG,WAAW;AACjC,cAAE,KAAK,GAAG,cAAc;AACxB,cAAE,KAAK,GAAG,aAAa,CAAC;;;;;QAM5B,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;QACxD,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;;;;;QAM1D,MAAM,eAAe,GAAG,WAAW,GAAG,YAAY,GAAG,WAAW,CAAC;AACjE,QAAA,MAAM,UAAU,GAAG,aAAa,GAAG,eAAe,CAAC;;;;QAKnD,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,kBAAkB,EAAE,CAAG,EAAA,aAAa,CAAI,EAAA,CAAA,CAAC,CAAC;QACxE,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAG,EAAA,cAAc,CAAI,EAAA,CAAA,CAAC,CAAC;QAC1E,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,eAAe,EAAE,CAAG,EAAA,UAAU,CAAE,CAAA,CAAC,CAAC;KACnE;;uGApTQ,UAAU,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAV,UAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,UAAU,EAZR,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,EAAA,aAAA,EAAA,eAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,WAAA,EAAA,aAAA,EAAA,YAAA,EAAA,cAAA,EAAA,EAAA,OAAA,EAAA,EAAA,iBAAA,EAAA,mBAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,YAAA,EAAA,0BAAA,EAAA,iBAAA,EAAA,8CAAA,EAAA,gBAAA,EAAA,8CAAA,EAAA,+BAAA,EAAA,2CAAA,EAAA,8BAAA,EAAA,0CAAA,EAAA,aAAA,EAAA,2BAAA,EAAA,uBAAA,EAAA,kBAAA,EAAA,wBAAA,EAAA,mBAAA,EAAA,EAAA,EAAA,SAAA,EAAA,CAAC,wBAAwB,CAAC,0BC/CzC,yMAQA,EAAA,MAAA,EAAA,CAAA,27DAAA,CAAA,EAAA,CAAA,CAAA;2FDmDa,UAAU,EAAA,UAAA,EAAA,CAAA;kBAjBtB,SAAS;AACI,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,aAAa,cAEX,IAAI,EAAA,SAAA,EAEL,CAAC,wBAAwB,CAAC,EAC/B,IAAA,EAAA;AACF,wBAAA,cAAc,EAAE,wBAAwB;AACxC,wBAAA,mBAAmB,EAAE,4CAA4C;AACjE,wBAAA,kBAAkB,EAAE,4CAA4C;AAChE,wBAAA,iCAAiC,EAAE,yCAAyC;AAC5E,wBAAA,gCAAgC,EAAE,wCAAwC;AAC1E,wBAAA,eAAe,EAAE,yBAAyB;AAC1C,wBAAA,yBAAyB,EAAE,kBAAkB;AAC7C,wBAAA,0BAA0B,EAAE,mBAAmB;qBAClD,EAAA,QAAA,EAAA,yMAAA,EAAA,MAAA,EAAA,CAAA,27DAAA,CAAA,EAAA,CAAA;8BAYQ,aAAa,EAAA,CAAA;sBAArB,KAAK;gBAMG,iBAAiB,EAAA,CAAA;sBAAzB,KAAK;gBAWG,WAAW,EAAA,CAAA;sBAAnB,KAAK;gBAKG,YAAY,EAAA,CAAA;sBAApB,KAAK;gBAMG,WAAW,EAAA,CAAA;sBAAnB,KAAK;gBAMG,YAAY,EAAA,CAAA;sBAApB,KAAK;gBAOI,iBAAiB,EAAA,CAAA;sBAA1B,MAAM;;;AE9GX;;AAEG;;ACFH;;AAEG;;;;"}
@@ -111,6 +111,10 @@ class BsBoundary {
111
111
  if (this.orientation === 'portraitLockRotation') {
112
112
  return false;
113
113
  }
114
+ // fluid: 不區分橫直向,以寬度為基準
115
+ if (this.orientation === 'fluid') {
116
+ return false;
117
+ }
114
118
  // landscape: 鎖定橫向
115
119
  if (this.orientation === 'landscape') {
116
120
  return true;
@@ -156,8 +160,8 @@ class BsBoundary {
156
160
  this.orientationChange.emit(true);
157
161
  return;
158
162
  }
159
- // portrait 或 portraitLockRotation: 鎖定為直向
160
- if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation') {
163
+ // portrait、portraitLockRotationfluid: 鎖定為直向
164
+ if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation' || this.orientation === 'fluid') {
161
165
  this.boundaryContext.setIsLandscape(false);
162
166
  this.orientationChange.emit(false);
163
167
  return;
@@ -257,6 +261,18 @@ class BsBoundary {
257
261
  [vw100, vh100] = [vh100, vw100];
258
262
  }
259
263
  // ========================================
264
+ // Fluid 模式:不參考寬高比,直接使用螢幕尺寸
265
+ // ========================================
266
+ if (this.orientation === 'fluid') {
267
+ const boundaryWidth = vw100;
268
+ const boundaryHeight = vh100;
269
+ const px2vwRatio = vw100 / designWidth;
270
+ hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);
271
+ hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);
272
+ hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);
273
+ return;
274
+ }
275
+ // ========================================
260
276
  // Step 3: 計算比例和邊界最大值
261
277
  // ========================================
262
278
  const landscapeRatio = designWidth / designHeight;
@@ -290,7 +306,7 @@ class BsBoundary {
290
306
  }
291
307
  }
292
308
  BsBoundary.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, deps: [], target: i0.ɵɵFactoryTarget.Component });
293
- BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
309
+ BsBoundary.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: BsBoundary, isStandalone: true, selector: "bs-boundary", inputs: { isFixedCenter: "isFixedCenter", pointerEventsNone: "pointerEventsNone", orientation: "orientation", forwardStyle: "forwardStyle", designWidth: "designWidth", designHeight: "designHeight" }, outputs: { orientationChange: "orientationChange" }, host: { properties: { "class.auto": "orientation === \"auto\"", "class.landscape": "isLandscape && orientation === \"landscape\"", "class.portrait": "!isLandscape && orientation === \"portrait\"", "class.landscape-lock-rotation": "orientation === \"landscapeLockRotation\"", "class.portrait-lock-rotation": "orientation === \"portraitLockRotation\"", "class.fluid": "orientation === \"fluid\"", "class.actual-portrait": "actualIsPortrait", "class.actual-landscape": "!actualIsPortrait" } }, providers: [BsBoundaryContextService], ngImport: i0, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] });
294
310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: BsBoundary, decorators: [{
295
311
  type: Component,
296
312
  args: [{ selector: 'bs-boundary', standalone: true, providers: [BsBoundaryContextService], host: {
@@ -299,9 +315,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
299
315
  '[class.portrait]': '!isLandscape && orientation === "portrait"',
300
316
  '[class.landscape-lock-rotation]': 'orientation === "landscapeLockRotation"',
301
317
  '[class.portrait-lock-rotation]': 'orientation === "portraitLockRotation"',
318
+ '[class.fluid]': 'orientation === "fluid"',
302
319
  '[class.actual-portrait]': 'actualIsPortrait',
303
320
  '[class.actual-landscape]': '!actualIsPortrait'
304
- }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
321
+ }, template: "<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n", styles: [":host{--landscape-ratio: calc(var(--design-width) / var(--design-height));--portrait-ratio: calc(var(--design-height) / var(--design-width));--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}.boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:var(--boundary-max-width);max-height:var(--boundary-max-height)}.boundary-wrapper.pointerEventsNone{pointer-events:none}:host.portrait{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.landscape{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}@media (orientation: landscape){:host.auto{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}}.fixed-center{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);transform-origin:center;z-index:99}:host.landscape-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--portrait-ratio));--boundary-max-height: calc(var(--vw100) * var(--landscape-ratio))}:host.landscape-lock-rotation.actual-portrait .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}:host.fluid .boundary-wrapper{width:var(--vw100);height:var(--vh100);max-width:none;max-height:none}:host.portrait-lock-rotation{--boundary-max-width: calc(var(--vh100) * var(--landscape-ratio));--boundary-max-height: calc(var(--vw100) * var(--portrait-ratio))}:host.portrait-lock-rotation.actual-landscape .boundary-wrapper{position:fixed;top:50%;left:50%;transform:translate(-50%,-50%) rotate(-90deg);transform-origin:center;width:var(--boundary-width);height:var(--boundary-height);max-width:none;max-height:none}\n"] }]
305
322
  }], propDecorators: { isFixedCenter: [{
306
323
  type: Input
307
324
  }], pointerEventsNone: [{
@@ -1 +1 @@
1
- {"version":3,"file":"bitstack-ng-boundary.mjs","sources":["../../../projects/bitstack-ng-boundary/src/lib/bs-boundary-context.service.ts","../../../projects/bitstack-ng-boundary/src/lib/bs-boundary.ts","../../../projects/bitstack-ng-boundary/src/lib/template.html","../../../projects/bitstack-ng-boundary/src/public-api.ts","../../../projects/bitstack-ng-boundary/src/bitstack-ng-boundary.ts"],"sourcesContent":["import {Injectable} from '@angular/core';\nimport {BehaviorSubject} from 'rxjs';\n\n@Injectable()\nexport class BsBoundaryContextService {\n private _isLandscape = new BehaviorSubject<boolean>(false);\n\n readonly isLandscape$ = this._isLandscape.asObservable();\n\n setIsLandscape(value: boolean): void {\n this._isLandscape.next(value);\n }\n\n getIsLandscape(): boolean {\n return this._isLandscape.value;\n }\n}\n","import {BreakpointObserver} from '@angular/cdk/layout';\nimport {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input, OnDestroy,\n OnInit,\n Output,\n} from '@angular/core';\nimport {debounceTime, fromEvent, Subject, takeUntil} from 'rxjs';\n\nimport {BsBoundaryContextService} from './bs-boundary-context.service';\nimport {TOrientationMode} from './model';\n\n/**\n * ============================================================\n * BsBoundary Component - AWD 自適應邊界容器\n * ============================================================\n *\n * 功能說明:\n * 1. 提供響應式邊界容器,自動適應不同設備尺寸\n * 2. 支援 5 種方向模式:auto, portrait, landscape, portraitLockRotation, landscapeLockRotation\n * 3. 使用 CSS 變數實現動態計算,支援 px2vw() 函數\n * 4. 相容 Chrome 74+,使用 JavaScript 計算邊界尺寸\n *\n * 使用範例:\n * ```html\n * <bs-boundary [orientation]=\"'auto'\" [isFixedCenter]=\"true\">\n * <div class=\"content\">...</div>\n * </bs-boundary>\n * ```\n *\n * CSS 變數設定:\n * ```scss\n * bs-boundary {\n * --design-width: 375; // 設計稿寬度\n * --design-height: 667; // 設計稿高度\n * }\n * ```\n */\n@Component({\n selector: 'bs-boundary',\n templateUrl: './template.html',\n standalone: true,\n styleUrls: ['./styles.scss'],\n providers: [BsBoundaryContextService],\n host: {\n '[class.auto]': 'orientation === \"auto\"',\n '[class.landscape]': 'isLandscape && orientation === \"landscape\"',\n '[class.portrait]': '!isLandscape && orientation === \"portrait\"',\n '[class.landscape-lock-rotation]': 'orientation === \"landscapeLockRotation\"',\n '[class.portrait-lock-rotation]': 'orientation === \"portraitLockRotation\"',\n '[class.actual-portrait]': 'actualIsPortrait',\n '[class.actual-landscape]': '!actualIsPortrait'\n }\n})\nexport class BsBoundary implements OnInit, AfterViewInit, OnDestroy {\n\n // ============================================================\n // Inputs & Outputs\n // ============================================================\n\n /**\n * 是否將內容固定在視窗中央\n * @default false\n */\n @Input() isFixedCenter?: boolean = false;\n\n /**\n * 是否禁用指標事件\n * @default false\n */\n @Input() pointerEventsNone?: boolean = false;\n\n /**\n * 方向模式\n * - auto: 自動檢測方向\n * - portrait: 鎖定直向\n * - landscape: 鎖定橫向\n * - portraitLockRotation: 強制直向(橫向設備時旋轉 -90°)\n * - landscapeLockRotation: 強制橫向(直向設備時旋轉 90°)\n * @default 'auto'\n */\n @Input() orientation?: TOrientationMode = 'auto';\n\n /**\n * 向內層容器轉發的自訂樣式\n */\n @Input() forwardStyle?: Record<string, string>;\n\n /**\n * 設計稿寬度(單位:px)\n * 必填參數\n */\n @Input() designWidth!: number;\n\n /**\n * 設計稿高度(單位:px)\n * 必填參數\n */\n @Input() designHeight!: number;\n\n /**\n * 方向變化事件\n * @emits true: landscape(橫屏)\n * @emits false: portrait(直屏)\n */\n @Output() orientationChange = new EventEmitter<boolean>();\n\n // ============================================================\n // Private Dependencies\n // ============================================================\n\n private breakpointObserver = inject(BreakpointObserver);\n private boundaryContext = inject(BsBoundaryContextService);\n private elementRef = inject(ElementRef);\n private destroy$ = new Subject<void>();\n\n // ============================================================\n // Public Properties\n // ============================================================\n\n /**\n * 實際設備方向(基於視口尺寸)\n * true: 直向 (height > width)\n * false: 橫向 (width >= height)\n */\n actualIsPortrait = false;\n\n // ============================================================\n // Getters\n // ============================================================\n\n /**\n * 判斷當前是否為橫向模式\n * 根據 orientation 設定和實際設備方向判斷\n */\n get isLandscape(): boolean {\n // landscapeLockRotation: 強制橫屏模式\n if (this.orientation === 'landscapeLockRotation') {\n return true;\n }\n // portraitLockRotation: 強制直屏模式\n if (this.orientation === 'portraitLockRotation') {\n return false;\n }\n // landscape: 鎖定橫向\n if (this.orientation === 'landscape') {\n return true;\n }\n // portrait: 鎖定直向\n if (this.orientation === 'portrait') {\n return false;\n }\n // auto: 自動檢測\n return this.boundaryContext.getIsLandscape();\n }\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n ngOnInit(): void {\n this.updateActualOrientation();\n this.setupBreakpointObserver();\n this.setupResizeObserver();\n }\n\n ngAfterViewInit(): void {\n // 使用 @Input 參數,可以立即計算(無需等待 CSS)\n this.updateBoundaryCalculations();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ============================================================\n // Observers Setup - 監聽器設定\n // ============================================================\n\n /**\n * 設定方向變化監控\n *\n * 工作原理:\n * - lock 模式(portrait/landscape):直接設定固定方向,不監聽變化\n * - lockRotation 模式:設定固定方向,但需監聽實際設備方向以觸發旋轉\n * - auto 模式:使用 BreakpointObserver 監聽設備方向變化\n */\n private setupBreakpointObserver() {\n // landscape 或 landscapeLockRotation: 鎖定為橫向\n if (this.orientation === 'landscape' || this.orientation === 'landscapeLockRotation') {\n this.boundaryContext.setIsLandscape(true);\n this.orientationChange.emit(true);\n return;\n }\n\n // portrait 或 portraitLockRotation: 鎖定為直向\n if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation') {\n this.boundaryContext.setIsLandscape(false);\n this.orientationChange.emit(false);\n return;\n }\n\n // auto 模式:監聽實際的設備方向(用於 orientationChange 事件)\n this.breakpointObserver\n .observe('(orientation: landscape)')\n .pipe(takeUntil(this.destroy$))\n .subscribe(result => {\n this.boundaryContext.setIsLandscape(result.matches);\n this.orientationChange.emit(result.matches);\n // 方向變化時重新計算邊界\n this.updateBoundaryCalculations();\n });\n }\n\n /**\n * 設定視窗大小變化監控\n *\n * 功能:\n * - 監聽 window resize 事件\n * - 更新實際設備方向\n * - 重新計算邊界尺寸\n */\n private setupResizeObserver() {\n fromEvent(window, 'resize')\n .pipe(\n // debounceTime(150), // 可選:防抖優化性能\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.updateActualOrientation();\n this.updateBoundaryCalculations();\n });\n }\n\n // ============================================================\n // Calculation Methods - 計算方法\n // ============================================================\n\n /**\n * 更新實際設備方向(基於視口尺寸)\n *\n * 工作原理:\n * - 只在 lockRotation 模式下需要檢測實際方向\n * - 通過比較 window.innerHeight 和 window.innerWidth 判斷\n * - 結果用於觸發 CSS 旋轉變換\n */\n private updateActualOrientation() {\n // 只有在 lockRotation 模式下才需要檢測實際方向\n if (this.orientation !== 'landscapeLockRotation' && this.orientation !== 'portraitLockRotation') {\n this.actualIsPortrait = false;\n return;\n }\n\n // 檢測實際視口方向:高度 > 寬度 = 直向\n this.actualIsPortrait = window.innerHeight > window.innerWidth;\n }\n\n /**\n * 更新邊界計算(支援 Chrome 74,使用 JavaScript 模擬 min 函數)\n *\n * 工作原理:\n * 1. 從 @Input 參數讀取設計尺寸\n * 2. 讀取視口尺寸(vw100, vh100)\n * 3. 處理 lockRotation 模式的視口尺寸交換\n * 4. 計算邊界最大值和實際邊界尺寸\n * 5. 計算 px2vw 轉換比例\n * 6. 設定 CSS 變數供樣式使用\n *\n * 設定的 CSS 變數:\n * - --design-width: 設計稿寬度\n * - --design-height: 設計稿高度\n * - --boundary-width: 實際邊界寬度(px)\n * - --boundary-height: 實際邊界高度(px)\n * - --px2vw-ratio: px 轉 vw 的比例係數\n */\n private updateBoundaryCalculations() {\n const hostElement = this.elementRef.nativeElement as HTMLElement;\n\n // ========================================\n // Step 1: 讀取設計尺寸並設定 CSS 變數\n // ========================================\n const designWidth = this.designWidth;\n const designHeight = this.designHeight;\n\n // 設定 CSS 變數,供樣式使用(例如 px2vw() 函數)\n hostElement.style.setProperty('--design-width', `${designWidth}`);\n hostElement.style.setProperty('--design-height', `${designHeight}`);\n\n // ========================================\n // Step 2: 讀取視口尺寸(直接使用 window.inner* 確保一致性)\n // ========================================\n let vw100 = window.innerWidth;\n let vh100 = window.innerHeight;\n\n // ========================================\n // Step 2: 處理 lockRotation 模式的視口尺寸交換\n // ========================================\n // landscapeLockRotation + 實際直向:交換視口尺寸\n // 原因:旋轉後,內容的寬度對應設備的高度,內容的高度對應設備的寬度\n if (this.orientation === 'landscapeLockRotation' && this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // portraitLockRotation + 實際橫向:交換視口尺寸\n if (this.orientation === 'portraitLockRotation' && !this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // ========================================\n // Step 3: 計算比例和邊界最大值\n // ========================================\n const landscapeRatio = designWidth / designHeight;\n const portraitRatio = designHeight / designWidth;\n\n // 根據方向模式計算邊界最大值\n const isLandscape = this.isLandscape;\n const boundaryMaxWidth = isLandscape\n ? vh100 * portraitRatio // 橫向:高度 * 高寬比\n : vh100 * landscapeRatio; // 直向:高度 * 寬高比\n const boundaryMaxHeight = isLandscape\n ? vw100 * landscapeRatio // 橫向:寬度 * 寬高比\n : vw100 * portraitRatio; // 直向:寬度 * 高寬比\n\n // ========================================\n // Step 4: 計算實際邊界尺寸(使用 Math.min 模擬 CSS min())\n // ========================================\n // Chrome 79 才支援 CSS min() 函數,所以在 JavaScript 中計算\n const boundaryWidth = Math.min(vw100, boundaryMaxWidth);\n const boundaryHeight = Math.min(vh100, boundaryMaxHeight);\n\n // ========================================\n // Step 5: 計算 px2vw 轉換比例\n // ========================================\n // 橫向模式使用 design-height 作為基準,直向模式使用 design-width 作為基準\n const designBaseWidth = isLandscape ? designHeight : designWidth;\n const px2vwRatio = boundaryWidth / designBaseWidth;\n\n // ========================================\n // Step 6: 設定 CSS 變數\n // ========================================\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n }\n}\n","<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n","/*\n * Public API Surface of @bitstack/ng-boundary\n */\n\nexport * from './lib/bs-boundary';\nexport * from './lib/bs-boundary-context.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitstack-ng-boundary.mjs","sources":["../../../projects/bitstack-ng-boundary/src/lib/bs-boundary-context.service.ts","../../../projects/bitstack-ng-boundary/src/lib/bs-boundary.ts","../../../projects/bitstack-ng-boundary/src/lib/template.html","../../../projects/bitstack-ng-boundary/src/public-api.ts","../../../projects/bitstack-ng-boundary/src/bitstack-ng-boundary.ts"],"sourcesContent":["import {Injectable} from '@angular/core';\nimport {BehaviorSubject} from 'rxjs';\n\n@Injectable()\nexport class BsBoundaryContextService {\n private _isLandscape = new BehaviorSubject<boolean>(false);\n\n readonly isLandscape$ = this._isLandscape.asObservable();\n\n setIsLandscape(value: boolean): void {\n this._isLandscape.next(value);\n }\n\n getIsLandscape(): boolean {\n return this._isLandscape.value;\n }\n}\n","import {BreakpointObserver} from '@angular/cdk/layout';\nimport {\n AfterViewInit,\n Component,\n ElementRef,\n EventEmitter,\n inject,\n Input, OnDestroy,\n OnInit,\n Output,\n} from '@angular/core';\nimport {debounceTime, fromEvent, Subject, takeUntil} from 'rxjs';\n\nimport {BsBoundaryContextService} from './bs-boundary-context.service';\nimport {TOrientationMode} from './model';\n\n/**\n * ============================================================\n * BsBoundary Component - AWD 自適應邊界容器\n * ============================================================\n *\n * 功能說明:\n * 1. 提供響應式邊界容器,自動適應不同設備尺寸\n * 2. 支援 5 種方向模式:auto, portrait, landscape, portraitLockRotation, landscapeLockRotation\n * 3. 使用 CSS 變數實現動態計算,支援 px2vw() 函數\n * 4. 相容 Chrome 74+,使用 JavaScript 計算邊界尺寸\n *\n * 使用範例:\n * ```html\n * <bs-boundary [orientation]=\"'auto'\" [isFixedCenter]=\"true\">\n * <div class=\"content\">...</div>\n * </bs-boundary>\n * ```\n *\n * CSS 變數設定:\n * ```scss\n * bs-boundary {\n * --design-width: 375; // 設計稿寬度\n * --design-height: 667; // 設計稿高度\n * }\n * ```\n */\n@Component({\n selector: 'bs-boundary',\n templateUrl: './template.html',\n standalone: true,\n styleUrls: ['./styles.scss'],\n providers: [BsBoundaryContextService],\n host: {\n '[class.auto]': 'orientation === \"auto\"',\n '[class.landscape]': 'isLandscape && orientation === \"landscape\"',\n '[class.portrait]': '!isLandscape && orientation === \"portrait\"',\n '[class.landscape-lock-rotation]': 'orientation === \"landscapeLockRotation\"',\n '[class.portrait-lock-rotation]': 'orientation === \"portraitLockRotation\"',\n '[class.fluid]': 'orientation === \"fluid\"',\n '[class.actual-portrait]': 'actualIsPortrait',\n '[class.actual-landscape]': '!actualIsPortrait'\n }\n})\nexport class BsBoundary implements OnInit, AfterViewInit, OnDestroy {\n\n // ============================================================\n // Inputs & Outputs\n // ============================================================\n\n /**\n * 是否將內容固定在視窗中央\n * @default false\n */\n @Input() isFixedCenter?: boolean = false;\n\n /**\n * 是否禁用指標事件\n * @default false\n */\n @Input() pointerEventsNone?: boolean = false;\n\n /**\n * 方向模式\n * - auto: 自動檢測方向\n * - portrait: 鎖定直向\n * - landscape: 鎖定橫向\n * - portraitLockRotation: 強制直向(橫向設備時旋轉 -90°)\n * - landscapeLockRotation: 強制橫向(直向設備時旋轉 90°)\n * @default 'auto'\n */\n @Input() orientation?: TOrientationMode = 'auto';\n\n /**\n * 向內層容器轉發的自訂樣式\n */\n @Input() forwardStyle?: Record<string, string>;\n\n /**\n * 設計稿寬度(單位:px)\n * 必填參數\n */\n @Input() designWidth!: number;\n\n /**\n * 設計稿高度(單位:px)\n * 必填參數\n */\n @Input() designHeight!: number;\n\n /**\n * 方向變化事件\n * @emits true: landscape(橫屏)\n * @emits false: portrait(直屏)\n */\n @Output() orientationChange = new EventEmitter<boolean>();\n\n // ============================================================\n // Private Dependencies\n // ============================================================\n\n private breakpointObserver = inject(BreakpointObserver);\n private boundaryContext = inject(BsBoundaryContextService);\n private elementRef = inject(ElementRef);\n private destroy$ = new Subject<void>();\n\n // ============================================================\n // Public Properties\n // ============================================================\n\n /**\n * 實際設備方向(基於視口尺寸)\n * true: 直向 (height > width)\n * false: 橫向 (width >= height)\n */\n actualIsPortrait = false;\n\n // ============================================================\n // Getters\n // ============================================================\n\n /**\n * 判斷當前是否為橫向模式\n * 根據 orientation 設定和實際設備方向判斷\n */\n get isLandscape(): boolean {\n // landscapeLockRotation: 強制橫屏模式\n if (this.orientation === 'landscapeLockRotation') {\n return true;\n }\n // portraitLockRotation: 強制直屏模式\n if (this.orientation === 'portraitLockRotation') {\n return false;\n }\n // fluid: 不區分橫直向,以寬度為基準\n if (this.orientation === 'fluid') {\n return false;\n }\n // landscape: 鎖定橫向\n if (this.orientation === 'landscape') {\n return true;\n }\n // portrait: 鎖定直向\n if (this.orientation === 'portrait') {\n return false;\n }\n // auto: 自動檢測\n return this.boundaryContext.getIsLandscape();\n }\n\n // ============================================================\n // Lifecycle Hooks\n // ============================================================\n\n ngOnInit(): void {\n this.updateActualOrientation();\n this.setupBreakpointObserver();\n this.setupResizeObserver();\n }\n\n ngAfterViewInit(): void {\n // 使用 @Input 參數,可以立即計算(無需等待 CSS)\n this.updateBoundaryCalculations();\n }\n\n ngOnDestroy(): void {\n this.destroy$.next();\n this.destroy$.complete();\n }\n\n // ============================================================\n // Observers Setup - 監聽器設定\n // ============================================================\n\n /**\n * 設定方向變化監控\n *\n * 工作原理:\n * - lock 模式(portrait/landscape):直接設定固定方向,不監聽變化\n * - lockRotation 模式:設定固定方向,但需監聽實際設備方向以觸發旋轉\n * - auto 模式:使用 BreakpointObserver 監聽設備方向變化\n */\n private setupBreakpointObserver() {\n // landscape 或 landscapeLockRotation: 鎖定為橫向\n if (this.orientation === 'landscape' || this.orientation === 'landscapeLockRotation') {\n this.boundaryContext.setIsLandscape(true);\n this.orientationChange.emit(true);\n return;\n }\n\n // portrait、portraitLockRotation 或 fluid: 鎖定為直向\n if (this.orientation === 'portrait' || this.orientation === 'portraitLockRotation' || this.orientation === 'fluid') {\n this.boundaryContext.setIsLandscape(false);\n this.orientationChange.emit(false);\n return;\n }\n\n // auto 模式:監聽實際的設備方向(用於 orientationChange 事件)\n this.breakpointObserver\n .observe('(orientation: landscape)')\n .pipe(takeUntil(this.destroy$))\n .subscribe(result => {\n this.boundaryContext.setIsLandscape(result.matches);\n this.orientationChange.emit(result.matches);\n // 方向變化時重新計算邊界\n this.updateBoundaryCalculations();\n });\n }\n\n /**\n * 設定視窗大小變化監控\n *\n * 功能:\n * - 監聽 window resize 事件\n * - 更新實際設備方向\n * - 重新計算邊界尺寸\n */\n private setupResizeObserver() {\n fromEvent(window, 'resize')\n .pipe(\n // debounceTime(150), // 可選:防抖優化性能\n takeUntil(this.destroy$)\n )\n .subscribe(() => {\n this.updateActualOrientation();\n this.updateBoundaryCalculations();\n });\n }\n\n // ============================================================\n // Calculation Methods - 計算方法\n // ============================================================\n\n /**\n * 更新實際設備方向(基於視口尺寸)\n *\n * 工作原理:\n * - 只在 lockRotation 模式下需要檢測實際方向\n * - 通過比較 window.innerHeight 和 window.innerWidth 判斷\n * - 結果用於觸發 CSS 旋轉變換\n */\n private updateActualOrientation() {\n // 只有在 lockRotation 模式下才需要檢測實際方向\n if (this.orientation !== 'landscapeLockRotation' && this.orientation !== 'portraitLockRotation') {\n this.actualIsPortrait = false;\n return;\n }\n\n // 檢測實際視口方向:高度 > 寬度 = 直向\n this.actualIsPortrait = window.innerHeight > window.innerWidth;\n }\n\n /**\n * 更新邊界計算(支援 Chrome 74,使用 JavaScript 模擬 min 函數)\n *\n * 工作原理:\n * 1. 從 @Input 參數讀取設計尺寸\n * 2. 讀取視口尺寸(vw100, vh100)\n * 3. 處理 lockRotation 模式的視口尺寸交換\n * 4. 計算邊界最大值和實際邊界尺寸\n * 5. 計算 px2vw 轉換比例\n * 6. 設定 CSS 變數供樣式使用\n *\n * 設定的 CSS 變數:\n * - --design-width: 設計稿寬度\n * - --design-height: 設計稿高度\n * - --boundary-width: 實際邊界寬度(px)\n * - --boundary-height: 實際邊界高度(px)\n * - --px2vw-ratio: px 轉 vw 的比例係數\n */\n private updateBoundaryCalculations() {\n const hostElement = this.elementRef.nativeElement as HTMLElement;\n\n // ========================================\n // Step 1: 讀取設計尺寸並設定 CSS 變數\n // ========================================\n const designWidth = this.designWidth;\n const designHeight = this.designHeight;\n\n // 設定 CSS 變數,供樣式使用(例如 px2vw() 函數)\n hostElement.style.setProperty('--design-width', `${designWidth}`);\n hostElement.style.setProperty('--design-height', `${designHeight}`);\n\n // ========================================\n // Step 2: 讀取視口尺寸(直接使用 window.inner* 確保一致性)\n // ========================================\n let vw100 = window.innerWidth;\n let vh100 = window.innerHeight;\n\n // ========================================\n // Step 2: 處理 lockRotation 模式的視口尺寸交換\n // ========================================\n // landscapeLockRotation + 實際直向:交換視口尺寸\n // 原因:旋轉後,內容的寬度對應設備的高度,內容的高度對應設備的寬度\n if (this.orientation === 'landscapeLockRotation' && this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // portraitLockRotation + 實際橫向:交換視口尺寸\n if (this.orientation === 'portraitLockRotation' && !this.actualIsPortrait) {\n [vw100, vh100] = [vh100, vw100];\n }\n\n // ========================================\n // Fluid 模式:不參考寬高比,直接使用螢幕尺寸\n // ========================================\n if (this.orientation === 'fluid') {\n const boundaryWidth = vw100;\n const boundaryHeight = vh100;\n const px2vwRatio = vw100 / designWidth;\n\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n return;\n }\n\n // ========================================\n // Step 3: 計算比例和邊界最大值\n // ========================================\n const landscapeRatio = designWidth / designHeight;\n const portraitRatio = designHeight / designWidth;\n\n // 根據方向模式計算邊界最大值\n const isLandscape = this.isLandscape;\n const boundaryMaxWidth = isLandscape\n ? vh100 * portraitRatio // 橫向:高度 * 高寬比\n : vh100 * landscapeRatio; // 直向:高度 * 寬高比\n const boundaryMaxHeight = isLandscape\n ? vw100 * landscapeRatio // 橫向:寬度 * 寬高比\n : vw100 * portraitRatio; // 直向:寬度 * 高寬比\n\n // ========================================\n // Step 4: 計算實際邊界尺寸(使用 Math.min 模擬 CSS min())\n // ========================================\n // Chrome 79 才支援 CSS min() 函數,所以在 JavaScript 中計算\n const boundaryWidth = Math.min(vw100, boundaryMaxWidth);\n const boundaryHeight = Math.min(vh100, boundaryMaxHeight);\n\n // ========================================\n // Step 5: 計算 px2vw 轉換比例\n // ========================================\n // 橫向模式使用 design-height 作為基準,直向模式使用 design-width 作為基準\n const designBaseWidth = isLandscape ? designHeight : designWidth;\n const px2vwRatio = boundaryWidth / designBaseWidth;\n\n // ========================================\n // Step 6: 設定 CSS 變數\n // ========================================\n hostElement.style.setProperty('--boundary-width', `${boundaryWidth}px`);\n hostElement.style.setProperty('--boundary-height', `${boundaryHeight}px`);\n hostElement.style.setProperty('--px2vw-ratio', `${px2vwRatio}`);\n }\n}\n","<div\n class=\"boundary-wrapper\"\n [class.fixed-center]=\"isFixedCenter\"\n [class.pointerEventsNone]=\"pointerEventsNone\"\n [style]=\"forwardStyle\"\n>\n <ng-content></ng-content>\n</div>\n","/*\n * Public API Surface of @bitstack/ng-boundary\n */\n\nexport * from './lib/bs-boundary';\nexport * from './lib/bs-boundary-context.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/lib/model.d.ts CHANGED
@@ -1 +1 @@
1
- export declare type TOrientationMode = 'auto' | 'portrait' | 'landscape' | 'landscapeLockRotation' | 'portraitLockRotation';
1
+ export declare type TOrientationMode = 'auto' | 'portrait' | 'landscape' | 'landscapeLockRotation' | 'portraitLockRotation' | 'fluid';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitstack/ng-boundary",
3
- "version": "14.0.6-alpha.5",
3
+ "version": "14.0.7-alpha.0",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=14 <16",
6
6
  "@angular/core": ">=14 <16",
@@ -25,7 +25,7 @@
25
25
  // --design-height: 667;
26
26
  // }
27
27
  @function px2vw($px) {
28
- @return calc(#{$px}px * var(--px2vw-ratio));
28
+ @return calc(#{$px}px * var(--px2vw-ratio, 1));
29
29
  }
30
30
 
31
31