├── .babelrc ├── .yarnrc.yml ├── .gitignore ├── .editorconfig ├── webpack.dev.js ├── webpack.pro.js ├── .eslintrc ├── webpack.common.js ├── src ├── constants.js ├── helpers.js ├── converter.js └── jdate.js ├── .github └── workflows │ ├── node.js.yml │ └── codeql-analysis.yml ├── LICENSE ├── tests ├── converter.test.js └── jdate.test.js ├── package.json ├── README.md └── lib ├── jdate.min.js └── jdate.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"], 3 | "plugins": ["add-module-exports"] 4 | } 5 | -------------------------------------------------------------------------------- /.yarnrc.yml: -------------------------------------------------------------------------------- 1 | compressionLevel: mixed 2 | 3 | enableGlobalCache: false 4 | 5 | nodeLinker: node-modules 6 | 7 | yarnPath: .yarn/releases/yarn-4.7.0.cjs 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | components 3 | node_modules 4 | .eslintcache 5 | .yarn/* 6 | !.yarn/patches 7 | !.yarn/plugins 8 | !.yarn/releases 9 | !.yarn/sdks 10 | !.yarn/versions 11 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | mode: 'development', 6 | devtool: 'inline-source-map' 7 | }); 8 | -------------------------------------------------------------------------------- /webpack.pro.js: -------------------------------------------------------------------------------- 1 | const { merge } = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | 4 | module.exports = merge(common, { 5 | output: { 6 | filename: '[name].min.js' 7 | }, 8 | mode: 'production' 9 | }); 10 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | "parser": "babel-eslint", 4 | "plugins": [ 5 | "babel", 6 | "jest" 7 | ], 8 | "env": { 9 | "node": true, 10 | "es6": true, 11 | "jest": true 12 | }, 13 | "rules": { 14 | "comma-dangle": ["error", "never"], 15 | "no-underscore-dangle": 0, 16 | "import/no-extraneous-dependencies": ["error", {"devDependencies": true}] 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | jdate: path.join(__dirname, '/src/jdate.js') 6 | }, 7 | devtool: 'inline-source-map', 8 | output: { 9 | path: path.join(__dirname, '/lib'), 10 | filename: '[name].js', 11 | library: 'JDate', 12 | libraryTarget: 'umd', 13 | libraryExport: 'default', 14 | umdNamedDefine: true, 15 | globalObject: 'this' 16 | }, 17 | module: { 18 | rules: [ 19 | { 20 | test: /\.js$/, 21 | exclude: /node_modules/, 22 | use: { 23 | loader: 'babel-loader', 24 | options: { 25 | presets: ['@babel/preset-env'] 26 | } 27 | } 28 | } 29 | ] 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | MONTH_NAMES: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'امرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'], 3 | ABBR_DAYS: ['۱ش', '۲ش', '۳ش', '۴ش', '۵ش', 'ج', 'ش'], 4 | DAYS_NAMES: ['یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه', 'شنبه'], 5 | GREGORIAN_EPOCH: 1, 6 | GREGORIAN_TO_FIXED_OFFSET: 719528, 7 | PERSIAN_EPOCH: 226896, 8 | PERSIAN_CYCLE_DAYS: 12053, 9 | NON_LEAP_CORRECTION: [ 10 | 1502, 11 | 1601, 1634, 1667, 12 | 1700, 1733, 1766, 1799, 13 | 1832, 1865, 1898, 14 | 1931, 1964, 1997, 15 | 2030, 2059, 2063, 2096, 16 | 2129, 2158, 2162, 2191, 2195, 17 | 2224, 2228, 2257, 2261, 2290, 2294, 18 | 2323, 2327, 2356, 2360, 2389, 2393, 19 | 2422, 2426, 2455, 2459, 2488, 2492, 20 | 2521, 2525, 2554, 2558, 2587, 2591, 21 | 2620, 2624, 2653, 2657, 2686, 2690, 22 | 2719, 2723, 2748, 2752, 2756, 2781, 2785, 2789, 23 | 2818, 2822, 2847, 2851, 2855, 2880, 2884, 2888, 24 | 2913, 2917, 2921, 2946, 2950, 2954, 2979, 2983, 2987 25 | ] 26 | }; 27 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Tests & Build 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | strategy: 16 | matrix: 17 | node-version: [18.x, 20.x, 21.x, 22.x, 23.x] 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v4 21 | - name: Enable Corepack 22 | run: corepack enable 23 | - name: Setup Node ${{ matrix.node-version }} 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: "yarn" 28 | - name: Install Yarn dependencies 29 | run: | 30 | yarn set version 4.7.0 31 | yarn install --immutable 32 | - run: yarn build 33 | - run: yarn test 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Arash Mousavi 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /tests/converter.test.js: -------------------------------------------------------------------------------- 1 | import converter from '../src/converter'; 2 | 3 | describe('Converter', () => { 4 | test('jalaliToFixed', () => { 5 | expect(converter.jalaliToFixed(1399, 1, 1)).toBe(737504); 6 | expect(converter.jalaliToFixed(1400, 1, 1)).toBe(737870); 7 | }); 8 | 9 | test('gregorianToFixed', () => { 10 | expect(converter.gregorianToFixed(2021, 3, 21)).toBe(737870); 11 | expect(converter.gregorianToFixed(2022, 3, 21)).toBe(738235); 12 | }); 13 | 14 | test('fixedToGregorian', () => { 15 | expect(converter.fixedToGregorian(737870)).toEqual([2021, 3, 21]); 16 | expect(converter.fixedToGregorian(738235)).toEqual([2022, 3, 21]); 17 | }); 18 | 19 | test('fixedToJalali', () => { 20 | expect(converter.fixedToJalali(737504)).toEqual([1399, 1, 1]); 21 | expect(converter.fixedToJalali(737870)).toEqual([1400, 1, 1]); 22 | }); 23 | 24 | test('leapPersian', () => { 25 | expect(converter.leapPersian(1400)).toBe(false); 26 | expect(converter.leapPersian(1403)).toBe(true); 27 | }); 28 | 29 | test('leapGregorian', () => { 30 | expect(converter.leapGregorian(2016)).toBe(true); 31 | expect(converter.leapGregorian(2017)).toBe(false); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jalali-date", 3 | "version": "1.2.0", 4 | "description": "A Jalali to Gregorian converter with support of formatting output", 5 | "scripts": { 6 | "start": "webpack --progress --colors --watch --env dev", 7 | "lint": "eslint ./src --ext .js --cache", 8 | "test": "jest", 9 | "watch": "webpack --watch --config webpack.dev.js", 10 | "build": "webpack --config webpack.pro.js && webpack --config webpack.dev.js" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git@github.com:arashm/JDate.git" 15 | }, 16 | "main": "lib/jdate.js", 17 | "keywords": [ 18 | "jalali", 19 | "sun", 20 | "shamsi", 21 | "calendar", 22 | "gregorian", 23 | "converter" 24 | ], 25 | "author": "Arash Mousavi", 26 | "license": "MIT", 27 | "bugs": { 28 | "url": "https://github.com/arashm/JDate/issues" 29 | }, 30 | "homepage": "https://github.com/arashm/JDate", 31 | "devDependencies": { 32 | "@babel/core": "^7.5.5", 33 | "@babel/preset-env": "^7.5.5", 34 | "babel-eslint": "^10.0.2", 35 | "babel-jest": "^27.2.0", 36 | "babel-loader": "^8.0.6", 37 | "babel-plugin-add-module-exports": "^1.0.2", 38 | "eslint": "^7.5.0", 39 | "eslint-config-airbnb-base": "^14.0.0", 40 | "eslint-plugin-babel": "^5.3.0", 41 | "eslint-plugin-import": "^2.3.0", 42 | "eslint-plugin-jest": "^24.0", 43 | "jest": "^27.2.0", 44 | "jest-cli": "^27.2.0", 45 | "jest-date-mock": "^1.0.7", 46 | "webpack": "^5.53.0", 47 | "webpack-cli": "^4.8.0", 48 | "webpack-merge": "^5.0.0" 49 | }, 50 | "jest": { 51 | "setupFiles": [ 52 | "jest-date-mock" 53 | ] 54 | }, 55 | "packageManager": "yarn@4.7.0" 56 | } 57 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '26 13 * * 5' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'javascript' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /src/helpers.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | 3 | import { 4 | MONTH_NAMES, 5 | ABBR_DAYS, 6 | DAYS_NAMES 7 | } from './constants'; 8 | 9 | export function divCeil(a, b) { 10 | return Math.floor((a + b - 1) / b); 11 | } 12 | 13 | export function fixMonth(year, month) { 14 | if (month > 12 || month <= 0) { 15 | const yearDiff = Math.floor((month - 1) / 12); 16 | const newYear = year - yearDiff; 17 | const newMonth = month - (yearDiff * 12); 18 | 19 | return [newYear, newMonth]; 20 | } 21 | 22 | return [year, month]; 23 | } 24 | 25 | export function zeroLeading(str) { 26 | if (str && str.length === 1) { return `0${str}`; } 27 | return str; 28 | } 29 | 30 | export function replaceYear(str, date) { 31 | const match = str.match(/[yY]+/); 32 | if (!match) { return str; } 33 | switch (match[0]) { 34 | case 'YYYY': 35 | case 'YYY': { 36 | const value = replaceYear(str.replace(match, date.getFullYear()), date); 37 | return value; 38 | } 39 | case 'YY': { 40 | const value = replaceYear( 41 | str.replace(match, String(date.getFullYear()).slice(2)), date 42 | ); 43 | return value; 44 | } 45 | default: { 46 | return str; 47 | } 48 | } 49 | } 50 | 51 | export function replaceMonth(str, date) { 52 | const match = str.match(/[mM]+/); 53 | if (!match) { return str; } 54 | switch (match[0]) { 55 | case 'M': { 56 | const value = replaceMonth(str.replace(match, date.getMonth()), date); 57 | return value; 58 | } 59 | case 'MM': { 60 | const zeroLeadingMonth = zeroLeading(date.getMonth().toString()); 61 | const value = replaceMonth(str.replace(match, zeroLeadingMonth), date); 62 | return value; 63 | } 64 | case 'MMM': 65 | case 'MMMM': { 66 | const value = replaceMonth( 67 | str.replace(match, MONTH_NAMES[date.getMonth() - 1]), date 68 | ); 69 | return value; 70 | } 71 | default: { 72 | return str; 73 | } 74 | } 75 | } 76 | 77 | export function replaceDay(str, date) { 78 | const match = str.match(/[dD]+/); 79 | if (!match) { return str; } 80 | switch (match[0]) { 81 | case 'D': { 82 | const value = replaceDay(str.replace(match, date.getDate()), date); 83 | return value; 84 | } 85 | case 'DD': { 86 | const zeroLeadingDate = zeroLeading(date.getDate().toString()); 87 | const value = replaceDay(str.replace(match, zeroLeadingDate), date); 88 | return value; 89 | } 90 | case 'd': 91 | case 'dd': { 92 | const value = replaceDay(str.replace(match, ABBR_DAYS[date.getDay()]), date); 93 | return value; 94 | } 95 | case 'ddd': 96 | case 'dddd': { 97 | const value = replaceDay(str.replace(match, DAYS_NAMES[date.getDay()]), date); 98 | return value; 99 | } 100 | default: { 101 | return str; 102 | } 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JDate 2 | ===== 3 | 4 | ![Build Status](https://github.com/arashm/JDate/actions/workflows/node.js.yml/badge.svg?branch=master) 5 | [![NPM Version](https://img.shields.io/npm/v/jalali-date)](https://www.npmjs.com/package/jalali-date) 6 | [![NPM License](https://img.shields.io/npm/l/all-contributors.svg?style=flat)](https://github.com/arashm/JDate/blob/master/LICENSE) 7 | 8 | A Jalali to Gregorian converter in JavaScript with support of formatting output 9 | 10 | ## Installation 11 | 12 | Install via NPM/Yarn: 13 | 14 | ``` 15 | npm install jalali-date 16 | ``` 17 | 18 | You could grab the latest version from `lib` directory and use it: 19 | 20 | ```html 21 | 22 | 23 | 24 | 25 | ``` 26 | 27 | The full-version is useful for debugging. You may want to use minified version in production as it is smaller. 28 | 29 | ### Initialization 30 | 31 | For initializing `JDate` you may either pass an array of Jalali date to it or a `Date` object. If no parameter is passed, the default is today: 32 | 33 | ```javascript 34 | const JDate = require('jalali-date'); 35 | const jdate = new JDate; // => default to today 36 | const jdate2 = new JDate(1393, 10, 11); 37 | const jdate3 = new JDate([1393, 10, 11]); 38 | const jdate4 = new JDate(new Date(2014, 1, 3)); 39 | 40 | ``` 41 | 42 | ### API 43 | ```javascript 44 | jdate.date //=> [1393, 5, 13] An Array of Jalali Date 45 | jdate._d // => Gregorian Date Object 46 | 47 | // Getters 48 | jdate.getFullYear() // => 1393 49 | jdate.getMonth() // => 5 50 | jdate.getDate() // => 13 51 | jdate.getDay() // => 1 52 | 53 | // Setters 54 | jdate.setFullYear(1394) 55 | jdate.setMonth(6) 56 | jdate.setDate(12) 57 | 58 | // Formatting output 59 | jdate.format('dddd DD MMMM YYYY') // => پنج‌شنبه 12 شهریور 1394 60 | 61 | // Static functions 62 | JDate.isLeapYear(1393) // => false 63 | JDate.daysInMonth(1393, 5) // => 31 64 | JDate.toGregorian(1393, 12, 11) // => Gregorian Date object 65 | JDate.toJalali(new Date) // => JDate object 66 | ``` 67 | 68 | ## Formatting output 69 | Use `format()` and following conversion identifiers as follows: 70 | 71 | ```javascript 72 | date.format('dddd DD MMMM YYYY') //=> دوشنبه 6 امرداد 1393 73 | ``` 74 | 75 | The conversion identifiers are as follows: 76 | 77 | | Identifier | Description | Example | 78 | | ------------- | ------------- | ---------- | 79 | | `YYY` or `YYYY` | Full Year (4 digits) | 1393 | 80 | | `YY` | Year (2 digits) | 93 | 81 | | `M` | Month in number | returns `5` for `امرداد` | 82 | | `MM` | Month in number | returns `05` for `امرداد` | 83 | | `MMM` or `MMMM` | Month in string | `امرداد` | 84 | | `D` | Day in number | 26 | 85 | | `DD` | Day in number | 06 | 86 | | `d` or `dd` | Abbreviation of day name in string | `۱ش` (for یکشنبه) | 87 | | `ddd` or `dddd` | Full day name in string | `یکشنبه` | 88 | 89 | 90 | ## Contribute 91 | 92 | Report bugs and suggest feature in [issue tracker](https://github.com/arashm/Jalali-Calendar/issues). Feel free to `Fork` and send `Pull Requests`. 93 | 94 | ## License 95 | 96 | [MIT](https://github.com/arashm/JDate/blob/master/LICENSE) 97 | -------------------------------------------------------------------------------- /src/converter.js: -------------------------------------------------------------------------------- 1 | import { divCeil } from './helpers'; 2 | import { 3 | GREGORIAN_EPOCH, PERSIAN_EPOCH, NON_LEAP_CORRECTION, PERSIAN_CYCLE_DAYS 4 | } from './constants'; 5 | 6 | export default class Converter { 7 | static gregorianToFixed(year, month, day) { 8 | const result = GREGORIAN_EPOCH - 1 9 | + 365 * (year - 1) 10 | + Math.floor((year - 1) / 4) 11 | - Math.floor((year - 1) / 100) 12 | + Math.floor((year - 1) / 400) 13 | + Math.floor((367 * month - 362) / 12) 14 | // eslint-disable-next-line no-nested-ternary 15 | + (month <= 2 ? 0 : Converter.leapGregorian(year) ? -1 : -2) 16 | + day; 17 | return result; 18 | } 19 | 20 | static gregorianYearFromFixed(date) { 21 | const d0 = date - GREGORIAN_EPOCH; 22 | const n400 = Math.floor(d0 / 146097); 23 | const d1 = d0 % 146097; 24 | const n100 = Math.floor(d1 / 36524); 25 | const d2 = d1 % 36524; 26 | const n4 = Math.floor(d2 / 1461); 27 | const d3 = d2 % 1461; 28 | const n1 = Math.floor(d3 / 365); 29 | const year = 400 * n400 + 100 * n100 + 4 * n4 + n1; 30 | if (n100 === 4 || n1 === 4) { 31 | return year; 32 | } 33 | return year + 1; 34 | } 35 | 36 | static gregorianNewYear(year) { 37 | return Converter.gregorianToFixed(year, 1, 1); 38 | } 39 | 40 | static fixedToGregorian(date) { 41 | const year = Converter.gregorianYearFromFixed(date); 42 | const priorDays = date - Converter.gregorianNewYear(year); 43 | let correction; 44 | if (date < Converter.gregorianToFixed([year, 3, 1])) { 45 | correction = 0; 46 | } else if (Converter.leapGregorian(year)) { 47 | correction = 1; 48 | } else { 49 | correction = 2; 50 | } 51 | const month = Math.floor((12 * (priorDays + correction) + 373) / 367); 52 | const day = date - Converter.gregorianToFixed(year, month, 1) + 1; 53 | return [year, month, day]; 54 | } 55 | 56 | static jalaliToFixed(year, month, day) { 57 | let newYear = PERSIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((8 * year + 21) / 33); 58 | if (NON_LEAP_CORRECTION.includes(year - 1)) { 59 | newYear -= 1; 60 | } 61 | return ( 62 | newYear - 1 63 | + ((month <= 7) ? 31 * (month - 1) : 30 * (month - 1) + 6) 64 | + day 65 | ); 66 | } 67 | 68 | static fixedToJalali(fixedDate) { 69 | const daysSinceEpoch = fixedDate - Converter.jalaliToFixed(1, 1, 1); 70 | let year = 1 + Math.floor((33 * daysSinceEpoch + 3) / PERSIAN_CYCLE_DAYS); 71 | let dayOfYear = fixedDate - Converter.jalaliToFixed(year, 1, 1) + 1; 72 | 73 | if (dayOfYear === 366 && NON_LEAP_CORRECTION.includes(year)) { 74 | year += 1; 75 | dayOfYear = 1; 76 | } 77 | 78 | const month = (dayOfYear <= 186) ? divCeil(dayOfYear, 31) : divCeil(dayOfYear - 6, 30); 79 | const day = fixedDate - Converter.jalaliToFixed(year, month, 1) + 1; 80 | 81 | return [year, month, day]; 82 | } 83 | 84 | static leapPersian(jdate) { 85 | if (NON_LEAP_CORRECTION.includes(jdate)) { 86 | return false; 87 | } if (NON_LEAP_CORRECTION.includes(jdate - 1)) { 88 | return true; 89 | } 90 | return (25 * jdate + 11) % 33 < 8; 91 | } 92 | 93 | static leapGregorian(year) { 94 | return (year % 4 === 0 && ![100, 200, 300].includes(year % 400)); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/jdate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * https://github.com/arashm/JDate 3 | * @author: Arash Mousavi 4 | */ 5 | 6 | import Converter from './converter'; 7 | import * as helpers from './helpers'; 8 | 9 | export default class JDate { 10 | constructor(...args) { 11 | if (Array.isArray(args[0]) || args[0] instanceof Date) { 12 | [this.input] = args; 13 | } else if (args.length === 3) { 14 | this.input = args; 15 | } else if (!args.length) { 16 | this.input = new Date(); 17 | } else { 18 | throw new Error('Unexpected input'); 19 | } 20 | 21 | if (Array.isArray(this.input)) { 22 | this.date = this.input.map((num) => parseInt(num, 10)); 23 | this._d = this.toGregorian(); 24 | } else if (this.input instanceof Date) { 25 | this._d = this.input; 26 | this.date = JDate.toJalali(this.input); 27 | } 28 | } 29 | 30 | /* 31 | * Coverts a Gregorian date to Jalali date 32 | * 33 | * @params {Date} date 34 | * @return {Array} 35 | */ 36 | static toJalali(date) { 37 | const fixedDate = Converter.gregorianToFixed( 38 | date.getFullYear(), 39 | date.getMonth() + 1, 40 | date.getDate() 41 | ); 42 | const jdate = Converter.fixedToJalali(fixedDate); 43 | 44 | return jdate; 45 | } 46 | 47 | // eslint-disable-next-line camelcase 48 | static to_jalali(date) { return JDate.toJalali(date); } 49 | 50 | /* 51 | * converts a Jalali date to Gregorian 52 | * 53 | * @params {Number} year 54 | * @params {Number} month 55 | * @params {Number} day 56 | * @return {Date} 57 | */ 58 | static toGregorian(year, month, day) { 59 | const gdate = Converter.fixedToGregorian( 60 | Converter.jalaliToFixed(year, month, day) 61 | ); 62 | 63 | return new Date(+gdate[0], +gdate[1] - 1, +gdate[2]); 64 | } 65 | 66 | // eslint-disable-next-line camelcase 67 | static to_gregorian(year, month, day) { return JDate.toGregorian(year, month, day); } 68 | 69 | /* 70 | * Checks if a given year is a leap year or not 71 | * 72 | * @params {Number} year 73 | * @return {Boolean} 74 | */ 75 | static isLeapYear(year) { 76 | return Converter.leapPersian(year); 77 | } 78 | 79 | /* 80 | * Returns month length. 81 | * 82 | * @params {Number} year 83 | * @params {Number} month zero based 84 | * @return {Number} 85 | */ 86 | static daysInMonth(year, month) { 87 | let calcedYear = year - Math.floor(month / 12); 88 | let calcedMonth = month - (Math.floor(month / 12) * 12); 89 | 90 | if (calcedMonth < 0) { 91 | calcedMonth += 12; 92 | calcedYear -= 1; 93 | } else if (calcedMonth === 0) { 94 | calcedMonth = 12; 95 | } 96 | 97 | if (calcedMonth < 6) { 98 | return 31; 99 | } if (calcedMonth < 11) { 100 | return 30; 101 | } if (JDate.isLeapYear(calcedYear)) { 102 | return 30; 103 | } 104 | return 29; 105 | } 106 | 107 | /* 108 | * Converts JDate date to Gregorian 109 | */ 110 | toGregorian() { 111 | return JDate.toGregorian(this.date[0], this.date[1], this.date[2]); 112 | } 113 | 114 | /* 115 | * Shows Jalali's full year, ex: 1393 116 | * 117 | * @return {Integer} 118 | */ 119 | getFullYear() { 120 | return this.date[0]; 121 | } 122 | 123 | /* 124 | * Sets the Jalali full year 125 | * 126 | * @params {Number} year 127 | * @return {JDate} 128 | */ 129 | setFullYear(year) { 130 | this.date[0] = parseInt(year, 10); 131 | this.input = this.toGregorian(); 132 | return this; 133 | } 134 | 135 | /* 136 | * Shows Jalali month number. 137 | * 138 | * @return {Number} Jalali month number 139 | */ 140 | getMonth() { 141 | return this.date[1]; 142 | } 143 | 144 | /* 145 | * Sets the Jalali month number. An integer between 0 and 11 146 | * 147 | * @params {Number} month 148 | * @returns {JDate} 149 | */ 150 | setMonth(month) { 151 | const fixed = helpers.fixMonth(this.getFullYear(), parseInt(month, 10)); 152 | [this.date[0], this.date[1]] = fixed; 153 | this.input = this.toGregorian(); 154 | 155 | return this; 156 | } 157 | 158 | /* 159 | * Shows Jalali day number. A number between 0 to 31 160 | * 161 | * @return {Number} Jalali day number 162 | */ 163 | getDate() { 164 | return this.date[2]; 165 | } 166 | 167 | /* 168 | * Sets Jalali day number. A number between 0 to 31 169 | * 170 | * @params {Number} date 171 | * @return {JDate} 172 | */ 173 | setDate(date) { 174 | this.date[2] = parseInt(date, 10); 175 | this.input = this.toGregorian(); 176 | 177 | return this; 178 | } 179 | 180 | /* 181 | * Returns the day of the week for the specified date. A number between 0 to 6 182 | * 183 | * @returns {Number} 184 | */ 185 | getDay() { 186 | return this._d.getDay(); 187 | } 188 | 189 | /* 190 | * Returns a formated output of current date 191 | * 192 | * @params {String} format 193 | * @return {String} 194 | */ 195 | format(format) { 196 | let result = helpers.replaceYear(format, this); 197 | result = helpers.replaceMonth(result, this); 198 | result = helpers.replaceDay(result, this); 199 | 200 | return result; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /tests/jdate.test.js: -------------------------------------------------------------------------------- 1 | import { advanceTo, clear } from 'jest-date-mock'; 2 | import JDate from '../src/jdate'; 3 | 4 | describe('JDate', () => { 5 | it('should returns the current date by default', () => { 6 | advanceTo(new Date(2017, 10, 28)); 7 | const jdate = new JDate(); 8 | 9 | expect(jdate.date).toEqual([1396, 9, 7]); 10 | clear(); 11 | }); 12 | 13 | it('should convert a custom array', () => { 14 | const jdate = new JDate([1396, 10, 11]); 15 | 16 | expect(jdate.date).toEqual([1396, 10, 11]); 17 | expect(jdate.input).toEqual([1396, 10, 11]); 18 | expect(jdate._d).toBeInstanceOf(Date); 19 | expect(jdate._d.getFullYear()).toEqual(2018); 20 | expect(jdate._d.getMonth()).toEqual(0); 21 | expect(jdate._d.getDate()).toEqual(1); 22 | }); 23 | 24 | it('should convert by passing just integers', () => { 25 | const jdate = new JDate(1396, 10, 11); 26 | 27 | expect(jdate.date).toEqual([1396, 10, 11]); 28 | expect(jdate.input).toEqual([1396, 10, 11]); 29 | expect(jdate._d).toBeInstanceOf(Date); 30 | expect(jdate._d.getFullYear()).toEqual(2018); 31 | expect(jdate._d.getMonth()).toEqual(0); 32 | expect(jdate._d.getDate()).toEqual(1); 33 | }); 34 | 35 | it('should convert a JS date object', () => { 36 | const currentDate = new Date(2018, 0, 1); 37 | const jdate = new JDate(currentDate); 38 | 39 | expect(jdate.date).toEqual([1396, 10, 11]); 40 | expect(jdate.input).toEqual(currentDate); 41 | expect(jdate._d).toBeInstanceOf(Date); 42 | expect(jdate._d.getFullYear()).toEqual(2018); 43 | expect(jdate._d.getMonth()).toEqual(0); 44 | expect(jdate._d.getDate()).toEqual(1); 45 | }); 46 | 47 | it('should return correctly for #getFullYear', () => { 48 | const currentDate = new Date(2018, 0, 1); 49 | const jdate = new JDate(currentDate); 50 | 51 | expect(jdate.getFullYear()).toEqual(1396); 52 | }); 53 | 54 | it('should return correctly for #getMonth', () => { 55 | const currentDate = new Date(2018, 0, 1); 56 | const jdate = new JDate(currentDate); 57 | 58 | expect(jdate.getMonth()).toEqual(10); 59 | }); 60 | 61 | it('should return correctly for #getDate', () => { 62 | const currentDate = new Date(2018, 0, 1); 63 | const jdate = new JDate(currentDate); 64 | 65 | expect(jdate.getDate()).toEqual(11); 66 | }); 67 | 68 | it('should return correctly for #getDay', () => { 69 | const currentDate = new Date(2018, 0, 1); 70 | const jdate = new JDate(currentDate); 71 | 72 | expect(jdate.getDay()).toEqual(1); 73 | }); 74 | 75 | describe('.isLeapYear', () => { 76 | it('should return false for not leap year', () => { 77 | const result = JDate.isLeapYear(1393); 78 | 79 | expect(result).toBeFalsy(); 80 | }); 81 | 82 | it('should return true for leap year', () => { 83 | const result = JDate.isLeapYear(1395); 84 | 85 | expect(result).toBeTruthy(); 86 | }); 87 | }); 88 | 89 | describe('.daysInMonth', () => { 90 | it('should return 31 for month 5', () => { 91 | const result = JDate.daysInMonth(1393, 5); 92 | 93 | expect(result).toEqual(31); 94 | }); 95 | 96 | it('should return 30 for month 7', () => { 97 | const result = JDate.daysInMonth(1393, 6); 98 | 99 | expect(result).toEqual(30); 100 | }); 101 | 102 | it('should return 30 for leap year and month 11', () => { 103 | const result = JDate.daysInMonth(1395, 11); 104 | 105 | expect(result).toEqual(30); 106 | }); 107 | }); 108 | 109 | describe('.toGregorian', () => { 110 | it('should return the correct result', () => { 111 | const result = JDate.toGregorian(1393, 12, 11); 112 | 113 | expect([ 114 | result.getFullYear(), 115 | result.getMonth(), 116 | result.getDate() 117 | ]).toEqual([2015, 2, 2]); 118 | }); 119 | 120 | it('should also respond to "to_gregorian" for backport compatibility', () => { 121 | const result = JDate.to_gregorian(1393, 12, 11); 122 | 123 | expect([ 124 | result.getFullYear(), 125 | result.getMonth(), 126 | result.getDate() 127 | ]).toEqual([2015, 2, 2]); 128 | }); 129 | }); 130 | 131 | describe('.toJalali', () => { 132 | it('should return the correct result', () => { 133 | const result = JDate.toJalali(new Date(2025, 2, 20)); 134 | 135 | expect(result).toEqual([1403, 12, 30]); 136 | }); 137 | 138 | it('should also respond to "to_jalali" for backoprt compatibility', () => { 139 | const result = JDate.to_jalali(new Date(2015, 2, 2)); 140 | 141 | expect(result).toEqual([1393, 12, 11]); 142 | }); 143 | }); 144 | 145 | describe('.format', () => { 146 | it('should format the given date correctly', () => { 147 | const result = new JDate([1396, 8, 26]); 148 | 149 | expect(result.format('dddd DD MMMM YYYY')).toEqual('جمعه 26 آبان 1396'); 150 | }); 151 | 152 | it('should correctly format zero leading month', () => { 153 | const result = new JDate([1396, 8, 26]); 154 | 155 | expect(result.format('DD/MM/YYYY')).toEqual('26/08/1396'); 156 | expect(result.format('DD/M/YYYY')).toEqual('26/8/1396'); 157 | }); 158 | 159 | it('should correctly format zero leading day', () => { 160 | const result = new JDate([1396, 8, 6]); 161 | 162 | expect(result.format('D/MM/YYYY')).toEqual('6/08/1396'); 163 | expect(result.format('DD/MM/YYYY')).toEqual('06/08/1396'); 164 | }); 165 | }); 166 | }); 167 | -------------------------------------------------------------------------------- /lib/jdate.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define("JDate",[],t):"object"==typeof exports?exports.JDate=t():e.JDate=t()}(this,(()=>(()=>{var e={51:e=>{e.exports={MONTH_NAMES:["فروردین","اردیبهشت","خرداد","تیر","امرداد","شهریور","مهر","آبان","آذر","دی","بهمن","اسفند"],ABBR_DAYS:["۱ش","۲ش","۳ش","۴ش","۵ش","ج","ش"],DAYS_NAMES:["یکشنبه","دوشنبه","سه‌شنبه","چهارشنبه","پنج‌شنبه","جمعه","شنبه"],GREGORIAN_EPOCH:1,GREGORIAN_TO_FIXED_OFFSET:719528,PERSIAN_EPOCH:226896,PERSIAN_CYCLE_DAYS:12053,NON_LEAP_CORRECTION:[1502,1601,1634,1667,1700,1733,1766,1799,1832,1865,1898,1931,1964,1997,2030,2059,2063,2096,2129,2158,2162,2191,2195,2224,2228,2257,2261,2290,2294,2323,2327,2356,2360,2389,2393,2422,2426,2455,2459,2488,2492,2521,2525,2554,2558,2587,2591,2620,2624,2653,2657,2686,2690,2719,2723,2748,2752,2756,2781,2785,2789,2818,2822,2847,2851,2855,2880,2884,2888,2913,2917,2921,2946,2950,2954,2979,2983,2987]}}},t={};function r(n){var o=t[n];if(void 0!==o)return o.exports;var a=t[n]={exports:{}};return e[n](a,a.exports,r),a.exports}r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t);var n={};return(()=>{"use strict";r.d(n,{default:()=>d});var e=r(51);function t(e,t){return Math.floor((e+t-1)/t)}function o(e){return e&&1===e.length?"0".concat(e):e}function a(e,t){var r=e.match(/[yY]+/);if(!r)return e;switch(r[0]){case"YYYY":case"YYY":return a(e.replace(r,t.getFullYear()),t);case"YY":return a(e.replace(r,String(t.getFullYear()).slice(2)),t);default:return e}}function i(t,r){var n=t.match(/[mM]+/);if(!n)return t;switch(n[0]){case"M":return i(t.replace(n,r.getMonth()),r);case"MM":var a=o(r.getMonth().toString());return i(t.replace(n,a),r);case"MMM":case"MMMM":return i(t.replace(n,e.MONTH_NAMES[r.getMonth()-1]),r);default:return t}}function u(t,r){var n=t.match(/[dD]+/);if(!n)return t;switch(n[0]){case"D":return u(t.replace(n,r.getDate()),r);case"DD":var a=o(r.getDate().toString());return u(t.replace(n,a),r);case"d":case"dd":return u(t.replace(n,e.ABBR_DAYS[r.getDay()]),r);case"ddd":case"dddd":return u(t.replace(n,e.DAYS_NAMES[r.getDay()]),r);default:return t}}function l(e){return l="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},l(e)}function f(e,t){for(var r=0;re.length)&&(t=e.length);for(var r=0,n=Array(t);r12||t<=0){var r=Math.floor((t-1)/12);return[e-r,t-12*r]}return[e,t]}(this.getFullYear(),parseInt(e,10)),r=function(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var r=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null!=r){var n,o,a,i,u=[],l=!0,f=!1;try{if(a=(r=r.call(e)).next,0===t){if(Object(r)!==r)return;l=!1}else for(;!(l=(n=a.call(r)).done)&&(u.push(n.value),u.length!==t);l=!0);}catch(e){f=!0,o=e}finally{try{if(!l&&null!=r.return&&(i=r.return(),Object(i)!==i))return}finally{if(f)throw o}}return u}}(e,t)||function(e,t){if(e){if("string"==typeof e)return p(e,t);var r={}.toString.call(e).slice(8,-1);return"Object"===r&&e.constructor&&(r=e.constructor.name),"Map"===r||"Set"===r?Array.from(e):"Arguments"===r||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?p(e,t):void 0}}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}(t,2);return this.date[0]=r[0],this.date[1]=r[1],this.input=this.toGregorian(),this}},{key:"getDate",value:function(){return this.date[2]}},{key:"setDate",value:function(e){return this.date[2]=parseInt(e,10),this.input=this.toGregorian(),this}},{key:"getDay",value:function(){return this._d.getDay()}},{key:"format",value:function(e){var t=a(e,this);return u(t=i(t,this),this)}}])&&h(t.prototype,r),n&&h(t,n),Object.defineProperty(t,"prototype",{writable:!1}),t;var t,r,n}()})(),n.default})())); 2 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,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QUFxQyxNQU1BLFNBQVNFLEdBQ1AsSUFBTThDLEVGMUlILFNBQWtCL0MsRUFBTUMsR0FDN0IsR0FBSUEsRUFBUSxJQUFNQSxHQUFTLEVBQUcsQ0FDNUIsSUFBTStDLEVBQVd4RSxLQUFLQyxPQUFPd0IsRUFBUSxHQUFLLElBSTFDLE1BQU8sQ0FIU0QsRUFBT2dELEVBQ04vQyxFQUFvQixHQUFYK0MsRUFHNUIsQ0FFQSxNQUFPLENBQUNoRCxFQUFNQyxFQUNoQixDRWdJa0JnRCxDQUFpQnhHLEtBQUt5QyxjQUFla0QsU0FBU25DLEVBQU8sS0FBS2lELEUsdzVCQUFBQyxDQUN6Q0osRUFBSyxHQUdwQyxPQUhDdEcsS0FBS3NDLEtBQUssR0FBRW1FLEVBQUEsR0FBRXpHLEtBQUtzQyxLQUFLLEdBQUVtRSxFQUFBLEdBQzNCekcsS0FBS3VGLE1BQVF2RixLQUFLNkYsY0FFWDdGLElBQ1QsR0FFQSxDQUFBaUIsSUFBQSxVQUFBcUMsTUFLQSxXQUNFLE9BQU90RCxLQUFLc0MsS0FBSyxFQUNuQixHQUVBLENBQUFyQixJQUFBLFVBQUFxQyxNQU1BLFNBQVFoQixHQUlOLE9BSEF0QyxLQUFLc0MsS0FBSyxHQUFLcUQsU0FBU3JELEVBQU0sSUFDOUJ0QyxLQUFLdUYsTUFBUXZGLEtBQUs2RixjQUVYN0YsSUFDVCxHQUVBLENBQUFpQixJQUFBLFNBQUFxQyxNQUtBLFdBQ0UsT0FBT3RELEtBQUs0RixHQUFHekMsUUFDakIsR0FFQSxDQUFBbEMsSUFBQSxTQUFBcUMsTUFNQSxTQUFPcUQsR0FDTCxJQUFJQyxFQUFTSixFQUFvQkcsRUFBUTNHLE1BSXpDLE9BRlN3RyxFQURUSSxFQUFTSixFQUFxQkksRUFBUTVHLE1BQ0ZBLEtBR3RDLE0seUZBaEdDLENBaEd1QixFIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay91bml2ZXJzYWxNb2R1bGVEZWZpbml0aW9uIiwid2VicGFjazovL0pEYXRlLy4vc3JjL2NvbnN0YW50cy5qcyIsIndlYnBhY2s6Ly9KRGF0ZS93ZWJwYWNrL2Jvb3RzdHJhcCIsIndlYnBhY2s6Ly9KRGF0ZS93ZWJwYWNrL3J1bnRpbWUvZGVmaW5lIHByb3BlcnR5IGdldHRlcnMiLCJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay9ydW50aW1lL2hhc093blByb3BlcnR5IHNob3J0aGFuZCIsIndlYnBhY2s6Ly9KRGF0ZS8uL3NyYy9oZWxwZXJzLmpzIiwid2VicGFjazovL0pEYXRlLy4vc3JjL2NvbnZlcnRlci5qcyIsIndlYnBhY2s6Ly9KRGF0ZS8uL3NyYy9qZGF0ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdGVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxuXHRcdGRlZmluZShcIkpEYXRlXCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIkpEYXRlXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcIkpEYXRlXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuICIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBNT05USF9OQU1FUzogWyfZgdix2YjYsdiv24zZhicsICfYp9ix2K/bjNio2YfYtNiqJywgJ9iu2LHYr9in2K8nLCAn2KrbjNixJywgJ9in2YXYsdiv2KfYrycsICfYtNmH2LHbjNmI2LEnLCAn2YXZh9ixJywgJ9ii2KjYp9mGJywgJ9ii2LDYsScsICfYr9uMJywgJ9io2YfZhdmGJywgJ9in2LPZgdmG2K8nXSxcbiAgQUJCUl9EQVlTOiBbJ9ux2LQnLCAn27LYtCcsICfbs9i0JywgJ9u02LQnLCAn27XYtCcsICfYrCcsICfYtCddLFxuICBEQVlTX05BTUVTOiBbJ9uM2qnYtNmG2KjZhycsICfYr9mI2LTZhtio2YcnLCAn2LPZh+KAjNi02YbYqNmHJywgJ9qG2YfYp9ix2LTZhtio2YcnLCAn2b7Zhtis4oCM2LTZhtio2YcnLCAn2KzZhdi52YcnLCAn2LTZhtio2YcnXSxcbiAgR1JFR09SSUFOX0VQT0NIOiAxLFxuICBHUkVHT1JJQU5fVE9fRklYRURfT0ZGU0VUOiA3MTk1MjgsXG4gIFBFUlNJQU5fRVBPQ0g6IDIyNjg5NixcbiAgUEVSU0lBTl9DWUNMRV9EQVlTOiAxMjA1MyxcbiAgTk9OX0xFQVBfQ09SUkVDVElPTjogW1xuICAgIDE1MDIsXG4gICAgMTYwMSwgMTYzNCwgMTY2NyxcbiAgICAxNzAwLCAxNzMzLCAxNzY2LCAxNzk5LFxuICAgIDE4MzIsIDE4NjUsIDE4OTgsXG4gICAgMTkzMSwgMTk2NCwgMTk5NyxcbiAgICAyMDMwLCAyMDU5LCAyMDYzLCAyMDk2LFxuICAgIDIxMjksIDIxNTgsIDIxNjIsIDIxOTEsIDIxOTUsXG4gICAgMjIyNCwgMjIyOCwgMjI1NywgMjI2MSwgMjI5MCwgMjI5NCxcbiAgICAyMzIzLCAyMzI3LCAyMzU2LCAyMzYwLCAyMzg5LCAyMzkzLFxuICAgIDI0MjIsIDI0MjYsIDI0NTUsIDI0NTksIDI0ODgsIDI0OTIsXG4gICAgMjUyMSwgMjUyNSwgMjU1NCwgMjU1OCwgMjU4NywgMjU5MSxcbiAgICAyNjIwLCAyNjI0LCAyNjUzLCAyNjU3LCAyNjg2LCAyNjkwLFxuICAgIDI3MTksIDI3MjMsIDI3NDgsIDI3NTIsIDI3NTYsIDI3ODEsIDI3ODUsIDI3ODksXG4gICAgMjgxOCwgMjgyMiwgMjg0NywgMjg1MSwgMjg1NSwgMjg4MCwgMjg4NCwgMjg4OCxcbiAgICAyOTEzLCAyOTE3LCAyOTIxLCAyOTQ2LCAyOTUwLCAyOTU0LCAyOTc5LCAyOTgzLCAyOTg3XG4gIF1cbn07XG4iLCIvLyBUaGUgbW9kdWxlIGNhY2hlXG52YXIgX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fID0ge307XG5cbi8vIFRoZSByZXF1aXJlIGZ1bmN0aW9uXG5mdW5jdGlvbiBfX3dlYnBhY2tfcmVxdWlyZV9fKG1vZHVsZUlkKSB7XG5cdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuXHR2YXIgY2FjaGVkTW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXTtcblx0aWYgKGNhY2hlZE1vZHVsZSAhPT0gdW5kZWZpbmVkKSB7XG5cdFx0cmV0dXJuIGNhY2hlZE1vZHVsZS5leHBvcnRzO1xuXHR9XG5cdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG5cdHZhciBtb2R1bGUgPSBfX3dlYnBhY2tfbW9kdWxlX2NhY2hlX19bbW9kdWxlSWRdID0ge1xuXHRcdC8vIG5vIG1vZHVsZS5pZCBuZWVkZWRcblx0XHQvLyBubyBtb2R1bGUubG9hZGVkIG5lZWRlZFxuXHRcdGV4cG9ydHM6IHt9XG5cdH07XG5cblx0Ly8gRXhlY3V0ZSB0aGUgbW9kdWxlIGZ1bmN0aW9uXG5cdF9fd2VicGFja19tb2R1bGVzX19bbW9kdWxlSWRdKG1vZHVsZSwgbW9kdWxlLmV4cG9ydHMsIF9fd2VicGFja19yZXF1aXJlX18pO1xuXG5cdC8vIFJldHVybiB0aGUgZXhwb3J0cyBvZiB0aGUgbW9kdWxlXG5cdHJldHVybiBtb2R1bGUuZXhwb3J0cztcbn1cblxuIiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5cbmltcG9ydCB7XG4gIE1PTlRIX05BTUVTLFxuICBBQkJSX0RBWVMsXG4gIERBWVNfTkFNRVNcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZGl2Q2VpbChhLCBiKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKChhICsgYiAtIDEpIC8gYik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaXhNb250aCh5ZWFyLCBtb250aCkge1xuICBpZiAobW9udGggPiAxMiB8fCBtb250aCA8PSAwKSB7XG4gICAgY29uc3QgeWVhckRpZmYgPSBNYXRoLmZsb29yKChtb250aCAtIDEpIC8gMTIpO1xuICAgIGNvbnN0IG5ld1llYXIgPSB5ZWFyIC0geWVhckRpZmY7XG4gICAgY29uc3QgbmV3TW9udGggPSBtb250aCAtICh5ZWFyRGlmZiAqIDEyKTtcblxuICAgIHJldHVybiBbbmV3WWVhciwgbmV3TW9udGhdO1xuICB9XG5cbiAgcmV0dXJuIFt5ZWFyLCBtb250aF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvTGVhZGluZyhzdHIpIHtcbiAgaWYgKHN0ciAmJiBzdHIubGVuZ3RoID09PSAxKSB7IHJldHVybiBgMCR7c3RyfWA7IH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VZZWFyKHN0ciwgZGF0ZSkge1xuICBjb25zdCBtYXRjaCA9IHN0ci5tYXRjaCgvW3lZXSsvKTtcbiAgaWYgKCFtYXRjaCkgeyByZXR1cm4gc3RyOyB9XG4gIHN3aXRjaCAobWF0Y2hbMF0pIHtcbiAgICBjYXNlICdZWVlZJzpcbiAgICBjYXNlICdZWVknOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VZZWFyKHN0ci5yZXBsYWNlKG1hdGNoLCBkYXRlLmdldEZ1bGxZZWFyKCkpLCBkYXRlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgY2FzZSAnWVknOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VZZWFyKFxuICAgICAgICBzdHIucmVwbGFjZShtYXRjaCwgU3RyaW5nKGRhdGUuZ2V0RnVsbFllYXIoKSkuc2xpY2UoMikpLCBkYXRlXG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZU1vbnRoKHN0ciwgZGF0ZSkge1xuICBjb25zdCBtYXRjaCA9IHN0ci5tYXRjaCgvW21NXSsvKTtcbiAgaWYgKCFtYXRjaCkgeyByZXR1cm4gc3RyOyB9XG4gIHN3aXRjaCAobWF0Y2hbMF0pIHtcbiAgICBjYXNlICdNJzoge1xuICAgICAgY29uc3QgdmFsdWUgPSByZXBsYWNlTW9udGgoc3RyLnJlcGxhY2UobWF0Y2gsIGRhdGUuZ2V0TW9udGgoKSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdNTSc6IHtcbiAgICAgIGNvbnN0IHplcm9MZWFkaW5nTW9udGggPSB6ZXJvTGVhZGluZyhkYXRlLmdldE1vbnRoKCkudG9TdHJpbmcoKSk7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VNb250aChzdHIucmVwbGFjZShtYXRjaCwgemVyb0xlYWRpbmdNb250aCksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdNTU0nOlxuICAgIGNhc2UgJ01NTU0nOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VNb250aChcbiAgICAgICAgc3RyLnJlcGxhY2UobWF0Y2gsIE1PTlRIX05BTUVTW2RhdGUuZ2V0TW9udGgoKSAtIDFdKSwgZGF0ZVxuICAgICAgKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VEYXkoc3RyLCBkYXRlKSB7XG4gIGNvbnN0IG1hdGNoID0gc3RyLm1hdGNoKC9bZERdKy8pO1xuICBpZiAoIW1hdGNoKSB7IHJldHVybiBzdHI7IH1cbiAgc3dpdGNoIChtYXRjaFswXSkge1xuICAgIGNhc2UgJ0QnOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VEYXkoc3RyLnJlcGxhY2UobWF0Y2gsIGRhdGUuZ2V0RGF0ZSgpKSwgZGF0ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNhc2UgJ0REJzoge1xuICAgICAgY29uc3QgemVyb0xlYWRpbmdEYXRlID0gemVyb0xlYWRpbmcoZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKSk7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VEYXkoc3RyLnJlcGxhY2UobWF0Y2gsIHplcm9MZWFkaW5nRGF0ZSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdkJzpcbiAgICBjYXNlICdkZCc6IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcmVwbGFjZURheShzdHIucmVwbGFjZShtYXRjaCwgQUJCUl9EQVlTW2RhdGUuZ2V0RGF5KCldKSwgZGF0ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNhc2UgJ2RkZCc6XG4gICAgY2FzZSAnZGRkZCc6IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcmVwbGFjZURheShzdHIucmVwbGFjZShtYXRjaCwgREFZU19OQU1FU1tkYXRlLmdldERheSgpXSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgfVxufVxuIiwiaW1wb3J0IHsgZGl2Q2VpbCB9IGZyb20gJy4vaGVscGVycyc7XG5pbXBvcnQge1xuICBHUkVHT1JJQU5fRVBPQ0gsIFBFUlNJQU5fRVBPQ0gsIE5PTl9MRUFQX0NPUlJFQ1RJT04sIFBFUlNJQU5fQ1lDTEVfREFZU1xufSBmcm9tICcuL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIENvbnZlcnRlciB7XG4gIHN0YXRpYyBncmVnb3JpYW5Ub0ZpeGVkKHllYXIsIG1vbnRoLCBkYXkpIHtcbiAgICBjb25zdCByZXN1bHQgPSBHUkVHT1JJQU5fRVBPQ0ggLSAxXG4gICAgICAgICsgMzY1ICogKHllYXIgLSAxKVxuICAgICAgICArIE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDQpXG4gICAgICAgIC0gTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gMTAwKVxuICAgICAgICArIE1hdGguZmxvb3IoKHllYXIgLSAxKSAvIDQwMClcbiAgICAgICAgKyBNYXRoLmZsb29yKCgzNjcgKiBtb250aCAtIDM2MikgLyAxMilcbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLW5lc3RlZC10ZXJuYXJ5XG4gICAgICAgICsgKG1vbnRoIDw9IDIgPyAwIDogQ29udmVydGVyLmxlYXBHcmVnb3JpYW4oeWVhcikgPyAtMSA6IC0yKVxuICAgICAgICArIGRheTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgc3RhdGljIGdyZWdvcmlhblllYXJGcm9tRml4ZWQoZGF0ZSkge1xuICAgIGNvbnN0IGQwID0gZGF0ZSAtIEdSRUdPUklBTl9FUE9DSDtcbiAgICBjb25zdCBuNDAwID0gTWF0aC5mbG9vcihkMCAvIDE0NjA5Nyk7XG4gICAgY29uc3QgZDEgPSBkMCAlIDE0NjA5NztcbiAgICBjb25zdCBuMTAwID0gTWF0aC5mbG9vcihkMSAvIDM2NTI0KTtcbiAgICBjb25zdCBkMiA9IGQxICUgMzY1MjQ7XG4gICAgY29uc3QgbjQgPSBNYXRoLmZsb29yKGQyIC8gMTQ2MSk7XG4gICAgY29uc3QgZDMgPSBkMiAlIDE0NjE7XG4gICAgY29uc3QgbjEgPSBNYXRoLmZsb29yKGQzIC8gMzY1KTtcbiAgICBjb25zdCB5ZWFyID0gNDAwICogbjQwMCArIDEwMCAqIG4xMDAgKyA0ICogbjQgKyBuMTtcbiAgICBpZiAobjEwMCA9PT0gNCB8fCBuMSA9PT0gNCkge1xuICAgICAgcmV0dXJuIHllYXI7XG4gICAgfVxuICAgIHJldHVybiB5ZWFyICsgMTtcbiAgfVxuXG4gIHN0YXRpYyBncmVnb3JpYW5OZXdZZWFyKHllYXIpIHtcbiAgICByZXR1cm4gQ29udmVydGVyLmdyZWdvcmlhblRvRml4ZWQoeWVhciwgMSwgMSk7XG4gIH1cblxuICBzdGF0aWMgZml4ZWRUb0dyZWdvcmlhbihkYXRlKSB7XG4gICAgY29uc3QgeWVhciA9IENvbnZlcnRlci5ncmVnb3JpYW5ZZWFyRnJvbUZpeGVkKGRhdGUpO1xuICAgIGNvbnN0IHByaW9yRGF5cyA9IGRhdGUgLSBDb252ZXJ0ZXIuZ3JlZ29yaWFuTmV3WWVhcih5ZWFyKTtcbiAgICBsZXQgY29ycmVjdGlvbjtcbiAgICBpZiAoZGF0ZSA8IENvbnZlcnRlci5ncmVnb3JpYW5Ub0ZpeGVkKFt5ZWFyLCAzLCAxXSkpIHtcbiAgICAgIGNvcnJlY3Rpb24gPSAwO1xuICAgIH0gZWxzZSBpZiAoQ29udmVydGVyLmxlYXBHcmVnb3JpYW4oeWVhcikpIHtcbiAgICAgIGNvcnJlY3Rpb24gPSAxO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb3JyZWN0aW9uID0gMjtcbiAgICB9XG4gICAgY29uc3QgbW9udGggPSBNYXRoLmZsb29yKCgxMiAqIChwcmlvckRheXMgKyBjb3JyZWN0aW9uKSArIDM3MykgLyAzNjcpO1xuICAgIGNvbnN0IGRheSA9IGRhdGUgLSBDb252ZXJ0ZXIuZ3JlZ29yaWFuVG9GaXhlZCh5ZWFyLCBtb250aCwgMSkgKyAxO1xuICAgIHJldHVybiBbeWVhciwgbW9udGgsIGRheV07XG4gIH1cblxuICBzdGF0aWMgamFsYWxpVG9GaXhlZCh5ZWFyLCBtb250aCwgZGF5KSB7XG4gICAgbGV0IG5ld1llYXIgPSBQRVJTSUFOX0VQT0NIIC0gMSArIDM2NSAqICh5ZWFyIC0gMSkgKyBNYXRoLmZsb29yKCg4ICogeWVhciArIDIxKSAvIDMzKTtcbiAgICBpZiAoTk9OX0xFQVBfQ09SUkVDVElPTi5pbmNsdWRlcyh5ZWFyIC0gMSkpIHtcbiAgICAgIG5ld1llYXIgLT0gMTtcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIG5ld1llYXIgLSAxXG4gICAgICAgICsgKChtb250aCA8PSA3KSA/IDMxICogKG1vbnRoIC0gMSkgOiAzMCAqIChtb250aCAtIDEpICsgNilcbiAgICAgICAgKyBkYXlcbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGZpeGVkVG9KYWxhbGkoZml4ZWREYXRlKSB7XG4gICAgY29uc3QgZGF5c1NpbmNlRXBvY2ggPSBmaXhlZERhdGUgLSBDb252ZXJ0ZXIuamFsYWxpVG9GaXhlZCgxLCAxLCAxKTtcbiAgICBsZXQgeWVhciA9IDEgKyBNYXRoLmZsb29yKCgzMyAqIGRheXNTaW5jZUVwb2NoICsgMykgLyBQRVJTSUFOX0NZQ0xFX0RBWVMpO1xuICAgIGxldCBkYXlPZlllYXIgPSBmaXhlZERhdGUgLSBDb252ZXJ0ZXIuamFsYWxpVG9GaXhlZCh5ZWFyLCAxLCAxKSArIDE7XG5cbiAgICBpZiAoZGF5T2ZZZWFyID09PSAzNjYgJiYgTk9OX0xFQVBfQ09SUkVDVElPTi5pbmNsdWRlcyh5ZWFyKSkge1xuICAgICAgeWVhciArPSAxO1xuICAgICAgZGF5T2ZZZWFyID0gMTtcbiAgICB9XG5cbiAgICBjb25zdCBtb250aCA9IChkYXlPZlllYXIgPD0gMTg2KSA/IGRpdkNlaWwoZGF5T2ZZZWFyLCAzMSkgOiBkaXZDZWlsKGRheU9mWWVhciAtIDYsIDMwKTtcbiAgICBjb25zdCBkYXkgPSBmaXhlZERhdGUgLSBDb252ZXJ0ZXIuamFsYWxpVG9GaXhlZCh5ZWFyLCBtb250aCwgMSkgKyAxO1xuXG4gICAgcmV0dXJuIFt5ZWFyLCBtb250aCwgZGF5XTtcbiAgfVxuXG4gIHN0YXRpYyBsZWFwUGVyc2lhbihqZGF0ZSkge1xuICAgIGlmIChOT05fTEVBUF9DT1JSRUNUSU9OLmluY2x1ZGVzKGpkYXRlKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0gaWYgKE5PTl9MRUFQX0NPUlJFQ1RJT04uaW5jbHVkZXMoamRhdGUgLSAxKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiAoMjUgKiBqZGF0ZSArIDExKSAlIDMzIDwgODtcbiAgfVxuXG4gIHN0YXRpYyBsZWFwR3JlZ29yaWFuKHllYXIpIHtcbiAgICByZXR1cm4gKHllYXIgJSA0ID09PSAwICYmICFbMTAwLCAyMDAsIDMwMF0uaW5jbHVkZXMoeWVhciAlIDQwMCkpO1xuICB9XG59XG4iLCIvKlxuICogaHR0cHM6Ly9naXRodWIuY29tL2FyYXNobS9KRGF0ZVxuICogQGF1dGhvcjogQXJhc2ggTW91c2F2aVxuICovXG5cbmltcG9ydCBDb252ZXJ0ZXIgZnJvbSAnLi9jb252ZXJ0ZXInO1xuaW1wb3J0ICogYXMgaGVscGVycyBmcm9tICcuL2hlbHBlcnMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBKRGF0ZSB7XG4gIGNvbnN0cnVjdG9yKC4uLmFyZ3MpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhcmdzWzBdKSB8fCBhcmdzWzBdIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgW3RoaXMuaW5wdXRdID0gYXJncztcbiAgICB9IGVsc2UgaWYgKGFyZ3MubGVuZ3RoID09PSAzKSB7XG4gICAgICB0aGlzLmlucHV0ID0gYXJncztcbiAgICB9IGVsc2UgaWYgKCFhcmdzLmxlbmd0aCkge1xuICAgICAgdGhpcy5pbnB1dCA9IG5ldyBEYXRlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBpbnB1dCcpO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHRoaXMuaW5wdXQpKSB7XG4gICAgICB0aGlzLmRhdGUgPSB0aGlzLmlucHV0Lm1hcCgobnVtKSA9PiBwYXJzZUludChudW0sIDEwKSk7XG4gICAgICB0aGlzLl9kID0gdGhpcy50b0dyZWdvcmlhbigpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5pbnB1dCBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHRoaXMuX2QgPSB0aGlzLmlucHV0O1xuICAgICAgdGhpcy5kYXRlID0gSkRhdGUudG9KYWxhbGkodGhpcy5pbnB1dCk7XG4gICAgfVxuICB9XG5cbiAgLypcbiAgICogQ292ZXJ0cyBhIEdyZWdvcmlhbiBkYXRlIHRvIEphbGFsaSBkYXRlXG4gICAqXG4gICAqIEBwYXJhbXMge0RhdGV9IGRhdGVcbiAgICogQHJldHVybiB7QXJyYXl9XG4gICAqL1xuICBzdGF0aWMgdG9KYWxhbGkoZGF0ZSkge1xuICAgIGNvbnN0IGZpeGVkRGF0ZSA9IENvbnZlcnRlci5ncmVnb3JpYW5Ub0ZpeGVkKFxuICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpLFxuICAgICAgZGF0ZS5nZXRNb250aCgpICsgMSxcbiAgICAgIGRhdGUuZ2V0RGF0ZSgpXG4gICAgKTtcbiAgICBjb25zdCBqZGF0ZSA9IENvbnZlcnRlci5maXhlZFRvSmFsYWxpKGZpeGVkRGF0ZSk7XG5cbiAgICByZXR1cm4gamRhdGU7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgY2FtZWxjYXNlXG4gIHN0YXRpYyB0b19qYWxhbGkoZGF0ZSkgeyByZXR1cm4gSkRhdGUudG9KYWxhbGkoZGF0ZSk7IH1cblxuICAvKlxuICAgKiBjb252ZXJ0cyBhIEphbGFsaSBkYXRlIHRvIEdyZWdvcmlhblxuICAgKlxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IHllYXJcbiAgICogQHBhcmFtcyB7TnVtYmVyfSBtb250aFxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IGRheVxuICAgKiBAcmV0dXJuIHtEYXRlfVxuICAgKi9cbiAgc3RhdGljIHRvR3JlZ29yaWFuKHllYXIsIG1vbnRoLCBkYXkpIHtcbiAgICBjb25zdCBnZGF0ZSA9IENvbnZlcnRlci5maXhlZFRvR3JlZ29yaWFuKFxuICAgICAgQ29udmVydGVyLmphbGFsaVRvRml4ZWQoeWVhciwgbW9udGgsIGRheSlcbiAgICApO1xuXG4gICAgcmV0dXJuIG5ldyBEYXRlKCtnZGF0ZVswXSwgK2dkYXRlWzFdIC0gMSwgK2dkYXRlWzJdKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgc3RhdGljIHRvX2dyZWdvcmlhbih5ZWFyLCBtb250aCwgZGF5KSB7IHJldHVybiBKRGF0ZS50b0dyZWdvcmlhbih5ZWFyLCBtb250aCwgZGF5KTsgfVxuXG4gIC8qXG4gICAqIENoZWNrcyBpZiBhIGdpdmVuIHllYXIgaXMgYSBsZWFwIHllYXIgb3Igbm90XG4gICAqXG4gICAqIEBwYXJhbXMge051bWJlcn0geWVhclxuICAgKiBAcmV0dXJuIHtCb29sZWFufVxuICAgKi9cbiAgc3RhdGljIGlzTGVhcFllYXIoeWVhcikge1xuICAgIHJldHVybiBDb252ZXJ0ZXIubGVhcFBlcnNpYW4oeWVhcik7XG4gIH1cblxuICAvKlxuICAgKiBSZXR1cm5zIG1vbnRoIGxlbmd0aC5cbiAgICpcbiAgICogQHBhcmFtcyB7TnVtYmVyfSB5ZWFyXG4gICAqIEBwYXJhbXMge051bWJlcn0gbW9udGggemVybyBiYXNlZFxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAqL1xuICBzdGF0aWMgZGF5c0luTW9udGgoeWVhciwgbW9udGgpIHtcbiAgICBsZXQgY2FsY2VkWWVhciA9IHllYXIgLSBNYXRoLmZsb29yKG1vbnRoIC8gMTIpO1xuICAgIGxldCBjYWxjZWRNb250aCA9IG1vbnRoIC0gKE1hdGguZmxvb3IobW9udGggLyAxMikgKiAxMik7XG5cbiAgICBpZiAoY2FsY2VkTW9udGggPCAwKSB7XG4gICAgICBjYWxjZWRNb250aCArPSAxMjtcbiAgICAgIGNhbGNlZFllYXIgLT0gMTtcbiAgICB9IGVsc2UgaWYgKGNhbGNlZE1vbnRoID09PSAwKSB7XG4gICAgICBjYWxjZWRNb250aCA9IDEyO1xuICAgIH1cblxuICAgIGlmIChjYWxjZWRNb250aCA8IDYpIHtcbiAgICAgIHJldHVybiAzMTtcbiAgICB9IGlmIChjYWxjZWRNb250aCA8IDExKSB7XG4gICAgICByZXR1cm4gMzA7XG4gICAgfSBpZiAoSkRhdGUuaXNMZWFwWWVhcihjYWxjZWRZZWFyKSkge1xuICAgICAgcmV0dXJuIDMwO1xuICAgIH1cbiAgICByZXR1cm4gMjk7XG4gIH1cblxuICAvKlxuICAgKiBDb252ZXJ0cyBKRGF0ZSBkYXRlIHRvIEdyZWdvcmlhblxuICAgKi9cbiAgdG9HcmVnb3JpYW4oKSB7XG4gICAgcmV0dXJuIEpEYXRlLnRvR3JlZ29yaWFuKHRoaXMuZGF0ZVswXSwgdGhpcy5kYXRlWzFdLCB0aGlzLmRhdGVbMl0pO1xuICB9XG5cbiAgLypcbiAgICogU2hvd3MgSmFsYWxpJ3MgZnVsbCB5ZWFyLCBleDogMTM5M1xuICAgKlxuICAgKiBAcmV0dXJuIHtJbnRlZ2VyfVxuICAgKi9cbiAgZ2V0RnVsbFllYXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZVswXTtcbiAgfVxuXG4gIC8qXG4gICAqIFNldHMgdGhlIEphbGFsaSBmdWxsIHllYXJcbiAgICpcbiAgICogQHBhcmFtcyB7TnVtYmVyfSB5ZWFyXG4gICAqIEByZXR1cm4ge0pEYXRlfVxuICAgKi9cbiAgc2V0RnVsbFllYXIoeWVhcikge1xuICAgIHRoaXMuZGF0ZVswXSA9IHBhcnNlSW50KHllYXIsIDEwKTtcbiAgICB0aGlzLmlucHV0ID0gdGhpcy50b0dyZWdvcmlhbigpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgICogU2hvd3MgSmFsYWxpIG1vbnRoIG51bWJlci5cbiAgICpcbiAgICogQHJldHVybiB7TnVtYmVyfSBKYWxhbGkgbW9udGggbnVtYmVyXG4gICAqL1xuICBnZXRNb250aCgpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRlWzFdO1xuICB9XG5cbiAgLypcbiAgICogU2V0cyB0aGUgSmFsYWxpIG1vbnRoIG51bWJlci4gQW4gaW50ZWdlciBiZXR3ZWVuIDAgYW5kIDExXG4gICAqXG4gICAqIEBwYXJhbXMge051bWJlcn0gbW9udGhcbiAgICogQHJldHVybnMge0pEYXRlfVxuICAgKi9cbiAgc2V0TW9udGgobW9udGgpIHtcbiAgICBjb25zdCBmaXhlZCA9IGhlbHBlcnMuZml4TW9udGgodGhpcy5nZXRGdWxsWWVhcigpLCBwYXJzZUludChtb250aCwgMTApKTtcbiAgICBbdGhpcy5kYXRlWzBdLCB0aGlzLmRhdGVbMV1dID0gZml4ZWQ7XG4gICAgdGhpcy5pbnB1dCA9IHRoaXMudG9HcmVnb3JpYW4oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgICogU2hvd3MgSmFsYWxpIGRheSBudW1iZXIuIEEgbnVtYmVyIGJldHdlZW4gMCB0byAzMVxuICAgKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IEphbGFsaSBkYXkgbnVtYmVyXG4gICAqL1xuICBnZXREYXRlKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGVbMl07XG4gIH1cblxuICAvKlxuICAgKiBTZXRzIEphbGFsaSBkYXkgbnVtYmVyLiBBIG51bWJlciBiZXR3ZWVuIDAgdG8gMzFcbiAgICpcbiAgICogQHBhcmFtcyB7TnVtYmVyfSBkYXRlXG4gICAqIEByZXR1cm4ge0pEYXRlfVxuICAgKi9cbiAgc2V0RGF0ZShkYXRlKSB7XG4gICAgdGhpcy5kYXRlWzJdID0gcGFyc2VJbnQoZGF0ZSwgMTApO1xuICAgIHRoaXMuaW5wdXQgPSB0aGlzLnRvR3JlZ29yaWFuKCk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qXG4gICAqIFJldHVybnMgdGhlIGRheSBvZiB0aGUgd2VlayBmb3IgdGhlIHNwZWNpZmllZCBkYXRlLiBBIG51bWJlciBiZXR3ZWVuIDAgdG8gNlxuICAgKlxuICAgKiBAcmV0dXJucyB7TnVtYmVyfVxuICAgKi9cbiAgZ2V0RGF5KCkge1xuICAgIHJldHVybiB0aGlzLl9kLmdldERheSgpO1xuICB9XG5cbiAgLypcbiAgICogUmV0dXJucyBhIGZvcm1hdGVkIG91dHB1dCBvZiBjdXJyZW50IGRhdGVcbiAgICpcbiAgICogQHBhcmFtcyB7U3RyaW5nfSBmb3JtYXRcbiAgICogQHJldHVybiB7U3RyaW5nfVxuICAgKi9cbiAgZm9ybWF0KGZvcm1hdCkge1xuICAgIGxldCByZXN1bHQgPSBoZWxwZXJzLnJlcGxhY2VZZWFyKGZvcm1hdCwgdGhpcyk7XG4gICAgcmVzdWx0ID0gaGVscGVycy5yZXBsYWNlTW9udGgocmVzdWx0LCB0aGlzKTtcbiAgICByZXN1bHQgPSBoZWxwZXJzLnJlcGxhY2VEYXkocmVzdWx0LCB0aGlzKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn1cbiJdLCJuYW1lcyI6WyJyb290IiwiZmFjdG9yeSIsImV4cG9ydHMiLCJtb2R1bGUiLCJkZWZpbmUiLCJhbWQiLCJ0aGlzIiwiTU9OVEhfTkFNRVMiLCJBQkJSX0RBWVMiLCJEQVlTX05BTUVTIiwiR1JFR09SSUFOX0VQT0NIIiwiR1JFR09SSUFOX1RPX0ZJWEVEX09GRlNFVCIsIlBFUlNJQU5fRVBPQ0giLCJQRVJTSUFOX0NZQ0xFX0RBWVMiLCJOT05fTEVBUF9DT1JSRUNUSU9OIiwiX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fIiwiX193ZWJwYWNrX3JlcXVpcmVfXyIsIm1vZHVsZUlkIiwiY2FjaGVkTW9kdWxlIiwidW5kZWZpbmVkIiwiX193ZWJwYWNrX21vZHVsZXNfXyIsImQiLCJkZWZpbml0aW9uIiwia2V5IiwibyIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZW51bWVyYWJsZSIsImdldCIsIm9iaiIsInByb3AiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJkaXZDZWlsIiwiYSIsImIiLCJNYXRoIiwiZmxvb3IiLCJ6ZXJvTGVhZGluZyIsInN0ciIsImxlbmd0aCIsImNvbmNhdCIsInJlcGxhY2VZZWFyIiwiZGF0ZSIsIm1hdGNoIiwicmVwbGFjZSIsImdldEZ1bGxZZWFyIiwiU3RyaW5nIiwic2xpY2UiLCJyZXBsYWNlTW9udGgiLCJnZXRNb250aCIsInplcm9MZWFkaW5nTW9udGgiLCJ0b1N0cmluZyIsInJlcGxhY2VEYXkiLCJnZXREYXRlIiwiemVyb0xlYWRpbmdEYXRlIiwiZ2V0RGF5IiwiQ29udmVydGVyIiwiX2NsYXNzQ2FsbENoZWNrIiwidmFsdWUiLCJ5ZWFyIiwibW9udGgiLCJkYXkiLCJsZWFwR3JlZ29yaWFuIiwiZDAiLCJuNDAwIiwiZDEiLCJuMTAwIiwiZDIiLCJuNCIsImQzIiwibjEiLCJncmVnb3JpYW5Ub0ZpeGVkIiwiY29ycmVjdGlvbiIsImdyZWdvcmlhblllYXJGcm9tRml4ZWQiLCJwcmlvckRheXMiLCJncmVnb3JpYW5OZXdZZWFyIiwibmV3WWVhciIsImluY2x1ZGVzIiwiZml4ZWREYXRlIiwiZGF5c1NpbmNlRXBvY2giLCJqYWxhbGlUb0ZpeGVkIiwiZGF5T2ZZZWFyIiwiamRhdGUiLCJKRGF0ZSIsIl9sZW4iLCJhcmd1bWVudHMiLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiaXNBcnJheSIsIkRhdGUiLCJpbnB1dCIsIkVycm9yIiwibWFwIiwibnVtIiwicGFyc2VJbnQiLCJfZCIsInRvR3JlZ29yaWFuIiwidG9KYWxhbGkiLCJmaXhlZFRvSmFsYWxpIiwiZ2RhdGUiLCJmaXhlZFRvR3JlZ29yaWFuIiwibGVhcFBlcnNpYW4iLCJjYWxjZWRZZWFyIiwiY2FsY2VkTW9udGgiLCJpc0xlYXBZZWFyIiwiZml4ZWQiLCJ5ZWFyRGlmZiIsImhlbHBlcnMiLCJfZml4ZWQiLCJfc2xpY2VkVG9BcnJheSIsImZvcm1hdCIsInJlc3VsdCJdLCJzb3VyY2VSb290IjoiIn0= -------------------------------------------------------------------------------- /lib/jdate.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define("JDate", [], factory); 6 | else if(typeof exports === 'object') 7 | exports["JDate"] = factory(); 8 | else 9 | root["JDate"] = factory(); 10 | })(this, () => { 11 | return /******/ (() => { // webpackBootstrap 12 | /******/ var __webpack_modules__ = ({ 13 | 14 | /***/ "./src/constants.js": 15 | /*!**************************!*\ 16 | !*** ./src/constants.js ***! 17 | \**************************/ 18 | /***/ ((module) => { 19 | 20 | module.exports = { 21 | MONTH_NAMES: ['فروردین', 'اردیبهشت', 'خرداد', 'تیر', 'امرداد', 'شهریور', 'مهر', 'آبان', 'آذر', 'دی', 'بهمن', 'اسفند'], 22 | ABBR_DAYS: ['۱ش', '۲ش', '۳ش', '۴ش', '۵ش', 'ج', 'ش'], 23 | DAYS_NAMES: ['یکشنبه', 'دوشنبه', 'سه‌شنبه', 'چهارشنبه', 'پنج‌شنبه', 'جمعه', 'شنبه'], 24 | GREGORIAN_EPOCH: 1, 25 | GREGORIAN_TO_FIXED_OFFSET: 719528, 26 | PERSIAN_EPOCH: 226896, 27 | PERSIAN_CYCLE_DAYS: 12053, 28 | NON_LEAP_CORRECTION: [1502, 1601, 1634, 1667, 1700, 1733, 1766, 1799, 1832, 1865, 1898, 1931, 1964, 1997, 2030, 2059, 2063, 2096, 2129, 2158, 2162, 2191, 2195, 2224, 2228, 2257, 2261, 2290, 2294, 2323, 2327, 2356, 2360, 2389, 2393, 2422, 2426, 2455, 2459, 2488, 2492, 2521, 2525, 2554, 2558, 2587, 2591, 2620, 2624, 2653, 2657, 2686, 2690, 2719, 2723, 2748, 2752, 2756, 2781, 2785, 2789, 2818, 2822, 2847, 2851, 2855, 2880, 2884, 2888, 2913, 2917, 2921, 2946, 2950, 2954, 2979, 2983, 2987] 29 | }; 30 | 31 | /***/ }), 32 | 33 | /***/ "./src/converter.js": 34 | /*!**************************!*\ 35 | !*** ./src/converter.js ***! 36 | \**************************/ 37 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 38 | 39 | "use strict"; 40 | __webpack_require__.r(__webpack_exports__); 41 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 42 | /* harmony export */ "default": () => (/* binding */ Converter) 43 | /* harmony export */ }); 44 | /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./helpers */ "./src/helpers.js"); 45 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constants */ "./src/constants.js"); 46 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_constants__WEBPACK_IMPORTED_MODULE_1__); 47 | function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 48 | function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 49 | function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 50 | function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 51 | function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 52 | function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 53 | 54 | 55 | var Converter = /*#__PURE__*/function () { 56 | function Converter() { 57 | _classCallCheck(this, Converter); 58 | } 59 | return _createClass(Converter, null, [{ 60 | key: "gregorianToFixed", 61 | value: function gregorianToFixed(year, month, day) { 62 | var result = _constants__WEBPACK_IMPORTED_MODULE_1__.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) 63 | // eslint-disable-next-line no-nested-ternary 64 | + (month <= 2 ? 0 : Converter.leapGregorian(year) ? -1 : -2) + day; 65 | return result; 66 | } 67 | }, { 68 | key: "gregorianYearFromFixed", 69 | value: function gregorianYearFromFixed(date) { 70 | var d0 = date - _constants__WEBPACK_IMPORTED_MODULE_1__.GREGORIAN_EPOCH; 71 | var n400 = Math.floor(d0 / 146097); 72 | var d1 = d0 % 146097; 73 | var n100 = Math.floor(d1 / 36524); 74 | var d2 = d1 % 36524; 75 | var n4 = Math.floor(d2 / 1461); 76 | var d3 = d2 % 1461; 77 | var n1 = Math.floor(d3 / 365); 78 | var year = 400 * n400 + 100 * n100 + 4 * n4 + n1; 79 | if (n100 === 4 || n1 === 4) { 80 | return year; 81 | } 82 | return year + 1; 83 | } 84 | }, { 85 | key: "gregorianNewYear", 86 | value: function gregorianNewYear(year) { 87 | return Converter.gregorianToFixed(year, 1, 1); 88 | } 89 | }, { 90 | key: "fixedToGregorian", 91 | value: function fixedToGregorian(date) { 92 | var year = Converter.gregorianYearFromFixed(date); 93 | var priorDays = date - Converter.gregorianNewYear(year); 94 | var correction; 95 | if (date < Converter.gregorianToFixed([year, 3, 1])) { 96 | correction = 0; 97 | } else if (Converter.leapGregorian(year)) { 98 | correction = 1; 99 | } else { 100 | correction = 2; 101 | } 102 | var month = Math.floor((12 * (priorDays + correction) + 373) / 367); 103 | var day = date - Converter.gregorianToFixed(year, month, 1) + 1; 104 | return [year, month, day]; 105 | } 106 | }, { 107 | key: "jalaliToFixed", 108 | value: function jalaliToFixed(year, month, day) { 109 | var newYear = _constants__WEBPACK_IMPORTED_MODULE_1__.PERSIAN_EPOCH - 1 + 365 * (year - 1) + Math.floor((8 * year + 21) / 33); 110 | if (_constants__WEBPACK_IMPORTED_MODULE_1__.NON_LEAP_CORRECTION.includes(year - 1)) { 111 | newYear -= 1; 112 | } 113 | return newYear - 1 + (month <= 7 ? 31 * (month - 1) : 30 * (month - 1) + 6) + day; 114 | } 115 | }, { 116 | key: "fixedToJalali", 117 | value: function fixedToJalali(fixedDate) { 118 | var daysSinceEpoch = fixedDate - Converter.jalaliToFixed(1, 1, 1); 119 | var year = 1 + Math.floor((33 * daysSinceEpoch + 3) / _constants__WEBPACK_IMPORTED_MODULE_1__.PERSIAN_CYCLE_DAYS); 120 | var dayOfYear = fixedDate - Converter.jalaliToFixed(year, 1, 1) + 1; 121 | if (dayOfYear === 366 && _constants__WEBPACK_IMPORTED_MODULE_1__.NON_LEAP_CORRECTION.includes(year)) { 122 | year += 1; 123 | dayOfYear = 1; 124 | } 125 | var month = dayOfYear <= 186 ? (0,_helpers__WEBPACK_IMPORTED_MODULE_0__.divCeil)(dayOfYear, 31) : (0,_helpers__WEBPACK_IMPORTED_MODULE_0__.divCeil)(dayOfYear - 6, 30); 126 | var day = fixedDate - Converter.jalaliToFixed(year, month, 1) + 1; 127 | return [year, month, day]; 128 | } 129 | }, { 130 | key: "leapPersian", 131 | value: function leapPersian(jdate) { 132 | if (_constants__WEBPACK_IMPORTED_MODULE_1__.NON_LEAP_CORRECTION.includes(jdate)) { 133 | return false; 134 | } 135 | if (_constants__WEBPACK_IMPORTED_MODULE_1__.NON_LEAP_CORRECTION.includes(jdate - 1)) { 136 | return true; 137 | } 138 | return (25 * jdate + 11) % 33 < 8; 139 | } 140 | }, { 141 | key: "leapGregorian", 142 | value: function leapGregorian(year) { 143 | return year % 4 === 0 && ![100, 200, 300].includes(year % 400); 144 | } 145 | }]); 146 | }(); 147 | 148 | 149 | /***/ }), 150 | 151 | /***/ "./src/helpers.js": 152 | /*!************************!*\ 153 | !*** ./src/helpers.js ***! 154 | \************************/ 155 | /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 156 | 157 | "use strict"; 158 | __webpack_require__.r(__webpack_exports__); 159 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 160 | /* harmony export */ divCeil: () => (/* binding */ divCeil), 161 | /* harmony export */ fixMonth: () => (/* binding */ fixMonth), 162 | /* harmony export */ replaceDay: () => (/* binding */ replaceDay), 163 | /* harmony export */ replaceMonth: () => (/* binding */ replaceMonth), 164 | /* harmony export */ replaceYear: () => (/* binding */ replaceYear), 165 | /* harmony export */ zeroLeading: () => (/* binding */ zeroLeading) 166 | /* harmony export */ }); 167 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./constants */ "./src/constants.js"); 168 | /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_constants__WEBPACK_IMPORTED_MODULE_0__); 169 | /* eslint-disable no-unused-vars */ 170 | 171 | 172 | function divCeil(a, b) { 173 | return Math.floor((a + b - 1) / b); 174 | } 175 | function fixMonth(year, month) { 176 | if (month > 12 || month <= 0) { 177 | var yearDiff = Math.floor((month - 1) / 12); 178 | var newYear = year - yearDiff; 179 | var newMonth = month - yearDiff * 12; 180 | return [newYear, newMonth]; 181 | } 182 | return [year, month]; 183 | } 184 | function zeroLeading(str) { 185 | if (str && str.length === 1) { 186 | return "0".concat(str); 187 | } 188 | return str; 189 | } 190 | function replaceYear(str, date) { 191 | var match = str.match(/[yY]+/); 192 | if (!match) { 193 | return str; 194 | } 195 | switch (match[0]) { 196 | case 'YYYY': 197 | case 'YYY': 198 | { 199 | var value = replaceYear(str.replace(match, date.getFullYear()), date); 200 | return value; 201 | } 202 | case 'YY': 203 | { 204 | var _value = replaceYear(str.replace(match, String(date.getFullYear()).slice(2)), date); 205 | return _value; 206 | } 207 | default: 208 | { 209 | return str; 210 | } 211 | } 212 | } 213 | function replaceMonth(str, date) { 214 | var match = str.match(/[mM]+/); 215 | if (!match) { 216 | return str; 217 | } 218 | switch (match[0]) { 219 | case 'M': 220 | { 221 | var value = replaceMonth(str.replace(match, date.getMonth()), date); 222 | return value; 223 | } 224 | case 'MM': 225 | { 226 | var zeroLeadingMonth = zeroLeading(date.getMonth().toString()); 227 | var _value2 = replaceMonth(str.replace(match, zeroLeadingMonth), date); 228 | return _value2; 229 | } 230 | case 'MMM': 231 | case 'MMMM': 232 | { 233 | var _value3 = replaceMonth(str.replace(match, _constants__WEBPACK_IMPORTED_MODULE_0__.MONTH_NAMES[date.getMonth() - 1]), date); 234 | return _value3; 235 | } 236 | default: 237 | { 238 | return str; 239 | } 240 | } 241 | } 242 | function replaceDay(str, date) { 243 | var match = str.match(/[dD]+/); 244 | if (!match) { 245 | return str; 246 | } 247 | switch (match[0]) { 248 | case 'D': 249 | { 250 | var value = replaceDay(str.replace(match, date.getDate()), date); 251 | return value; 252 | } 253 | case 'DD': 254 | { 255 | var zeroLeadingDate = zeroLeading(date.getDate().toString()); 256 | var _value4 = replaceDay(str.replace(match, zeroLeadingDate), date); 257 | return _value4; 258 | } 259 | case 'd': 260 | case 'dd': 261 | { 262 | var _value5 = replaceDay(str.replace(match, _constants__WEBPACK_IMPORTED_MODULE_0__.ABBR_DAYS[date.getDay()]), date); 263 | return _value5; 264 | } 265 | case 'ddd': 266 | case 'dddd': 267 | { 268 | var _value6 = replaceDay(str.replace(match, _constants__WEBPACK_IMPORTED_MODULE_0__.DAYS_NAMES[date.getDay()]), date); 269 | return _value6; 270 | } 271 | default: 272 | { 273 | return str; 274 | } 275 | } 276 | } 277 | 278 | /***/ }) 279 | 280 | /******/ }); 281 | /************************************************************************/ 282 | /******/ // The module cache 283 | /******/ var __webpack_module_cache__ = {}; 284 | /******/ 285 | /******/ // The require function 286 | /******/ function __webpack_require__(moduleId) { 287 | /******/ // Check if module is in cache 288 | /******/ var cachedModule = __webpack_module_cache__[moduleId]; 289 | /******/ if (cachedModule !== undefined) { 290 | /******/ return cachedModule.exports; 291 | /******/ } 292 | /******/ // Create a new module (and put it into the cache) 293 | /******/ var module = __webpack_module_cache__[moduleId] = { 294 | /******/ // no module.id needed 295 | /******/ // no module.loaded needed 296 | /******/ exports: {} 297 | /******/ }; 298 | /******/ 299 | /******/ // Execute the module function 300 | /******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 301 | /******/ 302 | /******/ // Return the exports of the module 303 | /******/ return module.exports; 304 | /******/ } 305 | /******/ 306 | /************************************************************************/ 307 | /******/ /* webpack/runtime/compat get default export */ 308 | /******/ (() => { 309 | /******/ // getDefaultExport function for compatibility with non-harmony modules 310 | /******/ __webpack_require__.n = (module) => { 311 | /******/ var getter = module && module.__esModule ? 312 | /******/ () => (module['default']) : 313 | /******/ () => (module); 314 | /******/ __webpack_require__.d(getter, { a: getter }); 315 | /******/ return getter; 316 | /******/ }; 317 | /******/ })(); 318 | /******/ 319 | /******/ /* webpack/runtime/define property getters */ 320 | /******/ (() => { 321 | /******/ // define getter functions for harmony exports 322 | /******/ __webpack_require__.d = (exports, definition) => { 323 | /******/ for(var key in definition) { 324 | /******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 325 | /******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 326 | /******/ } 327 | /******/ } 328 | /******/ }; 329 | /******/ })(); 330 | /******/ 331 | /******/ /* webpack/runtime/hasOwnProperty shorthand */ 332 | /******/ (() => { 333 | /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 334 | /******/ })(); 335 | /******/ 336 | /******/ /* webpack/runtime/make namespace object */ 337 | /******/ (() => { 338 | /******/ // define __esModule on exports 339 | /******/ __webpack_require__.r = (exports) => { 340 | /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 341 | /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 342 | /******/ } 343 | /******/ Object.defineProperty(exports, '__esModule', { value: true }); 344 | /******/ }; 345 | /******/ })(); 346 | /******/ 347 | /************************************************************************/ 348 | var __webpack_exports__ = {}; 349 | // This entry need to be wrapped in an IIFE because it need to be in strict mode. 350 | (() => { 351 | "use strict"; 352 | /*!**********************!*\ 353 | !*** ./src/jdate.js ***! 354 | \**********************/ 355 | __webpack_require__.r(__webpack_exports__); 356 | /* harmony export */ __webpack_require__.d(__webpack_exports__, { 357 | /* harmony export */ "default": () => (/* binding */ JDate) 358 | /* harmony export */ }); 359 | /* harmony import */ var _converter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./converter */ "./src/converter.js"); 360 | /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./helpers */ "./src/helpers.js"); 361 | function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } 362 | function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } 363 | function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } 364 | function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } 365 | function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } 366 | function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } 367 | function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } 368 | function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); } 369 | function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } } 370 | function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; } 371 | function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } 372 | function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } 373 | /* 374 | * https://github.com/arashm/JDate 375 | * @author: Arash Mousavi 376 | */ 377 | 378 | 379 | 380 | var JDate = /*#__PURE__*/function () { 381 | function JDate() { 382 | _classCallCheck(this, JDate); 383 | for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { 384 | args[_key] = arguments[_key]; 385 | } 386 | if (Array.isArray(args[0]) || args[0] instanceof Date) { 387 | this.input = args[0]; 388 | } else if (args.length === 3) { 389 | this.input = args; 390 | } else if (!args.length) { 391 | this.input = new Date(); 392 | } else { 393 | throw new Error('Unexpected input'); 394 | } 395 | if (Array.isArray(this.input)) { 396 | this.date = this.input.map(function (num) { 397 | return parseInt(num, 10); 398 | }); 399 | this._d = this.toGregorian(); 400 | } else if (this.input instanceof Date) { 401 | this._d = this.input; 402 | this.date = JDate.toJalali(this.input); 403 | } 404 | } 405 | 406 | /* 407 | * Coverts a Gregorian date to Jalali date 408 | * 409 | * @params {Date} date 410 | * @return {Array} 411 | */ 412 | return _createClass(JDate, [{ 413 | key: "toGregorian", 414 | value: 415 | /* 416 | * Converts JDate date to Gregorian 417 | */ 418 | function toGregorian() { 419 | return JDate.toGregorian(this.date[0], this.date[1], this.date[2]); 420 | } 421 | 422 | /* 423 | * Shows Jalali's full year, ex: 1393 424 | * 425 | * @return {Integer} 426 | */ 427 | }, { 428 | key: "getFullYear", 429 | value: function getFullYear() { 430 | return this.date[0]; 431 | } 432 | 433 | /* 434 | * Sets the Jalali full year 435 | * 436 | * @params {Number} year 437 | * @return {JDate} 438 | */ 439 | }, { 440 | key: "setFullYear", 441 | value: function setFullYear(year) { 442 | this.date[0] = parseInt(year, 10); 443 | this.input = this.toGregorian(); 444 | return this; 445 | } 446 | 447 | /* 448 | * Shows Jalali month number. 449 | * 450 | * @return {Number} Jalali month number 451 | */ 452 | }, { 453 | key: "getMonth", 454 | value: function getMonth() { 455 | return this.date[1]; 456 | } 457 | 458 | /* 459 | * Sets the Jalali month number. An integer between 0 and 11 460 | * 461 | * @params {Number} month 462 | * @returns {JDate} 463 | */ 464 | }, { 465 | key: "setMonth", 466 | value: function setMonth(month) { 467 | var fixed = _helpers__WEBPACK_IMPORTED_MODULE_1__.fixMonth(this.getFullYear(), parseInt(month, 10)); 468 | var _fixed = _slicedToArray(fixed, 2); 469 | this.date[0] = _fixed[0]; 470 | this.date[1] = _fixed[1]; 471 | this.input = this.toGregorian(); 472 | return this; 473 | } 474 | 475 | /* 476 | * Shows Jalali day number. A number between 0 to 31 477 | * 478 | * @return {Number} Jalali day number 479 | */ 480 | }, { 481 | key: "getDate", 482 | value: function getDate() { 483 | return this.date[2]; 484 | } 485 | 486 | /* 487 | * Sets Jalali day number. A number between 0 to 31 488 | * 489 | * @params {Number} date 490 | * @return {JDate} 491 | */ 492 | }, { 493 | key: "setDate", 494 | value: function setDate(date) { 495 | this.date[2] = parseInt(date, 10); 496 | this.input = this.toGregorian(); 497 | return this; 498 | } 499 | 500 | /* 501 | * Returns the day of the week for the specified date. A number between 0 to 6 502 | * 503 | * @returns {Number} 504 | */ 505 | }, { 506 | key: "getDay", 507 | value: function getDay() { 508 | return this._d.getDay(); 509 | } 510 | 511 | /* 512 | * Returns a formated output of current date 513 | * 514 | * @params {String} format 515 | * @return {String} 516 | */ 517 | }, { 518 | key: "format", 519 | value: function format(_format) { 520 | var result = _helpers__WEBPACK_IMPORTED_MODULE_1__.replaceYear(_format, this); 521 | result = _helpers__WEBPACK_IMPORTED_MODULE_1__.replaceMonth(result, this); 522 | result = _helpers__WEBPACK_IMPORTED_MODULE_1__.replaceDay(result, this); 523 | return result; 524 | } 525 | }], [{ 526 | key: "toJalali", 527 | value: function toJalali(date) { 528 | var fixedDate = _converter__WEBPACK_IMPORTED_MODULE_0__["default"].gregorianToFixed(date.getFullYear(), date.getMonth() + 1, date.getDate()); 529 | var jdate = _converter__WEBPACK_IMPORTED_MODULE_0__["default"].fixedToJalali(fixedDate); 530 | return jdate; 531 | } 532 | 533 | // eslint-disable-next-line camelcase 534 | }, { 535 | key: "to_jalali", 536 | value: function to_jalali(date) { 537 | return JDate.toJalali(date); 538 | } 539 | 540 | /* 541 | * converts a Jalali date to Gregorian 542 | * 543 | * @params {Number} year 544 | * @params {Number} month 545 | * @params {Number} day 546 | * @return {Date} 547 | */ 548 | }, { 549 | key: "toGregorian", 550 | value: function toGregorian(year, month, day) { 551 | var gdate = _converter__WEBPACK_IMPORTED_MODULE_0__["default"].fixedToGregorian(_converter__WEBPACK_IMPORTED_MODULE_0__["default"].jalaliToFixed(year, month, day)); 552 | return new Date(+gdate[0], +gdate[1] - 1, +gdate[2]); 553 | } 554 | 555 | // eslint-disable-next-line camelcase 556 | }, { 557 | key: "to_gregorian", 558 | value: function to_gregorian(year, month, day) { 559 | return JDate.toGregorian(year, month, day); 560 | } 561 | 562 | /* 563 | * Checks if a given year is a leap year or not 564 | * 565 | * @params {Number} year 566 | * @return {Boolean} 567 | */ 568 | }, { 569 | key: "isLeapYear", 570 | value: function isLeapYear(year) { 571 | return _converter__WEBPACK_IMPORTED_MODULE_0__["default"].leapPersian(year); 572 | } 573 | 574 | /* 575 | * Returns month length. 576 | * 577 | * @params {Number} year 578 | * @params {Number} month zero based 579 | * @return {Number} 580 | */ 581 | }, { 582 | key: "daysInMonth", 583 | value: function daysInMonth(year, month) { 584 | var calcedYear = year - Math.floor(month / 12); 585 | var calcedMonth = month - Math.floor(month / 12) * 12; 586 | if (calcedMonth < 0) { 587 | calcedMonth += 12; 588 | calcedYear -= 1; 589 | } else if (calcedMonth === 0) { 590 | calcedMonth = 12; 591 | } 592 | if (calcedMonth < 6) { 593 | return 31; 594 | } 595 | if (calcedMonth < 11) { 596 | return 30; 597 | } 598 | if (JDate.isLeapYear(calcedYear)) { 599 | return 30; 600 | } 601 | return 29; 602 | } 603 | }]); 604 | }(); 605 | 606 | })(); 607 | 608 | __webpack_exports__ = __webpack_exports__["default"]; 609 | /******/ return __webpack_exports__; 610 | /******/ })() 611 | ; 612 | }); 613 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,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O0lBQUU7O0lBRXBGO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtFQUxFO0lBQUFMLEdBQUE7SUFBQUMsS0FBQSxFQU1BLFNBQUFtRixXQUFrQmpGLElBQUksRUFBRTtNQUN0QixPQUFPTixrREFBUyxDQUFDa0MsV0FBVyxDQUFDNUIsSUFBSSxDQUFDO0lBQ3BDOztJQUVBO0FBQ0Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBTkU7SUFBQUgsR0FBQTtJQUFBQyxLQUFBLEVBT0EsU0FBQW9GLFlBQW1CbEYsSUFBSSxFQUFFQyxLQUFLLEVBQUU7TUFDOUIsSUFBSWtGLFVBQVUsR0FBR25GLElBQUksR0FBR0ksSUFBSSxDQUFDQyxLQUFLLENBQUNKLEtBQUssR0FBRyxFQUFFLENBQUM7TUFDOUMsSUFBSW1GLFdBQVcsR0FBR25GLEtBQUssR0FBSUcsSUFBSSxDQUFDQyxLQUFLLENBQUNKLEtBQUssR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFHO01BRXZELElBQUltRixXQUFXLEdBQUcsQ0FBQyxFQUFFO1FBQ25CQSxXQUFXLElBQUksRUFBRTtRQUNqQkQsVUFBVSxJQUFJLENBQUM7TUFDakIsQ0FBQyxNQUFNLElBQUlDLFdBQVcsS0FBSyxDQUFDLEVBQUU7UUFDNUJBLFdBQVcsR0FBRyxFQUFFO01BQ2xCO01BRUEsSUFBSUEsV0FBVyxHQUFHLENBQUMsRUFBRTtRQUNuQixPQUFPLEVBQUU7TUFDWDtNQUFFLElBQUlBLFdBQVcsR0FBRyxFQUFFLEVBQUU7UUFDdEIsT0FBTyxFQUFFO01BQ1g7TUFBRSxJQUFJN0IsS0FBSyxDQUFDMEIsVUFBVSxDQUFDRSxVQUFVLENBQUMsRUFBRTtRQUNsQyxPQUFPLEVBQUU7TUFDWDtNQUNBLE9BQU8sRUFBRTtJQUNYO0VBQUM7QUFBQSIsInNvdXJjZXMiOlsid2VicGFjazovL0pEYXRlL3dlYnBhY2svdW5pdmVyc2FsTW9kdWxlRGVmaW5pdGlvbiIsIndlYnBhY2s6Ly9KRGF0ZS8uL3NyYy9jb25zdGFudHMuanMiLCJ3ZWJwYWNrOi8vSkRhdGUvLi9zcmMvY29udmVydGVyLmpzIiwid2VicGFjazovL0pEYXRlLy4vc3JjL2hlbHBlcnMuanMiLCJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay9ib290c3RyYXAiLCJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay9ydW50aW1lL2NvbXBhdCBnZXQgZGVmYXVsdCBleHBvcnQiLCJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay9ydW50aW1lL2RlZmluZSBwcm9wZXJ0eSBnZXR0ZXJzIiwid2VicGFjazovL0pEYXRlL3dlYnBhY2svcnVudGltZS9oYXNPd25Qcm9wZXJ0eSBzaG9ydGhhbmQiLCJ3ZWJwYWNrOi8vSkRhdGUvd2VicGFjay9ydW50aW1lL21ha2UgbmFtZXNwYWNlIG9iamVjdCIsIndlYnBhY2s6Ly9KRGF0ZS8uL3NyYy9qZGF0ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gd2VicGFja1VuaXZlcnNhbE1vZHVsZURlZmluaXRpb24ocm9vdCwgZmFjdG9yeSkge1xuXHRpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSA9PT0gJ29iamVjdCcpXG5cdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCk7XG5cdGVsc2UgaWYodHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kKVxuXHRcdGRlZmluZShcIkpEYXRlXCIsIFtdLCBmYWN0b3J5KTtcblx0ZWxzZSBpZih0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcpXG5cdFx0ZXhwb3J0c1tcIkpEYXRlXCJdID0gZmFjdG9yeSgpO1xuXHRlbHNlXG5cdFx0cm9vdFtcIkpEYXRlXCJdID0gZmFjdG9yeSgpO1xufSkodGhpcywgKCkgPT4ge1xucmV0dXJuICIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBNT05USF9OQU1FUzogWyfZgdix2YjYsdiv24zZhicsICfYp9ix2K/bjNio2YfYtNiqJywgJ9iu2LHYr9in2K8nLCAn2KrbjNixJywgJ9in2YXYsdiv2KfYrycsICfYtNmH2LHbjNmI2LEnLCAn2YXZh9ixJywgJ9ii2KjYp9mGJywgJ9ii2LDYsScsICfYr9uMJywgJ9io2YfZhdmGJywgJ9in2LPZgdmG2K8nXSxcbiAgQUJCUl9EQVlTOiBbJ9ux2LQnLCAn27LYtCcsICfbs9i0JywgJ9u02LQnLCAn27XYtCcsICfYrCcsICfYtCddLFxuICBEQVlTX05BTUVTOiBbJ9uM2qnYtNmG2KjZhycsICfYr9mI2LTZhtio2YcnLCAn2LPZh+KAjNi02YbYqNmHJywgJ9qG2YfYp9ix2LTZhtio2YcnLCAn2b7Zhtis4oCM2LTZhtio2YcnLCAn2KzZhdi52YcnLCAn2LTZhtio2YcnXSxcbiAgR1JFR09SSUFOX0VQT0NIOiAxLFxuICBHUkVHT1JJQU5fVE9fRklYRURfT0ZGU0VUOiA3MTk1MjgsXG4gIFBFUlNJQU5fRVBPQ0g6IDIyNjg5NixcbiAgUEVSU0lBTl9DWUNMRV9EQVlTOiAxMjA1MyxcbiAgTk9OX0xFQVBfQ09SUkVDVElPTjogW1xuICAgIDE1MDIsXG4gICAgMTYwMSwgMTYzNCwgMTY2NyxcbiAgICAxNzAwLCAxNzMzLCAxNzY2LCAxNzk5LFxuICAgIDE4MzIsIDE4NjUsIDE4OTgsXG4gICAgMTkzMSwgMTk2NCwgMTk5NyxcbiAgICAyMDMwLCAyMDU5LCAyMDYzLCAyMDk2LFxuICAgIDIxMjksIDIxNTgsIDIxNjIsIDIxOTEsIDIxOTUsXG4gICAgMjIyNCwgMjIyOCwgMjI1NywgMjI2MSwgMjI5MCwgMjI5NCxcbiAgICAyMzIzLCAyMzI3LCAyMzU2LCAyMzYwLCAyMzg5LCAyMzkzLFxuICAgIDI0MjIsIDI0MjYsIDI0NTUsIDI0NTksIDI0ODgsIDI0OTIsXG4gICAgMjUyMSwgMjUyNSwgMjU1NCwgMjU1OCwgMjU4NywgMjU5MSxcbiAgICAyNjIwLCAyNjI0LCAyNjUzLCAyNjU3LCAyNjg2LCAyNjkwLFxuICAgIDI3MTksIDI3MjMsIDI3NDgsIDI3NTIsIDI3NTYsIDI3ODEsIDI3ODUsIDI3ODksXG4gICAgMjgxOCwgMjgyMiwgMjg0NywgMjg1MSwgMjg1NSwgMjg4MCwgMjg4NCwgMjg4OCxcbiAgICAyOTEzLCAyOTE3LCAyOTIxLCAyOTQ2LCAyOTUwLCAyOTU0LCAyOTc5LCAyOTgzLCAyOTg3XG4gIF1cbn07XG4iLCJpbXBvcnQgeyBkaXZDZWlsIH0gZnJvbSAnLi9oZWxwZXJzJztcbmltcG9ydCB7XG4gIEdSRUdPUklBTl9FUE9DSCwgUEVSU0lBTl9FUE9DSCwgTk9OX0xFQVBfQ09SUkVDVElPTiwgUEVSU0lBTl9DWUNMRV9EQVlTXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgQ29udmVydGVyIHtcbiAgc3RhdGljIGdyZWdvcmlhblRvRml4ZWQoeWVhciwgbW9udGgsIGRheSkge1xuICAgIGNvbnN0IHJlc3VsdCA9IEdSRUdPUklBTl9FUE9DSCAtIDFcbiAgICAgICAgKyAzNjUgKiAoeWVhciAtIDEpXG4gICAgICAgICsgTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNClcbiAgICAgICAgLSBNYXRoLmZsb29yKCh5ZWFyIC0gMSkgLyAxMDApXG4gICAgICAgICsgTWF0aC5mbG9vcigoeWVhciAtIDEpIC8gNDAwKVxuICAgICAgICArIE1hdGguZmxvb3IoKDM2NyAqIG1vbnRoIC0gMzYyKSAvIDEyKVxuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tbmVzdGVkLXRlcm5hcnlcbiAgICAgICAgKyAobW9udGggPD0gMiA/IDAgOiBDb252ZXJ0ZXIubGVhcEdyZWdvcmlhbih5ZWFyKSA/IC0xIDogLTIpXG4gICAgICAgICsgZGF5O1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBzdGF0aWMgZ3JlZ29yaWFuWWVhckZyb21GaXhlZChkYXRlKSB7XG4gICAgY29uc3QgZDAgPSBkYXRlIC0gR1JFR09SSUFOX0VQT0NIO1xuICAgIGNvbnN0IG40MDAgPSBNYXRoLmZsb29yKGQwIC8gMTQ2MDk3KTtcbiAgICBjb25zdCBkMSA9IGQwICUgMTQ2MDk3O1xuICAgIGNvbnN0IG4xMDAgPSBNYXRoLmZsb29yKGQxIC8gMzY1MjQpO1xuICAgIGNvbnN0IGQyID0gZDEgJSAzNjUyNDtcbiAgICBjb25zdCBuNCA9IE1hdGguZmxvb3IoZDIgLyAxNDYxKTtcbiAgICBjb25zdCBkMyA9IGQyICUgMTQ2MTtcbiAgICBjb25zdCBuMSA9IE1hdGguZmxvb3IoZDMgLyAzNjUpO1xuICAgIGNvbnN0IHllYXIgPSA0MDAgKiBuNDAwICsgMTAwICogbjEwMCArIDQgKiBuNCArIG4xO1xuICAgIGlmIChuMTAwID09PSA0IHx8IG4xID09PSA0KSB7XG4gICAgICByZXR1cm4geWVhcjtcbiAgICB9XG4gICAgcmV0dXJuIHllYXIgKyAxO1xuICB9XG5cbiAgc3RhdGljIGdyZWdvcmlhbk5ld1llYXIoeWVhcikge1xuICAgIHJldHVybiBDb252ZXJ0ZXIuZ3JlZ29yaWFuVG9GaXhlZCh5ZWFyLCAxLCAxKTtcbiAgfVxuXG4gIHN0YXRpYyBmaXhlZFRvR3JlZ29yaWFuKGRhdGUpIHtcbiAgICBjb25zdCB5ZWFyID0gQ29udmVydGVyLmdyZWdvcmlhblllYXJGcm9tRml4ZWQoZGF0ZSk7XG4gICAgY29uc3QgcHJpb3JEYXlzID0gZGF0ZSAtIENvbnZlcnRlci5ncmVnb3JpYW5OZXdZZWFyKHllYXIpO1xuICAgIGxldCBjb3JyZWN0aW9uO1xuICAgIGlmIChkYXRlIDwgQ29udmVydGVyLmdyZWdvcmlhblRvRml4ZWQoW3llYXIsIDMsIDFdKSkge1xuICAgICAgY29ycmVjdGlvbiA9IDA7XG4gICAgfSBlbHNlIGlmIChDb252ZXJ0ZXIubGVhcEdyZWdvcmlhbih5ZWFyKSkge1xuICAgICAgY29ycmVjdGlvbiA9IDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvcnJlY3Rpb24gPSAyO1xuICAgIH1cbiAgICBjb25zdCBtb250aCA9IE1hdGguZmxvb3IoKDEyICogKHByaW9yRGF5cyArIGNvcnJlY3Rpb24pICsgMzczKSAvIDM2Nyk7XG4gICAgY29uc3QgZGF5ID0gZGF0ZSAtIENvbnZlcnRlci5ncmVnb3JpYW5Ub0ZpeGVkKHllYXIsIG1vbnRoLCAxKSArIDE7XG4gICAgcmV0dXJuIFt5ZWFyLCBtb250aCwgZGF5XTtcbiAgfVxuXG4gIHN0YXRpYyBqYWxhbGlUb0ZpeGVkKHllYXIsIG1vbnRoLCBkYXkpIHtcbiAgICBsZXQgbmV3WWVhciA9IFBFUlNJQU5fRVBPQ0ggLSAxICsgMzY1ICogKHllYXIgLSAxKSArIE1hdGguZmxvb3IoKDggKiB5ZWFyICsgMjEpIC8gMzMpO1xuICAgIGlmIChOT05fTEVBUF9DT1JSRUNUSU9OLmluY2x1ZGVzKHllYXIgLSAxKSkge1xuICAgICAgbmV3WWVhciAtPSAxO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgbmV3WWVhciAtIDFcbiAgICAgICAgKyAoKG1vbnRoIDw9IDcpID8gMzEgKiAobW9udGggLSAxKSA6IDMwICogKG1vbnRoIC0gMSkgKyA2KVxuICAgICAgICArIGRheVxuICAgICk7XG4gIH1cblxuICBzdGF0aWMgZml4ZWRUb0phbGFsaShmaXhlZERhdGUpIHtcbiAgICBjb25zdCBkYXlzU2luY2VFcG9jaCA9IGZpeGVkRGF0ZSAtIENvbnZlcnRlci5qYWxhbGlUb0ZpeGVkKDEsIDEsIDEpO1xuICAgIGxldCB5ZWFyID0gMSArIE1hdGguZmxvb3IoKDMzICogZGF5c1NpbmNlRXBvY2ggKyAzKSAvIFBFUlNJQU5fQ1lDTEVfREFZUyk7XG4gICAgbGV0IGRheU9mWWVhciA9IGZpeGVkRGF0ZSAtIENvbnZlcnRlci5qYWxhbGlUb0ZpeGVkKHllYXIsIDEsIDEpICsgMTtcblxuICAgIGlmIChkYXlPZlllYXIgPT09IDM2NiAmJiBOT05fTEVBUF9DT1JSRUNUSU9OLmluY2x1ZGVzKHllYXIpKSB7XG4gICAgICB5ZWFyICs9IDE7XG4gICAgICBkYXlPZlllYXIgPSAxO1xuICAgIH1cblxuICAgIGNvbnN0IG1vbnRoID0gKGRheU9mWWVhciA8PSAxODYpID8gZGl2Q2VpbChkYXlPZlllYXIsIDMxKSA6IGRpdkNlaWwoZGF5T2ZZZWFyIC0gNiwgMzApO1xuICAgIGNvbnN0IGRheSA9IGZpeGVkRGF0ZSAtIENvbnZlcnRlci5qYWxhbGlUb0ZpeGVkKHllYXIsIG1vbnRoLCAxKSArIDE7XG5cbiAgICByZXR1cm4gW3llYXIsIG1vbnRoLCBkYXldO1xuICB9XG5cbiAgc3RhdGljIGxlYXBQZXJzaWFuKGpkYXRlKSB7XG4gICAgaWYgKE5PTl9MRUFQX0NPUlJFQ1RJT04uaW5jbHVkZXMoamRhdGUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSBpZiAoTk9OX0xFQVBfQ09SUkVDVElPTi5pbmNsdWRlcyhqZGF0ZSAtIDEpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuICgyNSAqIGpkYXRlICsgMTEpICUgMzMgPCA4O1xuICB9XG5cbiAgc3RhdGljIGxlYXBHcmVnb3JpYW4oeWVhcikge1xuICAgIHJldHVybiAoeWVhciAlIDQgPT09IDAgJiYgIVsxMDAsIDIwMCwgMzAwXS5pbmNsdWRlcyh5ZWFyICUgNDAwKSk7XG4gIH1cbn1cbiIsIi8qIGVzbGludC1kaXNhYmxlIG5vLXVudXNlZC12YXJzICovXG5cbmltcG9ydCB7XG4gIE1PTlRIX05BTUVTLFxuICBBQkJSX0RBWVMsXG4gIERBWVNfTkFNRVNcbn0gZnJvbSAnLi9jb25zdGFudHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZGl2Q2VpbChhLCBiKSB7XG4gIHJldHVybiBNYXRoLmZsb29yKChhICsgYiAtIDEpIC8gYik7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBmaXhNb250aCh5ZWFyLCBtb250aCkge1xuICBpZiAobW9udGggPiAxMiB8fCBtb250aCA8PSAwKSB7XG4gICAgY29uc3QgeWVhckRpZmYgPSBNYXRoLmZsb29yKChtb250aCAtIDEpIC8gMTIpO1xuICAgIGNvbnN0IG5ld1llYXIgPSB5ZWFyIC0geWVhckRpZmY7XG4gICAgY29uc3QgbmV3TW9udGggPSBtb250aCAtICh5ZWFyRGlmZiAqIDEyKTtcblxuICAgIHJldHVybiBbbmV3WWVhciwgbmV3TW9udGhdO1xuICB9XG5cbiAgcmV0dXJuIFt5ZWFyLCBtb250aF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB6ZXJvTGVhZGluZyhzdHIpIHtcbiAgaWYgKHN0ciAmJiBzdHIubGVuZ3RoID09PSAxKSB7IHJldHVybiBgMCR7c3RyfWA7IH1cbiAgcmV0dXJuIHN0cjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VZZWFyKHN0ciwgZGF0ZSkge1xuICBjb25zdCBtYXRjaCA9IHN0ci5tYXRjaCgvW3lZXSsvKTtcbiAgaWYgKCFtYXRjaCkgeyByZXR1cm4gc3RyOyB9XG4gIHN3aXRjaCAobWF0Y2hbMF0pIHtcbiAgICBjYXNlICdZWVlZJzpcbiAgICBjYXNlICdZWVknOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VZZWFyKHN0ci5yZXBsYWNlKG1hdGNoLCBkYXRlLmdldEZ1bGxZZWFyKCkpLCBkYXRlKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgY2FzZSAnWVknOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VZZWFyKFxuICAgICAgICBzdHIucmVwbGFjZShtYXRjaCwgU3RyaW5nKGRhdGUuZ2V0RnVsbFllYXIoKSkuc2xpY2UoMikpLCBkYXRlXG4gICAgICApO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmVwbGFjZU1vbnRoKHN0ciwgZGF0ZSkge1xuICBjb25zdCBtYXRjaCA9IHN0ci5tYXRjaCgvW21NXSsvKTtcbiAgaWYgKCFtYXRjaCkgeyByZXR1cm4gc3RyOyB9XG4gIHN3aXRjaCAobWF0Y2hbMF0pIHtcbiAgICBjYXNlICdNJzoge1xuICAgICAgY29uc3QgdmFsdWUgPSByZXBsYWNlTW9udGgoc3RyLnJlcGxhY2UobWF0Y2gsIGRhdGUuZ2V0TW9udGgoKSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdNTSc6IHtcbiAgICAgIGNvbnN0IHplcm9MZWFkaW5nTW9udGggPSB6ZXJvTGVhZGluZyhkYXRlLmdldE1vbnRoKCkudG9TdHJpbmcoKSk7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VNb250aChzdHIucmVwbGFjZShtYXRjaCwgemVyb0xlYWRpbmdNb250aCksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdNTU0nOlxuICAgIGNhc2UgJ01NTU0nOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VNb250aChcbiAgICAgICAgc3RyLnJlcGxhY2UobWF0Y2gsIE1PTlRIX05BTUVTW2RhdGUuZ2V0TW9udGgoKSAtIDFdKSwgZGF0ZVxuICAgICAgKTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9XG4gICAgZGVmYXVsdDoge1xuICAgICAgcmV0dXJuIHN0cjtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHJlcGxhY2VEYXkoc3RyLCBkYXRlKSB7XG4gIGNvbnN0IG1hdGNoID0gc3RyLm1hdGNoKC9bZERdKy8pO1xuICBpZiAoIW1hdGNoKSB7IHJldHVybiBzdHI7IH1cbiAgc3dpdGNoIChtYXRjaFswXSkge1xuICAgIGNhc2UgJ0QnOiB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VEYXkoc3RyLnJlcGxhY2UobWF0Y2gsIGRhdGUuZ2V0RGF0ZSgpKSwgZGF0ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNhc2UgJ0REJzoge1xuICAgICAgY29uc3QgemVyb0xlYWRpbmdEYXRlID0gemVyb0xlYWRpbmcoZGF0ZS5nZXREYXRlKCkudG9TdHJpbmcoKSk7XG4gICAgICBjb25zdCB2YWx1ZSA9IHJlcGxhY2VEYXkoc3RyLnJlcGxhY2UobWF0Y2gsIHplcm9MZWFkaW5nRGF0ZSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBjYXNlICdkJzpcbiAgICBjYXNlICdkZCc6IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcmVwbGFjZURheShzdHIucmVwbGFjZShtYXRjaCwgQUJCUl9EQVlTW2RhdGUuZ2V0RGF5KCldKSwgZGF0ZSk7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIGNhc2UgJ2RkZCc6XG4gICAgY2FzZSAnZGRkZCc6IHtcbiAgICAgIGNvbnN0IHZhbHVlID0gcmVwbGFjZURheShzdHIucmVwbGFjZShtYXRjaCwgREFZU19OQU1FU1tkYXRlLmdldERheSgpXSksIGRhdGUpO1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cbiAgICBkZWZhdWx0OiB7XG4gICAgICByZXR1cm4gc3RyO1xuICAgIH1cbiAgfVxufVxuIiwiLy8gVGhlIG1vZHVsZSBjYWNoZVxudmFyIF9fd2VicGFja19tb2R1bGVfY2FjaGVfXyA9IHt9O1xuXG4vLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcblx0dmFyIGNhY2hlZE1vZHVsZSA9IF9fd2VicGFja19tb2R1bGVfY2FjaGVfX1ttb2R1bGVJZF07XG5cdGlmIChjYWNoZWRNb2R1bGUgIT09IHVuZGVmaW5lZCkge1xuXHRcdHJldHVybiBjYWNoZWRNb2R1bGUuZXhwb3J0cztcblx0fVxuXHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuXHR2YXIgbW9kdWxlID0gX193ZWJwYWNrX21vZHVsZV9jYWNoZV9fW21vZHVsZUlkXSA9IHtcblx0XHQvLyBubyBtb2R1bGUuaWQgbmVlZGVkXG5cdFx0Ly8gbm8gbW9kdWxlLmxvYWRlZCBuZWVkZWRcblx0XHRleHBvcnRzOiB7fVxuXHR9O1xuXG5cdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuXHRfX3dlYnBhY2tfbW9kdWxlc19fW21vZHVsZUlkXShtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuXHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuXHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG59XG5cbiIsIi8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG5fX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSAobW9kdWxlKSA9PiB7XG5cdHZhciBnZXR0ZXIgPSBtb2R1bGUgJiYgbW9kdWxlLl9fZXNNb2R1bGUgP1xuXHRcdCgpID0+IChtb2R1bGVbJ2RlZmF1bHQnXSkgOlxuXHRcdCgpID0+IChtb2R1bGUpO1xuXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCB7IGE6IGdldHRlciB9KTtcblx0cmV0dXJuIGdldHRlcjtcbn07IiwiLy8gZGVmaW5lIGdldHRlciBmdW5jdGlvbnMgZm9yIGhhcm1vbnkgZXhwb3J0c1xuX193ZWJwYWNrX3JlcXVpcmVfXy5kID0gKGV4cG9ydHMsIGRlZmluaXRpb24pID0+IHtcblx0Zm9yKHZhciBrZXkgaW4gZGVmaW5pdGlvbikge1xuXHRcdGlmKF9fd2VicGFja19yZXF1aXJlX18ubyhkZWZpbml0aW9uLCBrZXkpICYmICFfX3dlYnBhY2tfcmVxdWlyZV9fLm8oZXhwb3J0cywga2V5KSkge1xuXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIGtleSwgeyBlbnVtZXJhYmxlOiB0cnVlLCBnZXQ6IGRlZmluaXRpb25ba2V5XSB9KTtcblx0XHR9XG5cdH1cbn07IiwiX193ZWJwYWNrX3JlcXVpcmVfXy5vID0gKG9iaiwgcHJvcCkgPT4gKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApKSIsIi8vIGRlZmluZSBfX2VzTW9kdWxlIG9uIGV4cG9ydHNcbl9fd2VicGFja19yZXF1aXJlX18uciA9IChleHBvcnRzKSA9PiB7XG5cdGlmKHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnICYmIFN5bWJvbC50b1N0cmluZ1RhZykge1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBTeW1ib2wudG9TdHJpbmdUYWcsIHsgdmFsdWU6ICdNb2R1bGUnIH0pO1xuXHR9XG5cdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG59OyIsIi8qXG4gKiBodHRwczovL2dpdGh1Yi5jb20vYXJhc2htL0pEYXRlXG4gKiBAYXV0aG9yOiBBcmFzaCBNb3VzYXZpXG4gKi9cblxuaW1wb3J0IENvbnZlcnRlciBmcm9tICcuL2NvbnZlcnRlcic7XG5pbXBvcnQgKiBhcyBoZWxwZXJzIGZyb20gJy4vaGVscGVycyc7XG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIEpEYXRlIHtcbiAgY29uc3RydWN0b3IoLi4uYXJncykge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3NbMF0pIHx8IGFyZ3NbMF0gaW5zdGFuY2VvZiBEYXRlKSB7XG4gICAgICBbdGhpcy5pbnB1dF0gPSBhcmdzO1xuICAgIH0gZWxzZSBpZiAoYXJncy5sZW5ndGggPT09IDMpIHtcbiAgICAgIHRoaXMuaW5wdXQgPSBhcmdzO1xuICAgIH0gZWxzZSBpZiAoIWFyZ3MubGVuZ3RoKSB7XG4gICAgICB0aGlzLmlucHV0ID0gbmV3IERhdGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbmV4cGVjdGVkIGlucHV0Jyk7XG4gICAgfVxuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5pbnB1dCkpIHtcbiAgICAgIHRoaXMuZGF0ZSA9IHRoaXMuaW5wdXQubWFwKChudW0pID0+IHBhcnNlSW50KG51bSwgMTApKTtcbiAgICAgIHRoaXMuX2QgPSB0aGlzLnRvR3JlZ29yaWFuKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmlucHV0IGluc3RhbmNlb2YgRGF0ZSkge1xuICAgICAgdGhpcy5fZCA9IHRoaXMuaW5wdXQ7XG4gICAgICB0aGlzLmRhdGUgPSBKRGF0ZS50b0phbGFsaSh0aGlzLmlucHV0KTtcbiAgICB9XG4gIH1cblxuICAvKlxuICAgKiBDb3ZlcnRzIGEgR3JlZ29yaWFuIGRhdGUgdG8gSmFsYWxpIGRhdGVcbiAgICpcbiAgICogQHBhcmFtcyB7RGF0ZX0gZGF0ZVxuICAgKiBAcmV0dXJuIHtBcnJheX1cbiAgICovXG4gIHN0YXRpYyB0b0phbGFsaShkYXRlKSB7XG4gICAgY29uc3QgZml4ZWREYXRlID0gQ29udmVydGVyLmdyZWdvcmlhblRvRml4ZWQoXG4gICAgICBkYXRlLmdldEZ1bGxZZWFyKCksXG4gICAgICBkYXRlLmdldE1vbnRoKCkgKyAxLFxuICAgICAgZGF0ZS5nZXREYXRlKClcbiAgICApO1xuICAgIGNvbnN0IGpkYXRlID0gQ29udmVydGVyLmZpeGVkVG9KYWxhbGkoZml4ZWREYXRlKTtcblxuICAgIHJldHVybiBqZGF0ZTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjYW1lbGNhc2VcbiAgc3RhdGljIHRvX2phbGFsaShkYXRlKSB7IHJldHVybiBKRGF0ZS50b0phbGFsaShkYXRlKTsgfVxuXG4gIC8qXG4gICAqIGNvbnZlcnRzIGEgSmFsYWxpIGRhdGUgdG8gR3JlZ29yaWFuXG4gICAqXG4gICAqIEBwYXJhbXMge051bWJlcn0geWVhclxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IG1vbnRoXG4gICAqIEBwYXJhbXMge051bWJlcn0gZGF5XG4gICAqIEByZXR1cm4ge0RhdGV9XG4gICAqL1xuICBzdGF0aWMgdG9HcmVnb3JpYW4oeWVhciwgbW9udGgsIGRheSkge1xuICAgIGNvbnN0IGdkYXRlID0gQ29udmVydGVyLmZpeGVkVG9HcmVnb3JpYW4oXG4gICAgICBDb252ZXJ0ZXIuamFsYWxpVG9GaXhlZCh5ZWFyLCBtb250aCwgZGF5KVxuICAgICk7XG5cbiAgICByZXR1cm4gbmV3IERhdGUoK2dkYXRlWzBdLCArZ2RhdGVbMV0gLSAxLCArZ2RhdGVbMl0pO1xuICB9XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNhbWVsY2FzZVxuICBzdGF0aWMgdG9fZ3JlZ29yaWFuKHllYXIsIG1vbnRoLCBkYXkpIHsgcmV0dXJuIEpEYXRlLnRvR3JlZ29yaWFuKHllYXIsIG1vbnRoLCBkYXkpOyB9XG5cbiAgLypcbiAgICogQ2hlY2tzIGlmIGEgZ2l2ZW4geWVhciBpcyBhIGxlYXAgeWVhciBvciBub3RcbiAgICpcbiAgICogQHBhcmFtcyB7TnVtYmVyfSB5ZWFyXG4gICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAqL1xuICBzdGF0aWMgaXNMZWFwWWVhcih5ZWFyKSB7XG4gICAgcmV0dXJuIENvbnZlcnRlci5sZWFwUGVyc2lhbih5ZWFyKTtcbiAgfVxuXG4gIC8qXG4gICAqIFJldHVybnMgbW9udGggbGVuZ3RoLlxuICAgKlxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IHllYXJcbiAgICogQHBhcmFtcyB7TnVtYmVyfSBtb250aCB6ZXJvIGJhc2VkXG4gICAqIEByZXR1cm4ge051bWJlcn1cbiAgICovXG4gIHN0YXRpYyBkYXlzSW5Nb250aCh5ZWFyLCBtb250aCkge1xuICAgIGxldCBjYWxjZWRZZWFyID0geWVhciAtIE1hdGguZmxvb3IobW9udGggLyAxMik7XG4gICAgbGV0IGNhbGNlZE1vbnRoID0gbW9udGggLSAoTWF0aC5mbG9vcihtb250aCAvIDEyKSAqIDEyKTtcblxuICAgIGlmIChjYWxjZWRNb250aCA8IDApIHtcbiAgICAgIGNhbGNlZE1vbnRoICs9IDEyO1xuICAgICAgY2FsY2VkWWVhciAtPSAxO1xuICAgIH0gZWxzZSBpZiAoY2FsY2VkTW9udGggPT09IDApIHtcbiAgICAgIGNhbGNlZE1vbnRoID0gMTI7XG4gICAgfVxuXG4gICAgaWYgKGNhbGNlZE1vbnRoIDwgNikge1xuICAgICAgcmV0dXJuIDMxO1xuICAgIH0gaWYgKGNhbGNlZE1vbnRoIDwgMTEpIHtcbiAgICAgIHJldHVybiAzMDtcbiAgICB9IGlmIChKRGF0ZS5pc0xlYXBZZWFyKGNhbGNlZFllYXIpKSB7XG4gICAgICByZXR1cm4gMzA7XG4gICAgfVxuICAgIHJldHVybiAyOTtcbiAgfVxuXG4gIC8qXG4gICAqIENvbnZlcnRzIEpEYXRlIGRhdGUgdG8gR3JlZ29yaWFuXG4gICAqL1xuICB0b0dyZWdvcmlhbigpIHtcbiAgICByZXR1cm4gSkRhdGUudG9HcmVnb3JpYW4odGhpcy5kYXRlWzBdLCB0aGlzLmRhdGVbMV0sIHRoaXMuZGF0ZVsyXSk7XG4gIH1cblxuICAvKlxuICAgKiBTaG93cyBKYWxhbGkncyBmdWxsIHllYXIsIGV4OiAxMzkzXG4gICAqXG4gICAqIEByZXR1cm4ge0ludGVnZXJ9XG4gICAqL1xuICBnZXRGdWxsWWVhcigpIHtcbiAgICByZXR1cm4gdGhpcy5kYXRlWzBdO1xuICB9XG5cbiAgLypcbiAgICogU2V0cyB0aGUgSmFsYWxpIGZ1bGwgeWVhclxuICAgKlxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IHllYXJcbiAgICogQHJldHVybiB7SkRhdGV9XG4gICAqL1xuICBzZXRGdWxsWWVhcih5ZWFyKSB7XG4gICAgdGhpcy5kYXRlWzBdID0gcGFyc2VJbnQoeWVhciwgMTApO1xuICAgIHRoaXMuaW5wdXQgPSB0aGlzLnRvR3JlZ29yaWFuKCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKlxuICAgKiBTaG93cyBKYWxhbGkgbW9udGggbnVtYmVyLlxuICAgKlxuICAgKiBAcmV0dXJuIHtOdW1iZXJ9IEphbGFsaSBtb250aCBudW1iZXJcbiAgICovXG4gIGdldE1vbnRoKCkge1xuICAgIHJldHVybiB0aGlzLmRhdGVbMV07XG4gIH1cblxuICAvKlxuICAgKiBTZXRzIHRoZSBKYWxhbGkgbW9udGggbnVtYmVyLiBBbiBpbnRlZ2VyIGJldHdlZW4gMCBhbmQgMTFcbiAgICpcbiAgICogQHBhcmFtcyB7TnVtYmVyfSBtb250aFxuICAgKiBAcmV0dXJucyB7SkRhdGV9XG4gICAqL1xuICBzZXRNb250aChtb250aCkge1xuICAgIGNvbnN0IGZpeGVkID0gaGVscGVycy5maXhNb250aCh0aGlzLmdldEZ1bGxZZWFyKCksIHBhcnNlSW50KG1vbnRoLCAxMCkpO1xuICAgIFt0aGlzLmRhdGVbMF0sIHRoaXMuZGF0ZVsxXV0gPSBmaXhlZDtcbiAgICB0aGlzLmlucHV0ID0gdGhpcy50b0dyZWdvcmlhbigpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKlxuICAgKiBTaG93cyBKYWxhbGkgZGF5IG51bWJlci4gQSBudW1iZXIgYmV0d2VlbiAwIHRvIDMxXG4gICAqXG4gICAqIEByZXR1cm4ge051bWJlcn0gSmFsYWxpIGRheSBudW1iZXJcbiAgICovXG4gIGdldERhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0ZVsyXTtcbiAgfVxuXG4gIC8qXG4gICAqIFNldHMgSmFsYWxpIGRheSBudW1iZXIuIEEgbnVtYmVyIGJldHdlZW4gMCB0byAzMVxuICAgKlxuICAgKiBAcGFyYW1zIHtOdW1iZXJ9IGRhdGVcbiAgICogQHJldHVybiB7SkRhdGV9XG4gICAqL1xuICBzZXREYXRlKGRhdGUpIHtcbiAgICB0aGlzLmRhdGVbMl0gPSBwYXJzZUludChkYXRlLCAxMCk7XG4gICAgdGhpcy5pbnB1dCA9IHRoaXMudG9HcmVnb3JpYW4oKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLypcbiAgICogUmV0dXJucyB0aGUgZGF5IG9mIHRoZSB3ZWVrIGZvciB0aGUgc3BlY2lmaWVkIGRhdGUuIEEgbnVtYmVyIGJldHdlZW4gMCB0byA2XG4gICAqXG4gICAqIEByZXR1cm5zIHtOdW1iZXJ9XG4gICAqL1xuICBnZXREYXkoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2QuZ2V0RGF5KCk7XG4gIH1cblxuICAvKlxuICAgKiBSZXR1cm5zIGEgZm9ybWF0ZWQgb3V0cHV0IG9mIGN1cnJlbnQgZGF0ZVxuICAgKlxuICAgKiBAcGFyYW1zIHtTdHJpbmd9IGZvcm1hdFxuICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAqL1xuICBmb3JtYXQoZm9ybWF0KSB7XG4gICAgbGV0IHJlc3VsdCA9IGhlbHBlcnMucmVwbGFjZVllYXIoZm9ybWF0LCB0aGlzKTtcbiAgICByZXN1bHQgPSBoZWxwZXJzLnJlcGxhY2VNb250aChyZXN1bHQsIHRoaXMpO1xuICAgIHJlc3VsdCA9IGhlbHBlcnMucmVwbGFjZURheShyZXN1bHQsIHRoaXMpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbIm1vZHVsZSIsImV4cG9ydHMiLCJNT05USF9OQU1FUyIsIkFCQlJfREFZUyIsIkRBWVNfTkFNRVMiLCJHUkVHT1JJQU5fRVBPQ0giLCJHUkVHT1JJQU5fVE9fRklYRURfT0ZGU0VUIiwiUEVSU0lBTl9FUE9DSCIsIlBFUlNJQU5fQ1lDTEVfREFZUyIsIk5PTl9MRUFQX0NPUlJFQ1RJT04iLCJkaXZDZWlsIiwiQ29udmVydGVyIiwiX2NsYXNzQ2FsbENoZWNrIiwiX2NyZWF0ZUNsYXNzIiwia2V5IiwidmFsdWUiLCJncmVnb3JpYW5Ub0ZpeGVkIiwieWVhciIsIm1vbnRoIiwiZGF5IiwicmVzdWx0IiwiTWF0aCIsImZsb29yIiwibGVhcEdyZWdvcmlhbiIsImdyZWdvcmlhblllYXJGcm9tRml4ZWQiLCJkYXRlIiwiZDAiLCJuNDAwIiwiZDEiLCJuMTAwIiwiZDIiLCJuNCIsImQzIiwibjEiLCJncmVnb3JpYW5OZXdZZWFyIiwiZml4ZWRUb0dyZWdvcmlhbiIsInByaW9yRGF5cyIsImNvcnJlY3Rpb24iLCJqYWxhbGlUb0ZpeGVkIiwibmV3WWVhciIsImluY2x1ZGVzIiwiZml4ZWRUb0phbGFsaSIsImZpeGVkRGF0ZSIsImRheXNTaW5jZUVwb2NoIiwiZGF5T2ZZZWFyIiwibGVhcFBlcnNpYW4iLCJqZGF0ZSIsImRlZmF1bHQiLCJhIiwiYiIsImZpeE1vbnRoIiwieWVhckRpZmYiLCJuZXdNb250aCIsInplcm9MZWFkaW5nIiwic3RyIiwibGVuZ3RoIiwiY29uY2F0IiwicmVwbGFjZVllYXIiLCJtYXRjaCIsInJlcGxhY2UiLCJnZXRGdWxsWWVhciIsIlN0cmluZyIsInNsaWNlIiwicmVwbGFjZU1vbnRoIiwiZ2V0TW9udGgiLCJ6ZXJvTGVhZGluZ01vbnRoIiwidG9TdHJpbmciLCJyZXBsYWNlRGF5IiwiZ2V0RGF0ZSIsInplcm9MZWFkaW5nRGF0ZSIsImdldERheSIsImhlbHBlcnMiLCJKRGF0ZSIsIl9sZW4iLCJhcmd1bWVudHMiLCJhcmdzIiwiQXJyYXkiLCJfa2V5IiwiaXNBcnJheSIsIkRhdGUiLCJpbnB1dCIsIkVycm9yIiwibWFwIiwibnVtIiwicGFyc2VJbnQiLCJfZCIsInRvR3JlZ29yaWFuIiwidG9KYWxhbGkiLCJzZXRGdWxsWWVhciIsInNldE1vbnRoIiwiZml4ZWQiLCJfZml4ZWQiLCJfc2xpY2VkVG9BcnJheSIsInNldERhdGUiLCJmb3JtYXQiLCJ0b19qYWxhbGkiLCJnZGF0ZSIsInRvX2dyZWdvcmlhbiIsImlzTGVhcFllYXIiLCJkYXlzSW5Nb250aCIsImNhbGNlZFllYXIiLCJjYWxjZWRNb250aCJdLCJzb3VyY2VSb290IjoiIn0= --------------------------------------------------------------------------------