react-native-bikram-sambat 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (367) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +340 -0
  3. package/lib/commonjs/accessibility/index.js +25 -0
  4. package/lib/commonjs/accessibility/index.js.map +1 -0
  5. package/lib/commonjs/accessibility/labels.js +20 -0
  6. package/lib/commonjs/accessibility/labels.js.map +1 -0
  7. package/lib/commonjs/calendar/calendar-types.js +6 -0
  8. package/lib/commonjs/calendar/calendar-types.js.map +1 -0
  9. package/lib/commonjs/calendar/get-calendar-month-grid.js +114 -0
  10. package/lib/commonjs/calendar/get-calendar-month-grid.js.map +1 -0
  11. package/lib/commonjs/calendar/index.js +13 -0
  12. package/lib/commonjs/calendar/index.js.map +1 -0
  13. package/lib/commonjs/components/NepaliCalendar/CalendarDay.js +137 -0
  14. package/lib/commonjs/components/NepaliCalendar/CalendarDay.js.map +1 -0
  15. package/lib/commonjs/components/NepaliCalendar/CalendarGrid.js +116 -0
  16. package/lib/commonjs/components/NepaliCalendar/CalendarGrid.js.map +1 -0
  17. package/lib/commonjs/components/NepaliCalendar/CalendarHeader.js +114 -0
  18. package/lib/commonjs/components/NepaliCalendar/CalendarHeader.js.map +1 -0
  19. package/lib/commonjs/components/NepaliCalendar/CalendarWeekdays.js +44 -0
  20. package/lib/commonjs/components/NepaliCalendar/CalendarWeekdays.js.map +1 -0
  21. package/lib/commonjs/components/NepaliCalendar/NepaliCalendar.js +288 -0
  22. package/lib/commonjs/components/NepaliCalendar/NepaliCalendar.js.map +1 -0
  23. package/lib/commonjs/components/NepaliCalendar/index.js +13 -0
  24. package/lib/commonjs/components/NepaliCalendar/index.js.map +1 -0
  25. package/lib/commonjs/components/NepaliCalendar/types.js +6 -0
  26. package/lib/commonjs/components/NepaliCalendar/types.js.map +1 -0
  27. package/lib/commonjs/components/NepaliDatePicker/DatePickerModal.js +185 -0
  28. package/lib/commonjs/components/NepaliDatePicker/DatePickerModal.js.map +1 -0
  29. package/lib/commonjs/components/NepaliDatePicker/NepaliDatePicker.js +148 -0
  30. package/lib/commonjs/components/NepaliDatePicker/NepaliDatePicker.js.map +1 -0
  31. package/lib/commonjs/components/NepaliDatePicker/index.js +20 -0
  32. package/lib/commonjs/components/NepaliDatePicker/index.js.map +1 -0
  33. package/lib/commonjs/components/NepaliDatePicker/types.js +6 -0
  34. package/lib/commonjs/components/NepaliDatePicker/types.js.map +1 -0
  35. package/lib/commonjs/components/NepaliRangePicker/NepaliRangePicker.js +187 -0
  36. package/lib/commonjs/components/NepaliRangePicker/NepaliRangePicker.js.map +1 -0
  37. package/lib/commonjs/components/NepaliRangePicker/RangePickerModal.js +275 -0
  38. package/lib/commonjs/components/NepaliRangePicker/RangePickerModal.js.map +1 -0
  39. package/lib/commonjs/components/NepaliRangePicker/index.js +57 -0
  40. package/lib/commonjs/components/NepaliRangePicker/index.js.map +1 -0
  41. package/lib/commonjs/components/NepaliRangePicker/range-utils.js +70 -0
  42. package/lib/commonjs/components/NepaliRangePicker/range-utils.js.map +1 -0
  43. package/lib/commonjs/components/NepaliRangePicker/types.js +6 -0
  44. package/lib/commonjs/components/NepaliRangePicker/types.js.map +1 -0
  45. package/lib/commonjs/core/arithmetic.js +36 -0
  46. package/lib/commonjs/core/arithmetic.js.map +1 -0
  47. package/lib/commonjs/core/bsData.js +89 -0
  48. package/lib/commonjs/core/bsData.js.map +1 -0
  49. package/lib/commonjs/core/conversion.js +53 -0
  50. package/lib/commonjs/core/conversion.js.map +1 -0
  51. package/lib/commonjs/core/dateKey.js +31 -0
  52. package/lib/commonjs/core/dateKey.js.map +1 -0
  53. package/lib/commonjs/core/epochDay.js +47 -0
  54. package/lib/commonjs/core/epochDay.js.map +1 -0
  55. package/lib/commonjs/core/format/format.js +86 -0
  56. package/lib/commonjs/core/format/format.js.map +1 -0
  57. package/lib/commonjs/core/format/index.js +20 -0
  58. package/lib/commonjs/core/format/index.js.map +1 -0
  59. package/lib/commonjs/core/format/parse.js +41 -0
  60. package/lib/commonjs/core/format/parse.js.map +1 -0
  61. package/lib/commonjs/core/format/tokens.js +9 -0
  62. package/lib/commonjs/core/format/tokens.js.map +1 -0
  63. package/lib/commonjs/core/index.js +116 -0
  64. package/lib/commonjs/core/index.js.map +1 -0
  65. package/lib/commonjs/core/locale/en.js +15 -0
  66. package/lib/commonjs/core/locale/en.js.map +1 -0
  67. package/lib/commonjs/core/locale/index.js +20 -0
  68. package/lib/commonjs/core/locale/index.js.map +1 -0
  69. package/lib/commonjs/core/locale/ne.js +15 -0
  70. package/lib/commonjs/core/locale/ne.js.map +1 -0
  71. package/lib/commonjs/core/locale/types.js +2 -0
  72. package/lib/commonjs/core/locale/types.js.map +1 -0
  73. package/lib/commonjs/core/numerals/index.js +19 -0
  74. package/lib/commonjs/core/numerals/index.js.map +1 -0
  75. package/lib/commonjs/core/numerals/nepali-numerals.js +28 -0
  76. package/lib/commonjs/core/numerals/nepali-numerals.js.map +1 -0
  77. package/lib/commonjs/core/types.js +2 -0
  78. package/lib/commonjs/core/types.js.map +1 -0
  79. package/lib/commonjs/core/validation.js +125 -0
  80. package/lib/commonjs/core/validation.js.map +1 -0
  81. package/lib/commonjs/core/validation.test.js +248 -0
  82. package/lib/commonjs/core/validation.test.js.map +1 -0
  83. package/lib/commonjs/exports.test.js +133 -0
  84. package/lib/commonjs/exports.test.js.map +1 -0
  85. package/lib/commonjs/index.js +94 -0
  86. package/lib/commonjs/index.js.map +1 -0
  87. package/lib/commonjs/package.json +1 -0
  88. package/lib/commonjs/phase2.test.js +446 -0
  89. package/lib/commonjs/phase2.test.js.map +1 -0
  90. package/lib/commonjs/phase3.test.js +91 -0
  91. package/lib/commonjs/phase3.test.js.map +1 -0
  92. package/lib/commonjs/phase4.test.js +89 -0
  93. package/lib/commonjs/phase4.test.js.map +1 -0
  94. package/lib/commonjs/phase5.test.js +246 -0
  95. package/lib/commonjs/phase5.test.js.map +1 -0
  96. package/lib/commonjs/phase7.test.js +284 -0
  97. package/lib/commonjs/phase7.test.js.map +1 -0
  98. package/lib/commonjs/range-helpers.test.js +182 -0
  99. package/lib/commonjs/range-helpers.test.js.map +1 -0
  100. package/lib/commonjs/theme/create-theme.js +37 -0
  101. package/lib/commonjs/theme/create-theme.js.map +1 -0
  102. package/lib/commonjs/theme/default-theme.js +99 -0
  103. package/lib/commonjs/theme/default-theme.js.map +1 -0
  104. package/lib/commonjs/theme/index.js +26 -0
  105. package/lib/commonjs/theme/index.js.map +1 -0
  106. package/lib/commonjs/theme/types.js +6 -0
  107. package/lib/commonjs/theme/types.js.map +1 -0
  108. package/lib/commonjs/utils/date-helpers.js +106 -0
  109. package/lib/commonjs/utils/date-helpers.js.map +1 -0
  110. package/lib/commonjs/utils/index.js +49 -0
  111. package/lib/commonjs/utils/index.js.map +1 -0
  112. package/lib/module/accessibility/index.js +4 -0
  113. package/lib/module/accessibility/index.js.map +1 -0
  114. package/lib/module/accessibility/labels.js +15 -0
  115. package/lib/module/accessibility/labels.js.map +1 -0
  116. package/lib/module/calendar/calendar-types.js +4 -0
  117. package/lib/module/calendar/calendar-types.js.map +1 -0
  118. package/lib/module/calendar/get-calendar-month-grid.js +111 -0
  119. package/lib/module/calendar/get-calendar-month-grid.js.map +1 -0
  120. package/lib/module/calendar/index.js +4 -0
  121. package/lib/module/calendar/index.js.map +1 -0
  122. package/lib/module/components/NepaliCalendar/CalendarDay.js +132 -0
  123. package/lib/module/components/NepaliCalendar/CalendarDay.js.map +1 -0
  124. package/lib/module/components/NepaliCalendar/CalendarGrid.js +111 -0
  125. package/lib/module/components/NepaliCalendar/CalendarGrid.js.map +1 -0
  126. package/lib/module/components/NepaliCalendar/CalendarHeader.js +109 -0
  127. package/lib/module/components/NepaliCalendar/CalendarHeader.js.map +1 -0
  128. package/lib/module/components/NepaliCalendar/CalendarWeekdays.js +39 -0
  129. package/lib/module/components/NepaliCalendar/CalendarWeekdays.js.map +1 -0
  130. package/lib/module/components/NepaliCalendar/NepaliCalendar.js +283 -0
  131. package/lib/module/components/NepaliCalendar/NepaliCalendar.js.map +1 -0
  132. package/lib/module/components/NepaliCalendar/index.js +4 -0
  133. package/lib/module/components/NepaliCalendar/index.js.map +1 -0
  134. package/lib/module/components/NepaliCalendar/types.js +4 -0
  135. package/lib/module/components/NepaliCalendar/types.js.map +1 -0
  136. package/lib/module/components/NepaliDatePicker/DatePickerModal.js +180 -0
  137. package/lib/module/components/NepaliDatePicker/DatePickerModal.js.map +1 -0
  138. package/lib/module/components/NepaliDatePicker/NepaliDatePicker.js +143 -0
  139. package/lib/module/components/NepaliDatePicker/NepaliDatePicker.js.map +1 -0
  140. package/lib/module/components/NepaliDatePicker/index.js +5 -0
  141. package/lib/module/components/NepaliDatePicker/index.js.map +1 -0
  142. package/lib/module/components/NepaliDatePicker/types.js +4 -0
  143. package/lib/module/components/NepaliDatePicker/types.js.map +1 -0
  144. package/lib/module/components/NepaliRangePicker/NepaliRangePicker.js +182 -0
  145. package/lib/module/components/NepaliRangePicker/NepaliRangePicker.js.map +1 -0
  146. package/lib/module/components/NepaliRangePicker/RangePickerModal.js +270 -0
  147. package/lib/module/components/NepaliRangePicker/RangePickerModal.js.map +1 -0
  148. package/lib/module/components/NepaliRangePicker/index.js +6 -0
  149. package/lib/module/components/NepaliRangePicker/index.js.map +1 -0
  150. package/lib/module/components/NepaliRangePicker/range-utils.js +61 -0
  151. package/lib/module/components/NepaliRangePicker/range-utils.js.map +1 -0
  152. package/lib/module/components/NepaliRangePicker/types.js +4 -0
  153. package/lib/module/components/NepaliRangePicker/types.js.map +1 -0
  154. package/lib/module/core/arithmetic.js +29 -0
  155. package/lib/module/core/arithmetic.js.map +1 -0
  156. package/lib/module/core/bsData.js +82 -0
  157. package/lib/module/core/bsData.js.map +1 -0
  158. package/lib/module/core/conversion.js +48 -0
  159. package/lib/module/core/conversion.js.map +1 -0
  160. package/lib/module/core/dateKey.js +26 -0
  161. package/lib/module/core/dateKey.js.map +1 -0
  162. package/lib/module/core/epochDay.js +39 -0
  163. package/lib/module/core/epochDay.js.map +1 -0
  164. package/lib/module/core/format/format.js +82 -0
  165. package/lib/module/core/format/format.js.map +1 -0
  166. package/lib/module/core/format/index.js +5 -0
  167. package/lib/module/core/format/index.js.map +1 -0
  168. package/lib/module/core/format/parse.js +37 -0
  169. package/lib/module/core/format/parse.js.map +1 -0
  170. package/lib/module/core/format/tokens.js +5 -0
  171. package/lib/module/core/format/tokens.js.map +1 -0
  172. package/lib/module/core/index.js +13 -0
  173. package/lib/module/core/index.js.map +1 -0
  174. package/lib/module/core/locale/en.js +11 -0
  175. package/lib/module/core/locale/en.js.map +1 -0
  176. package/lib/module/core/locale/index.js +5 -0
  177. package/lib/module/core/locale/index.js.map +1 -0
  178. package/lib/module/core/locale/ne.js +11 -0
  179. package/lib/module/core/locale/ne.js.map +1 -0
  180. package/lib/module/core/locale/types.js +2 -0
  181. package/lib/module/core/locale/types.js.map +1 -0
  182. package/lib/module/core/numerals/index.js +4 -0
  183. package/lib/module/core/numerals/index.js.map +1 -0
  184. package/lib/module/core/numerals/nepali-numerals.js +23 -0
  185. package/lib/module/core/numerals/nepali-numerals.js.map +1 -0
  186. package/lib/module/core/types.js +2 -0
  187. package/lib/module/core/types.js.map +1 -0
  188. package/lib/module/core/validation.js +115 -0
  189. package/lib/module/core/validation.js.map +1 -0
  190. package/lib/module/core/validation.test.js +248 -0
  191. package/lib/module/core/validation.test.js.map +1 -0
  192. package/lib/module/exports.test.js +133 -0
  193. package/lib/module/exports.test.js.map +1 -0
  194. package/lib/module/index.js +11 -0
  195. package/lib/module/index.js.map +1 -0
  196. package/lib/module/package.json +1 -0
  197. package/lib/module/phase2.test.js +446 -0
  198. package/lib/module/phase2.test.js.map +1 -0
  199. package/lib/module/phase3.test.js +91 -0
  200. package/lib/module/phase3.test.js.map +1 -0
  201. package/lib/module/phase4.test.js +89 -0
  202. package/lib/module/phase4.test.js.map +1 -0
  203. package/lib/module/phase5.test.js +246 -0
  204. package/lib/module/phase5.test.js.map +1 -0
  205. package/lib/module/phase7.test.js +284 -0
  206. package/lib/module/phase7.test.js.map +1 -0
  207. package/lib/module/range-helpers.test.js +182 -0
  208. package/lib/module/range-helpers.test.js.map +1 -0
  209. package/lib/module/theme/create-theme.js +33 -0
  210. package/lib/module/theme/create-theme.js.map +1 -0
  211. package/lib/module/theme/default-theme.js +95 -0
  212. package/lib/module/theme/default-theme.js.map +1 -0
  213. package/lib/module/theme/index.js +5 -0
  214. package/lib/module/theme/index.js.map +1 -0
  215. package/lib/module/theme/types.js +4 -0
  216. package/lib/module/theme/types.js.map +1 -0
  217. package/lib/module/utils/date-helpers.js +96 -0
  218. package/lib/module/utils/date-helpers.js.map +1 -0
  219. package/lib/module/utils/index.js +4 -0
  220. package/lib/module/utils/index.js.map +1 -0
  221. package/lib/typescript/src/accessibility/index.d.ts +2 -0
  222. package/lib/typescript/src/accessibility/index.d.ts.map +1 -0
  223. package/lib/typescript/src/accessibility/labels.d.ts +6 -0
  224. package/lib/typescript/src/accessibility/labels.d.ts.map +1 -0
  225. package/lib/typescript/src/calendar/calendar-types.d.ts +23 -0
  226. package/lib/typescript/src/calendar/calendar-types.d.ts.map +1 -0
  227. package/lib/typescript/src/calendar/get-calendar-month-grid.d.ts +3 -0
  228. package/lib/typescript/src/calendar/get-calendar-month-grid.d.ts.map +1 -0
  229. package/lib/typescript/src/calendar/index.d.ts +3 -0
  230. package/lib/typescript/src/calendar/index.d.ts.map +1 -0
  231. package/lib/typescript/src/components/NepaliCalendar/CalendarDay.d.ts +23 -0
  232. package/lib/typescript/src/components/NepaliCalendar/CalendarDay.d.ts.map +1 -0
  233. package/lib/typescript/src/components/NepaliCalendar/CalendarGrid.d.ts +25 -0
  234. package/lib/typescript/src/components/NepaliCalendar/CalendarGrid.d.ts.map +1 -0
  235. package/lib/typescript/src/components/NepaliCalendar/CalendarHeader.d.ts +17 -0
  236. package/lib/typescript/src/components/NepaliCalendar/CalendarHeader.d.ts.map +1 -0
  237. package/lib/typescript/src/components/NepaliCalendar/CalendarWeekdays.d.ts +11 -0
  238. package/lib/typescript/src/components/NepaliCalendar/CalendarWeekdays.d.ts.map +1 -0
  239. package/lib/typescript/src/components/NepaliCalendar/NepaliCalendar.d.ts +4 -0
  240. package/lib/typescript/src/components/NepaliCalendar/NepaliCalendar.d.ts.map +1 -0
  241. package/lib/typescript/src/components/NepaliCalendar/index.d.ts +3 -0
  242. package/lib/typescript/src/components/NepaliCalendar/index.d.ts.map +1 -0
  243. package/lib/typescript/src/components/NepaliCalendar/types.d.ts +52 -0
  244. package/lib/typescript/src/components/NepaliCalendar/types.d.ts.map +1 -0
  245. package/lib/typescript/src/components/NepaliDatePicker/DatePickerModal.d.ts +4 -0
  246. package/lib/typescript/src/components/NepaliDatePicker/DatePickerModal.d.ts.map +1 -0
  247. package/lib/typescript/src/components/NepaliDatePicker/NepaliDatePicker.d.ts +4 -0
  248. package/lib/typescript/src/components/NepaliDatePicker/NepaliDatePicker.d.ts.map +1 -0
  249. package/lib/typescript/src/components/NepaliDatePicker/index.d.ts +4 -0
  250. package/lib/typescript/src/components/NepaliDatePicker/index.d.ts.map +1 -0
  251. package/lib/typescript/src/components/NepaliDatePicker/types.d.ts +50 -0
  252. package/lib/typescript/src/components/NepaliDatePicker/types.d.ts.map +1 -0
  253. package/lib/typescript/src/components/NepaliRangePicker/NepaliRangePicker.d.ts +4 -0
  254. package/lib/typescript/src/components/NepaliRangePicker/NepaliRangePicker.d.ts.map +1 -0
  255. package/lib/typescript/src/components/NepaliRangePicker/RangePickerModal.d.ts +4 -0
  256. package/lib/typescript/src/components/NepaliRangePicker/RangePickerModal.d.ts.map +1 -0
  257. package/lib/typescript/src/components/NepaliRangePicker/index.d.ts +5 -0
  258. package/lib/typescript/src/components/NepaliRangePicker/index.d.ts.map +1 -0
  259. package/lib/typescript/src/components/NepaliRangePicker/range-utils.d.ts +13 -0
  260. package/lib/typescript/src/components/NepaliRangePicker/range-utils.d.ts.map +1 -0
  261. package/lib/typescript/src/components/NepaliRangePicker/types.d.ts +61 -0
  262. package/lib/typescript/src/components/NepaliRangePicker/types.d.ts.map +1 -0
  263. package/lib/typescript/src/core/arithmetic.d.ts +6 -0
  264. package/lib/typescript/src/core/arithmetic.d.ts.map +1 -0
  265. package/lib/typescript/src/core/bsData.d.ts +39 -0
  266. package/lib/typescript/src/core/bsData.d.ts.map +1 -0
  267. package/lib/typescript/src/core/conversion.d.ts +4 -0
  268. package/lib/typescript/src/core/conversion.d.ts.map +1 -0
  269. package/lib/typescript/src/core/dateKey.d.ts +4 -0
  270. package/lib/typescript/src/core/dateKey.d.ts.map +1 -0
  271. package/lib/typescript/src/core/epochDay.d.ts +7 -0
  272. package/lib/typescript/src/core/epochDay.d.ts.map +1 -0
  273. package/lib/typescript/src/core/format/format.d.ts +8 -0
  274. package/lib/typescript/src/core/format/format.d.ts.map +1 -0
  275. package/lib/typescript/src/core/format/index.d.ts +5 -0
  276. package/lib/typescript/src/core/format/index.d.ts.map +1 -0
  277. package/lib/typescript/src/core/format/parse.d.ts +7 -0
  278. package/lib/typescript/src/core/format/parse.d.ts.map +1 -0
  279. package/lib/typescript/src/core/format/tokens.d.ts +4 -0
  280. package/lib/typescript/src/core/format/tokens.d.ts.map +1 -0
  281. package/lib/typescript/src/core/index.d.ts +11 -0
  282. package/lib/typescript/src/core/index.d.ts.map +1 -0
  283. package/lib/typescript/src/core/locale/en.d.ts +3 -0
  284. package/lib/typescript/src/core/locale/en.d.ts.map +1 -0
  285. package/lib/typescript/src/core/locale/index.d.ts +4 -0
  286. package/lib/typescript/src/core/locale/index.d.ts.map +1 -0
  287. package/lib/typescript/src/core/locale/ne.d.ts +3 -0
  288. package/lib/typescript/src/core/locale/ne.d.ts.map +1 -0
  289. package/lib/typescript/src/core/locale/types.d.ts +11 -0
  290. package/lib/typescript/src/core/locale/types.d.ts.map +1 -0
  291. package/lib/typescript/src/core/numerals/index.d.ts +2 -0
  292. package/lib/typescript/src/core/numerals/index.d.ts.map +1 -0
  293. package/lib/typescript/src/core/numerals/nepali-numerals.d.ts +3 -0
  294. package/lib/typescript/src/core/numerals/nepali-numerals.d.ts.map +1 -0
  295. package/lib/typescript/src/core/types.d.ts +14 -0
  296. package/lib/typescript/src/core/types.d.ts.map +1 -0
  297. package/lib/typescript/src/core/validation.d.ts +17 -0
  298. package/lib/typescript/src/core/validation.d.ts.map +1 -0
  299. package/lib/typescript/src/index.d.ts +9 -0
  300. package/lib/typescript/src/index.d.ts.map +1 -0
  301. package/lib/typescript/src/theme/create-theme.d.ts +6 -0
  302. package/lib/typescript/src/theme/create-theme.d.ts.map +1 -0
  303. package/lib/typescript/src/theme/default-theme.d.ts +4 -0
  304. package/lib/typescript/src/theme/default-theme.d.ts.map +1 -0
  305. package/lib/typescript/src/theme/index.d.ts +4 -0
  306. package/lib/typescript/src/theme/index.d.ts.map +1 -0
  307. package/lib/typescript/src/theme/types.d.ts +43 -0
  308. package/lib/typescript/src/theme/types.d.ts.map +1 -0
  309. package/lib/typescript/src/utils/date-helpers.d.ts +27 -0
  310. package/lib/typescript/src/utils/date-helpers.d.ts.map +1 -0
  311. package/lib/typescript/src/utils/index.d.ts +2 -0
  312. package/lib/typescript/src/utils/index.d.ts.map +1 -0
  313. package/package.json +85 -0
  314. package/src/accessibility/index.ts +5 -0
  315. package/src/accessibility/labels.ts +22 -0
  316. package/src/calendar/calendar-types.ts +25 -0
  317. package/src/calendar/get-calendar-month-grid.ts +125 -0
  318. package/src/calendar/index.ts +2 -0
  319. package/src/components/NepaliCalendar/CalendarDay.tsx +198 -0
  320. package/src/components/NepaliCalendar/CalendarGrid.tsx +159 -0
  321. package/src/components/NepaliCalendar/CalendarHeader.tsx +126 -0
  322. package/src/components/NepaliCalendar/CalendarWeekdays.tsx +49 -0
  323. package/src/components/NepaliCalendar/NepaliCalendar.tsx +279 -0
  324. package/src/components/NepaliCalendar/index.ts +6 -0
  325. package/src/components/NepaliCalendar/types.ts +62 -0
  326. package/src/components/NepaliDatePicker/DatePickerModal.tsx +220 -0
  327. package/src/components/NepaliDatePicker/NepaliDatePicker.tsx +171 -0
  328. package/src/components/NepaliDatePicker/index.ts +3 -0
  329. package/src/components/NepaliDatePicker/types.ts +70 -0
  330. package/src/components/NepaliRangePicker/NepaliRangePicker.tsx +206 -0
  331. package/src/components/NepaliRangePicker/RangePickerModal.tsx +336 -0
  332. package/src/components/NepaliRangePicker/index.ts +11 -0
  333. package/src/components/NepaliRangePicker/range-utils.ts +75 -0
  334. package/src/components/NepaliRangePicker/types.ts +84 -0
  335. package/src/core/arithmetic.ts +34 -0
  336. package/src/core/bsData.ts +115 -0
  337. package/src/core/conversion.ts +73 -0
  338. package/src/core/dateKey.ts +31 -0
  339. package/src/core/epochDay.ts +49 -0
  340. package/src/core/format/format.ts +108 -0
  341. package/src/core/format/index.ts +4 -0
  342. package/src/core/format/parse.ts +68 -0
  343. package/src/core/format/tokens.ts +35 -0
  344. package/src/core/index.ts +10 -0
  345. package/src/core/locale/en.ts +23 -0
  346. package/src/core/locale/index.ts +3 -0
  347. package/src/core/locale/ne.ts +31 -0
  348. package/src/core/locale/types.ts +12 -0
  349. package/src/core/numerals/index.ts +1 -0
  350. package/src/core/numerals/nepali-numerals.ts +27 -0
  351. package/src/core/types.ts +15 -0
  352. package/src/core/validation.test.ts +207 -0
  353. package/src/core/validation.ts +141 -0
  354. package/src/exports.test.ts +135 -0
  355. package/src/index.ts +8 -0
  356. package/src/phase2.test.ts +424 -0
  357. package/src/phase3.test.ts +83 -0
  358. package/src/phase4.test.ts +86 -0
  359. package/src/phase5.test.ts +257 -0
  360. package/src/phase7.test.ts +307 -0
  361. package/src/range-helpers.test.ts +153 -0
  362. package/src/theme/create-theme.ts +29 -0
  363. package/src/theme/default-theme.ts +99 -0
  364. package/src/theme/index.ts +3 -0
  365. package/src/theme/types.ts +44 -0
  366. package/src/utils/date-helpers.ts +146 -0
  367. package/src/utils/index.ts +9 -0
