[
  {
    "path": ".browserslistrc",
    "content": "> 1%\nlast 2 versions\nnot dead\n"
  },
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\nindent_style = space\nindent_size = 2\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": ".eslintignore",
    "content": "dist/*\nnode_modules/*\n**/node_modules/*\nexample/*\nsrc/lunar.ts\n"
  },
  {
    "path": ".eslintrc.js",
    "content": "module.exports = {\n  root: true,\n  env: {\n    node: true,\n  },\n  extends: [\n    'plugin:vue/vue3-essential',\n    '@vue/airbnb',\n    '@vue/typescript/recommended',\n  ],\n  parserOptions: {\n    ecmaVersion: 2020,\n  },\n  rules: {\n    'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',\n    'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',\n    'import/no-named-as-default': ['off'],\n    'comma-dangle': ['off', 'never'],\n    'spaced-comment': ['off', 'always'],\n    'func-names': ['off'],\n//    'indent': ['error', 2, {'SwitchCase': 1}], //暂时关闭\n    'indent': 0, //暂时关闭\n    'import/prefer-default-export': 0, //暂时关闭\n    'no-unused-expressions': ['off'],\n//    'max-len': ['warn', 100, 2, {'ignoreComments': true}], //暂时关闭\n    'max-len': 0,\n    'object-curly-spacing': 0,\n    /* 暂时关闭 */\n    'arrow-parens': 0,\n    '@typescript-eslint/no-explicit-any': 0,\n    '@typescript-eslint/no-use-before-define': 0,\n    'array-callback-return': 0,\n    'class-methods-use-this': 0,\n    'default-case': 0,\n    'no-continue': 0,\n    'prefer-template': 0,\n    'consistent-return': 0,\n    'global-require': 0,\n    'import/extensions': 0,\n    'import/no-extraneous-dependencies': 0,\n    'import/no-unresolved': 0,\n    'no-bitwise': 0,\n    'no-case-declarations': 0,\n    'no-confusing-arrow': 0,\n    'no-mixed-operators': 0,\n    'no-param-reassign': 0,\n    'no-plusplus': 0,\n    'no-return-assign': 0,\n    'no-underscore-dangle': 0,\n    'prefer-object-spread': 0,\n    'no-unused-vars': 0,\n    'no-useless-concat': 0,\n    'object-curly-newline': 0,\n    'no-restricted-globals': 0,\n    'no-else-return': 0,\n    'space-infix-ops': 0,\n    'prefer-destructuring': ['error', {\n      'VariableDeclarator': {\n        'array': false,\n        'object': false\n      },\n      'AssignmentExpression': {\n        'array': false,\n        'object': false\n      }\n    }, {\n      'enforceForRenamedProperties': true\n    }]\n  },\n};\n"
  },
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules/\ndist/\nlib/\ndemo/\nnpm-debug.log\nyarn-error.log\n\n# Editor directories and files\n.idea\n.vscode\n*.suo\n*.ntvs*\n*.njsproj\n*.sln\n"
  },
  {
    "path": ".npmignore",
    "content": "node_modules\nbuild\nconfig\nexample\ndemo\ndist/demo.html\ndist/mpvue-calendar.umd.js\nstatic\npublic\nsrc\nlib\n.babelrc\n.browserslistrc\n.editorconfig\n.eslintignore\n.eslintrc.js\nbabel.config.js\n.postcssrc.js\ntsconfig.json\nvue.config.js\nyarn.lock\n.gitignore\nindex.html\npackage-lock.json\nmpvue-calendar.common.js\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2018-present, ZhaoYun (Ricky) Han\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<p align=\"center\">\n<a href=\"http://preview.binlive.cn/mpvue-calendar#/\">\n<img width=\"100\" src=\"https://raw.githubusercontent.com/Hzy0913/hanlibrary/master/mpvue-calendar.png\" alt=\"mpvue-calendar logo\">\n</a>\n</p>\n<p align=\"center\">\n  <a href=\"https://npmcharts.com/compare/mpvue-calendar?minimal=true\">\n  <img src=\"https://img.shields.io/npm/dm/mpvue-calendar.svg\" alt=\"Downloads\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/mpvue-calendar\">\n  <img src=\"https://img.shields.io/npm/v/mpvue-calendar.svg\" alt=\"Version\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/mpvue-calendar\">\n  <img src=\"https://img.shields.io/npm/l/mpvue-calendar.svg\" alt=\"License\">\n  </a>\n</p>\n\n<h1 align=\"center\">mpvue-calendar</h1>\n\n> A feature-rich calendar component, support multiple modes and gesture sliding. For vue 3.0+\n\n<p align=\"center\">\n<img width=\"940\" src=\"http://img.binlive.cn/687474703a2f2f696d672e62696e6c6976652e636e2f75706c6f61642f3136313339373433383732383363616c656e6461722d707265766965772e706e67.png\" alt=\"mpvue-calendar preview\">\n</p>\n\n- #### [Preview](http://preview.binlive.cn/mpvue-calendar#/ \"Preview\")\n- #### [Demo](https://github.com/Hzy0913/mpvue-calendar/blob/master/example/App.vue \"Demo\")\n- #### [中文文档](https://github.com/Hzy0913/mpvue-calendar/blob/master/README.zh.md \"Docs\")\n\n## 💻 Install\nmpvue-calendar only support **vue@3.0+**\n\n```\nnpm i mpvue-calendar -S\n```\n## 🔨 Usage\n\n```javascript\n<Calendar\n  backgroundText\n  class-name=\"select-mode\"\n  :remarks=\"remarks\"\n/>\n\nimport { ref } from 'vue'\nimport Calendar from 'mpvue-calendar'\n\nexport default {\n  components: {\n    Calendar,\n  },\n  setup() {\n    const remarks = ref({'2021-1-13': 'some tings'})\n\n    return {\n      remarks,\n    }\n  }\n}\n```\n## ⚙️ API\n|  name  |  type  |  default  | description   |\n| ------------ | ------------ | ------------ | ------------ |\n| selectMode  | String  | 'select'  |  For the selection mode of calendar component, can be used by **'select'**, **'multi'**,**'range'**, **'multiRange'** mode  |\n|  mode | String  |  'month'|  Configure calendar display mode, the modes has **'month'**, **'week'**,**'monthRange'** |\n| selectDate  | String / String[] / {start: String; end: String} / {start: String; end: String} [] |   |   In different selection modes, there are use different types.  `String` type for **select** mode, `String[]` type for **multi** mode, `{start: String; end: String}` type for **range** mode, and `{start: String; end: String} []` type for **multiRange** mode.  |\n|  monthRange  |  String[]  |    | If you use **monthRange mode**,  you need to set the content of the month to be displayed. for example `[2021-1, 2021-2, 2021-6, 2021-9]`   |\n| remarks  | Object  |   |  Create remark for a day, key is date string, and value is remark content. for example `{ '2021-1-13': 'some things' }`  |\n| tileContent  |  Object |   | Create tile content  for a day, key is date string, and value is `object`, object have **className** and **content**. for example `{ '2021-1-5': { className: 'tip-class', content: 'some tip' } } `   |\n|  holidays  |  Object  |    |   Custom holiday information,  for example `{'2021-1-1': 'New Year'}`  |\n|  completion | Boolean  | false  |  Complete the calendar table with 6 lines   |\n| useSwipe  | Boolean  |  true |  The mobile terminal supports gesture sliding to switch calendar   |\n| arrowLeft  | String  |   |  Left arrow image url of toolbar    |\n| arrowRight  | String  |   |  Right arrow image url of toolbar   |\n| monFirst  | Boolean  |  false |   The first day of the week begins on Monday  |\n| backgroundText  | Boolean  |  false |  Displays the background text of the current month calendar  |\n|  language  |  String  |    | use **'en'** or **'cn'** language   |\n|  format  |  (year, month) => [String, String]  |    | Format the date display at the header. you need return a array,  the contents of the array are year and month  |\n|  weeks  |  String[]  |    |  Weekly display content of custom header, for example ['S', 'M', 'T', 'W', 'T', 'F', 'S']   |\n|  begin  |  String  |    |   Set the available date of the start, and the date before it will be disabled, for example ` '2021-1-5' `  |\n|  end  |  String  |    |  Set the available date of the end, and the date after it will be disabled, for example `'2021-2-5'`  |\n|  disabled  |  String[]  |    |  Disable certain dates , for example `['2021-1-9', '2021-2-5']`  |\n\n#### Chinese lunar\nIf you need show chinese lunar, you need import lunar module.\n```javascript\n<Calendar\n  :lunar=\"lunar\"\n/>\n\nimport lunar from 'mpvue-calendar/dist/lunar'\nexport default {\n  ...,\n  setup() {\n    return {\n      lunar,\n    }\n  }\n}\n```\n\n## ⚙️ methods\n|  name | type  |  description |\n| ------------ | ------------ | ------------ |\n| onSelect  |  (selectDate) => void |   This function is triggered when the date is selected  |\n| onMonthChange | (year, month, day) => void  |   The callback is triggered when the month is change  |\n| next | (year, month) => void  |    Callback this method when triggered next month   |\n| prev | (year, month) => void  |    Callback this method when triggered prev month   |\n| setToday | ref method |   Back today, you need to pass the ref parameter to call the internal method |\n\n\n"
  },
  {
    "path": "README.zh.md",
    "content": "<p align=\"center\">\n<a href=\"http://preview.binlive.cn/mpvue-calendar#/\">\n<img width=\"100\" src=\"https://raw.githubusercontent.com/Hzy0913/hanlibrary/master/mpvue-calendar.png\" alt=\"mpvue-calendar logo\">\n</a>\n</p>\n<p align=\"center\">\n  <a href=\"https://npmcharts.com/compare/mpvue-calendar?minimal=true\">\n  <img src=\"https://img.shields.io/npm/dm/mpvue-calendar.svg\" alt=\"Downloads\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/mpvue-calendar\">\n  <img src=\"https://img.shields.io/npm/v/mpvue-calendar.svg\" alt=\"Version\">\n  </a>\n  <a href=\"https://www.npmjs.com/package/mpvue-calendar\">\n  <img src=\"https://img.shields.io/npm/l/mpvue-calendar.svg\" alt=\"License\">\n  </a>\n</p>\n\n<h1 align=\"center\">mpvue-calendar</h1>\n\n> 一款功能丰富的日历组件，支持多种模式和手势滑动。 基于vue 3.0+\n\n<p align=\"center\">\n<img width=\"940\" src=\"http://img.binlive.cn/upload/1613974387283calendar-preview.png\" alt=\"mpvue-calendar preview\">\n</p>\n\n- #### [预览](http://preview.binlive.cn/mpvue-calendar#/ \"Preview\")\n- #### [例子](https://github.com/Hzy0913/mpvue-calendar/blob/master/example/App.vue \"Demo\")\n\n## 💻 安装\nmpvue-calendar 只支持 **vue@3.0+**\n\n```\nnpm i mpvue-calendar -S\n```\n## 🔨 使用\n\n```javascript\n<Calendar\n  backgroundText\n  class-name=\"select-mode\"\n  :remarks=\"remarks\"\n/>\n\nimport { ref } from 'vue'\nimport Calendar from 'mpvue-calendar'\n\nexport default {\n  components: {\n    Calendar,\n  },\n  setup() {\n    const remarks = ref({'2021-1-13': 'some tings'})\n\n    return {\n      remarks,\n    }\n  }\n}\n```\n## ⚙️ API\n|  name  |  type  |  default  | description   |\n| ------------ | ------------ | ------------ | ------------ |\n| selectMode  | String  | 'select'  | 对于日历组件的选择模式，可以通过传入 **'select'**, **'multi'**, **'range'**, **'multiRange'** 参数使用  |\n|  mode | String  |  'month'|  配置日历显示模式，可以通过传入 **'month'**, **'week'**,**'monthRange'**  使用该功能 |\n| selectDate  | String / String[] / {start: String; end: String} / {start: String; end: String} [] |   |在不同的选择模式下，需要对应不同的数据类型。  `String` 类型对应在 'select' 模式下，`String[]` 数组类型对应在 'multi' 模式下，`{start: String; end: String}` 类型对应在 'range' 模式下，`{start: String; end: String}[]` 数组类型对应在 'multiRange' 模式下 |\n|  monthRange  |  String[]  |    |如果使用monthRange模式，则需要设置要显示的月份的内容。 例如[2021-1、2021-2、2021-3]   |\n| remarks  | Object  |   |  创建某一天的备注，key是日期字符串，value是备注内容。 例如{'2021-1-13'：'一些备注'} |\n| tileContent  |  Object |   | 创建某一天的贴片内容，key是日期字符串，value是object类型，`object`有**className**和**content**字段。例如{2021-1-5'：{className:'tip class'，content:'some tip'}  |\n|  holidays  |  Object  |    |  自定义节假日信息，例如{'2021-1 ':'New Year'} |\n|  completion | Boolean  | false  | 用6行补全日历表格 |\n| useSwipe  | Boolean  |  true |  启用移动端支持手势滑动切换日历   |\n| arrowLeft  | String  |   |  工具栏左侧箭头图片   |\n| arrowRight  | String  |   |  工具栏右侧箭头图片   |\n| monFirst  | Boolean  |  false |  一周的第一天从星期一开始 |\n| backgroundText  | Boolean  |  false | 显示当前月份的背景文本 |\n|  language  |  String  |    | 使用 **'en'** 或 **'cn'** 语言   |\n|  format  |  (year, month) => [String, String]  |    | 格式化头部的日期显示。 您需要返回一个数组，该数组的内容是对应的年和月  |\n|  weeks  |  String[]  |    | 自定义标题的每周显示内容，例如['星期一', '星期二', '星期三', '星期四', ...] |\n|  begin  |  String  |    |   设置开始的可用日期，在此之前的日期将被禁用，例如 '2021-1-5'  |\n|  end  |  String  |    |  设置结束的可用日期，在此之后的日期将被禁用，例如 '2021-2-5'   |\n|  disabled  |  String[]  |    | 禁用某些日期，例如 `['2021-1-9', '2021-2-5']`|\n\n#### 农历\n如果你需要展示中国农历，你需要导入农历模块。\n```javascript\n<Calendar\n  :lunar=\"lunar\"\n/>\n\nimport lunar from 'mpvue-calendar/dist/lunar'\nexport default {\n  ...,\n  setup() {\n    return {\n      lunar,\n    }\n  }\n}\n```\n\n## ⚙️ methods\n|  name | type  |  description |\n| ------------ | ------------ | ------------ |\n| onSelect  |  (selectDate) => void |   选择日期时触发此函数 |\n| onMonthChange | (year, month, day) => void  |   当月份发生变化时会触发该回调  |\n| next | (year, month) => void  |  进入下月时触发该回调方法|\n| prev | (year, month) => void  |    进入上月时触发该回调方法 |\n| setToday | ref method | 回到今天，您需要传递ref参数来调用组件内部方法 |\n"
  },
  {
    "path": "babel.config.js",
    "content": "module.exports = {\n  presets: [\n    '@vue/cli-plugin-babel/preset',\n  ],\n};\n"
  },
  {
    "path": "example/App.vue",
    "content": "<template>\n  <div class=\"container\">\n    <div class=\"container-select-modes\">\n      <!--select mode-->\n      <Calendar\n        backgroundText\n        completion\n        class-name=\"select-mode\"\n        :format=\"formatOfSelecteMode\"\n        :holidays=\"holidays\"\n        :select-date=\"selectModeDate\"\n        language=\"en\"\n        @selectYear=\"selectYear\"\n        @selectMonth=\"selectMonth\"\n        @next=\"next\"\n        @prev=\"prev\"\n        @onMonthChange=\"onMonthChange\"\n        @onSelect=\"onSelect\"\n      />\n      <!--multi mode-->\n      <Calendar\n        selectMode=\"multi\"\n        class-name=\"multi-mode\"\n        language=\"en\"\n        :tile-content=\"multiTileContent\"\n        :select-date=\"multiModeDate\"\n        :begin=\"begin\"\n        :end=\"end\"\n        @onSelect=\"onSelect\"\n      />\n      <!--range mode-->\n      <Calendar\n        monFirst\n        backgroundText\n        selectMode=\"range\"\n        :lunar=\"lunar\"\n        class-name=\"range-mode\"\n        :format=\"formatOfRangeMode\"\n        :select-date=\"rangeModeDate\"\n        language=\"cn\"\n        @onSelect=\"onSelect\"\n      />\n      <!--multiRange mode-->\n      <Calendar\n        monFirst\n        completion\n        backgroundText\n        selectMode=\"multiRange\"\n        class-name=\"multiRange-mode\"\n        :select-date=\"multiRangeModeDate\"\n        :format=\"formatOfmultiMode\"\n        :weeks=\"weeks\"\n        @onSelect=\"onSelect\"\n      />\n    </div>\n    <div class=\"container-view-modes\">\n      <!--week mode-->\n      <Calendar\n        backgroundText\n        :lunar=\"lunar\"\n        selectMode=\"range\"\n        class-name=\"week-mode\"\n        mode=\"week\"\n        ref=\"weekModeRef\"\n      />\n      <button @click=\"backToToday\" class=\"back-to-today\">Back to Today</button>\n      <!--monthRange mode-->\n      <Calendar\n        backgroundText\n        selectMode=\"range\"\n        class-name=\"monthRange-mode\"\n        mode=\"monthRange\"\n        :monthRange=\"['2021-2', '2021-3', '2021-4']\"\n      />\n    </div>\n  </div>\n</template>\n\n<script>\n  import Calendar from '../src/mpvue-calendar';\n  import lunar from '../src/lunar';\n  import { defineComponent, ref, reactive, onMounted, watchEffect, watch } from 'vue';\n\n  export default {\n    name: 'app',\n    components: {\n      Calendar\n    },\n    setup() {\n      const currentDate = new Date();\n      const currentYear = currentDate.getFullYear();\n      const currentMonth = currentDate.getMonth() + 1;\n      const currentDay = currentDate.getDate();\n\n      const holidays = ref({\n        '1-1': 'New Year',\n        '2-2': 'Wetlands',\n        '2-14': 'Valentine',\n        '3-8': 'Women',\n        '4-1': 'April Fools',\n        '4-22': 'World Earth',\n        '5-1': 'Labour',\n        '6-1': 'Children',\n        '8-1': 'Youth',\n        '10-5': 'World Teachers',\n        '10-31': 'Halloween',\n        '12-25': 'Christmas',\n      })\n      const completion = ref(false)\n\n      const getRandom = () => Math.floor(Math.random() * (28 - 1 + 1)) + 1\n      const selectModeDate = ref(`${currentYear}-${currentMonth}-${getRandom()}`)\n      const multiModeDate = ref([`${currentYear}-${currentMonth}-${getRandom()}`, `${currentYear}-${currentMonth}-${getRandom()}`, `${currentYear}-${currentMonth}-${getRandom()}`])\n      const rangeModeDate = ref({start: `${currentYear}-${currentMonth}-10`, end: `${currentYear}-${currentMonth}-14`})\n      const multiRangeModeDate = ref([{start: `${currentYear}-${currentMonth}-8`, end: `${currentYear}-${currentMonth}-12`}, {start: `${currentYear}-${currentMonth}-20`, end: `${currentYear}-${currentMonth}-23`}])\n\n      const weekModeRef = ref()\n      const begin = ref('2021-1-13')\n      const end = ref('2025-2-13')\n      const monthRange = ref(['2021-1', '2021-6', '2021-12'])\n      const disabled = ref(['2021-1-2', '2021-1-4', '2021-1-23'])\n      const multiTileContent = ref({\n        [`${currentYear}-${currentMonth}-${currentDay}`]: {\n          className: 'content-item-classname',\n          content: 'some things'\n        }\n      })\n\n      function onSelect(selectDate) {\n        console.log(selectDate, 'selectDate')\n      }\n\n      function backToToday() {\n        weekModeRef.value.setToday();\n      }\n\n      function rangeMonthFormat(year, month) {\n        return [year, month + '月']\n      }\n\n      function formatOfSelecteMode(year, month) {\n        const transform = {\n          1: 'Jan',\n          2: 'Feb',\n          3: 'Mar',\n          4: 'Apr',\n          5: 'May',\n          6: 'Jun',\n          7: 'Jul',\n          8: 'Aug',\n          9: 'Sept',\n          10: 'Oct',\n          11: 'Nov',\n          12: 'Dec',\n        }\n        return [`${year}`, `${transform[month]}`];\n      }\n\n      function formatOfRangeMode(year, month) {\n        const transform = {\n          1: '一',\n          2: '二',\n          3: '三',\n          4: '四',\n          5: '五',\n          6: '六',\n          7: '七',\n          8: '八',\n          9: '九',\n          10: '十',\n          11: '十一',\n          12: '十二',\n        }\n        return [`${year}年`, `${transform[month]}月`];\n      }\n\n      function formatOfmultiMode(year, month) {\n        return [`${year}年`, `${month}月`];\n      }\n\n      function selectYear(y, m) {\n        console.log(y, m, 'selectYear')\n      }\n\n      function onMonthChange(y, m) {\n        console.log(y, m, 'onMonthChange')\n      }\n\n      function selectMonth(y, m) {\n        console.log(y, m, 'selectMonth')\n      }\n\n      function next(y, m, d) {\n        console.log(y, m, d, 'nextnext')\n      }\n\n      function prev(y, m, d) {\n        console.log(y, m, d, 'prevprev')\n      }\n\n      return {\n        lunar,\n        holidays,\n        onSelect,\n        monthRange,\n        disabled,\n        completion,\n        begin,\n        weeks: ['一', '二', '三', '四', '五', '六', '日'],\n        end,\n        selectModeDate,\n        onMonthChange,\n        next,\n        prev,\n        selectMonth,\n        selectYear,\n        weekModeRef,\n        multiModeDate,\n        multiRangeModeDate,\n        rangeModeDate,\n        backToToday,\n        multiTileContent,\n        formatOfmultiMode,\n        formatOfRangeMode,\n        formatOfSelecteMode,\n      }\n    }\n  };\n</script>\n\n<style lang=\"less\">\n  body, html {\n    background-color: #fbf9fe;\n    margin: 0;\n    padding: 0;\n  }\n  .container{\n    width: 1000px;\n    margin: 0 auto;\n    .select-mode{\n      .vc-calendar-year{\n        margin-right: 10px;\n      }\n    }\n    .container-select-modes{\n      display: flex;\n      flex-wrap: wrap;\n      .select-mode, .multi-mode, .range-mode, .multiRange-mode{\n        &.mpvue-calendar{\n          width: 400px;\n          margin: 0 auto;\n          flex: none;\n        }\n      }\n    }\n    .container-view-modes{\n      display: flex;\n      flex-wrap: wrap;\n      position: relative;\n      .week-mode, .multi-mode, .range-mode, .multiRange-mode, .monthRange-mode{\n        &.mpvue-calendar{\n          width: 400px;\n          margin: 0 auto;\n          flex: none;\n        }\n      }\n    }\n  }\n\n  .select-mode{\n    &:before{\n      content: 'select mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n    .vc-calendar-holiday{\n      white-space: nowrap;\n    }\n  }\n\n  .multi-mode{\n    &:before{\n      content: 'multi select mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n    .content-item-classname{\n      color: #fff;\n      background: #0b6cbc;\n      display: inline-block;\n      white-space: nowrap;\n      padding: 0 3px;\n      border-radius: 3px;\n      transform: scale(.8);\n    }\n  }\n\n  .range-mode{\n    &:before{\n      content: 'range select mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n  }\n\n  .multiRange-mode{\n    &:before{\n      content: 'multi range select mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n  }\n\n  .week-mode{\n    &:before{\n      content: 'week mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n  }\n\n  .monthRange-mode{\n    &:before{\n      content: 'month range mode';\n      text-align: center;\n      display: block;\n      color: #38778a;\n      font-weight: bold;\n      margin-bottom: 5px;\n    }\n  }\n\n  .back-to-today{\n    position: absolute;\n    left: 50px;\n    top: 220px;\n    box-shadow: 2px 0px 2px rgb(68, 146, 123, .2);\n    position: absolute;\n    left: 50px;\n    top: 220px;\n    height: 22px;\n    border: none;\n    cursor: pointer;\n  }\n\n  @media screen and (max-width: 600px) {\n    .container{\n      width: 100%;\n    }\n  }\n</style>\n"
  },
  {
    "path": "example/main.js",
    "content": "import { createApp } from 'vue';\nimport App from './App.vue'\n\ncreateApp(App).mount('#app')\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"mpvue-calendar\",\n  \"version\": \"3.0.1\",\n  \"description\": \"vue calendar mpvue-calendar vue-calendar\",\n  \"main\": \"dist/mpvue-calendar.umd.min.js\",\n  \"scripts\": {\n    \"start\": \"vue-cli-service serve\",\n    \"build\": \"npm run build:calendar && npm run build:lunar && npm run remove\",\n    \"build:calendar\": \"vue-cli-service build --target lib --name mpvue-calendar './src/mpvue-calendar.vue'\",\n    \"build:lunar\": \"vue-cli-service build --target lib --name lunar --dest lib './src/lunar.ts'\",\n    \"remove\": \"cp ./lib/lunar.umd.min.js ./dist/lunar.js\",\n    \"demo\": \"vue-cli-service build --dest demo './example/main.js'\",\n    \"lint\": \"vue-cli-service lint\",\n    \"publish\": \"npm publish --registry https://registry.npmjs.org\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git+https://github.com/Hzy0913/mpvue-calendar.git\"\n  },\n  \"keywords\": [\n    \"vue\",\n    \"calendar\",\n    \"mpvue-calendar\",\n    \"calendar component\",\n    \"日历组件\"\n  ],\n  \"author\": \"hzy\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/Hzy0913/mpvue-calendar/issues\"\n  },\n  \"homepage\": \"https://github.com/Hzy0913/mpvue-calendar#readme\",\n  \"dependencies\": {\n    \"core-js\": \"^3.6.5\",\n    \"vue\": \"^3.0.0\"\n  },\n  \"devDependencies\": {\n    \"@typescript-eslint/eslint-plugin\": \"^2.33.0\",\n    \"@typescript-eslint/parser\": \"^2.33.0\",\n    \"@vue/cli-plugin-babel\": \"~4.5.0\",\n    \"@vue/cli-plugin-eslint\": \"~4.5.0\",\n    \"@vue/cli-plugin-typescript\": \"~4.5.0\",\n    \"@vue/cli-service\": \"~4.5.0\",\n    \"@vue/compiler-sfc\": \"^3.0.0\",\n    \"@vue/eslint-config-airbnb\": \"^5.0.2\",\n    \"@vue/eslint-config-typescript\": \"^5.0.2\",\n    \"eslint\": \"^6.7.2\",\n    \"eslint-plugin-import\": \"^2.20.2\",\n    \"eslint-plugin-vue\": \"^7.0.0-0\",\n    \"less\": \"^3.12.2\",\n    \"less-loader\": \"^7.1.0\",\n    \"typescript\": \"~3.9.3\"\n  }\n}\n"
  },
  {
    "path": "public/index.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n    <link rel=\"icon\" href=\"<%= BASE_URL %>favicon.ico\">\n    <title>mpvue-calendar</title>\n  </head>\n  <body>\n    <noscript>\n      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>\n    </noscript>\n    <div id=\"app\"></div>\n    <!-- built files will be auto injected -->\n  </body>\n</html>\n"
  },
  {
    "path": "src/components/icon/icon.css",
    "content": "@font-face {\n    font-family: \"calendar-iconfont\";\n    src: url('data:font/truetype;charset=utf-8;base64,d09GRgABAAAAAASEAAsAAAAABuwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY7d0f0Y21hcAAAAYAAAABTAAABhmJUzs9nbHlmAAAB1AAAALcAAADIzC0F5mhlYWQAAAKMAAAALwAAADYS7IZUaGhlYQAAArwAAAAcAAAAJAfeA4RobXR4AAAC2AAAAAwAAAAMDAAAAGxvY2EAAALkAAAACAAAAAgANgBkbWF4cAAAAuwAAAAfAAAAIAEOACluYW1lAAADDAAAAUUAAAJtPlT+fXBvc3QAAARUAAAALQAAAEOUPjuMeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMj5jYm7438AQw9zA0AAUZgTJAQDdSgvleJztkMERgDAIBPdIzMOxEB8W5MvuTRsRMHbhzSwHR/IBWIDiHE4FXYjQ6akyL6yZ13zT3IXd6jYGfO6S75q7xT81fm1Z9zlZXOsl+j5BD35IDU4AeJwVzUEOwUAYBeD/mfxTEso/mkEJoYluqgtajUjYsHEOSytncROJK/QErjNMd+8lL+8jEP3eqq8uNCPiokK1L4t1ihzVCSPMEekAep3mQCh4tpVm95JWz2QGj3iyiN3LZMJBODU49IMuDxk32YifuI89X4+xqwcsHUtEjfVVWt1p5MvWNs9RY4RowNLrJ7Tq8ZKNN7wmvMp8jBc7PDpW3RPfPrISV5ss4QEO9pxcdrix/gMMIyHOAHicY2BkYGAAYmNBZtV4fpuvDNwsDCBw/dlCBQT9fzMLA3MKkMvBwAQSBQDyNAlAAHicY2BkYGBu+N/AEMPCAAJAkpEBFTADAEcJAmwEAAAABAAAAAQAAAAAAAAAADYAZHicY2BkYGBgZpBlANEMDExAzAWEDAz/wXwGAAuHATgAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAmZGJkZmRhYEnKzMxryS/tDgjMS+dC8qpzC9lYAAAiPIJlAAAAA==');\n}\n\n.iconfont {\n    font-family:\"calendar-iconfont\" !important;\n    font-size:16px;\n    font-style:normal;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n\n.icon-arrow-right:before { content: \"\\e602\"; }\n\n.icon-arrow-left:before { content: \"\\e501\"; }\n"
  },
  {
    "path": "src/components/swipe/declare.ts",
    "content": "interface SwipeInterface {\n  initialSlide?: number;\n  auto?: number;\n  speed: number;\n  timetableHeight?: number;\n  loop?: boolean;\n  useSwipe?: boolean;\n}\n\ninterface SlideInterface {\n  className?: string;\n  useSwipe?: boolean;\n}\n\ntype startType = {\n  x: number;\n  y: number;\n  time: number;\n}\n\ntype deltaType = {\n  x: number;\n  y: number;\n}\n\nexport {\n  SwipeInterface,\n  SlideInterface,\n  startType,\n  deltaType,\n}\n"
  },
  {
    "path": "src/components/swipe/index.vue",
    "content": "<template>\n  <div\n    style='margin:0 auto'\n    :class=\"[useSwipe ? 'vc-calendar-swipe': 'vc-calendar-timetable-container']\"\n    ref=\"swipeRef\"\n  >\n    <div\n      :class=\"[useSwipe ? 'swipe-wrap': 'vc-calendar-timetable-wrapper']\"\n    >\n      <slot></slot>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import { ref, onMounted } from 'vue';\n  import { offloadFn } from '../utils';\n  import { hasTransitions } from './utils';\n  import { SwipeInterface, startType, deltaType } from './declare';\n  import './style.less';\n\n  export default {\n    props: {\n      initialSlide: {\n        type: Number,\n        default: 0\n      },\n      auto: {\n        type: Number,\n        default: 3000\n      },\n      speed: {\n        type: Number,\n        default: 300\n      },\n      loop: {\n        type: Boolean,\n        default: false\n      },\n      useSwipe: {\n        type: Boolean,\n      },\n    },\n    emits: ['swiperChange', 'swiperChangeEnd', 'start', 'containerChange'],\n    setup(props: SwipeInterface, { emit }: any) {\n      let isTransitionEnd = true;\n      const { initialSlide, auto, speed, loop, useSwipe } = props;  // eslint-disable-line\n\n      if (!useSwipe) return;\n\n      const options = {\n        initialSlide,\n        auto,\n        speed,\n        loop,\n        disableScroll: false,\n        stopPropagation: false,\n        callback(index: number, element: HTMLElement) {\n          emit('swiperChange', index, element);\n        },\n        transitionEnd(index: number, element: HTMLElement) {\n          emit('swiperChangeEnd', index, element);\n\n          setTimeout(() => {\n            isTransitionEnd = true;\n          });\n        },\n      };\n      const swipeRef = ref(null);\n      const browser = {\n        addEventListener: !!window.addEventListener,\n        touch: ('ontouchstart' in window) || (window as any).DocumentTouch && document instanceof (window as any).DocumentTouch,\n        transitions: hasTransitions(),\n      };\n\n      let index: number = options.initialSlide || 0;\n      let container: HTMLElement;\n      let element: any;\n      let slides: any;\n      let slidePos: any;\n      let width: number;\n      options.loop = options.loop ?? true;\n\n      function setup() {\n        if (!container) return;\n        setTimeout(() => emit('containerChange', container));\n\n        element = container.children[0];\n        // cache slides\n        slides = element.children;\n\n        // set loop to false if only one slide\n        if (slides.length < 2) options.loop = false;\n\n        //special case if two slides\n        if (browser.transitions && options.loop && slides.length < 3) {\n          element.appendChild(slides[0].cloneNode(true));\n          element.appendChild(element.children[1].cloneNode(true));\n          slides = element.children;\n        }\n\n        // create an array to store current positions of each slide\n        slidePos = new Array(slides.length);\n\n        // determine width of each slide\n        width = container.getBoundingClientRect().width || container.offsetWidth;\n\n        element.style.width = `${slides.length * width}px`;\n\n        // stack elements\n\n        let pos = slides.length;\n        while (pos--) {\n          const slideDom = slides[pos];\n\n          slideDom.style.width = `${width}px`;\n          slideDom.setAttribute('data-index', pos);\n\n          if (browser.transitions) {\n            slideDom.style.left = `${pos * -width}px`;\n            move(pos, index > pos ? -width : (index < pos ? width : 0), 0); // eslint-disable-line\n          }\n        }\n\n        // reposition elements before and after index\n        if (options.loop && browser.transitions) {\n          move(circle(index - 1), -width, 0);\n          move(circle(index + 1), width, 0);\n        }\n\n        if (!browser.transitions) {\n          element.style.left = `${index * -width}px`;\n        }\n\n        container.style.visibility = 'visible';\n      }\n\n      function prev() {\n        if (options.loop) {\n          slide(index - 1);\n        } else if (index) {\n          slide(index - 1);\n        }\n      }\n\n      function next() {\n        if (options.loop) {\n          slide(index + 1);\n        } else if (index < slides.length - 1) {\n          slide(index + 1);\n        }\n      }\n\n      function slide(to: number, slideSpeed?: number) {\n        // do nothing if already on requested slide\n        if (index === to) return;\n\n        if (browser.transitions) {\n          let direction = Math.abs(index - to) / (index - to); // 1: backward, -1: forward\n\n          // get the actual position of the slide\n          if (options.loop) {\n            const naturalDirection = direction;\n            direction = -slidePos[circle(to)] / width;\n\n            // if going forward but to < index, use to = slides.length + to\n            // if going backward but to > index, use to = -slides.length + to\n            if (direction !== naturalDirection) {\n              to = -direction * slides.length + to;\n            }\n          }\n\n          let diff = Math.abs(index - to) - 1;\n\n          // move all the slides between index and to in the right direction\n          while (diff--) {\n            move(circle((to > index ? to : index) - diff - 1), width * direction, 0);\n          }\n\n          to = circle(to);\n\n          move(index, width * direction, slideSpeed ?? speed);\n          move(to, 0, slideSpeed ?? speed);\n\n          if (options.loop) { // we need to get the next in place\n            move(circle(to - direction), -(width * direction), 0);\n          }\n        } else {\n          to = circle(to);\n          animate(index * -width, to * -width, slideSpeed || speed as number);\n          //no fallback for a circular loop if the browser does not accept transitions\n        }\n\n        index = to;\n        offloadFn(options.callback && options.callback(index, slides[index]));\n      }\n\n      function circle(circleIndex: number) {\n        // a simple positive modulo using slides.length\n        return (slides.length + (circleIndex % slides.length)) % slides.length;\n      }\n\n      function move(moveIndex: number, dist: any, moveSpeed: number) {\n        translate(moveIndex, dist, moveSpeed);\n        slidePos[moveIndex] = dist;\n      }\n\n      function translate(translateIndex: number, dist: any, translateSpeed: number) {\n        const slideDom = slides[translateIndex];\n        const style = slideDom && slideDom.style;\n\n        if (!style) return;\n\n        const duration = `${translateSpeed}ms`;\n        style.webkitTransitionDuration = duration;\n        style.MozTransitionDuration = duration;\n        style.msTransitionDuration = duration;\n        style.OTransitionDuration = duration;\n        style.transitionDuration = duration;\n\n        style.webkitTransform = `translate(${dist}px, 0)translateZ(0)`;\n        style.msTransform = style.MozTransform = style.OTransform = `translateX(${dist}px)`; // eslint-disable-line\n      }\n\n      function animate(from: any, to: any, animateSpeed: number) {\n        // if not an animation, just reposition\n        if (!animateSpeed) {\n          element.style.left = `${to}px`;\n          return;\n        }\n\n        const start = +new Date();\n        const timer = setInterval(() => {\n          const timeElap = +new Date() - start;\n\n          if (timeElap > animateSpeed) {\n            element.style.left = `${to}px`;\n            options.transitionEnd && options.transitionEnd.call(event, index, slides[index]);\n            clearInterval(timer);\n            return;\n          }\n\n          element.style.left = (( (to - from) * (Math.floor((timeElap / animateSpeed) * 100) / 100) ) + from) + 'px'; // eslint-disable-line\n        }, 4);\n      }\n\n      // setup initial vars\n      let start = {} as startType;\n      let delta = {} as deltaType;\n      let isScrolling: boolean | undefined;\n\n      // setup event capturing\n      const events = {\n        handleEvent(event: any) {\n          switch (event.type) {\n            case 'touchstart':\n              this.start(event);\n              break;\n            case 'touchmove':\n              this.move(event);\n              break;\n            case 'touchend':\n              offloadFn(this.end(event));\n              break;\n            case 'webkitTransitionEnd':\n            case 'msTransitionEnd':\n            case 'oTransitionEnd':\n            case 'otransitionend':\n            case 'transitionend':\n              offloadFn(this.transitionEnd(event));\n              break;\n            case 'resize':\n              offloadFn(setup);\n              break;\n          }\n\n          if (options.stopPropagation) {\n            event.stopPropagation();\n            event.preventDefault();\n          }\n        },\n        start(event: any) {\n          emit('start');\n\n          if (!isTransitionEnd) {\n            return setTimeout(() => {\n              isTransitionEnd = true;\n            });\n          }\n\n          const touches = event.touches[0];\n          // measure start values\n          start = {\n            // get initial touch coords\n            x: touches.pageX,\n            y: touches.pageY,\n            time: +new Date() // store time to determine touch duration\n          };\n\n          // used for testing first move event\n          isScrolling = undefined;\n\n          // reset delta and end measurements\n          delta = {\n            x: 0,\n            y: 0,\n          };\n\n          // attach touchmove and touchend listeners\n          element.addEventListener('touchmove', this, false);\n          element.addEventListener('touchend', this, false);\n        },\n        move(event: any) {\n          // ensure swiping with one touch and not pinching\n          if (event.touches.length > 1 || event.scale && event.scale !== 1) return;\n\n          if (options.disableScroll) event.preventDefault();\n\n          const touches = event.touches[0];\n\n          // measure change in x and y\n          delta = {\n            x: touches.pageX - start.x,\n            y: touches.pageY - start.y\n          };\n\n          // determine if scrolling test has run - one time test\n          if (typeof isScrolling === 'undefined') {\n            isScrolling = !!(isScrolling || Math.abs(delta.x) < Math.abs(delta.y));\n          }\n\n          // if user is not trying to scroll vertically\n          if (!isScrolling) {\n            // prevent native scrolling\n            event.preventDefault();\n\n            // stop slideshow\n            stop();\n\n            // increase resistance if first or last slide\n            if (options.loop) { // we don't add resistance at the end\n              translate(circle(index - 1), delta.x + slidePos[circle(index - 1)], 0);\n              translate(index, delta.x + slidePos[index], 0);\n              translate(circle(index + 1), delta.x + slidePos[circle(index + 1)], 0);\n            } else {\n              /* eslint-disable */\n              delta.x =\n                delta.x /\n                ( (!index && delta.x > 0               // if first slide and sliding left\n                  || index == slides.length - 1        // or if last slide and sliding right\n                  && delta.x < 0                       // and if sliding at all\n                ) ?\n                  ( Math.abs(delta.x) / width + 1 )      // determine resistance level\n                  : 1 );                                 // no resistance if false\n              /* eslint-disable */\n\n              // translate 1:1\n              translate(index - 1, delta.x + slidePos[index - 1], 0);\n              translate(index, delta.x + slidePos[index], 0);\n              translate(index + 1, delta.x + slidePos[index + 1], 0);\n            }\n          }\n        },\n        end(event: any) {\n          isTransitionEnd = false;\n          // measure duration\n          const duration = +new Date - start.time;\n\n          // determine if slide attempt triggers next/prev slide\n          const isValidSlide =\n            Number(duration) < 250               // if slide duration is less than 250ms\n            && Math.abs(delta.x) > 20            // and if slide amt is greater than 20px\n            || Math.abs(delta.x) > width / 2;      // or if slide amt is greater than half the width\n\n          // determine if slide attempt is past start and end\n          let isPastBounds =\n            !index && delta.x > 0                            // if first slide and slide amt is greater than 0\n            || index == slides.length - 1 && delta.x < 0;    // or if last slide and slide amt is less than 0\n\n          if (options.loop) {\n            isPastBounds = false;\n          }\n\n          // determine direction of swipe (true:right, false:left)\n          const direction = delta.x < 0;\n\n          // if not scrolling vertically\n          if (!isScrolling) {\n            if (isValidSlide && !isPastBounds) {\n              if (direction) {\n                if (options.loop) { // we need to get the next in this direction in place\n                  move(circle(index - 1), -width, 0);\n                  move(circle(index + 2), width, 0);\n                } else {\n                  move(index - 1, -width, 0);\n                }\n\n                move(index, slidePos[index] - width, speed);\n                move(circle(index + 1), slidePos[circle(index + 1)]-width, speed);\n                index = circle(index + 1);\n              } else {\n                if (options.loop) { // we need to get the next in this direction in place\n                  move(circle(index + 1), width, 0);\n                  move(circle(index - 2), -width, 0);\n                } else {\n                  move(index + 1, width, 0);\n                }\n\n                move(index, slidePos[index]+width, speed);\n                move(circle(index - 1), slidePos[circle(index - 1)]+width, speed);\n                index = circle(index - 1);\n              }\n\n              options.callback && options.callback(index, slides[index]);\n            } else {\n              if (options.loop) {\n                move(circle(index - 1), -width, speed);\n                move(index, 0, speed);\n                move(circle(index + 1), width, speed);\n              } else {\n                move(index - 1, -width, speed);\n                move(index, 0, speed);\n                move(index + 1, width, speed);\n              }\n            }\n          }\n\n          // kill touchmove and touchend event listeners until touchstart called again\n          element.removeEventListener('touchmove', events, false)\n          element.removeEventListener('touchend', events, false)\n        },\n        transitionEnd(event: any) {\n          if (parseInt(event.target.getAttribute('data-index'), 10) === index) {\n            options.transitionEnd && options.transitionEnd.call(event, index, slides[index]);\n          }\n        }\n      }\n\n      onMounted(() => {\n        container = swipeRef.value as any;\n        setup();\n\n        if (browser.addEventListener) {\n          // set touchstart event on element\n          if (browser.touch) {\n            element.addEventListener('touchstart', events, false);\n          }\n\n          if (browser.transitions) {\n            element.addEventListener('webkitTransitionEnd', events, false);\n            element.addEventListener('msTransitionEnd', events, false);\n            element.addEventListener('oTransitionEnd', events, false);\n            element.addEventListener('otransitionend', events, false);\n            element.addEventListener('transitionend', events, false);\n          }\n\n          // set resize event on window\n          window.addEventListener('resize', events, false);\n        }\n      });\n\n      return {\n        swipeRef,\n        slide,\n        useSwipe,\n        prev,\n        next,\n      }\n    }\n  }\n</script>\n"
  },
  {
    "path": "src/components/swipe/slide.vue",
    "content": "<template>\n  <div\n    :class=\"[{[className]: !!className}, useSwipe ? 'swipe-slide': 'vc-calendar-timetable-item']\"\n  >\n    <slot></slot>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import './style.less';\n\n  export default {\n    props: {\n      className: {\n        type: String,\n        default: ''\n      },\n      useSwipe: {\n        type: Boolean,\n      },\n    },\n  };\n</script>\n"
  },
  {
    "path": "src/components/swipe/style.less",
    "content": ".vc-calendar-swipe {\n  overflow: hidden;\n  width: 100%;\n  .swipe-wrap{\n    width: 100%;\n    overflow: hidden;\n    position: relative;\n    .swipe-slide{\n      width: 100%;\n      height: 100%;\n      float: left;\n      position: relative;\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/swipe/utils.ts",
    "content": "export function hasTransitions() {\n  const element = document.createElement('div');\n  const property = ['transitionProperty', 'WebkitTransition', 'MozTransition', 'OTransition', 'msTransition'];\n\n  for (let value of property) {// eslint-disable-line\n    if ((element.style as any)[value] !== undefined) return true;\n  }\n\n  return false;\n}\n"
  },
  {
    "path": "src/components/timetable/computed.ts",
    "content": "import { computedNextMonth, computedPrevMonth, getToday, computedNextYear } from '../utils';\n\nfunction date2ymd(date: string): number[] {\n  const [y, m, d] = date.split('-');\n  return [Number(y), Number(m), Number(d)];\n}\n\nfunction date2timeStamp(date: string): number {\n  const [y, m, d] = date2ymd(date);\n  return +new Date(y, m - 1, d);\n}\n\nfunction getLunarInfo(y: string, m: string, d: string, lunar: any) {\n  const date = `${y}-${m}-${d}`;\n  if (!lunar) {\n    return { date };\n  }\n\n  const lunarInfo = lunar.solar2lunar(y, m, d) as any;\n  const { Term, lMonth, lDay, lYear } = lunarInfo || {};\n  const { lunarHoliday, gregorianHoliday } = lunar || {};\n  const lunarValue = lunarInfo.IDayCn;\n  const yearEve = lMonth === 12 && lDay === lunar.monthDays(lYear, 12) ? '除夕' : undefined;\n\n  const lunarInfoObj = {\n    date,\n    lunar: Term || lunarValue,\n    gregorianHoliday: gregorianHoliday?.[`${m}-${d}`],\n    lunarHoliday: lunarHoliday?.[`${lMonth}-${lDay}`] || yearEve,\n    isTerm: !!yearEve || lunarInfo.isTerm\n  };\n  return lunarInfoObj;\n}\n\nconst setRemark = (function () {\n  let remarksInfo: any = {};\n\n  return function () {\n    return {\n      update(remarks: any = {}) {\n        remarksInfo = remarks;\n      },\n      getRemark(date: string) {\n        if (remarksInfo) {\n          return {\n            remark: remarksInfo[date]\n          };\n        }\n      }\n    };\n  };\n}());\n\nfunction computedPrevDay(year: string, month: string, day: string | number): string {\n  if ((Number(day) - 1) === 0) {\n    const prevMonth = computedPrevMonth(month);\n    if (prevMonth === 12) { //prev year\n      const prevYear = Number(year) - 1;\n      const prevDay = new Date(prevYear, prevMonth - 2, 0).getDate();\n      return `${prevYear}-${prevMonth}-${prevDay}`;\n    } else { //current year and prev month\n      const prevDay = new Date(Number(year), prevMonth, 0).getDate();\n      return `${year}-${prevMonth}-${prevDay}`;\n    }\n  } else {\n    return `${year}-${month}-${Number(day) - 1}`;\n  }\n}\n\nfunction computedNextDay(year: string, month: string, day: string): string {\n  const lastDateOfCurrentMonth = new Date(Number(year), Number(month), 0).getDate(); //last date of current month\n\n  if ((Number(day) + 1) > lastDateOfCurrentMonth) {\n    const nextMonth = computedNextMonth(month);\n    if (nextMonth === 1) { //next year\n      const nextYear = computedNextYear(year, month);\n      const nextDay = new Date(nextYear, 0, 1).getDate();\n      return `${nextYear}-1-${nextDay}`;\n    } else { //current year and next month\n      const nextDay = new Date(Number(year), nextMonth - 1, 1).getDate();\n      return `${year}-${nextMonth}-${nextDay}`;\n    }\n  } else {\n    return `${year}-${month}-${Number(day) + 1}`;\n  }\n}\n\ntype rangeOptionType = {\n  date: string;\n  isWeekMode: boolean;\n  rangeDate: [string, string];\n  getLunarInfo: (year: number, month: number, day: number) => any;\n  getEvents: (year: number, month: number, day: number) => any;\n}\n\nfunction isCurrentMonthToday(date: string) {\n  const todayString = getToday();\n  return todayString === date;\n}\n\nfunction rangeOption({selectDate, date}: any) {\n  const { start, end } = selectDate;\n  if (start === date) {\n    const notCompleteClassName = end ? '' : ' selected-range-not-complete';\n    return 'vc-day-selected selected-range-start' + notCompleteClassName;\n  }\n  if (end === date) {\n    return 'vc-day-selected selected-range-end';\n  }\n\n  if (start && end && date) {\n    const startTimeStamp: number = date2timeStamp(start);\n    const endTimeStamp: number = date2timeStamp(end);\n    const currentTimeStamp: number = date2timeStamp(date);\n\n    if (startTimeStamp < currentTimeStamp && currentTimeStamp < endTimeStamp) {\n      return 'vc-day-selected selected-range-includes';\n    }\n  }\n}\n\nfunction multiRangeOption({selectDate = [], date}: any) {\n  let className;\n  selectDate.some((selectItem: any) => {\n    const { start, end } = selectItem;\n    if (start === date) {\n      const notCompleteClassName = end ? '' : ' selected-range-not-complete';\n      className = 'vc-day-selected selected-range-start' + notCompleteClassName;\n      return true;\n    }\n    if (end === date) {\n      className = 'vc-day-selected selected-range-end';\n      return true;\n    }\n\n    if (start && end && date) {\n      const startTimeStamp: number = date2timeStamp(start);\n      const endTimeStamp: number = date2timeStamp(end);\n      const currentTimeStamp: number = date2timeStamp(date);\n\n      if (startTimeStamp < currentTimeStamp && currentTimeStamp < endTimeStamp) {\n        className = 'vc-day-selected selected-range-includes';\n        return true;\n      }\n    }\n  });\n  return className;\n}\n\nfunction multiOption({selectDate, date}: any) {\n  return selectDate.includes(date) ? 'vc-day-selected' : undefined;\n}\n\nfunction selectOption({date, selectDate}: any) {\n  return selectDate === date ? 'vc-day-selected' : undefined;\n}\n\ntype selectOptionType = {\n  date: string;\n  playload: any;\n  isWeekMode: boolean;\n  weekSwitch: boolean;\n  selectDate: string;\n  getLunarInfo: (year: number, month: number, day: number) => any;\n  getEvents: (year: number, month: number, day: number) => any;\n}\n\nconst disabledDate = (function () {\n  let disabledDates: any = {};\n  return function () {\n    return {\n      update(disabled: any[] = []) {\n        disabledDates = disabled.reduce((previousValue, currentValue) => {\n          previousValue[currentValue] = true;\n          return previousValue;\n        }, {});\n\n        return disabledDate;\n      },\n      isDisabled(date: string) {\n        return !!disabledDates[date];\n      }\n    };\n  };\n}());\n\nconst setTileContent = (function () {\n  let tileContentInfo: any = {};\n\n  return function () {\n    return {\n      update(tileContent: any) {\n        tileContentInfo = tileContent || [];\n      },\n      getTileContent(date: string) {\n        return {\n          tileContent: (tileContentInfo || {})[date]\n        };\n      }\n    };\n  };\n}());\n\nexport {\n  getToday,\n  rangeOption,\n  multiOption,\n  multiRangeOption,\n  selectOption,\n  disabledDate,\n  setRemark,\n  setTileContent,\n  getLunarInfo,\n  computedPrevMonth,\n  computedNextYear,\n  isCurrentMonthToday,\n  date2timeStamp,\n  computedNextDay,\n  computedPrevDay,\n  date2ymd,\n};\n"
  },
  {
    "path": "src/components/timetable/controller.ts",
    "content": "import { date2timeStamp } from './computed';\n\nfunction singleSelect(selectDate: string, date: string) {\n  return date;\n}\n\nfunction multiSelect(selectDate: string[] = [], date: string) {\n  const index = selectDate.indexOf(date);\n  if (~index) {\n    selectDate.splice(index, 1);\n    return selectDate;\n  }\n\n  selectDate.push(date);\n  return selectDate;\n}\n\nfunction rangeSelect(selectDate: { start?: string; end?: string }, date: string) {\n  const { start, end } = selectDate;\n\n  if (start && end) {\n    return {\n      start: date,\n      end: ''\n    };\n  }\n\n  if (start) {\n    if (start === date) {\n      return {};\n    }\n\n    if (date2timeStamp(start) > date2timeStamp(date)) {\n      return {\n        start: date,\n        end: start\n      };\n    }\n\n    return {\n      start,\n      end: date,\n    };\n  }\n\n  return {\n    start: date,\n    end,\n  };\n}\n\nfunction multiRange(selectDates: { start?: string; end?: string }[], date: string) {\n  const selects = [...selectDates];\n  let deleteIndex;\n\n  if (!selects.length) {\n    selects.push({start: date});\n    return selects;\n  }\n\n  const searchResult = selects.some((selectItem: any, index: number) => {\n    const { start, end } = selectItem;\n    if (start && end) {\n      if (date2timeStamp(start) < date2timeStamp(date) && date2timeStamp(date) < date2timeStamp(end)) {\n        return true;\n      }\n\n      if (start === date || end === date) {\n        deleteIndex = index;\n        return true;\n      }\n    } else if (start) {\n      const selectItemDate: { start: string; end: string } = { start: '', end: '' };\n      if (start === date) {\n        deleteIndex = index;\n        return true;\n      }\n      if (date2timeStamp(start) > date2timeStamp(date)) {\n        selectItemDate.start = date;\n        selectItemDate.end = start;\n      } else {\n        selectItemDate.start = start;\n        selectItemDate.end = date;\n      }\n\n      let isIncludeOtherRange;\n      if (selects.length > 1) {\n        isIncludeOtherRange = selects.some((item: any, i: number) => {\n          if (i === selects.length - 1) return;\n          const { start: prevItemDate } = item;\n\n          if (date2timeStamp(selectItemDate.start) < date2timeStamp(prevItemDate) && date2timeStamp(prevItemDate) < date2timeStamp(selectItemDate.end)) {\n            return true;\n          }\n        });\n      }\n\n      if (!isIncludeOtherRange) {\n        selectItem.start = selectItemDate.start;\n        selectItem.end = selectItemDate.end;\n      }\n\n      return true;\n    }\n  });\n\n  if (typeof deleteIndex === 'number') {\n    selects.splice(deleteIndex, 1);\n  } else if (!searchResult) {\n    selects.push({start: date});\n  }\n  return selects;\n}\n\nexport {\n  singleSelect,\n  multiSelect,\n  rangeSelect,\n  multiRange,\n};\n"
  },
  {
    "path": "src/components/timetable/declare.ts",
    "content": "interface TimeTableInterface {\n  monFirst?: boolean;\n  format?: (year: string | number, month: string | number) => any[];\n  weeks: string[];\n  tableMode: 'month' | 'week' | 'monthRange';\n  lunar?: any;\n  useSwipe: boolean;\n  tableIndex?: number;\n  timestamp?: number;\n  year?: string | number\n  month?: string | number\n  day?: string | number\n  begin?: string;\n  end?: string;\n  completion: boolean;\n  holidays?: {[key: string]: string};\n  tileContent: {className?: string, tileContent?: string}[];\n  remarks: {[key: string]: string};\n  selectMode: 'select' | 'multi' | 'range' | 'multiRange';\n  selectDate?: string | string[] | {start?: string, end?: string} | {start?: string, end?: string}[]\n  disabled: string[];\n};\n\ninterface SwipeInterface {\n  initialSlide?: number;\n  auto?: number;\n  speed: number;\n  loop?: boolean;\n}\n\ninterface SlideInterface {\n  className?: string;\n}\n\ntype startType = {\n  x: number;\n  y: number;\n  time: number;\n}\n\ntype deltaType = {\n  x: number;\n  y: number;\n}\n\nexport {\n  SwipeInterface,\n  SlideInterface,\n  startType,\n  deltaType,\n  TimeTableInterface,\n}\n"
  },
  {
    "path": "src/components/timetable/index.vue",
    "content": "<template>\n  <div\n    style='margin:0 auto'\n    class=\"vc-calendar-timetable\"\n    :class=\"{\n      'vc-calendar-timetable-prev': tableIndex === 0,\n      'vc-calendar-timetable-current': tableIndex === 1,\n      'vc-calendar-timetable-next': tableIndex === 2,\n    }\"\n  >\n    <div class=\"vc-calendar-timetable-wrap\">\n        <div\n          :class=\"['vc-calendar-body', `mc-range-mode-${tableMode}`]\"\n        >\n          <div class=\"vc-calendar-rang-head\" v-if=\"tableMode === 'monthRange'\">\n            <div class=\"vc-calendar-rang-year-month-box\">\n              <span className=\"vc-calendar-rang-head-year\">{{formatRangeMonth[0]}}</span>\n              <span className=\"vc-calendar-rang-head-month\">{{formatRangeMonth[1]}}</span>\n            </div>\n            <div class=\"vc-calendar-rang-week-box\">\n              <span v-for=\"(week, index) in weeks\" :key=\"index\">{{week}}</span>\n            </div>\n          </div>\n          <div className=\"vc-calendar-content\">\n            <div v-for=\"(days,k1) in monthRender.value\" :key=\"k1\" class=\"vc-calendar-row\" >\n              <div\n                v-for=\"(child,k2) in days\"\n                :key=\"k2\"\n                class=\"vc-calendar-day\"\n                :class=\"[\n                  {\n                    'vc-calendar-today': child.isToday,\n                    'vc-calendar-dayoff': k2 === (monFirst ? 5 : 0) || k2 === 6,\n                    'vc-calendar-disabled': child.disabled,\n                    'vc-calendar-prev-month-day': child.prevMonthDay,\n                    'vc-calendar-next-month-day': child.nextMonthDay,\n                    'vc-calendar-row-first': k2 === 0,\n                    'vc-calendar-row-last': k2 === 6,\n                    'month-last-date': child.lastDay, 'month-first-date': 1 === child.day,\n                    'mc-last-month': child.lastMonth,\n                    'mc-next-month': child.nextMonth\n                  },\n                  child.className,\n                  child.selectedClassName,\n                  child.rangeClassName\n                ]\"\n                @click=\"select(k1, k2, child, $event, index)\"\n              >\n                <div class=\"vc-calendar-day-container\">\n                  <span :class=\"['vc-calendar-date']\" >{{child.day}}</span>\n                  <div :class=\"['vc-calendar-slot-element', child.tileContent.className]\" v-if=\"child.tileContent\">{{child.tileContent.content}}</div>\n                  <div class=\"vc-calendar-remark-text\" v-if=\"child.remark\">{{child.remark}}</div>\n                  <div\n                    class=\"vc-calendar-almanac\"\n                    :class=\"{'vc-calendar-holiday': child.holiday, 'vc-calendar-isTerm': child.isTerm, 'isLunarFestival': child.isAlmanac || child.isLunarFestival, 'isGregorianFestival': child.isGregorianFestival}\"\n                  >\n                    {{child.holiday || child.lunarHoliday || child.gregorianHoliday || child.lunar}}\n                  </div>\n                </div>\n              </div>\n            </div>\n            <div v-if=\"backgroundText\" className=\"vc-calendar-month-background-text\">{{month}}</div>\n          </div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import { ref, reactive, watch, toRefs } from 'vue';\n  import { disabledDate, computedPrevDay, date2ymd, selectOption, multiOption, rangeOption,\n    multiRangeOption, getLunarInfo, isCurrentMonthToday, setTileContent, setRemark,\n    computedPrevMonth, computedNextYear, computedNextDay\n  } from './computed';\n  import { rangeSelect, singleSelect, multiSelect, multiRange } from './controller';\n  import { computedNextMonth, computedPrevYear } from '../utils';\n  import { TimeTableInterface } from './declare';\n  import './style.less';\n\n  const disabledDateHandle = disabledDate();\n  const setRemarkHandle = setRemark();\n  const setTileContentHandle = setTileContent();\n\n  export default {\n    props: {\n      format: {\n        type: Function,\n      },\n      weeks: {\n        type: Array,\n      },\n      tableMode: {\n        type: String,\n        default: 'month'\n      },\n      language: {\n        type: String,\n      },\n      year: {\n        type: [String, Number],\n      },\n      month: {\n        type: [String, Number],\n      },\n      day: {\n        type: [String, Number],\n      },\n      lunar: {\n        type: Object,\n      },\n      monFirst: {\n        type: Boolean,\n        default: true\n      },\n      useSwipe: {\n        type: Boolean,\n        default: true\n      },\n      backgroundText: {\n        type: Boolean,\n        default: true\n      },\n      tableIndex: {\n        type: Number,\n      },\n      begin: {\n        type: String,\n      },\n      end: {\n        type: String,\n      },\n      completion: {\n        type: Boolean,\n        default: false\n      },\n      holidays: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      tileContent: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      remarks: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      timestamp: {\n        type: Number,\n      },\n      selectMode: {\n        type: String,\n      },\n      disabled: {\n        type: Array,\n      },\n      selectDate: {\n        type: [String, Array, Object],\n      },\n    },\n    emits: ['onSelect', 'onMonthChange'],\n    setup(props: TimeTableInterface, { emit }: any) {\n      const { year, month, selectMode, tableMode: propsTableMode, monFirst, begin: propsBegin,\n        end: propsEnd, completion: propsCompletion, day, tileContent, disabled, remarks, holidays,\n        selectDate,\n      } = toRefs(props);\n\n      const tableMode = ref(propsTableMode);\n      const begin = ref(propsBegin);\n      const end = ref(propsEnd);\n      const completion = ref(propsTableMode.value === 'week' || propsCompletion.value);\n      const formatRangeMonth = ref([year?.value, month?.value]);\n      disabledDateHandle.update(disabled.value);\n      setRemarkHandle.update(remarks.value);\n      setTileContentHandle.update(tileContent.value);\n\n      function selectComputed(date: string) {\n        switch (selectMode.value) {\n          case 'range':\n            return rangeOption({selectDate: selectDate?.value, date} as any);\n          case 'multiRange':\n            return multiRangeOption({selectDate: selectDate?.value, date} as any);\n          case 'multi':\n            return multiOption({selectDate: selectDate?.value, date} as any);\n          case 'select':\n            return selectOption({selectDate: selectDate?.value, date});\n        }\n      }\n\n      function select(k1: any, k2: any, child: any) {\n        const { date, prevMonthDay, nextMonthDay } = child;\n\n        if (prevMonthDay || nextMonthDay) {\n          if (propsTableMode.value === 'monthRange') return;\n\n          return emit('onMonthChange', {prevMonthDay, nextMonthDay});\n        }\n\n        let selectValue;\n        switch (selectMode.value) {\n          case 'select':\n            selectValue = singleSelect(selectDate?.value as string, date);\n            break;\n          case 'multi':\n            selectValue = multiSelect(selectDate?.value as string[], date);\n            break;\n          case 'range':\n            selectValue = rangeSelect(selectDate?.value as {start?: string; end?: string}, date);\n            break;\n          case 'multiRange':\n            selectValue = multiRange(selectDate?.value as {start?: string; end?: string}[], date);\n            break;\n        }\n\n        emit('onSelect', selectValue);\n      }\n\n      function setDisabledDate(options: { year: string; month: string; i: string; date: string }) {\n        const { year: disYear, month: disMonth, i, date } = options;\n        const dateTimestamp = +new Date(Number(disYear), Number(disMonth) - 1, Number(i));\n        const disabledOptions = {} as { disabled: boolean };\n        if (begin.value) {\n          const [beginY, beginM, beginD] = begin.value.split('-');\n          const beginTimestamp = +new Date(Number(beginY), Number(beginM) - 1, Number(beginD));\n          if (beginTimestamp > dateTimestamp) {\n            disabledOptions.disabled = true;\n          }\n        }\n\n        if (end.value) {\n          const [endY, endM, endD] = end.value.split('-');\n          const endTimestamp = +new Date(Number(endY), Number(endM) - 1, Number(endD));\n          if (endTimestamp < dateTimestamp) {\n            disabledOptions.disabled = true;\n          }\n        }\n\n        if (disabledDateHandle.isDisabled(date)) {\n          disabledOptions.disabled = true;\n        }\n\n        return disabledOptions;\n      }\n\n      function getToday(date: string) {\n        return {\n          isToday: isCurrentMonthToday(date),\n        };\n      }\n\n      function renderOption({year, month, i, playload}: any) { // eslint-disable-line\n        const date = `${year}-${month}-${i}`;\n        const modeOptions = {\n          selectedClassName: selectComputed(date)\n        };\n        const options = {\n          day: i,\n          holiday: holidays?.value?.[`${month}-${i}`],\n          ...getLunarInfo(year, month, i, props.lunar),\n          ...setRemarkHandle.getRemark(date),\n          ...setTileContentHandle.getTileContent(date),\n          ...setDisabledDate({year, month, i, date}),\n          ...getToday(date),\n        };\n\n        return Object.assign(options, modeOptions);\n      }\n\n      const monthRender = reactive({value: render({year: year?.value, month: month?.value, day: day?.value})});\n\n      function render({year, month, day, renderer, payload}: any) { // eslint-disable-line\n        completion.value = propsTableMode.value === 'week' || propsCompletion.value;\n        const firstDayOfMonth = new Date(year, month - 1, 1).getDay(); //what day is the first day of the month\n        const lastDateOfCurrentMonth = new Date(year, month, 0).getDate(); //last date of current month\n        const lastDateOfLastMonth = new Date(year, month - 1, 0).getDate(); // last day Of last month\n\n        let firstWeekDayCompletionCount;\n        if (monFirst?.value) {\n          firstWeekDayCompletionCount = (firstDayOfMonth === 0 ? 7 : firstDayOfMonth) - 1;\n        } else {\n          firstWeekDayCompletionCount = firstDayOfMonth === 0 ? 0 : firstDayOfMonth;\n        }\n\n        const firstWeekDayCount = 7 - firstWeekDayCompletionCount;\n        const temp: any[] = [];\n\n        if (tableMode.value === 'week') {\n          let dayOfCurrentWeek = new Date(year, month - 1, day).getDay() - (monFirst?.value ? 1: 0); // what day is the current week\n          if (dayOfCurrentWeek === -1) { // when current day is sunday and use monFirst mode\n            dayOfCurrentWeek = 6;\n          }\n\n          temp.push(renderOption({year, month, i: day}));\n\n          let countDate = [year, month, day];\n          for (let i = 0; i < dayOfCurrentWeek; i++) {\n            const [y, m, d] = countDate;\n            const prevDate = computedPrevDay(y, m, d);\n            countDate = date2ymd(prevDate);\n            temp.unshift(renderOption({year: countDate[0], month: countDate[1], i: countDate[2]}));\n          }\n\n          countDate = [year, month, day];\n          for (let i = dayOfCurrentWeek; i < 6; i++) {\n            const [y, m, d] = countDate;\n            const nextDate = computedNextDay(y, m, d);\n            countDate = date2ymd(nextDate);\n            temp.push(renderOption({year: countDate[0], month: countDate[1], i: countDate[2]}));\n          }\n\n          return [temp];\n        }\n\n        let line = 0;\n        for (let i = 1; i <= lastDateOfCurrentMonth; i++) {\n          if (!Array.isArray(temp[line])) temp[line] = [];\n\n          if (line === 0) {\n            temp[line].push(renderOption({year, month, i}));\n            if (temp[line].length === firstWeekDayCount) {\n              line += 1;\n            }\n          } else {\n            temp[line].push(renderOption({year, month, i}));\n            if (temp[line].length === 7) line += 1;\n          }\n        }\n\n        if (completion.value) {\n          //completion prev month\n          let completionCounting = 0;\n          const [prevYear, prevMonth] = [computedPrevYear(year, month), computedPrevMonth(month)];\n          while (firstWeekDayCompletionCount !== completionCounting) {\n            temp[0].unshift(Object.assign(\n              renderOption({year: prevYear, month: prevMonth, i: lastDateOfLastMonth - completionCounting}),\n              {prevMonthDay: true, disabled: true},\n            ));\n            completionCounting += 1;\n          }\n\n          //completion next month\n          const completionWeeksCount = (5 - line) > 0 ? 5 - line : 0;\n          const [nextYear, nextMonth] = [computedNextYear(year, month), computedNextMonth(month)];\n\n          if (!Array.isArray(temp[line])) temp[line] = [];\n\n          const lastWeekDayCompletionCount = 7 - temp[line].length + (7 * completionWeeksCount);\n          let completionCountingNext = 0;\n\n          while (lastWeekDayCompletionCount !== completionCountingNext) {\n            if (temp[line].length === 7) {\n              line += 1;\n              temp[line] = [];\n              continue;\n            }\n\n            completionCountingNext += 1;\n            temp[line].push(Object.assign(\n              renderOption({year: nextYear, month: nextMonth, i: completionCountingNext}),\n              {nextMonthDay: true, disabled: true},\n            ));\n          }\n        } else if (firstWeekDayCompletionCount) {\n          temp[0].unshift(...Array.from({length: firstWeekDayCompletionCount}).fill('PLACEHOLDER'));\n        }\n\n        return temp;\n      }\n\n      function refreshRender() {\n        monthRender.value = render({year: year?.value, month: month?.value, day: day?.value});\n      }\n\n      function formatYearAndMonth() {\n        const { format } = props;\n        if (format) {\n          formatRangeMonth.value = format(year?.value as any, month?.value as any);\n        } else {\n          formatRangeMonth.value = [`${year?.value}-`, month?.value];\n        }\n      }\n\n      formatYearAndMonth();\n\n      watch(() => props.timestamp, () => {\n        disabledDateHandle.update(disabled.value);\n        setRemarkHandle.update(remarks.value);\n        setTileContentHandle.update(tileContent.value);\n        refreshRender();\n      });\n\n      watch(() => [props.monFirst, props.completion, props.year, props.month, props.day], () => {\n        refreshRender();\n      });\n\n      watch(() => props.month, () => {\n        formatYearAndMonth();\n      });\n\n      return {\n        select,\n        monthRender,\n        selectComputed,\n        refreshRender,\n        formatRangeMonth,\n      };\n    }\n  };\n</script>\n"
  },
  {
    "path": "src/components/timetable/style.less",
    "content": ".vc-calendar-timetable{\n  background: #fff;\n  padding-bottom: 10px;\n  .vc-calendar-timetable-wrap{\n    .vc-calendar-body{\n      .vc-calendar-row{\n        overflow: hidden;\n        .vc-calendar-day{\n          -webkit-tap-highlight-color:transparent;\n          width: 14.285714285714285%;\n          position: relative;\n          float: left;\n          color: #7C86A2;\n          cursor: pointer;\n          padding: 1%;\n          box-sizing: border-box;\n          &:before{\n            content: '';\n            padding-top: 100%;\n            display: block;\n            position: relative;\n            z-index: 1;\n          }\n          &.selected-range-includes{\n            &:after{\n              content: '';\n              display: block;\n              position: absolute;\n              width: 100%;\n              height: 86%;\n              background: #E8F4FF ;\n              top: 7%;\n              z-index: 1;\n            }\n          }\n          &.selected-range-start{\n            &:after{\n              content: '';\n              display: block;\n              position: absolute;\n              width: 100%;\n              height: 86%;\n              background: #E8F4FF ;\n              top: 7%;\n              z-index: 0;\n              left: 50%;\n            }\n            &.selected-range-not-complete, &.vc-calendar-row-last{\n              &:after{\n                content: none;\n              }\n            }\n          }\n          .vc-calendar-day-container{\n            position: absolute;\n            left: 0;\n            right: 0;\n            top: 0;\n            bottom: 0;\n            padding: 1%;\n            z-index: 3;\n          }\n          &.vc-day-selected{\n            &:before{\n              background: #60CDFF;\n              overflow: hidden;\n              border-radius: 4%;\n            }\n            .vc-calendar-date{\n              color: #fff;\n            }\n            &.selected-range-includes{\n              .vc-calendar-date{\n                color: #7C86A2;\n              }\n            }\n          }\n          &.vc-calendar-dayoff{\n            .vc-calendar-date {\n              color: #FF6260;\n            }\n          }\n          .vc-calendar-date{\n            width: 100%;\n            display: block;\n            position: absolute;\n            text-align: center;\n            top: 50%;\n            transform: translateY(-50%);\n          }\n          .vc-calendar-almanac{\n            display: block;\n            position: absolute;\n            bottom: 8%;\n            font-size: 12px;\n            width: 100%;\n            text-align: center;\n            &.vc-calendar-holiday, &.vc-calendar-isTerm{\n              color: #FF6260;\n            }\n          }\n          .vc-calendar-slot-element{\n            font-size: 12px;\n            position: absolute;\n            top: 0;\n          }\n          .vc-calendar-text{\n            font-size: 12px;\n            position: absolute;\n            bottom: 0;\n            width: 100%;\n            display: block;\n            text-align: center;\n          }\n          &.vc-calendar-disabled{\n            pointer-events: none;\n            .vc-calendar-day-container{\n              .vc-calendar-date, .vc-calendar-almanac{\n                color: #ccc;\n              }\n            }\n            &.vc-calendar-prev-month-day, &.vc-calendar-next-month-day{\n              pointer-events: inherit;\n            }\n          }\n        }\n      }\n      .vc-calendar-rang-head{\n        .vc-calendar-rang-week-box{\n          width: 100%;\n          display: flex;\n          align-items: center;\n          height: 30px;\n          margin-top: 10px;\n          span{\n            flex: 1;\n            text-align: center;\n            color: #6B7897;\n          }\n        }\n        .vc-calendar-rang-year-month-box{\n          background: #fafafa;\n          padding: 10px 0;\n          color: #646464;\n          text-align: center;\n          font-size: 16px;\n        }\n      }\n      .vc-calendar-content{\n        position: relative;\n        .vc-calendar-month-background-text{\n          position: absolute;\n          top: 50%;\n          text-align: center;\n          width: 100%;\n          font-size: 200px;\n          transform: translateY(-50%);\n          font-weight: 900;\n          color: #f4f5f9;\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/tools/index.vue",
    "content": "<template>\n  <div\n    class=\"vc-calendar-tools\"\n    ref=\"toolsRef\"\n    v-if=\"tableMode !== 'monthRange'\"\n  >\n    <div\n      class=\"vc-calendar-tools-container\"\n    >\n      <div class=\"vc-calendar-prev\" @click=\"prev\">\n        <img :src=\"arrowLeft\" v-if=\"arrowLeft\" />\n        <i class=\"iconfont icon-arrow-left\" v-else />\n      </div>\n      <div class=\"vc-calendar-next\" @click=\"next\">\n        <img :src=\"arrowRight\" v-if=\"arrowRight\" />\n        <i class=\"iconfont icon-arrow-right\" v-else />\n      </div>\n      <div class=\"vc-calendar-info\" @click.stop=\"switchDate\">\n        <div class=\"vc-calendar-year\">{{formatText[0]}}</div>\n        <div class=\"vc-calendar-month\">{{formatText[1]}}</div>\n      </div>\n    </div>\n    <div\n      class=\"vc-calendar-picker\"\n      :class=\"{'vc-picker-show': pickerVisible}\"\n      :style=\"{height: toolsStyle.timetableHeight + toolsStyle.weekHeadHeight + toolsStyle.toolsHeight + 'px', paddingTop: toolsStyle.toolsHeight + 'px'}\"\n    >\n      <div :class=\"['vc-calendar-months', {'vc-calendar-week-switch-months': weekSwitch}]\">\n        <span\n          v-for=\"(m, i) in months\"\n          :key=\"m\"\n          @click.stop=\"selectMonth(i + 1)\"\n          :class=\"{'piecker-month-active': (i + 1) === month}\"\n        >\n          <i>{{m}}</i>\n        </span>\n      </div>\n      <div class=\"vc-calendar-years\">\n        <span\n          v-for=\"y in years\"\n          :key=\"y\"\n          @click.stop=\"selectYearHandle(y)\"\n          :class=\"{'piecker-year-active': y === year}\"\n        >\n          <i>{{y}}</i>\n        </span>\n      </div>\n    </div>\n    <div class=\"vc-calendar-week-head\">\n      <div class=\"vc-calendar-week-head-container\">\n        <div v-for=\"(weekItem, index) in weeks\" :key=\"index\" class=\"vc-calendar-week-item\">{{weekItem}}</div>\n      </div>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import { ref, reactive, watch, toRefs } from 'vue';\n  import './style.less';\n  import '../icon/icon.css';\n\n  export default {\n    props: {\n      months: {\n        type: Array,\n      },\n      weeks: {\n        type: Array,\n      },\n      weekSwitch: {\n        type: Boolean,\n        default: false\n      },\n      monFirst: {\n        type: Boolean,\n        default: false\n      },\n      format: {\n        type: Function,\n      },\n      tableMode: {\n        type: String,\n        default: 'month'\n      },\n      arrowLeft: {\n        type: String,\n        default: ''\n      },\n      arrowRight: {\n        type: String,\n        default: ''\n      },\n      year: {\n        type: [String, Number],\n      },\n      month: {\n        type: [String, Number],\n      },\n      timetableHeight: {\n        type: Number,\n      }\n    },\n    emits: ['next', 'prev', 'selectMonth', 'selectYear', 'onMonthChange'],\n    setup(props: any, { emit }: any) {\n      const { year, month, tableMode } = toRefs(props);\n      const pickerVisible = ref(false);\n      const toolsStyle = reactive({\n        toolsContainerHeight: 0,\n        toolsHeight: 0,\n        timetableHeight: 0,\n        weekHeadHeight: 0,\n      });\n      const toolsRef = ref();\n      const formatText = ref([] as string[]);\n      const years = ref(createYears(year.value));\n\n      function selectMonth(selectedMonth: number) {\n        pickerVisible.value = false;\n        emit('selectMonth', year.value, selectedMonth);\n        emit('onMonthChange', year.value, selectedMonth);\n      }\n\n      function selectYearHandle(selectedYear: number) {\n        pickerVisible.value = false;\n        years.value = createYears(selectedYear);\n        emit('selectYear', selectedYear, month.value);\n        emit('onMonthChange', selectedYear, month.value);\n      }\n\n      function next() {\n        emit('next', year.value, month.value);\n      }\n\n      function prev() {\n        emit('prev', year.value, month.value);\n      }\n\n      function switchDate() {\n        if (tableMode.value === 'week') return;\n\n        toolsStyle.toolsContainerHeight = toolsRef.value.clientHeight;\n        toolsStyle.toolsHeight = toolsRef.value.querySelector('.vc-calendar-tools-container').clientHeight;\n        toolsStyle.weekHeadHeight = toolsRef.value.querySelector('.vc-calendar-week-head').clientHeight;\n        toolsStyle.timetableHeight = toolsRef.value.parentNode.querySelector('.vc-calendar-timetable-current').clientHeight;\n        pickerVisible.value = !pickerVisible.value;\n      }\n\n      function formatYearAndMonth() {\n        const { format } = props;\n        if (format) {\n          return formatText.value = format(year.value, month.value);\n        }\n        formatText.value = [`${year.value}-`, `${month.value}`];\n      }\n\n      formatYearAndMonth();\n\n      watch(year, () => {\n        formatYearAndMonth();\n      });\n\n      watch(month, () => {\n        formatYearAndMonth();\n        if (pickerVisible.value) {\n          setTimeout(() => {\n            toolsStyle.timetableHeight = toolsRef.value.parentNode.querySelector('.vc-calendar-timetable-current').clientHeight;\n          });\n        }\n\n        if (!years.value.includes(year.value)) {\n          years.value = createYears(year.value);\n        }\n      });\n\n      function createYears(creatorYear: number) {\n        const yearRange = [];\n        for (let i = creatorYear - 7; i < creatorYear + 8; i++) {\n          yearRange.push(i);\n        }\n        return yearRange;\n      }\n\n      return {\n        next,\n        prev,\n        years,\n        selectMonth,\n        selectYearHandle,\n        pickerVisible,\n        switchDate,\n        toolsStyle,\n        toolsRef,\n        formatText,\n      };\n    }\n  };\n</script>\n"
  },
  {
    "path": "src/components/tools/style.less",
    "content": ".vc-calendar-tools {\n  margin: auto;\n  width: 100%;\n  background: #fff;\n  user-select: none;\n  position: relative;\n  .vc-calendar-tools-container {\n    height: 40px;\n    font-size: 20px;\n    line-height: 40px;\n    color: #5e7a88;\n    -webkit-box-shadow: 0 4px 8px rgba(25, 47, 89, .1);\n    box-shadow: 0 4px 8px rgba(25, 47, 89, .1);\n    border-top: 1px solid hsla(0, 0%, 78.4%, .1);\n    z-index: 5;\n    position: relative;\n  }\n  .vc-calendar-week-head{\n    .vc-calendar-week-head-container{\n      width: 100%;\n      display: flex;\n      align-items: center;\n      height: 30px;\n      padding-top: 10px;\n      .vc-calendar-week-item{\n        flex: 1;\n        text-align: center;\n        color: #6B7897;\n      }\n    }\n  }\n  .vc-calendar-prev, .vc-calendar-next {\n    cursor: pointer;\n    img {\n      width: 34px;\n      height: 34px;\n    }\n  }\n  .vc-calendar-prev {\n    width: 14.28571429%;\n    float: left;\n    text-align: center;\n  }\n  .vc-calendar-next {\n    width: 14.28571429%;\n    float: right;\n    text-align: center;\n  }\n  .vc-calendar-info {\n    font-size: 16px;\n    width: 50%;\n    margin: 0 auto;\n    height: 100%;\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    cursor: pointer;\n    .vc-calendar-month {\n      color: #5e7a88;\n    }\n    .vc-calendar-year {\n      color: #5e7a88;\n    }\n  }\n  .vc-calendar-picker{\n    color: #5e7a88;\n    opacity: 0;\n    position: absolute;\n    top: 0px;\n    background: #fff;\n    width: 100%;\n    height: 100%;\n    z-index: 4;\n    display: none;\n    box-sizing: border-box;\n    >div{\n      height: 50%;\n    }\n    &.vc-picker-show{\n      animation-name: pickerShow;\n      animation-duration: .3s;\n      animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);\n      animation-fill-mode: both;\n      display: block;\n      @keyframes pickerShow {\n        from {\n          top: -30%;\n          opacity: 0;\n        }\n        to {\n          top: 0;\n          opacity: 1;\n        }\n      }\n    }\n    .vc-calendar-months{\n      display: flex;\n      flex-wrap: wrap;\n      padding: 10px 5px;\n      position: relative;\n      box-sizing: border-box;\n      .piecker-month-active{\n        i{\n          background: #60CDFF;\n          color: #fff;\n          border-radius: 5px;\n          box-shadow: 2px 2px 2px rgba(0, 81, 118, .1);\n        }\n      }\n      &:after {\n        content: '';\n        display: block;\n        width: 94%;\n        height: 1px;\n        background-color: #eee;\n        position: absolute;\n        bottom: 0;\n        left: 3%;\n      }\n      span{\n        flex-basis: 25%;\n        text-align: center;\n        font-size: 16px;\n        position: relative;\n        i{\n          position: absolute;\n          font-style: normal;\n          text-align: center;\n          word-break: keep-all;\n          left: 50%;\n          top: 50%;\n          transform: translate3d(-50%, -50%, 0);\n          padding: 5% 22%;\n          cursor: pointer;\n        }\n      }\n    }\n    .vc-calendar-years{\n      display: flex;\n      flex-wrap: wrap;\n      padding: 10px 5px;\n      box-sizing: border-box;\n      .piecker-year-active{\n        i{\n          background: #60CDFF;\n          color: #fff;\n          border-radius: 5px;\n          box-shadow: 2px 2px 2px rgba(0, 81, 118, .1);\n        }\n      }\n      span{\n        flex-basis: 20%;\n        text-align: center;\n        margin-bottom: 10px;\n        font-size: 16px;\n        position: relative;\n        i{\n          position: absolute;\n          font-style: normal;\n          text-align: center;\n          word-break: keep-all;\n          left: 50%;\n          top: 50%;\n          transform: translate3d(-50%, -50%, 0);\n          padding: 5% 22%;\n          cursor: pointer;\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/components/utils/index.ts",
    "content": "function noop() {} // eslint-disable-line\n\nfunction computedNextYear(year: string | number, month: string | number): number {\n  if ((Number(month) + 1) > 12) {\n    return Number(year) + 1;\n  }\n  return Number(year);\n}\n\nfunction computedPrevYear(year: string | number, month: string | number): number {\n  if ((Number(month) - 1 - 1) < 0) {\n    return Number(year) - 1;\n  }\n\n  return +year;\n}\n\nfunction date2ymd(date: string): number[] {\n  const [y, m, d] = date.split('-');\n  return [Number(y), Number(m), Number(d)];\n}\n\nfunction offloadFn(fn: any) {\n  setTimeout(fn || noop, 0);\n}\n\nfunction language(): string {\n  return (navigator.language || (navigator as any).browserLanguage).toLowerCase();\n}\n\nfunction isZh(languageValue?: string) {\n  if (languageValue) {\n    return languageValue === 'cn';\n  }\n  return language() === 'zh-cn';\n}\n\nconst enWeeks = ['Sun', 'Mon', 'Tue', 'Wed', 'Thur', 'Fri', 'Sat'];\nconst zhWeeks = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];\nconst enMonths = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'];\nconst zhMonths = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'];\n\nfunction getWeeks(languageParam: string) {\n  return isZh(languageParam) ? zhWeeks : enWeeks;\n}\n\nfunction getMonths(languageParam: string | undefined) {\n  return isZh(languageParam) ? zhMonths : enMonths;\n}\n\nfunction computedNextMonth(month: string | number) {\n  if ((Number(month) + 1) > 12) {\n    return 1;\n  } else {\n    return Number(month) + 1;\n  }\n}\n\nfunction computedPrevMonth(month: string | number): number {\n  if ((Number(month) - 1) === 0) {\n    return 12;\n  } else {\n    return Number(month) - 1;\n  }\n}\n\nfunction getDateByCount(date: string, count: number): string {\n  const [y, m, d] = date2ymd(date);\n  const timestamp = +new Date(y, m - 1, d);\n  const dateObj = new Date(timestamp + count * 86400000);\n  const year = dateObj.getFullYear();\n  const month = dateObj.getMonth();\n  const day = dateObj.getDate();\n  return `${year}-${month + 1}-${day}`;\n}\n\nfunction getPrevDate(year: string | number, month: string | number, day?: string | number): any[] {\n  if (day) {\n    return date2ymd(getDateByCount(`${year}-${month}-${day}`, -7));\n  }\n  return [computedPrevYear(year, month), computedPrevMonth(month)];\n}\n\nfunction getNextDate(year: string | number, month: string | number, day?: string | number): any[] {\n  if (day) {\n    return date2ymd(getDateByCount(`${year}-${month}-${day}`, 7));\n  }\n  return [computedNextYear(year, month), computedNextMonth(month)];\n}\n\nfunction delay(time?: number) {\n  return new Promise(resolve => setTimeout(() => resolve(), time || 0));\n}\n\nfunction getToday(needArray?: boolean) {\n  const now = new Date();\n  const year = now.getFullYear();\n  const month = now.getMonth() + 1;\n  const day = now.getDate();\n\n  if (needArray) {\n    return [year, month, day];\n  }\n  return [year, month, day].join('-');\n}\n\nfunction getSomeNextMonths(year: string | number, month: string | number, count: number) {\n  let currentYear = year;\n  let currentMonth = month;\n  return Array.from({length: count}).map((v, index) => {\n    if (!index) {\n      return `${currentYear}-${currentMonth}`;\n    }\n    const [y, m] = getNextDate(currentYear, currentMonth);\n    currentYear = y;\n    currentMonth = m;\n    return `${currentYear}-${currentMonth}`;\n  });\n}\n\nexport {\n  noop,\n  isZh,\n  delay,\n  language,\n  offloadFn,\n  zhWeeks,\n  enWeeks,\n  date2ymd,\n  getDateByCount,\n  computedNextMonth,\n  computedPrevMonth,\n  getPrevDate,\n  getNextDate,\n  getToday,\n  getWeeks,\n  getMonths,\n  computedPrevYear,\n  computedNextYear,\n  getSomeNextMonths,\n};\n"
  },
  {
    "path": "src/declare.ts",
    "content": "interface CalendarInterface {\n  monFirst?: boolean;\n  completion?: boolean;\n  useSwipe?: boolean;\n  weeks?: string[];\n  className?: string;\n  language?: string;\n  holidays: {[key: string]: string};\n  tileContent: {[key: string]: any };\n  remarks: {[key: string]: any };\n  disabled: string[];\n  begin: string[];\n  end: string[];\n  monthRange: string[];\n  mode: 'monthRange' | 'week' | 'month';\n  selectMode: 'select' | 'multi' | 'range' | 'multiRange';\n  lunar: any;\n  selectDate: any;\n  format: (year: string, month: string) => string[];\n}\n\nexport {\n  CalendarInterface,\n}\n"
  },
  {
    "path": "src/lunar.ts",
    "content": "// @ts-nocheck\n/**\n * @1900-2100区间内的公历、农历互转\n * @charset UTF-8\n * @Author  Jea杨(JJonline@JJonline.Cn)\n * @Time    2014-7-21\n * @Time    2016-8-13 Fixed 2033hex、Attribution Annals\n * @Time    2016-9-25 Fixed lunar LeapMonth Param Bug\n * @Version 1.0.2\n * @公历转农历：calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]\n * @农历转公历：calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]\n */\nvar calendar = {\n\n  /**\n   * 农历1900-2100的润大小信息表\n   * @Array Of Property\n   * @return Hex\n   */\n  lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909\n    0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919\n    0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929\n    0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939\n    0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949\n    0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959\n    0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969\n    0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979\n    0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989\n    0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999\n    0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009\n    0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019\n    0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029\n    0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039\n    0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049\n    /**Add By JJonline@JJonline.Cn**/\n    0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059\n    0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069\n    0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079\n    0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089\n    0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099\n    0x0d520],//2100\n\n  /**\n   * 公历每个月份的天数普通表\n   * @Array Of Property\n   * @return Number\n   */\n  solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],\n\n  /**\n   * 农历节日\n   * @return String\n   */\n  lunarHoliday: {\n    '1-1': '春节',\n    '1-15': '元宵节',\n    '2-2': '龙头节',\n    '5-5': '端午节',\n    '7-7': '七夕节',\n    '7-15': '中元节',\n    '8-15': '中秋节',\n    '9-9': '重阳节',\n    '10-1': '寒衣节',\n    '10-15': '下元节',\n    '12-8': '腊八节',\n    '12-23': '小年',\n  },\n\n  /**\n   * 阳历节日\n   * @return String\n   */\n  gregorianHoliday: {\n    '1-1': '元旦',\n    '2-14': '情人节',\n    '3-8': '妇女节',\n    '3-12': '植树节',\n    '5-1': '劳动节',\n    '5-4': '青年节',\n    '6-1': '儿童节',\n    '7-1': '建党节',\n    '8-1': '建军节',\n    '9-10': '教师节',\n    '10-1': '国庆节',\n    '12-24': '平安夜',\n    '12-25': '圣诞节',\n  },\n\n  /**\n   * 天干地支之天干速查表\n   * @Array Of Property trans[\"甲\",\"乙\",\"丙\",\"丁\",\"戊\",\"己\",\"庚\",\"辛\",\"壬\",\"癸\"]\n   * @return Cn string\n   */\n  Gan:[\"\\u7532\",\"\\u4e59\",\"\\u4e19\",\"\\u4e01\",\"\\u620a\",\"\\u5df1\",\"\\u5e9a\",\"\\u8f9b\",\"\\u58ec\",\"\\u7678\"],\n\n  /**\n   * 天干地支之地支速查表\n   * @Array Of Property\n   * @trans[\"子\",\"丑\",\"寅\",\"卯\",\"辰\",\"巳\",\"午\",\"未\",\"申\",\"酉\",\"戌\",\"亥\"]\n   * @return Cn string\n   */\n  Zhi:[\"\\u5b50\",\"\\u4e11\",\"\\u5bc5\",\"\\u536f\",\"\\u8fb0\",\"\\u5df3\",\"\\u5348\",\"\\u672a\",\"\\u7533\",\"\\u9149\",\"\\u620c\",\"\\u4ea5\"],\n\n  /**\n   * 天干地支之地支速查表<=>生肖\n   * @Array Of Property\n   * @trans[\"鼠\",\"牛\",\"虎\",\"兔\",\"龙\",\"蛇\",\"马\",\"羊\",\"猴\",\"鸡\",\"狗\",\"猪\"]\n   * @return Cn string\n   */\n  Animals:[\"\\u9f20\",\"\\u725b\",\"\\u864e\",\"\\u5154\",\"\\u9f99\",\"\\u86c7\",\"\\u9a6c\",\"\\u7f8a\",\"\\u7334\",\"\\u9e21\",\"\\u72d7\",\"\\u732a\"],\n\n  /**\n   * 24节气速查表\n   * @Array Of Property\n   * @trans[\"小寒\",\"大寒\",\"立春\",\"雨水\",\"惊蛰\",\"春分\",\"清明\",\"谷雨\",\"立夏\",\"小满\",\"芒种\",\"夏至\",\"小暑\",\"大暑\",\"立秋\",\"处暑\",\"白露\",\"秋分\",\"寒露\",\"霜降\",\"立冬\",\"小雪\",\"大雪\",\"冬至\"]\n   * @return Cn string\n   */\n  solarTerm:[\"\\u5c0f\\u5bd2\",\"\\u5927\\u5bd2\",\"\\u7acb\\u6625\",\"\\u96e8\\u6c34\",\"\\u60ca\\u86f0\",\"\\u6625\\u5206\",\"\\u6e05\\u660e\",\"\\u8c37\\u96e8\",\"\\u7acb\\u590f\",\"\\u5c0f\\u6ee1\",\"\\u8292\\u79cd\",\"\\u590f\\u81f3\",\"\\u5c0f\\u6691\",\"\\u5927\\u6691\",\"\\u7acb\\u79cb\",\"\\u5904\\u6691\",\"\\u767d\\u9732\",\"\\u79cb\\u5206\",\"\\u5bd2\\u9732\",\"\\u971c\\u964d\",\"\\u7acb\\u51ac\",\"\\u5c0f\\u96ea\",\"\\u5927\\u96ea\",\"\\u51ac\\u81f3\"],\n\n  /**\n   * 1900-2100各年的24节气日期速查表\n   * @Array Of Property\n   * @return 0x string For splice\n   */\n  sTermInfo:['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',\n    '97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',\n    '97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',\n    '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',\n    'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',\n    '97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',\n    '97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',\n    '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',\n    '97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',\n    '97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',\n    '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',\n    '97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',\n    '97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',\n    '9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',\n    '97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',\n    '97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',\n    '9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',\n    '7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',\n    '97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',\n    '9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',\n    '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',\n    '97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',\n    '9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',\n    '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',\n    '97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',\n    '9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',\n    '7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',\n    '7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',\n    '9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',\n    '7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',\n    '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',\n    '97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',\n    '9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',\n    '7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',\n    '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',\n    '977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',\n    '7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',\n    '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',\n    '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',\n    '977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',\n    '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',\n    '7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',\n    '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',\n    '977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',\n    '7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',\n    '7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',\n    '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',\n    '7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',\n    '7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',\n    '7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',\n    '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',\n    '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',\n    '7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',\n    '7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',\n    '7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',\n    '7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',\n    '7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',\n    '7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',\n    '665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',\n    '7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',\n    '7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',\n    '7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],\n\n  /**\n   * 数字转中文速查表\n   * @Array Of Property\n   * @trans ['日','一','二','三','四','五','六','七','八','九','十']\n   * @return Cn string\n   */\n  nStr1:[\"\\u65e5\",\"\\u4e00\",\"\\u4e8c\",\"\\u4e09\",\"\\u56db\",\"\\u4e94\",\"\\u516d\",\"\\u4e03\",\"\\u516b\",\"\\u4e5d\",\"\\u5341\"],\n\n  /**\n   * 日期转农历称呼速查表\n   * @Array Of Property\n   * @trans ['初','十','廿','卅']\n   * @return Cn string\n   */\n  nStr2:[\"\\u521d\",\"\\u5341\",\"\\u5eff\",\"\\u5345\"],\n\n  /**\n   * 月份转农历称呼速查表\n   * @Array Of Property\n   * @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']\n   * @return Cn string\n   */\n  nStr3:[\"\\u6b63\",\"\\u4e8c\",\"\\u4e09\",\"\\u56db\",\"\\u4e94\",\"\\u516d\",\"\\u4e03\",\"\\u516b\",\"\\u4e5d\",\"\\u5341\",\"\\u51ac\",\"\\u814a\"],\n\n  /**\n   * 返回农历y年一整年的总天数\n   * @param lunar Year\n   * @return Number\n   * @eg:var count = calendar.lYearDays(1987) ;//count=387\n   */\n  lYearDays:function(y) {\n    var i, sum = 348;\n    for(i=0x8000; i>0x8; i>>=1) { sum += (calendar.lunarInfo[y-1900] & i)? 1: 0; }\n    return(sum+calendar.leapDays(y));\n  },\n\n  /**\n   * 返回农历y年闰月是哪个月；若y年没有闰月 则返回0\n   * @param lunar Year\n   * @return Number (0-12)\n   * @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6\n   */\n  leapMonth:function(y) { //闰字编码 \\u95f0\n    return(calendar.lunarInfo[y-1900] & 0xf);\n  },\n\n  /**\n   * 返回农历y年闰月的天数 若该年没有闰月则返回0\n   * @param lunar Year\n   * @return Number (0、29、30)\n   * @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29\n   */\n  leapDays:function(y) {\n    if(calendar.leapMonth(y))  {\n      return((calendar.lunarInfo[y-1900] & 0x10000)? 30: 29);\n    }\n    return(0);\n  },\n\n  /**\n   * 返回农历y年m月（非闰月）的总天数，计算m为闰月时的天数请使用leapDays方法\n   * @param lunar Year\n   * @return Number (-1、29、30)\n   * @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29\n   */\n  monthDays:function(y,m) {\n    if(m>12 || m<1) {return -1}//月份参数从1至12，参数错误返回-1\n    return( (calendar.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 );\n  },\n\n  /**\n   * 返回公历(!)y年m月的天数\n   * @param solar Year\n   * @return Number (-1、28、29、30、31)\n   * @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30\n   */\n  solarDays:function(y,m) {\n    if(m>12 || m<1) {return -1} //若参数错误 返回-1\n    var ms = m-1;\n    if(ms==1) { //2月份的闰平规律测算后确认返回28或29\n      return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28);\n    }else {\n      return(calendar.solarMonth[ms]);\n    }\n  },\n\n  /**\n   * 农历年份转换为干支纪年\n   * @param  lYear 农历年的年份数\n   * @return Cn string\n   */\n  toGanZhiYear:function(lYear) {\n    var ganKey = (lYear - 3) % 10;\n    var zhiKey = (lYear - 3) % 12;\n    if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干\n    if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支\n    return calendar.Gan[ganKey-1] + calendar.Zhi[zhiKey-1];\n\n  },\n\n  /**\n   * 公历月、日判断所属星座\n   * @param  cMonth [description]\n   * @param  cDay [description]\n   * @return Cn string\n   */\n  toAstro:function(cMonth,cDay) {\n    var s   = \"\\u9b54\\u7faf\\u6c34\\u74f6\\u53cc\\u9c7c\\u767d\\u7f8a\\u91d1\\u725b\\u53cc\\u5b50\\u5de8\\u87f9\\u72ee\\u5b50\\u5904\\u5973\\u5929\\u79e4\\u5929\\u874e\\u5c04\\u624b\\u9b54\\u7faf\";\n    var arr = [20,19,21,21,21,22,23,23,23,23,22,22];\n    return s.substr(cMonth*2 - (cDay < arr[cMonth-1] ? 2 : 0),2) + \"\\u5ea7\";//座\n  },\n\n  /**\n   * 传入offset偏移量返回干支\n   * @param offset 相对甲子的偏移量\n   * @return Cn string\n   */\n  toGanZhi:function(offset) {\n    return calendar.Gan[offset%10] + calendar.Zhi[offset%12];\n  },\n\n  /**\n   * 传入公历(!)y年获得该年第n个节气的公历日期\n   * @param y公历年(1900-2100)；n二十四节气中的第几个节气(1~24)；从n=1(小寒)算起\n   * @return day Number\n   * @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春\n   */\n  getTerm:function(y,n) {\n    if(y<1900 || y>2100) {return -1;}\n    if(n<1 || n>24) {return -1;}\n    var _table = calendar.sTermInfo[y-1900];\n    var _info = [\n      parseInt('0x'+_table.substr(0,5)).toString() ,\n      parseInt('0x'+_table.substr(5,5)).toString(),\n      parseInt('0x'+_table.substr(10,5)).toString(),\n      parseInt('0x'+_table.substr(15,5)).toString(),\n      parseInt('0x'+_table.substr(20,5)).toString(),\n      parseInt('0x'+_table.substr(25,5)).toString()\n    ];\n    var _calday = [\n      _info[0].substr(0,1),\n      _info[0].substr(1,2),\n      _info[0].substr(3,1),\n      _info[0].substr(4,2),\n\n      _info[1].substr(0,1),\n      _info[1].substr(1,2),\n      _info[1].substr(3,1),\n      _info[1].substr(4,2),\n\n      _info[2].substr(0,1),\n      _info[2].substr(1,2),\n      _info[2].substr(3,1),\n      _info[2].substr(4,2),\n\n      _info[3].substr(0,1),\n      _info[3].substr(1,2),\n      _info[3].substr(3,1),\n      _info[3].substr(4,2),\n\n      _info[4].substr(0,1),\n      _info[4].substr(1,2),\n      _info[4].substr(3,1),\n      _info[4].substr(4,2),\n\n      _info[5].substr(0,1),\n      _info[5].substr(1,2),\n      _info[5].substr(3,1),\n      _info[5].substr(4,2),\n    ];\n    return parseInt(_calday[n-1]);\n  },\n\n  /**\n   * 传入农历数字月份返回汉语通俗表示法\n   * @param lunar month\n   * @return Cn string\n   * @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'\n   */\n  toChinaMonth:function(m) { // 月 => \\u6708\n    if(m>12 || m<1) {return -1} //若参数错误 返回-1\n    var s = calendar.nStr3[m-1];\n    s+= \"\\u6708\";//加上月字\n    return s;\n  },\n\n  /**\n   * 传入农历日期数字返回汉字表示法\n   * @param lunar day\n   * @return Cn string\n   * @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'\n   */\n  toChinaDay:function(d){ //日 => \\u65e5\n    var s;\n    switch (d) {\n      case 10:\n        s = '\\u521d\\u5341'; break;\n      case 20:\n        s = '\\u4e8c\\u5341'; break;\n        break;\n      case 30:\n        s = '\\u4e09\\u5341'; break;\n        break;\n      default :\n        s = calendar.nStr2[Math.floor(d/10)];\n        s += calendar.nStr1[d%10];\n    }\n    return(s);\n  },\n\n  /**\n   * 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是“立春”\n   * @param y year\n   * @return Cn string\n   * @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'\n   */\n  getAnimal: function(y) {\n    return calendar.Animals[(y - 4) % 12]\n  },\n\n  /**\n   * 传入阳历年月日获得详细的公历、农历object信息 <=>JSON\n   * @param y  solar year\n   * @param m  solar month\n   * @param d  solar day\n   * @return JSON object\n   * @eg:console.log(calendar.solar2lunar(1987,11,01));\n   */\n  solar2lunar:function (y,m,d) { //参数区间1900.1.31~2100.12.31\n    if(y<1900 || y>2100) {return -1;}//年份限定、上限\n    if(y==1900&&m==1&&d<31) {return -1;}//下限\n    if(!y) { //未传参  获得当天\n      var objDate = new Date();\n    }else {\n      var objDate = new Date(y,parseInt(m)-1,d)\n    }\n    var i, leap=0, temp=0;\n    //修正ymd参数\n    var y = objDate.getFullYear(),m = objDate.getMonth()+1,d = objDate.getDate();\n    var offset   = (Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate()) - Date.UTC(1900,0,31))/86400000;\n    for(i=1900; i<2101 && offset>0; i++) { temp=calendar.lYearDays(i); offset-=temp; }\n    if(offset<0) { offset+=temp; i--; }\n\n    //是否今天\n    var isTodayObj = new Date(),isToday=false;\n    if(isTodayObj.getFullYear()==y && isTodayObj.getMonth()+1==m && isTodayObj.getDate()==d) {\n      isToday = true;\n    }\n    //星期几\n    var nWeek = objDate.getDay(),cWeek = calendar.nStr1[nWeek];\n    if(nWeek==0) {nWeek =7;}//数字表示周几顺应天朝周一开始的惯例\n    //农历年\n    var year = i;\n\n    var leap = calendar.leapMonth(i); //闰哪个月\n    var isLeap = false;\n\n    //效验闰月\n    for(i=1; i<13 && offset>0; i++) {\n      //闰月\n      if(leap>0 && i==(leap+1) && isLeap==false){\n        --i;\n        isLeap = true; temp = calendar.leapDays(year); //计算农历闰月天数\n      }\n      else{\n        temp = calendar.monthDays(year, i);//计算农历普通月天数\n      }\n      //解除闰月\n      if(isLeap==true && i==(leap+1)) { isLeap = false; }\n      offset -= temp;\n    }\n\n    if(offset==0 && leap>0 && i==leap+1)\n      if(isLeap){\n        isLeap = false;\n      }else{\n        isLeap = true; --i;\n      }\n    if(offset<0){ offset += temp; --i; }\n    //农历月\n    var month   = i;\n    //农历日\n    var day     = offset + 1;\n\n    //天干地支处理\n    var sm      =   m-1;\n    var gzY     =   calendar.toGanZhiYear(year);\n\n    //月柱 1900年1月小寒以前为 丙子月(60进制12)\n    var firstNode   = calendar.getTerm(year,(m*2-1));//返回当月「节」为几日开始\n    var secondNode  = calendar.getTerm(year,(m*2));//返回当月「节」为几日开始\n\n    //依据12节气修正干支月\n    var gzM     =   calendar.toGanZhi((y-1900)*12+m+11);\n    if(d>=firstNode) {\n      gzM     =   calendar.toGanZhi((y-1900)*12+m+12);\n    }\n\n    //传入的日期的节气与否\n    var isTerm = false;\n    var Term   = null;\n    if(firstNode==d) {\n      isTerm  = true;\n      Term    = calendar.solarTerm[m*2-2];\n    }\n    if(secondNode==d) {\n      isTerm  = true;\n      Term    = calendar.solarTerm[m*2-1];\n    }\n    //日柱 当月一日与 1900/1/1 相差天数\n    var dayCyclical = Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;\n    var gzD = calendar.toGanZhi(dayCyclical+d-1);\n    //该日期所属的星座\n    var astro = calendar.toAstro(m,d);\n\n    return {'lYear':year,'lMonth':month,'lDay':day,'Animal':calendar.getAnimal(year),'IMonthCn':(isLeap?\"\\u95f0\":'')+calendar.toChinaMonth(month),'IDayCn':calendar.toChinaDay(day),'cYear':y,'cMonth':m,'cDay':d,'gzYear':gzY,'gzMonth':gzM,'gzDay':gzD,'isToday':isToday,'isLeap':isLeap,'nWeek':nWeek,'ncWeek':\"\\u661f\\u671f\"+cWeek,'isTerm':isTerm,'Term':Term,'astro':astro};\n  },\n\n  /**\n   * 传入农历年月日以及传入的月份是否闰月获得详细的公历、农历object信息 <=>JSON\n   * @param y  lunar year\n   * @param m  lunar month\n   * @param d  lunar day\n   * @param isLeapMonth  lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]\n   * @return JSON object\n   * @eg:console.log(calendar.lunar2solar(1987,9,10));\n   */\n  lunar2solar:function(y,m,d,isLeapMonth) {   //参数区间1900.1.31~2100.12.1\n    var isLeapMonth = !!isLeapMonth;\n    var leapOffset  = 0;\n    var leapMonth   = calendar.leapMonth(y);\n    var leapDay     = calendar.leapDays(y);\n    if(isLeapMonth&&(leapMonth!=m)) {return -1;}//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同\n    if(y==2100&&m==12&&d>1 || y==1900&&m==1&&d<31) {return -1;}//超出了最大极限值\n    var day  = calendar.monthDays(y,m);\n    var _day = day;\n    //bugFix 2016-9-25\n    //if month is leap, _day use leapDays method\n    if(isLeapMonth) {\n      _day = calendar.leapDays(y,m);\n    }\n    if(y < 1900 || y > 2100 || d > _day) {return -1;}//参数合法性效验\n\n    //计算农历的时间差\n    var offset = 0;\n    for(var i=1900;i<y;i++) {\n      offset+=calendar.lYearDays(i);\n    }\n    var leap = 0,isAdd= false;\n    for(var i=1;i<m;i++) {\n      leap = calendar.leapMonth(y);\n      if(!isAdd) {//处理闰月\n        if(leap<=i && leap>0) {\n          offset+=calendar.leapDays(y);isAdd = true;\n        }\n      }\n      offset+=calendar.monthDays(y,i);\n    }\n    //转换闰月农历 需补充该年闰月的前一个月的时差\n    if(isLeapMonth) {offset+=day;}\n    //1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)\n    var stmap   =   Date.UTC(1900,1,30,0,0,0);\n    var calObj  =   new Date((offset+d-31)*86400000+stmap);\n    var cY      =   calObj.getUTCFullYear();\n    var cM      =   calObj.getUTCMonth()+1;\n    var cD      =   calObj.getUTCDate();\n\n    return calendar.solar2lunar(cY,cM,cD);\n  }\n};\n\nexport default calendar;\n"
  },
  {
    "path": "src/mpvue-calendar.vue",
    "content": "<template>\n  <div\n    class=\"mpvue-calendar\"\n    :class=\"[`mpvue-calendar-mode-${tableMode}`, className]\"\n  >\n    <Tools\n      @onMonthChange=\"onToolsMonthChange\"\n      @next=\"nextChange\"\n      @prev=\"prevChange\"\n      @selectMonth=\"selectMonth\"\n      @selectYear=\"selectYear\"\n      :month=\"month\"\n      :year=\"year\"\n      :monFirst=\"monFirst\"\n      :timetableHeight=\"timetableHeight\"\n      :format=\"format\"\n      :tableMode=\"tableMode\"\n      :weeks=\"weeksInner\"\n      :months=\"months\"\n      :language=\"language\"\n      :arrowLeft=\"arrowLeft\"\n      :arrowRight=\"arrowRight\"\n    />\n    <div\n      :style=\"{height: timetableHeight + 'px'}\"\n    >\n      <Swipe\n        :initialSlide=\"1\"\n        :useSwipe=\"useSwipeInner\"\n        @swiperChangeEnd=\"swiperChangeEnd\"\n        @containerChange=\"containerChange\"\n        ref=\"swipeRef\"\n      >\n        <Slide\n          :useSwipe=\"useSwipeInner\"\n          class-name=\"asdasdsd\"\n          v-for=\"(item, index) in timetableList.list\"\n          :key=\"index\"\n        >\n          <Timetable\n            :tableIndex=\"index\"\n            :language=\"language\"\n            :timestamp=\"timestamp\"\n            :weeks=\"weeksInner\"\n            ref=\"timetableRef\"\n            :useSwipe=\"useSwipeInner\"\n            :month=\"item.month\"\n            :year=\"item.year\"\n            :day=\"item.day\"\n            :remarks=\"remarks\"\n            :holidays=\"holidays\"\n            :tileContent=\"tileContent\"\n            :disabled=\"disabled\"\n            :completion=\"completion\"\n            :monFirst=\"monFirst\"\n            :tableMode=\"tableMode\"\n            :selectMode=\"selectMode\"\n            :selectDate=\"selectDateInner\"\n            :begin=\"begin\"\n            :end=\"end\"\n            :format=\"format\"\n            :lunar=\"lunar\"\n            :backgroundText=\"backgroundText\"\n            @onSelect=\"onSelect\"\n            @onMonthChange=\"monthChange\"\n          />\n        </Slide>\n      </Swipe>\n    </div>\n  </div>\n</template>\n\n<script lang=\"ts\">\n  import { ref, reactive, watch, toRefs } from 'vue';\n  import { CalendarInterface } from './declare';\n  import Tools from './components/tools/index.vue';\n  import Swipe from './components/swipe/index.vue';\n  import Slide from './components/swipe/slide.vue';\n  import Timetable from './components/timetable/index.vue';\n  import { delay, enWeeks, getToday, isZh, zhWeeks, computedNextMonth, computedPrevMonth,\n    getDateByCount, date2ymd, getPrevDate, getNextDate, getSomeNextMonths, getMonths,\n  } from './components/utils';\n  import './style.less';\n\n  export default {\n    props: {\n      format: {\n        type: Function,\n      },\n      holidays: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      lunar: {\n        type: Object,\n      },\n      remarks: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      monthRange: {\n        type: Array,\n      },\n      tileContent: {\n        type: Object,\n        default() {\n          return {};\n        }\n      },\n      completion: {\n        type: Boolean,\n        default: false\n      },\n      useSwipe: {\n        type: Boolean,\n        default: true\n      },\n      arrowLeft: {\n        type: String,\n        default: ''\n      },\n      arrowRight: {\n        type: String,\n        default: ''\n      },\n      backgroundText: {\n        type: Boolean,\n      },\n      monFirst: {\n        type: Boolean,\n        default: false\n      },\n      className: {\n        type: String,\n      },\n      mode: {\n        type: String,\n        default: 'month'\n      },\n      weeks: {\n        type: Array,\n        default: undefined\n      },\n      begin: {\n        type: String,\n      },\n      end: {\n        type: String,\n      },\n      selectMode: {\n        type: String,\n        default: 'select'\n      },\n      language: {\n        type: String,\n      },\n      selectDate: {\n        type: [String, Array, Object],\n      },\n      disabled: {\n        type: Object,\n      },\n    },\n    components: {\n      Tools,\n      Swipe,\n      Slide,\n      Timetable,\n    },\n    emits: ['onSelect', 'next', 'prev', 'selectMonth', 'selectYear', 'onMonthChange'],\n    setup(props: CalendarInterface, { emit }: any) {\n      const { tileContent, monFirst, monthRange, mode: tableMode, selectMode, selectDate, remarks,\n        weeks, language: propLanguage,\n      } = toRefs(props);\n      const timestamp = ref(+new Date()); // listener timestamp change to refresh timetable\n      const [todayYear, todayMonth, todaytDay] = getToday(true);\n      const year = ref(todayYear);\n      const month = ref(todayMonth);\n      const day = ref(todaytDay);\n      const timetableHeight = ref(undefined);\n      const months = ref(getMonths(propLanguage?.value));\n      const swipeRef = ref();\n      const timetableRef = ref();\n      const weeksInner = ref(computedWeek());\n      const useSwipeInner = ref(tableMode.value === 'monthRange' ? false : props.useSwipe);\n      const initSelectValue = selectDate?.value || {\n        select: '',\n        multi: [],\n        multiRange: [],\n        range: { start: '', end: '' },\n      }[selectMode.value];\n      const timetableList = reactive({list: getTimetableList()});\n      const selectDateInner = ref(initSelectValue);\n\n      function swiperChangeEnd(index: number) {\n        const isWeekMode = tableMode.value === 'week';\n        if (index === 2) {\n          const [nextYear, nextMonth, nextDay] = getNextDate(year.value, month.value, isWeekMode ? day.value : undefined);\n          year.value = nextYear;\n          month.value = nextMonth;\n\n          if (isWeekMode) {\n            day.value = nextDay;\n          }\n\n          emit('onMonthChange', year.value, month.value);\n          return swipeRef.value.slide(1, 0);\n        }\n\n        if (index === 0) {\n          const [prevYear, prevMonth, prevDay] = getPrevDate(year.value, month.value, isWeekMode ? day.value : undefined);\n          year.value = prevYear;\n          month.value = prevMonth;\n\n          if (isWeekMode) {\n            day.value = prevDay;\n          }\n\n          emit('onMonthChange', year.value, month.value);\n          return swipeRef.value.slide(1, 0);\n        }\n      }\n\n      function computedWeek() {\n        if (Array.isArray(props.weeks)) return props.weeks;\n\n        const language = isZh(propLanguage?.value) ? 'zh': 'en';\n        const weeksArray = {\n          en: enWeeks,\n          zh: zhWeeks,\n        }[language];\n\n        if (monFirst?.value) {\n          return weeksArray.reduce((previousValue: any, currentValue: any, index: number) => {\n            if (!index) {\n              previousValue.first = currentValue;\n              return previousValue;\n            }\n\n            previousValue.week.push(currentValue);\n\n            if (index === weeksArray.length - 1) {\n              return [...previousValue.week, previousValue.first];\n            }\n\n            return previousValue;\n          }, {first: undefined, week: []});\n        }\n\n        return weeksArray;\n      }\n\n      function getTimetableList() {\n        const isWeekMode = tableMode.value === 'week';\n\n        if (tableMode.value === 'monthRange') {\n          const monthRangeData = monthRange?.value || getSomeNextMonths(year?.value, month?.value, 3);\n\n          return monthRangeData.map((item: string) => {\n            const [rangeYear, rangeMonth] = item.split('-');\n            return { year: rangeYear, month: rangeMonth };\n          });\n        }\n\n        if (isWeekMode) {\n          const [prevYear, prevMonth, prevDay] = getPrevDate(year.value, month.value, day.value);\n          const [nextYear, nextMonth, nextDay] = getNextDate(year.value, month.value, day.value);\n          return [\n            {year: prevYear, month: prevMonth, day: prevDay, id: `${prevYear}-${prevMonth}-${prevDay}`},\n            {year: year.value, month: month.value, day: day.value, id: `${year.value}-${month.value}-${day.value}`},\n            {year: nextYear, month: nextMonth, day: nextDay, id: `${nextYear}-${nextMonth}-${nextDay}`},\n          ];\n        }\n\n        if (!useSwipeInner.value) {\n          return [{year: year.value, month: month.value, day: day.value, id: `${year.value}-${month.value}-${day.value}`}];\n        }\n\n        const [prevYear, prevMonth] = getPrevDate(year.value, month.value);\n        const [nextYear, nextMonth] = getNextDate(year.value, month.value);\n        return [\n          {year: prevYear, month: prevMonth, id: `${prevYear}-${prevMonth}`},\n          {year: year.value, month: month.value, id: `${year.value}-${month.value}`},\n          {year: nextYear, month: nextMonth, id: `${nextYear}-${nextMonth}`},\n        ];\n      }\n\n      function nextChange(currentYear: number | string, currentMonth: number | string) {\n        if (tableMode.value === 'week') {\n          const nextDate = getDateByCount(`${year.value}-${month.value}-${day.value}`, 7);\n          const [nextYear, nextMonth, nextDay] = date2ymd(nextDate);\n          year.value = nextYear;\n          month.value = nextMonth;\n          day.value = nextDay;\n\n          emit('next', nextYear, nextMonth, nextDay);\n          return emit('onMonthChange', nextYear, nextMonth, nextDay);\n        }\n        const nextMonth = computedNextMonth(currentMonth);\n        month.value = nextMonth;\n        year.value = nextMonth === 1 ? Number(year.value) + 1 : year.value;\n\n        emit('next', year.value, month.value);\n        emit('onMonthChange', year.value, month.value);\n      }\n\n      function prevChange(currentYear: number | string, currentMonth: number | string) {\n        if (tableMode.value === 'week') {\n          const nextDate = getDateByCount(`${year.value}-${month.value}-${day.value}`, -7);\n          const [prevYear, prevMonth, prevDay] = date2ymd(nextDate);\n          year.value = prevYear;\n          month.value = prevMonth;\n          day.value = prevDay;\n\n          emit('prev', prevYear, prevMonth, prevDay);\n          return emit('onMonthChange', prevYear, prevMonth, prevDay);\n        }\n        const prevMonth = computedPrevMonth(currentMonth);\n        month.value = prevMonth;\n        year.value = prevMonth === 12 ? Number(year.value) - 1 : year.value;\n\n        emit('prev', year.value, month.value);\n        emit('onMonthChange', year.value, month.value);\n      }\n\n      function selectMonth(selectedYear: number, selectedMonth: number) {\n        year.value = selectedYear;\n        month.value = selectedMonth;\n        emit('selectMonth', selectedYear, selectedMonth);\n      }\n\n      function selectYear(selectedYear: number, selectedMonth: number) {\n        year.value = selectedYear;\n        month.value = selectedMonth;\n        emit('selectYear', selectedYear, selectedMonth);\n      }\n\n      function containerChange(element: any) {\n        timetableHeight.value = element?.clientHeight;\n      }\n\n      function onSelect(param: any) {\n        selectDateInner.value = param;\n\n        emit('onSelect', param);\n        delay().then(refreshRender);\n      }\n\n      function refreshRender() {\n        timestamp.value = +new Date();\n      }\n\n      function onToolsMonthChange(...param: any) {\n        emit('onMonthChange', ...param);\n      }\n\n      function monthChange(param: any) {\n        const { prevMonthDay, nextMonthDay } = param || {};\n        if (nextMonthDay) {\n          nextChange(year.value, month.value);\n          return emit('next', year.value, month.value);\n        }\n        if (prevMonthDay) {\n          prevChange(year.value, month.value);\n          emit('prev', year.value, month.value);\n        }\n      }\n\n      function render(renderYear: string | number, renderMonth: string | number, renderDay?: string | number) {\n        if (renderYear && renderMonth) {\n          year.value = renderYear;\n          month.value = renderMonth;\n        }\n\n        if (renderDay) {\n          day.value = renderDay;\n        }\n      }\n\n      function setToday() {\n        if (tableMode.value === 'monthRange') return;\n\n        const [todayY, todayM, todaytD] = getToday(true);\n        render(todayY, todayM, todaytD);\n      }\n\n      watch([year, month, day], () => {\n        timetableList.list = getTimetableList();\n      });\n\n      watch(() => props.selectDate, () => {\n        selectDateInner.value = selectDate.value;\n      });\n\n      watch(tableMode, () => {\n        if (tableMode.value === 'monthRange') {\n          useSwipeInner.value = false;\n        }\n        timetableList.list = getTimetableList();\n        refreshRender();\n      });\n\n      watch(() => [props.begin, props.end, props.disabled, props.holidays, remarks, props.remarks], () => {\n        refreshRender();\n      });\n\n      watch(tileContent, () => {\n        refreshRender();\n      });\n\n      if (Object.keys(props.tileContent).length) {\n        watch(props.tileContent, () => {\n          refreshRender();\n        });\n      }\n\n      watch([weeks, monFirst], () => {\n        weeksInner.value = computedWeek();\n      });\n\n      return {\n        month,\n        year,\n        day,\n        nextChange,\n        prevChange,\n        selectMonth,\n        selectYear,\n        onSelect,\n        monthChange,\n        tableMode,\n        timetableList,\n        swiperChangeEnd,\n        containerChange,\n        timetableHeight,\n        onToolsMonthChange,\n        swipeRef,\n        timetableRef,\n        timestamp,\n        render,\n        selectDateInner,\n        weeksInner,\n        setToday,\n        useSwipeInner,\n        months,\n      };\n    }\n  };\n</script>\n"
  },
  {
    "path": "src/shims-vue.d.ts",
    "content": "declare module \"*.vue\" {\n  import Vue from 'vue'\n  export default Vue\n}\n"
  },
  {
    "path": "src/style.less",
    "content": ".mpvue-calendar{\n  position: relative;\n  width: 300px;\n  &.mpvue-calendar-mode-week{\n    .vc-calendar-info{\n      cursor: inherit;\n    }\n    .vc-calendar-timetable{\n      .vc-calendar-timetable-wrap{\n        .vc-calendar-body{\n          .vc-calendar-content{\n            .vc-calendar-month-background-text{\n              font-size: 80px;\n            }\n          }\n        }\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "tsconfig.json",
    "content": "{\n  \"compilerOptions\": {\n    \"target\": \"esnext\",\n    \"module\": \"esnext\",\n    \"strict\": true,\n    \"jsx\": \"preserve\",\n    \"importHelpers\": true,\n    \"moduleResolution\": \"node\",\n    \"skipLibCheck\": true,\n    \"esModuleInterop\": true,\n    \"allowSyntheticDefaultImports\": true,\n    \"sourceMap\": true,\n    \"baseUrl\": \".\",\n    \"types\": [\n      \"webpack-env\"\n    ],\n    \"paths\": {\n      \"@/*\": [\n        \"src/*\",\n        \"example/*\"\n      ]\n    },\n    \"lib\": [\n      \"esnext\",\n      \"dom\",\n      \"dom.iterable\",\n      \"scripthost\"\n    ]\n  },\n  \"include\": [\n    \"src/**/*.ts\",\n    \"src/**/*.tsx\",\n    \"src/**/*.vue\"\n  ],\n  \"exclude\": [\n    \"node_modules\"\n  ]\n}\n"
  },
  {
    "path": "vue.config.js",
    "content": "const path = require(\"path\");\n\nmodule.exports = {\n  publicPath: process.env.NODE_ENV === 'production' ? '/mpvue-calendar/' : '/',\n  configureWebpack: {\n    context: path.resolve(__dirname, './'),\n    entry: {\n      app: process.env.NODE_ENV === 'production' ? './src/mpvue-calendar.vue' : './example/main.js'\n    },\n  },\n  css: {\n    extract: false\n  },\n  productionSourceMap: false,\n  lintOnSave: process.env.NODE_ENV !== 'production'\n}\n"
  }
]