import { NgbCalendarHijri } from './ngb-calendar-hijri'; import { NgbDate } from '../ngb-date'; import { Injectable } from '@angular/core'; import * as i0 from "@angular/core"; /** * Checks if islamic year is a leap year */ function isIslamicLeapYear(hYear) { return (14 + 11 * hYear) % 30 < 11; } /** * Checks if gregorian years is a leap year */ function isGregorianLeapYear(gDate) { const year = gDate.getFullYear(); return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0; } /** * Returns the start of Hijri Month. * `hMonth` is 0 for Muharram, 1 for Safar, etc. * `hYear` is any Hijri hYear. */ function getIslamicMonthStart(hYear, hMonth) { return Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30.0); } /** * Returns the start of Hijri year. * `year` is any Hijri year. */ function getIslamicYearStart(year) { return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0); } function mod(a, b) { return a - b * Math.floor(a / b); } /** * The civil calendar is one type of Hijri calendars used in islamic countries. * Uses a fixed cycle of alternating 29- and 30-day months, * with a leap day added to the last month of 11 out of every 30 years. * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types * All the calculations here are based on the equations from "Calendrical Calculations" By Edward M. Reingold, Nachum * Dershowitz. */ const GREGORIAN_EPOCH = 1721425.5; const ISLAMIC_EPOCH = 1948439.5; export class NgbCalendarIslamicCivil extends NgbCalendarHijri { /** * Returns the equivalent islamic(civil) date value for a give input Gregorian date. * `gDate` is a JS Date to be converted to Hijri. */ fromGregorian(gDate) { const gYear = gDate.getFullYear(), gMonth = gDate.getMonth(), gDay = gDate.getDate(); let julianDay = GREGORIAN_EPOCH - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) + -Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) + Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear(gDate) ? -1 : -2) + gDay); julianDay = Math.floor(julianDay) + 0.5; const days = julianDay - ISLAMIC_EPOCH; const hYear = Math.floor((30 * days + 10646) / 10631.0); let hMonth = Math.ceil((days - 29 - getIslamicYearStart(hYear)) / 29.5); hMonth = Math.min(hMonth, 11); const hDay = Math.ceil(days - getIslamicMonthStart(hYear, hMonth)) + 1; return new NgbDate(hYear, hMonth + 1, hDay); } /** * Returns the equivalent JS date value for a give input islamic(civil) date. * `hDate` is an islamic(civil) date to be converted to Gregorian. */ toGregorian(hDate) { const hYear = hDate.year; const hMonth = hDate.month - 1; const hDay = hDate.day; const julianDay = hDay + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30) + ISLAMIC_EPOCH - 1; const wjd = Math.floor(julianDay - 0.5) + 0.5, depoch = wjd - GREGORIAN_EPOCH, quadricent = Math.floor(depoch / 146097), dqc = mod(depoch, 146097), cent = Math.floor(dqc / 36524), dcent = mod(dqc, 36524), quad = Math.floor(dcent / 1461), dquad = mod(dcent, 1461), yindex = Math.floor(dquad / 365); let year = quadricent * 400 + cent * 100 + quad * 4 + yindex; if (!(cent === 4 || yindex === 4)) { year++; } const gYearStart = GREGORIAN_EPOCH + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400); const yearday = wjd - gYearStart; const tjd = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor(739 / 12 + (isGregorianLeapYear(new Date(year, 3, 1)) ? -1 : -2) + 1); const leapadj = wjd < tjd ? 0 : isGregorianLeapYear(new Date(year, 3, 1)) ? 1 : 2; const month = Math.floor(((yearday + leapadj) * 12 + 373) / 367); const tjd2 = GREGORIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor((367 * month - 362) / 12 + (month <= 2 ? 0 : isGregorianLeapYear(new Date(year, month - 1, 1)) ? -1 : -2) + 1); const day = wjd - tjd2 + 1; return new Date(year, month - 1, day); } /** * Returns the number of days in a specific Hijri month. * `month` is 1 for Muharram, 2 for Safar, etc. * `year` is any Hijri year. */ getDaysPerMonth(month, year) { year = year + Math.floor(month / 13); month = ((month - 1) % 12) + 1; let length = 29 + (month % 2); if (month === 12 && isIslamicLeapYear(year)) { length++; } return length; } } NgbCalendarIslamicCivil.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbCalendarIslamicCivil, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); NgbCalendarIslamicCivil.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbCalendarIslamicCivil }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.6", ngImport: i0, type: NgbCalendarIslamicCivil, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmdiLWNhbGVuZGFyLWlzbGFtaWMtY2l2aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGF0ZXBpY2tlci9oaWpyaS9uZ2ItY2FsZW5kYXItaXNsYW1pYy1jaXZpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUN4RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7O0FBRTNDOztHQUVHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxLQUFhO0lBQ3ZDLE9BQU8sQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEtBQUssQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7QUFDcEMsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxLQUFXO0lBQ3ZDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNqQyxPQUFPLENBQUMsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxHQUFHLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxJQUFJLEdBQUcsR0FBRyxLQUFLLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsb0JBQW9CLENBQUMsS0FBYSxFQUFFLE1BQWM7SUFDMUQsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUM7QUFDM0YsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsbUJBQW1CLENBQUMsSUFBWTtJQUN4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QUFDO1FBQ3JDLEtBQUssR0FBRyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMvQixJQUFJLE1BQU0sR0FBRyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDOUIsSUFBSSxLQUFLLEtBQUssRUFBRSxJQUFJLGlCQUFpQixDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzVDLE1BQU0sRUFBRSxDQUFDO1NBQ1Q7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNmLENBQUM7O29IQXZHVyx1QkFBdUI7d0hBQXZCLHVCQUF1QjsyRkFBdkIsdUJBQXVCO2tCQURuQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTmdiQ2FsZW5kYXJIaWpyaSB9IGZyb20gJy4vbmdiLWNhbGVuZGFyLWhpanJpJztcbmltcG9ydCB7IE5nYkRhdGUgfSBmcm9tICcuLi9uZ2ItZGF0ZSc7XG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGlzbGFtaWMgeWVhciBpcyBhIGxlYXAgeWVhclxuICovXG5mdW5jdGlvbiBpc0lzbGFtaWNMZWFwWWVhcihoWWVhcjogbnVtYmVyKTogYm9vbGVhbiB7XG5cdHJldHVybiAoMTQgKyAxMSAqIGhZZWFyKSAlIDMwIDwgMTE7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGdyZWdvcmlhbiB5ZWFycyBpcyBhIGxlYXAgeWVhclxuICovXG5mdW5jdGlvbiBpc0dyZWdvcmlhbkxlYXBZZWFyKGdEYXRlOiBEYXRlKTogYm9vbGVhbiB7XG5cdGNvbnN0IHllYXIgPSBnRGF0ZS5nZXRGdWxsWWVhcigpO1xuXHRyZXR1cm4gKHllYXIgJSA0ID09PSAwICYmIHllYXIgJSAxMDAgIT09IDApIHx8IHllYXIgJSA0MDAgPT09IDA7XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhcnQgb2YgSGlqcmkgTW9udGguXG4gKiBgaE1vbnRoYCBpcyAwIGZvciBNdWhhcnJhbSwgMSBmb3IgU2FmYXIsIGV0Yy5cbiAqIGBoWWVhcmAgaXMgYW55IEhpanJpIGhZZWFyLlxuICovXG5mdW5jdGlvbiBnZXRJc2xhbWljTW9udGhTdGFydChoWWVhcjogbnVtYmVyLCBoTW9udGg6IG51bWJlcik6IG51bWJlciB7XG5cdHJldHVybiBNYXRoLmNlaWwoMjkuNSAqIGhNb250aCkgKyAoaFllYXIgLSAxKSAqIDM1NCArIE1hdGguZmxvb3IoKDMgKyAxMSAqIGhZZWFyKSAvIDMwLjApO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIHN0YXJ0IG9mIEhpanJpIHllYXIuXG4gKiBgeWVhcmAgaXMgYW55IEhpanJpIHllYXIuXG4gKi9cbmZ1bmN0aW9uIGdldElzbGFtaWNZZWFyU3RhcnQoeWVhcjogbnVtYmVyKTogbnVtYmVyIHtcblx0cmV0dXJuICh5ZWFyIC0gMSkgKiAzNTQgKyBNYXRoLmZsb29yKCgzICsgMTEgKiB5ZWFyKSAvIDMwLjApO1xufVxuXG5mdW5jdGlvbiBtb2QoYTogbnVtYmVyLCBiOiBudW1iZXIpOiBudW1iZXIge1xuXHRyZXR1cm4gYSAtIGIgKiBNYXRoLmZsb29yKGEgLyBiKTtcbn1cblxuLyoqXG4gKiBUaGUgY2l2aWwgY2FsZW5kYXIgaXMgb25lIHR5cGUgb2YgSGlqcmkgY2FsZW5kYXJzIHVzZWQgaW4gaXNsYW1pYyBjb3VudHJpZXMuXG4gKiBVc2VzIGEgZml4ZWQgY3ljbGUgb2YgYWx0ZXJuYXRpbmcgMjktIGFuZCAzMC1kYXkgbW9udGhzLFxuICogd2l0aCBhIGxlYXAgZGF5IGFkZGVkIHRvIHRoZSBsYXN0IG1vbnRoIG9mIDExIG91dCBvZiBldmVyeSAzMCB5ZWFycy5cbiAqIGh0dHA6Ly9jbGRyLnVuaWNvZGUub3JnL2RldmVsb3BtZW50L2RldmVsb3BtZW50LXByb2Nlc3MvZGVzaWduLXByb3Bvc2Fscy9pc2xhbWljLWNhbGVuZGFyLXR5cGVzXG4gKiBBbGwgdGhlIGNhbGN1bGF0aW9ucyBoZXJlIGFyZSBiYXNlZCBvbiB0aGUgZXF1YXRpb25zIGZyb20gXCJDYWxlbmRyaWNhbCBDYWxjdWxhdGlvbnNcIiBCeSBFZHdhcmQgTS4gUmVpbmdvbGQsIE5hY2h1bVxuICogRGVyc2hvd2l0ei5cbiAqL1xuXG5jb25zdCBHUkVHT1JJQU5fRVBPQ0ggPSAxNzIxNDI1LjU7XG5jb25zdCBJU0xBTUlDX0VQT0NIID0gMTk0ODQzOS41O1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgTmdiQ2FsZW5kYXJJc2xhbWljQ2l2aWwgZXh0ZW5kcyBOZ2JDYWxlbmRhckhpanJpIHtcblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGVxdWl2YWxlbnQgaXNsYW1pYyhjaXZpbCkgZGF0ZSB2YWx1ZSBmb3IgYSBnaXZlIGlucHV0IEdyZWdvcmlhbiBkYXRlLlxuXHQgKiBgZ0RhdGVgIGlzIGEgSlMgRGF0ZSB0byBiZSBjb252ZXJ0ZWQgdG8gSGlqcmkuXG5cdCAqL1xuXHRmcm9tR3JlZ29yaWFuKGdEYXRlOiBEYXRlKTogTmdiRGF0ZSB7XG5cdFx0Y29uc3QgZ1llYXIgPSBnRGF0ZS5nZXRGdWxsWWVhcigpLFxuXHRcdFx0Z01vbnRoID0gZ0RhdGUuZ2V0TW9udGgoKSxcblx0XHRcdGdEYXkgPSBnRGF0ZS5nZXREYXRlKCk7XG5cblx0XHRsZXQganVsaWFuRGF5ID1cblx0XHRcdEdSRUdPUklBTl9FUE9DSCAtXG5cdFx0XHQxICtcblx0XHRcdDM2NSAqIChnWWVhciAtIDEpICtcblx0XHRcdE1hdGguZmxvb3IoKGdZZWFyIC0gMSkgLyA0KSArXG5cdFx0XHQtTWF0aC5mbG9vcigoZ1llYXIgLSAxKSAvIDEwMCkgK1xuXHRcdFx0TWF0aC5mbG9vcigoZ1llYXIgLSAxKSAvIDQwMCkgK1xuXHRcdFx0TWF0aC5mbG9vcigoMzY3ICogKGdNb250aCArIDEpIC0gMzYyKSAvIDEyICsgKGdNb250aCArIDEgPD0gMiA/IDAgOiBpc0dyZWdvcmlhbkxlYXBZZWFyKGdEYXRlKSA/IC0xIDogLTIpICsgZ0RheSk7XG5cdFx0anVsaWFuRGF5ID0gTWF0aC5mbG9vcihqdWxpYW5EYXkpICsgMC41O1xuXG5cdFx0Y29uc3QgZGF5cyA9IGp1bGlhbkRheSAtIElTTEFNSUNfRVBPQ0g7XG5cdFx0Y29uc3QgaFllYXIgPSBNYXRoLmZsb29yKCgzMCAqIGRheXMgKyAxMDY0NikgLyAxMDYzMS4wKTtcblx0XHRsZXQgaE1vbnRoID0gTWF0aC5jZWlsKChkYXlzIC0gMjkgLSBnZXRJc2xhbWljWWVhclN0YXJ0KGhZZWFyKSkgLyAyOS41KTtcblx0XHRoTW9udGggPSBNYXRoLm1pbihoTW9udGgsIDExKTtcblx0XHRjb25zdCBoRGF5ID0gTWF0aC5jZWlsKGRheXMgLSBnZXRJc2xhbWljTW9udGhTdGFydChoWWVhciwgaE1vbnRoKSkgKyAxO1xuXHRcdHJldHVybiBuZXcgTmdiRGF0ZShoWWVhciwgaE1vbnRoICsgMSwgaERheSk7XG5cdH1cblxuXHQvKipcblx0ICogUmV0dXJucyB0aGUgZXF1aXZhbGVudCBKUyBkYXRlIHZhbHVlIGZvciBhIGdpdmUgaW5wdXQgaXNsYW1pYyhjaXZpbCkgZGF0ZS5cblx0ICogYGhEYXRlYCBpcyBhbiBpc2xhbWljKGNpdmlsKSBkYXRlIHRvIGJlIGNvbnZlcnRlZCB0byBHcmVnb3JpYW4uXG5cdCAqL1xuXHR0b0dyZWdvcmlhbihoRGF0ZTogTmdiRGF0ZSk6IERhdGUge1xuXHRcdGNvbnN0IGhZZWFyID0gaERhdGUueWVhcjtcblx0XHRjb25zdCBoTW9udGggPSBoRGF0ZS5tb250aCAtIDE7XG5cdFx0Y29uc3QgaERheSA9IGhEYXRlLmRheTtcblx0XHRjb25zdCBqdWxpYW5EYXkgPVxuXHRcdFx0aERheSArIE1hdGguY2VpbCgyOS41ICogaE1vbnRoKSArIChoWWVhciAtIDEpICogMzU0ICsgTWF0aC5mbG9vcigoMyArIDExICogaFllYXIpIC8gMzApICsgSVNMQU1JQ19FUE9DSCAtIDE7XG5cblx0XHRjb25zdCB3amQgPSBNYXRoLmZsb29yKGp1bGlhbkRheSAtIDAuNSkgKyAwLjUsXG5cdFx0XHRkZXBvY2ggPSB3amQgLSBHUkVHT1JJQU5fRVBPQ0gsXG5cdFx0XHRxdWFkcmljZW50ID0gTWF0aC5mbG9vcihkZXBvY2ggLyAxNDYwOTcpLFxuXHRcdFx0ZHFjID0gbW9kKGRlcG9jaCwgMTQ2MDk3KSxcblx0XHRcdGNlbnQgPSBNYXRoLmZsb29yKGRxYyAvIDM2NTI0KSxcblx0XHRcdGRjZW50ID0gbW9kKGRxYywgMzY1MjQpLFxuXHRcdFx0cXVhZCA9IE1hdGguZmxvb3IoZGNlbnQgLyAxNDYxKSxcblx0XHRcdGRxdWFkID0gbW9kKGRjZW50LCAxNDYxKSxcblx0XHRcdHlpbmRleCA9IE1hdGguZmxvb3IoZHF1YWQgLyAzNjUpO1xuXHRcdGxldCB5ZWFyID0gcXVhZHJpY2VudCAqIDQwMCArIGNlbnQgKiAxMDAgKyBxdWFkICogNCArIHlpbmRleDtcblx0XHRpZiAoIShjZW50ID09PSA0IHx8IHlpbmRleCA9PT0gNCkpIHtcblx0XHRcdHllYXIrKztcblx0XHR9XG5cblx0XHRjb25zdCBnWWVhclN0YXJ0ID1cblx0XHRcdEdSRUdPUklBTl9FUE9DSCArXG5cdFx0XHQzNjUgKiAoeWVhciAtIDEpICtcblx0XHRcdE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDQpIC1cblx0XHRcdE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDEwMCkgK1xuXHRcdFx0TWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNDAwKTtcblxuXHRcdGNvbnN0IHllYXJkYXkgPSB3amQgLSBnWWVhclN0YXJ0O1xuXG5cdFx0Y29uc3QgdGpkID1cblx0XHRcdEdSRUdPUklBTl9FUE9DSCAtXG5cdFx0XHQxICtcblx0XHRcdDM2NSAqICh5ZWFyIC0gMSkgK1xuXHRcdFx0TWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNCkgLVxuXHRcdFx0TWF0aC5mbG9vcigoeWVhciAtIDEpIC8gMTAwKSArXG5cdFx0XHRNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyA0MDApICtcblx0XHRcdE1hdGguZmxvb3IoNzM5IC8gMTIgKyAoaXNHcmVnb3JpYW5MZWFwWWVhcihuZXcgRGF0ZSh5ZWFyLCAzLCAxKSkgPyAtMSA6IC0yKSArIDEpO1xuXG5cdFx0Y29uc3QgbGVhcGFkaiA9IHdqZCA8IHRqZCA/IDAgOiBpc0dyZWdvcmlhbkxlYXBZZWFyKG5ldyBEYXRlKHllYXIsIDMsIDEpKSA/IDEgOiAyO1xuXG5cdFx0Y29uc3QgbW9udGggPSBNYXRoLmZsb29yKCgoeWVhcmRheSArIGxlYXBhZGopICogMTIgKyAzNzMpIC8gMzY3KTtcblx0XHRjb25zdCB0amQyID1cblx0XHRcdEdSRUdPUklBTl9FUE9DSCAtXG5cdFx0XHQxICtcblx0XHRcdDM2NSAqICh5ZWFyIC0gMSkgK1xuXHRcdFx0TWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNCkgLVxuXHRcdFx0TWF0aC5mbG9vcigoeWVhciAtIDEpIC8gMTAwKSArXG5cdFx0XHRNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyA0MDApICtcblx0XHRcdE1hdGguZmxvb3IoXG5cdFx0XHRcdCgzNjcgKiBtb250aCAtIDM2MikgLyAxMiArIChtb250aCA8PSAyID8gMCA6IGlzR3JlZ29yaWFuTGVhcFllYXIobmV3IERhdGUoeWVhciwgbW9udGggLSAxLCAxKSkgPyAtMSA6IC0yKSArIDEsXG5cdFx0XHQpO1xuXG5cdFx0Y29uc3QgZGF5ID0gd2pkIC0gdGpkMiArIDE7XG5cblx0XHRyZXR1cm4gbmV3IERhdGUoeWVhciwgbW9udGggLSAxLCBkYXkpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIG51bWJlciBvZiBkYXlzIGluIGEgc3BlY2lmaWMgSGlqcmkgbW9udGguXG5cdCAqIGBtb250aGAgaXMgMSBmb3IgTXVoYXJyYW0sIDIgZm9yIFNhZmFyLCBldGMuXG5cdCAqIGB5ZWFyYCBpcyBhbnkgSGlqcmkgeWVhci5cblx0ICovXG5cdGdldERheXNQZXJNb250aChtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXIpOiBudW1iZXIge1xuXHRcdHllYXIgPSB5ZWFyICsgTWF0aC5mbG9vcihtb250aCAvIDEzKTtcblx0XHRtb250aCA9ICgobW9udGggLSAxKSAlIDEyKSArIDE7XG5cdFx0bGV0IGxlbmd0aCA9IDI5ICsgKG1vbnRoICUgMik7XG5cdFx0aWYgKG1vbnRoID09PSAxMiAmJiBpc0lzbGFtaWNMZWFwWWVhcih5ZWFyKSkge1xuXHRcdFx0bGVuZ3RoKys7XG5cdFx0fVxuXHRcdHJldHVybiBsZW5ndGg7XG5cdH1cbn1cbiJdfQ==