@@ -0,0 +1,336 @@
1
+ import React, { useState, useEffect, useMemo, useCallback } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ Pressable,
6
+ Modal,
7
+ StyleSheet,
8
+ TouchableWithoutFeedback,
9
+ } from 'react-native';
10
+ import type { BSDateValue } from '../../core/types';
11
+ import { useCalendarTheme } from '../../theme';
12
+ import { safeFormatBSDate, getSafeInitialBSDate } from '../../utils';
13
+ import { NepaliCalendar } from '../NepaliCalendar';
14
+ import type { RangePickerModalProps, DateRangeValue } from './types';
15
+ import { selectRangeDate } from './range-utils';
16
+
17
+ function getInitialTempRange(
18
+ value: DateRangeValue | undefined,
19
+ defaultValue: DateRangeValue | undefined
20
+ ): DateRangeValue {
21
+ const start = value?.start ? getSafeInitialBSDate(value.start, undefined) : null;
22
+ const end = value?.end ? getSafeInitialBSDate(value.end, undefined) : null;
23
+
24
+ if (start) {
25
+ return { start, end };
26
+ }
27
+
28
+ const defStart = defaultValue?.start
29
+ ? getSafeInitialBSDate(defaultValue.start, undefined)
30
+ : null;
31
+ const defEnd = defaultValue?.end
32
+ ? getSafeInitialBSDate(defaultValue.end, undefined)
33
+ : null;
34
+
35
+ if (defStart) {
36
+ return { start: defStart, end: defEnd };
37
+ }
38
+
39
+ return { start: null, end: null };
40
+ }
41
+
42
+ export function RangePickerModal({
43
+ visible,
44
+ value,
45
+ defaultValue,
46
+ onChange,
47
+ onConfirm,
48
+ onCancel,
49
+ onClose,
50
+ onClear,
51
+ locale,
52
+ numerals,
53
+ minDate,
54
+ maxDate,
55
+ markedDates,
56
+ disabledDates,
57
+ weekStartsOn,
58
+ theme,
59
+ colorScheme,
60
+ title = 'Select Date Range',
61
+ confirmText = 'Confirm',
62
+ cancelText = 'Cancel',
63
+ clearText = 'Clear',
64
+ allowSameDay = true,
65
+ testID,
66
+ }: RangePickerModalProps) {
67
+ const calendarTheme = useCalendarTheme({ colorScheme, theme });
68
+
69
+ const [tempRange, setTempRange] = useState<DateRangeValue>(() =>
70
+ getInitialTempRange(value, defaultValue)
71
+ );
72
+
73
+ useEffect(() => {
74
+ if (visible) {
75
+ setTempRange(getInitialTempRange(value, defaultValue));
76
+ }
77
+ }, [visible, value, defaultValue]);
78
+
79
+ const handleDateSelect = useCallback(
80
+ (date: BSDateValue) => {
81
+ setTempRange((prev) => selectRangeDate(prev, date, { allowSameDay }));
82
+ },
83
+ [allowSameDay]
84
+ );
85
+
86
+ const handleConfirm = useCallback(() => {
87
+ if (!tempRange.start) return;
88
+ onConfirm?.(tempRange);
89
+ onChange?.(tempRange);
90
+ onClose?.();
91
+ }, [tempRange, onConfirm, onChange, onClose]);
92
+
93
+ const handleCancel = useCallback(() => {
94
+ onCancel?.();
95
+ onClose?.();
96
+ }, [onCancel, onClose]);
97
+
98
+ const handleClear = useCallback(() => {
99
+ setTempRange({ start: null, end: null });
100
+ onClear?.();
101
+ }, [onClear]);
102
+
103
+ const handleBackdropPress = useCallback(() => {
104
+ onCancel?.();
105
+ onClose?.();
106
+ }, [onCancel, onClose]);
107
+
108
+ const rangeSummary = useMemo(() => {
109
+ const startStr = tempRange.start
110
+ ? safeFormatBSDate(tempRange.start, 'yyyy-MM-dd', locale, numerals)
111
+ : null;
112
+ const endStr = tempRange.end
113
+ ? safeFormatBSDate(tempRange.end, 'yyyy-MM-dd', locale, numerals)
114
+ : null;
115
+
116
+ if (startStr && endStr) return `${startStr} → ${endStr}`;
117
+ if (startStr) return `${startStr} → ...`;
118
+ return `... → ...`;
119
+ }, [tempRange, locale, numerals]);
120
+
121
+ const isConfirmDisabled = tempRange.start == null || tempRange.end == null;
122
+
123
+ const modalContent = useMemo(
124
+ () => (
125
+ <View
126
+ style={[
127
+ styles.modalContent,
128
+ { backgroundColor: calendarTheme.colors.modalBackground },
129
+ ]}
130
+ testID={testID}
131
+ >
132
+ <Text
133
+ style={[
134
+ styles.title,
135
+ {
136
+ color: calendarTheme.colors.text,
137
+ borderBottomColor: calendarTheme.colors.border,
138
+ },
139
+ ]}
140
+ >
141
+ {title}
142
+ </Text>
143
+
144
+ <View
145
+ style={[
146
+ styles.rangeSummary,
147
+ { borderBottomColor: calendarTheme.colors.border },
148
+ ]}
149
+ >
150
+ <Text style={[styles.rangeText, { color: calendarTheme.colors.primary }]}>
151
+ {rangeSummary}
152
+ </Text>
153
+ </View>
154
+
155
+ <View style={styles.calendarWrapper}>
156
+ <NepaliCalendar
157
+ value={tempRange.start}
158
+ onChange={handleDateSelect}
159
+ locale={locale}
160
+ numerals={numerals}
161
+ minDate={minDate}
162
+ maxDate={maxDate}
163
+ markedDates={markedDates}
164
+ disabledDates={disabledDates}
165
+ weekStartsOn={weekStartsOn}
166
+ theme={theme}
167
+ colorScheme={colorScheme}
168
+ rangeValue={tempRange}
169
+ />
170
+ </View>
171
+
172
+ <View
173
+ style={[
174
+ styles.buttonRow,
175
+ { borderTopColor: calendarTheme.colors.border },
176
+ ]}
177
+ >
178
+ <Pressable
179
+ style={[styles.button, styles.clearButton]}
180
+ onPress={handleClear}
181
+ accessibilityRole="button"
182
+ accessibilityLabel="Clear selected date range"
183
+ >
184
+ <Text style={[styles.clearText, { color: calendarTheme.colors.danger }]}>
185
+ {clearText}
186
+ </Text>
187
+ </Pressable>
188
+
189
+ <Pressable
190
+ style={[styles.button, styles.cancelButton]}
191
+ onPress={handleCancel}
192
+ accessibilityRole="button"
193
+ accessibilityLabel="Cancel date range selection"
194
+ >
195
+ <Text style={[styles.cancelText, { color: calendarTheme.colors.mutedText }]}>
196
+ {cancelText}
197
+ </Text>
198
+ </Pressable>
199
+
200
+ <Pressable
201
+ style={[
202
+ styles.button,
203
+ {
204
+ backgroundColor: isConfirmDisabled
205
+ ? calendarTheme.colors.disabledText
206
+ : calendarTheme.colors.primary,
207
+ },
208
+ ]}
209
+ onPress={handleConfirm}
210
+ disabled={isConfirmDisabled}
211
+ accessibilityRole="button"
212
+ accessibilityLabel="Confirm selected date range"
213
+ accessibilityState={{ disabled: isConfirmDisabled }}
214
+ >
215
+ <Text
216
+ style={[
217
+ styles.confirmText,
218
+ { color: calendarTheme.colors.primaryText },
219
+ ]}
220
+ >
221
+ {confirmText}
222
+ </Text>
223
+ </Pressable>
224
+ </View>
225
+ </View>
226
+ ),
227
+ [
228
+ tempRange,
229
+ title,
230
+ rangeSummary,
231
+ locale,
232
+ numerals,
233
+ minDate,
234
+ maxDate,
235
+ markedDates,
236
+ disabledDates,
237
+ weekStartsOn,
238
+ theme,
239
+ colorScheme,
240
+ testID,
241
+ clearText,
242
+ cancelText,
243
+ confirmText,
244
+ isConfirmDisabled,
245
+ calendarTheme,
246
+ handleClear,
247
+ handleCancel,
248
+ handleConfirm,
249
+ handleDateSelect,
250
+ ]
251
+ );
252
+
253
+ return (
254
+ <Modal
255
+ visible={visible}
256
+ transparent
257
+ animationType="fade"
258
+ onRequestClose={handleCancel}
259
+ >
260
+ <TouchableWithoutFeedback onPress={handleBackdropPress}>
261
+ <View style={[styles.backdrop, { backgroundColor: calendarTheme.colors.overlay }]}>
262
+ <TouchableWithoutFeedback>{modalContent}</TouchableWithoutFeedback>
263
+ </View>
264
+ </TouchableWithoutFeedback>
265
+ </Modal>
266
+ );
267
+ }
268
+
269
+ const styles = StyleSheet.create({
270
+ backdrop: {
271
+ flex: 1,
272
+ justifyContent: 'center',
273
+ alignItems: 'center',
274
+ paddingHorizontal: 20,
275
+ },
276
+ modalContent: {
277
+ borderRadius: 16,
278
+ overflow: 'hidden',
279
+ width: '100%',
280
+ maxWidth: 400,
281
+ },
282
+ title: {
283
+ fontSize: 18,
284
+ fontWeight: '600',
285
+ textAlign: 'center',
286
+ paddingVertical: 16,
287
+ paddingHorizontal: 16,
288
+ borderBottomWidth: StyleSheet.hairlineWidth,
289
+ },
290
+ rangeSummary: {
291
+ paddingVertical: 12,
292
+ paddingHorizontal: 16,
293
+ borderBottomWidth: StyleSheet.hairlineWidth,
294
+ alignItems: 'center',
295
+ },
296
+ rangeText: {
297
+ fontSize: 16,
298
+ fontWeight: '500',
299
+ },
300
+ calendarWrapper: {
301
+ padding: 8,
302
+ },
303
+ buttonRow: {
304
+ flexDirection: 'row',
305
+ justifyContent: 'flex-end',
306
+ paddingHorizontal: 16,
307
+ paddingVertical: 12,
308
+ gap: 10,
309
+ borderTopWidth: StyleSheet.hairlineWidth,
310
+ },
311
+ button: {
312
+ paddingVertical: 10,
313
+ paddingHorizontal: 16,
314
+ borderRadius: 8,
315
+ minWidth: 70,
316
+ alignItems: 'center',
317
+ },
318
+ clearButton: {
319
+ backgroundColor: 'transparent',
320
+ },
321
+ cancelButton: {
322
+ backgroundColor: 'transparent',
323
+ },
324
+ clearText: {
325
+ fontSize: 15,
326
+ fontWeight: '600',
327
+ },
328
+ cancelText: {
329
+ fontSize: 15,
330
+ fontWeight: '600',
331
+ },
332
+ confirmText: {
333
+ fontSize: 15,
334
+ fontWeight: '600',
335
+ },
336
+ });
@@ -0,0 +1,11 @@
1
+ export { NepaliRangePicker } from './NepaliRangePicker';
2
+ export { RangePickerModal } from './RangePickerModal';
3
+ export type { NepaliRangePickerProps, RangePickerModalProps, DateRangeValue } from './types';
4
+ export {
5
+ isDateInRange,
6
+ isRangeStart,
7
+ isRangeEnd,
8
+ normalizeRange,
9
+ selectRangeDate,
10
+ getRangeDateKey,
11
+ } from './range-utils';
@@ -0,0 +1,75 @@
1
+ import type { BSDateValue } from '../../core/types';
2
+ import { compareBS } from '../../core';
3
+ import type { DateRangeValue } from './types';
4
+
5
+ export function isDateInRange(
6
+ date: BSDateValue,
7
+ range: DateRangeValue
8
+ ): boolean {
9
+ if (!range.start || !range.end) return false;
10
+ const cmpStart = compareBS(date, range.start);
11
+ const cmpEnd = compareBS(date, range.end);
12
+ return cmpStart >= 0 && cmpEnd <= 0;
13
+ }
14
+
15
+ export function isRangeStart(
16
+ date: BSDateValue,
17
+ range: DateRangeValue
18
+ ): boolean {
19
+ if (!range.start) return false;
20
+ return compareBS(date, range.start) === 0;
21
+ }
22
+
23
+ export function isRangeEnd(
24
+ date: BSDateValue,
25
+ range: DateRangeValue
26
+ ): boolean {
27
+ if (!range.end) return false;
28
+ return compareBS(date, range.end) === 0;
29
+ }
30
+
31
+ export function normalizeRange(
32
+ start: BSDateValue,
33
+ end: BSDateValue,
34
+ options?: { allowSameDay?: boolean }
35
+ ): DateRangeValue {
36
+ const allowSameDay = options?.allowSameDay ?? true;
37
+
38
+ if (!allowSameDay && compareBS(start, end) === 0) {
39
+ return { start, end: null };
40
+ }
41
+
42
+ if (compareBS(start, end) <= 0) {
43
+ return { start, end };
44
+ }
45
+
46
+ return { start: end, end: start };
47
+ }
48
+
49
+ export function selectRangeDate(
50
+ currentRange: DateRangeValue,
51
+ date: BSDateValue,
52
+ options?: { allowSameDay?: boolean }
53
+ ): DateRangeValue {
54
+ const allowSameDay = options?.allowSameDay ?? true;
55
+
56
+ if (!currentRange.start) {
57
+ return { start: date, end: null };
58
+ }
59
+
60
+ if (!currentRange.end) {
61
+ return normalizeRange(currentRange.start, date, { allowSameDay });
62
+ }
63
+
64
+ return { start: date, end: null };
65
+ }
66
+
67
+ export function getRangeDateKey(
68
+ range: DateRangeValue,
69
+ date: BSDateValue
70
+ ): 'start' | 'end' | 'in-range' | 'none' {
71
+ if (isRangeStart(date, range)) return 'start';
72
+ if (isRangeEnd(date, range)) return 'end';
73
+ if (isDateInRange(date, range)) return 'in-range';
74
+ return 'none';
75
+ }
@@ -0,0 +1,84 @@
1
+ import type { BSDateValue } from '../../core/types';
2
+ import type { LocaleCode, CalendarLocale, NumeralSystem } from '../../core/locale';
3
+ import type { CalendarTheme } from '../../theme/types';
4
+ import type { CalendarMarkedDate } from '../NepaliCalendar/types';
5
+
6
+ export type DateRangeValue = {
7
+ start: BSDateValue | null;
8
+ end: BSDateValue | null;
9
+ };
10
+
11
+ export type NepaliRangePickerProps = {
12
+ value?: DateRangeValue;
13
+ defaultValue?: DateRangeValue;
14
+ onChange?: (range: DateRangeValue) => void;
15
+
16
+ placeholder?: string;
17
+ startPlaceholder?: string;
18
+ endPlaceholder?: string;
19
+ disabled?: boolean;
20
+
21
+ locale?: LocaleCode | CalendarLocale;
22
+ numerals?: NumeralSystem;
23
+
24
+ displayFormat?: string;
25
+
26
+ minDate?: BSDateValue;
27
+ maxDate?: BSDateValue;
28
+
29
+ markedDates?: Record<string, CalendarMarkedDate>;
30
+ disabledDates?: string[] | ((date: BSDateValue) => boolean);
31
+
32
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
33
+
34
+ allowSameDay?: boolean;
35
+
36
+ theme?: Partial<CalendarTheme>;
37
+ colorScheme?: 'light' | 'dark' | 'system';
38
+
39
+ modalTitle?: string;
40
+ confirmText?: string;
41
+ cancelText?: string;
42
+ clearText?: string;
43
+
44
+ onOpen?: () => void;
45
+ onClose?: () => void;
46
+
47
+ testID?: string;
48
+ };
49
+
50
+ export type RangePickerModalProps = {
51
+ visible: boolean;
52
+
53
+ value?: DateRangeValue;
54
+ defaultValue?: DateRangeValue;
55
+
56
+ onChange?: (range: DateRangeValue) => void;
57
+ onConfirm?: (range: DateRangeValue) => void;
58
+ onCancel?: () => void;
59
+ onClose?: () => void;
60
+ onClear?: () => void;
61
+
62
+ locale?: LocaleCode | CalendarLocale;
63
+ numerals?: NumeralSystem;
64
+
65
+ minDate?: BSDateValue;
66
+ maxDate?: BSDateValue;
67
+
68
+ markedDates?: Record<string, CalendarMarkedDate>;
69
+ disabledDates?: string[] | ((date: BSDateValue) => boolean);
70
+
71
+ weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
72
+
73
+ allowSameDay?: boolean;
74
+
75
+ theme?: Partial<CalendarTheme>;
76
+ colorScheme?: 'light' | 'dark' | 'system';
77
+
78
+ title?: string;
79
+ confirmText?: string;
80
+ cancelText?: string;
81
+ clearText?: string;
82
+
83
+ testID?: string;
84
+ };
@@ -0,0 +1,34 @@
1
+ import type { BSDateValue } from './types';
2
+ import { toAD, toBS } from './conversion';
3
+ import { adDateToEpochDay, epochDayToADDate, jsDateToEpochDay } from './epochDay';
4
+ import { isValidBSDate } from './validation';
5
+
6
+ export function compareBS(a: BSDateValue, b: BSDateValue): number {
7
+ if (a.year !== b.year) return a.year - b.year;
8
+ if (a.month !== b.month) return a.month - b.month;
9
+ return a.day - b.day;
10
+ }
11
+
12
+ export function addBSDays(date: BSDateValue, days: number): BSDateValue {
13
+ if (!isValidBSDate(date)) {
14
+ throw new RangeError(`Invalid BS date.`);
15
+ }
16
+
17
+ const ad = toAD(date);
18
+ const epochDay = adDateToEpochDay(ad) + days;
19
+ const newAD = epochDayToADDate(epochDay);
20
+
21
+ return toBS(newAD);
22
+ }
23
+
24
+ export function subBSDays(date: BSDateValue, days: number): BSDateValue {
25
+ return addBSDays(date, -days);
26
+ }
27
+
28
+ export function todayBS(): BSDateValue {
29
+ const now = new Date();
30
+ const epochDay = jsDateToEpochDay(now);
31
+ const ad = epochDayToADDate(epochDay);
32
+
33
+ return toBS(ad);
34
+ }
@@ -0,0 +1,115 @@
1
+ import type { ADDateValue, BSDateValue } from './types';
2
+ import { adDateToEpochDay } from './epochDay';
3
+
4
+ export type BSYearMonthLengths = readonly [
5
+ number,
6
+ number,
7
+ number,
8
+ number,
9
+ number,
10
+ number,
11
+ number,
12
+ number,
13
+ number,
14
+ number,
15
+ number,
16
+ number
17
+ ];
18
+
19
+ export type BSCalendarData = {
20
+ readonly anchorBS: BSDateValue;
21
+ readonly anchorAD: ADDateValue;
22
+ readonly monthLengthsByYear: Readonly<Record<number, BSYearMonthLengths>>;
23
+ };
24
+
25
+ export type BSYearOffset = {
26
+ readonly year: number;
27
+ readonly startEpochDay: number;
28
+ readonly totalDays: number;
29
+ };
30
+
31
+ // TODO(verified-data): Replace this tiny anchor window with a sourced,
32
+ // verified BS month-length table before claiming full calendar accuracy.
33
+ // This placeholder exists only to prove the conversion architecture.
34
+ export const BS_CALENDAR_DATA: BSCalendarData = {
35
+ anchorBS: { calendar: 'BS', year: 2081, month: 1, day: 1 },
36
+ anchorAD: { calendar: 'AD', year: 2024, month: 4, day: 13 },
37
+ monthLengthsByYear: {
38
+ 2081: [31, 31, 32, 31, 31, 31, 30, 29, 30, 29, 30, 30],
39
+ },
40
+ };
41
+
42
+ export const BS_YEAR_OFFSETS: readonly BSYearOffset[] =
43
+ createBSYearOffsets(BS_CALENDAR_DATA);
44
+
45
+ export function createBSYearOffsets(data: BSCalendarData): readonly BSYearOffset[] {
46
+ assertSupportedAnchor(data);
47
+
48
+ let startEpochDay = adDateToEpochDay(data.anchorAD);
49
+ let expectedYear = data.anchorBS.year;
50
+
51
+ return Object.entries(data.monthLengthsByYear)
52
+ .map(([year, monthLengths]) => ({
53
+ year: Number(year),
54
+ monthLengths,
55
+ }))
56
+ .sort((a, b) => a.year - b.year)
57
+ .map(({ year, monthLengths }) => {
58
+ if (year !== expectedYear) {
59
+ throw new Error(
60
+ `BS month data must start at ${data.anchorBS.year} and be contiguous.`
61
+ );
62
+ }
63
+
64
+ assertMonthLengths(year, monthLengths);
65
+
66
+ const totalDays = monthLengths.reduce((sum, days) => sum + days, 0);
67
+ const offset = { year, startEpochDay, totalDays };
68
+ startEpochDay += totalDays;
69
+ expectedYear += 1;
70
+
71
+ return offset;
72
+ });
73
+ }
74
+
75
+ export function getSupportedBSYearRange(): { min: number; max: number } {
76
+ const years = Object.keys(BS_CALENDAR_DATA.monthLengthsByYear).map(Number);
77
+
78
+ return {
79
+ min: Math.min(...years),
80
+ max: Math.max(...years),
81
+ };
82
+ }
83
+
84
+ export const SUPPORTED_BS_START_YEAR = getSupportedBSYearRange().min;
85
+ export const SUPPORTED_BS_END_YEAR = getSupportedBSYearRange().max;
86
+
87
+ export function getSupportedBSRange(): { start: number; end: number } {
88
+ const range = getSupportedBSYearRange();
89
+ return { start: range.min, end: range.max };
90
+ }
91
+
92
+ function assertSupportedAnchor(data: BSCalendarData): void {
93
+ if (data.anchorBS.month !== 1 || data.anchorBS.day !== 1) {
94
+ throw new Error(
95
+ `BS calendar data anchor must be the first day of a BS year.`
96
+ );
97
+ }
98
+ }
99
+
100
+ function assertMonthLengths(
101
+ year: number,
102
+ monthLengths: BSYearMonthLengths
103
+ ): void {
104
+ if (monthLengths.length !== 12) {
105
+ throw new Error(`BS year ${year} must contain 12 month lengths.`);
106
+ }
107
+
108
+ monthLengths.forEach((days, monthIndex) => {
109
+ if (!Number.isInteger(days) || days < 1) {
110
+ throw new Error(
111
+ `BS year ${year} month ${monthIndex + 1} has an invalid length.`
112
+ );
113
+ }
114
+ });
115
+ }