@amir83nasr/map 1.0.4 → 1.1.2

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 (281) hide show
  1. package/README.md +26 -25
  2. package/dist/core/defaults.test.d.ts +1 -0
  3. package/dist/core/format.test.d.ts +1 -0
  4. package/dist/{emitter.d.ts → engine/emitter.d.ts} +1 -1
  5. package/dist/engine/engine.test.d.ts +1 -0
  6. package/dist/{picker.d.ts → engine/picker.d.ts} +4 -1
  7. package/dist/index.cjs +88 -0
  8. package/dist/index.d.cts +4 -0
  9. package/dist/index.d.ts +4 -18
  10. package/dist/{qompick-react.js → index.js} +286 -246
  11. package/dist/react/LocationPickerView.d.ts +16 -0
  12. package/dist/react/react.test.d.ts +1 -0
  13. package/dist/style/style.test.d.ts +1 -0
  14. package/dist/{qompick-react.css → styles.css} +1 -1
  15. package/package.json +18 -10
  16. package/dist/qompick-react.cjs +0 -76
  17. /package/dist/{defaults.d.ts → core/defaults.d.ts} +0 -0
  18. /package/dist/{format.d.ts → core/format.d.ts} +0 -0
  19. /package/dist/{geocode.d.ts → core/geocode.d.ts} +0 -0
  20. /package/dist/{i18n.d.ts → core/i18n.d.ts} +0 -0
  21. /package/dist/{icons.d.ts → core/icons.d.ts} +0 -0
  22. /package/dist/{types.d.ts → core/types.d.ts} +0 -0
  23. /package/dist/{snap.d.ts → engine/snap.d.ts} +0 -0
  24. /package/dist/{colors.d.ts → style/colors.d.ts} +0 -0
  25. /package/dist/{map-style.d.ts → style/map-style.d.ts} +0 -0
  26. /package/fonts/{IRANYekanX Regular → IRANYekanX}/0-255.pbf +0 -0
  27. /package/fonts/{IRANYekanX Regular → IRANYekanX}/1024-1279.pbf +0 -0
  28. /package/fonts/{IRANYekanX Regular → IRANYekanX}/10240-10495.pbf +0 -0
  29. /package/fonts/{IRANYekanX Regular → IRANYekanX}/10496-10751.pbf +0 -0
  30. /package/fonts/{IRANYekanX Regular → IRANYekanX}/10752-11007.pbf +0 -0
  31. /package/fonts/{IRANYekanX Regular → IRANYekanX}/11008-11263.pbf +0 -0
  32. /package/fonts/{IRANYekanX Regular → IRANYekanX}/11264-11519.pbf +0 -0
  33. /package/fonts/{IRANYekanX Regular → IRANYekanX}/11520-11775.pbf +0 -0
  34. /package/fonts/{IRANYekanX Regular → IRANYekanX}/11776-12031.pbf +0 -0
  35. /package/fonts/{IRANYekanX Regular → IRANYekanX}/12032-12287.pbf +0 -0
  36. /package/fonts/{IRANYekanX Regular → IRANYekanX}/12288-12543.pbf +0 -0
  37. /package/fonts/{IRANYekanX Regular → IRANYekanX}/12544-12799.pbf +0 -0
  38. /package/fonts/{IRANYekanX Regular → IRANYekanX}/1280-1535.pbf +0 -0
  39. /package/fonts/{IRANYekanX Regular → IRANYekanX}/12800-13055.pbf +0 -0
  40. /package/fonts/{IRANYekanX Regular → IRANYekanX}/13056-13311.pbf +0 -0
  41. /package/fonts/{IRANYekanX Regular → IRANYekanX}/13312-13567.pbf +0 -0
  42. /package/fonts/{IRANYekanX Regular → IRANYekanX}/13568-13823.pbf +0 -0
  43. /package/fonts/{IRANYekanX Regular → IRANYekanX}/13824-14079.pbf +0 -0
  44. /package/fonts/{IRANYekanX Regular → IRANYekanX}/14080-14335.pbf +0 -0
  45. /package/fonts/{IRANYekanX Regular → IRANYekanX}/14336-14591.pbf +0 -0
  46. /package/fonts/{IRANYekanX Regular → IRANYekanX}/14592-14847.pbf +0 -0
  47. /package/fonts/{IRANYekanX Regular → IRANYekanX}/14848-15103.pbf +0 -0
  48. /package/fonts/{IRANYekanX Regular → IRANYekanX}/15104-15359.pbf +0 -0
  49. /package/fonts/{IRANYekanX Regular → IRANYekanX}/1536-1791.pbf +0 -0
  50. /package/fonts/{IRANYekanX Regular → IRANYekanX}/15360-15615.pbf +0 -0
  51. /package/fonts/{IRANYekanX Regular → IRANYekanX}/15616-15871.pbf +0 -0
  52. /package/fonts/{IRANYekanX Regular → IRANYekanX}/15872-16127.pbf +0 -0
  53. /package/fonts/{IRANYekanX Regular → IRANYekanX}/16128-16383.pbf +0 -0
  54. /package/fonts/{IRANYekanX Regular → IRANYekanX}/16384-16639.pbf +0 -0
  55. /package/fonts/{IRANYekanX Regular → IRANYekanX}/16640-16895.pbf +0 -0
  56. /package/fonts/{IRANYekanX Regular → IRANYekanX}/16896-17151.pbf +0 -0
  57. /package/fonts/{IRANYekanX Regular → IRANYekanX}/17152-17407.pbf +0 -0
  58. /package/fonts/{IRANYekanX Regular → IRANYekanX}/17408-17663.pbf +0 -0
  59. /package/fonts/{IRANYekanX Regular → IRANYekanX}/17664-17919.pbf +0 -0
  60. /package/fonts/{IRANYekanX Regular → IRANYekanX}/1792-2047.pbf +0 -0
  61. /package/fonts/{IRANYekanX Regular → IRANYekanX}/17920-18175.pbf +0 -0
  62. /package/fonts/{IRANYekanX Regular → IRANYekanX}/18176-18431.pbf +0 -0
  63. /package/fonts/{IRANYekanX Regular → IRANYekanX}/18432-18687.pbf +0 -0
  64. /package/fonts/{IRANYekanX Regular → IRANYekanX}/18688-18943.pbf +0 -0
  65. /package/fonts/{IRANYekanX Regular → IRANYekanX}/18944-19199.pbf +0 -0
  66. /package/fonts/{IRANYekanX Regular → IRANYekanX}/19200-19455.pbf +0 -0
  67. /package/fonts/{IRANYekanX Regular → IRANYekanX}/19456-19711.pbf +0 -0
  68. /package/fonts/{IRANYekanX Regular → IRANYekanX}/19712-19967.pbf +0 -0
  69. /package/fonts/{IRANYekanX Regular → IRANYekanX}/19968-20223.pbf +0 -0
  70. /package/fonts/{IRANYekanX Regular → IRANYekanX}/20224-20479.pbf +0 -0
  71. /package/fonts/{IRANYekanX Regular → IRANYekanX}/2048-2303.pbf +0 -0
  72. /package/fonts/{IRANYekanX Regular → IRANYekanX}/20480-20735.pbf +0 -0
  73. /package/fonts/{IRANYekanX Regular → IRANYekanX}/20736-20991.pbf +0 -0
  74. /package/fonts/{IRANYekanX Regular → IRANYekanX}/20992-21247.pbf +0 -0
  75. /package/fonts/{IRANYekanX Regular → IRANYekanX}/21248-21503.pbf +0 -0
  76. /package/fonts/{IRANYekanX Regular → IRANYekanX}/21504-21759.pbf +0 -0
  77. /package/fonts/{IRANYekanX Regular → IRANYekanX}/21760-22015.pbf +0 -0
  78. /package/fonts/{IRANYekanX Regular → IRANYekanX}/22016-22271.pbf +0 -0
  79. /package/fonts/{IRANYekanX Regular → IRANYekanX}/22272-22527.pbf +0 -0
  80. /package/fonts/{IRANYekanX Regular → IRANYekanX}/22528-22783.pbf +0 -0
  81. /package/fonts/{IRANYekanX Regular → IRANYekanX}/22784-23039.pbf +0 -0
  82. /package/fonts/{IRANYekanX Regular → IRANYekanX}/2304-2559.pbf +0 -0
  83. /package/fonts/{IRANYekanX Regular → IRANYekanX}/23040-23295.pbf +0 -0
  84. /package/fonts/{IRANYekanX Regular → IRANYekanX}/23296-23551.pbf +0 -0
  85. /package/fonts/{IRANYekanX Regular → IRANYekanX}/23552-23807.pbf +0 -0
  86. /package/fonts/{IRANYekanX Regular → IRANYekanX}/23808-24063.pbf +0 -0
  87. /package/fonts/{IRANYekanX Regular → IRANYekanX}/24064-24319.pbf +0 -0
  88. /package/fonts/{IRANYekanX Regular → IRANYekanX}/24320-24575.pbf +0 -0
  89. /package/fonts/{IRANYekanX Regular → IRANYekanX}/24576-24831.pbf +0 -0
  90. /package/fonts/{IRANYekanX Regular → IRANYekanX}/24832-25087.pbf +0 -0
  91. /package/fonts/{IRANYekanX Regular → IRANYekanX}/25088-25343.pbf +0 -0
  92. /package/fonts/{IRANYekanX Regular → IRANYekanX}/25344-25599.pbf +0 -0
  93. /package/fonts/{IRANYekanX Regular → IRANYekanX}/256-511.pbf +0 -0
  94. /package/fonts/{IRANYekanX Regular → IRANYekanX}/2560-2815.pbf +0 -0
  95. /package/fonts/{IRANYekanX Regular → IRANYekanX}/25600-25855.pbf +0 -0
  96. /package/fonts/{IRANYekanX Regular → IRANYekanX}/25856-26111.pbf +0 -0
  97. /package/fonts/{IRANYekanX Regular → IRANYekanX}/26112-26367.pbf +0 -0
  98. /package/fonts/{IRANYekanX Regular → IRANYekanX}/26368-26623.pbf +0 -0
  99. /package/fonts/{IRANYekanX Regular → IRANYekanX}/26624-26879.pbf +0 -0
  100. /package/fonts/{IRANYekanX Regular → IRANYekanX}/26880-27135.pbf +0 -0
  101. /package/fonts/{IRANYekanX Regular → IRANYekanX}/27136-27391.pbf +0 -0
  102. /package/fonts/{IRANYekanX Regular → IRANYekanX}/27392-27647.pbf +0 -0
  103. /package/fonts/{IRANYekanX Regular → IRANYekanX}/27648-27903.pbf +0 -0
  104. /package/fonts/{IRANYekanX Regular → IRANYekanX}/27904-28159.pbf +0 -0
  105. /package/fonts/{IRANYekanX Regular → IRANYekanX}/2816-3071.pbf +0 -0
  106. /package/fonts/{IRANYekanX Regular → IRANYekanX}/28160-28415.pbf +0 -0
  107. /package/fonts/{IRANYekanX Regular → IRANYekanX}/28416-28671.pbf +0 -0
  108. /package/fonts/{IRANYekanX Regular → IRANYekanX}/28672-28927.pbf +0 -0
  109. /package/fonts/{IRANYekanX Regular → IRANYekanX}/28928-29183.pbf +0 -0
  110. /package/fonts/{IRANYekanX Regular → IRANYekanX}/29184-29439.pbf +0 -0
  111. /package/fonts/{IRANYekanX Regular → IRANYekanX}/29440-29695.pbf +0 -0
  112. /package/fonts/{IRANYekanX Regular → IRANYekanX}/29696-29951.pbf +0 -0
  113. /package/fonts/{IRANYekanX Regular → IRANYekanX}/29952-30207.pbf +0 -0
  114. /package/fonts/{IRANYekanX Regular → IRANYekanX}/30208-30463.pbf +0 -0
  115. /package/fonts/{IRANYekanX Regular → IRANYekanX}/30464-30719.pbf +0 -0
  116. /package/fonts/{IRANYekanX Regular → IRANYekanX}/3072-3327.pbf +0 -0
  117. /package/fonts/{IRANYekanX Regular → IRANYekanX}/30720-30975.pbf +0 -0
  118. /package/fonts/{IRANYekanX Regular → IRANYekanX}/30976-31231.pbf +0 -0
  119. /package/fonts/{IRANYekanX Regular → IRANYekanX}/31232-31487.pbf +0 -0
  120. /package/fonts/{IRANYekanX Regular → IRANYekanX}/31488-31743.pbf +0 -0
  121. /package/fonts/{IRANYekanX Regular → IRANYekanX}/31744-31999.pbf +0 -0
  122. /package/fonts/{IRANYekanX Regular → IRANYekanX}/32000-32255.pbf +0 -0
  123. /package/fonts/{IRANYekanX Regular → IRANYekanX}/32256-32511.pbf +0 -0
  124. /package/fonts/{IRANYekanX Regular → IRANYekanX}/32512-32767.pbf +0 -0
  125. /package/fonts/{IRANYekanX Regular → IRANYekanX}/32768-33023.pbf +0 -0
  126. /package/fonts/{IRANYekanX Regular → IRANYekanX}/33024-33279.pbf +0 -0
  127. /package/fonts/{IRANYekanX Regular → IRANYekanX}/3328-3583.pbf +0 -0
  128. /package/fonts/{IRANYekanX Regular → IRANYekanX}/33280-33535.pbf +0 -0
  129. /package/fonts/{IRANYekanX Regular → IRANYekanX}/33536-33791.pbf +0 -0
  130. /package/fonts/{IRANYekanX Regular → IRANYekanX}/33792-34047.pbf +0 -0
  131. /package/fonts/{IRANYekanX Regular → IRANYekanX}/34048-34303.pbf +0 -0
  132. /package/fonts/{IRANYekanX Regular → IRANYekanX}/34304-34559.pbf +0 -0
  133. /package/fonts/{IRANYekanX Regular → IRANYekanX}/34560-34815.pbf +0 -0
  134. /package/fonts/{IRANYekanX Regular → IRANYekanX}/34816-35071.pbf +0 -0
  135. /package/fonts/{IRANYekanX Regular → IRANYekanX}/35072-35327.pbf +0 -0
  136. /package/fonts/{IRANYekanX Regular → IRANYekanX}/35328-35583.pbf +0 -0
  137. /package/fonts/{IRANYekanX Regular → IRANYekanX}/35584-35839.pbf +0 -0
  138. /package/fonts/{IRANYekanX Regular → IRANYekanX}/3584-3839.pbf +0 -0
  139. /package/fonts/{IRANYekanX Regular → IRANYekanX}/35840-36095.pbf +0 -0
  140. /package/fonts/{IRANYekanX Regular → IRANYekanX}/36096-36351.pbf +0 -0
  141. /package/fonts/{IRANYekanX Regular → IRANYekanX}/36352-36607.pbf +0 -0
  142. /package/fonts/{IRANYekanX Regular → IRANYekanX}/36608-36863.pbf +0 -0
  143. /package/fonts/{IRANYekanX Regular → IRANYekanX}/36864-37119.pbf +0 -0
  144. /package/fonts/{IRANYekanX Regular → IRANYekanX}/37120-37375.pbf +0 -0
  145. /package/fonts/{IRANYekanX Regular → IRANYekanX}/37376-37631.pbf +0 -0
  146. /package/fonts/{IRANYekanX Regular → IRANYekanX}/37632-37887.pbf +0 -0
  147. /package/fonts/{IRANYekanX Regular → IRANYekanX}/37888-38143.pbf +0 -0
  148. /package/fonts/{IRANYekanX Regular → IRANYekanX}/38144-38399.pbf +0 -0
  149. /package/fonts/{IRANYekanX Regular → IRANYekanX}/3840-4095.pbf +0 -0
  150. /package/fonts/{IRANYekanX Regular → IRANYekanX}/38400-38655.pbf +0 -0
  151. /package/fonts/{IRANYekanX Regular → IRANYekanX}/38656-38911.pbf +0 -0
  152. /package/fonts/{IRANYekanX Regular → IRANYekanX}/38912-39167.pbf +0 -0
  153. /package/fonts/{IRANYekanX Regular → IRANYekanX}/39168-39423.pbf +0 -0
  154. /package/fonts/{IRANYekanX Regular → IRANYekanX}/39424-39679.pbf +0 -0
  155. /package/fonts/{IRANYekanX Regular → IRANYekanX}/39680-39935.pbf +0 -0
  156. /package/fonts/{IRANYekanX Regular → IRANYekanX}/39936-40191.pbf +0 -0
  157. /package/fonts/{IRANYekanX Regular → IRANYekanX}/40192-40447.pbf +0 -0
  158. /package/fonts/{IRANYekanX Regular → IRANYekanX}/40448-40703.pbf +0 -0
  159. /package/fonts/{IRANYekanX Regular → IRANYekanX}/40704-40959.pbf +0 -0
  160. /package/fonts/{IRANYekanX Regular → IRANYekanX}/4096-4351.pbf +0 -0
  161. /package/fonts/{IRANYekanX Regular → IRANYekanX}/40960-41215.pbf +0 -0
  162. /package/fonts/{IRANYekanX Regular → IRANYekanX}/41216-41471.pbf +0 -0
  163. /package/fonts/{IRANYekanX Regular → IRANYekanX}/41472-41727.pbf +0 -0
  164. /package/fonts/{IRANYekanX Regular → IRANYekanX}/41728-41983.pbf +0 -0
  165. /package/fonts/{IRANYekanX Regular → IRANYekanX}/41984-42239.pbf +0 -0
  166. /package/fonts/{IRANYekanX Regular → IRANYekanX}/42240-42495.pbf +0 -0
  167. /package/fonts/{IRANYekanX Regular → IRANYekanX}/42496-42751.pbf +0 -0
  168. /package/fonts/{IRANYekanX Regular → IRANYekanX}/42752-43007.pbf +0 -0
  169. /package/fonts/{IRANYekanX Regular → IRANYekanX}/43008-43263.pbf +0 -0
  170. /package/fonts/{IRANYekanX Regular → IRANYekanX}/43264-43519.pbf +0 -0
  171. /package/fonts/{IRANYekanX Regular → IRANYekanX}/4352-4607.pbf +0 -0
  172. /package/fonts/{IRANYekanX Regular → IRANYekanX}/43520-43775.pbf +0 -0
  173. /package/fonts/{IRANYekanX Regular → IRANYekanX}/43776-44031.pbf +0 -0
  174. /package/fonts/{IRANYekanX Regular → IRANYekanX}/44032-44287.pbf +0 -0
  175. /package/fonts/{IRANYekanX Regular → IRANYekanX}/44288-44543.pbf +0 -0
  176. /package/fonts/{IRANYekanX Regular → IRANYekanX}/44544-44799.pbf +0 -0
  177. /package/fonts/{IRANYekanX Regular → IRANYekanX}/44800-45055.pbf +0 -0
  178. /package/fonts/{IRANYekanX Regular → IRANYekanX}/45056-45311.pbf +0 -0
  179. /package/fonts/{IRANYekanX Regular → IRANYekanX}/45312-45567.pbf +0 -0
  180. /package/fonts/{IRANYekanX Regular → IRANYekanX}/45568-45823.pbf +0 -0
  181. /package/fonts/{IRANYekanX Regular → IRANYekanX}/45824-46079.pbf +0 -0
  182. /package/fonts/{IRANYekanX Regular → IRANYekanX}/4608-4863.pbf +0 -0
  183. /package/fonts/{IRANYekanX Regular → IRANYekanX}/46080-46335.pbf +0 -0
  184. /package/fonts/{IRANYekanX Regular → IRANYekanX}/46336-46591.pbf +0 -0
  185. /package/fonts/{IRANYekanX Regular → IRANYekanX}/46592-46847.pbf +0 -0
  186. /package/fonts/{IRANYekanX Regular → IRANYekanX}/46848-47103.pbf +0 -0
  187. /package/fonts/{IRANYekanX Regular → IRANYekanX}/47104-47359.pbf +0 -0
  188. /package/fonts/{IRANYekanX Regular → IRANYekanX}/47360-47615.pbf +0 -0
  189. /package/fonts/{IRANYekanX Regular → IRANYekanX}/47616-47871.pbf +0 -0
  190. /package/fonts/{IRANYekanX Regular → IRANYekanX}/47872-48127.pbf +0 -0
  191. /package/fonts/{IRANYekanX Regular → IRANYekanX}/48128-48383.pbf +0 -0
  192. /package/fonts/{IRANYekanX Regular → IRANYekanX}/48384-48639.pbf +0 -0
  193. /package/fonts/{IRANYekanX Regular → IRANYekanX}/4864-5119.pbf +0 -0
  194. /package/fonts/{IRANYekanX Regular → IRANYekanX}/48640-48895.pbf +0 -0
  195. /package/fonts/{IRANYekanX Regular → IRANYekanX}/48896-49151.pbf +0 -0
  196. /package/fonts/{IRANYekanX Regular → IRANYekanX}/49152-49407.pbf +0 -0
  197. /package/fonts/{IRANYekanX Regular → IRANYekanX}/49408-49663.pbf +0 -0
  198. /package/fonts/{IRANYekanX Regular → IRANYekanX}/49664-49919.pbf +0 -0
  199. /package/fonts/{IRANYekanX Regular → IRANYekanX}/49920-50175.pbf +0 -0
  200. /package/fonts/{IRANYekanX Regular → IRANYekanX}/50176-50431.pbf +0 -0
  201. /package/fonts/{IRANYekanX Regular → IRANYekanX}/50432-50687.pbf +0 -0
  202. /package/fonts/{IRANYekanX Regular → IRANYekanX}/50688-50943.pbf +0 -0
  203. /package/fonts/{IRANYekanX Regular → IRANYekanX}/50944-51199.pbf +0 -0
  204. /package/fonts/{IRANYekanX Regular → IRANYekanX}/512-767.pbf +0 -0
  205. /package/fonts/{IRANYekanX Regular → IRANYekanX}/5120-5375.pbf +0 -0
  206. /package/fonts/{IRANYekanX Regular → IRANYekanX}/51200-51455.pbf +0 -0
  207. /package/fonts/{IRANYekanX Regular → IRANYekanX}/51456-51711.pbf +0 -0
  208. /package/fonts/{IRANYekanX Regular → IRANYekanX}/51712-51967.pbf +0 -0
  209. /package/fonts/{IRANYekanX Regular → IRANYekanX}/51968-52223.pbf +0 -0
  210. /package/fonts/{IRANYekanX Regular → IRANYekanX}/52224-52479.pbf +0 -0
  211. /package/fonts/{IRANYekanX Regular → IRANYekanX}/52480-52735.pbf +0 -0
  212. /package/fonts/{IRANYekanX Regular → IRANYekanX}/52736-52991.pbf +0 -0
  213. /package/fonts/{IRANYekanX Regular → IRANYekanX}/52992-53247.pbf +0 -0
  214. /package/fonts/{IRANYekanX Regular → IRANYekanX}/53248-53503.pbf +0 -0
  215. /package/fonts/{IRANYekanX Regular → IRANYekanX}/53504-53759.pbf +0 -0
  216. /package/fonts/{IRANYekanX Regular → IRANYekanX}/5376-5631.pbf +0 -0
  217. /package/fonts/{IRANYekanX Regular → IRANYekanX}/53760-54015.pbf +0 -0
  218. /package/fonts/{IRANYekanX Regular → IRANYekanX}/54016-54271.pbf +0 -0
  219. /package/fonts/{IRANYekanX Regular → IRANYekanX}/54272-54527.pbf +0 -0
  220. /package/fonts/{IRANYekanX Regular → IRANYekanX}/54528-54783.pbf +0 -0
  221. /package/fonts/{IRANYekanX Regular → IRANYekanX}/54784-55039.pbf +0 -0
  222. /package/fonts/{IRANYekanX Regular → IRANYekanX}/55040-55295.pbf +0 -0
  223. /package/fonts/{IRANYekanX Regular → IRANYekanX}/55296-55551.pbf +0 -0
  224. /package/fonts/{IRANYekanX Regular → IRANYekanX}/55552-55807.pbf +0 -0
  225. /package/fonts/{IRANYekanX Regular → IRANYekanX}/55808-56063.pbf +0 -0
  226. /package/fonts/{IRANYekanX Regular → IRANYekanX}/56064-56319.pbf +0 -0
  227. /package/fonts/{IRANYekanX Regular → IRANYekanX}/5632-5887.pbf +0 -0
  228. /package/fonts/{IRANYekanX Regular → IRANYekanX}/56320-56575.pbf +0 -0
  229. /package/fonts/{IRANYekanX Regular → IRANYekanX}/56576-56831.pbf +0 -0
  230. /package/fonts/{IRANYekanX Regular → IRANYekanX}/56832-57087.pbf +0 -0
  231. /package/fonts/{IRANYekanX Regular → IRANYekanX}/57088-57343.pbf +0 -0
  232. /package/fonts/{IRANYekanX Regular → IRANYekanX}/57344-57599.pbf +0 -0
  233. /package/fonts/{IRANYekanX Regular → IRANYekanX}/57600-57855.pbf +0 -0
  234. /package/fonts/{IRANYekanX Regular → IRANYekanX}/57856-58111.pbf +0 -0
  235. /package/fonts/{IRANYekanX Regular → IRANYekanX}/58112-58367.pbf +0 -0
  236. /package/fonts/{IRANYekanX Regular → IRANYekanX}/58368-58623.pbf +0 -0
  237. /package/fonts/{IRANYekanX Regular → IRANYekanX}/58624-58879.pbf +0 -0
  238. /package/fonts/{IRANYekanX Regular → IRANYekanX}/5888-6143.pbf +0 -0
  239. /package/fonts/{IRANYekanX Regular → IRANYekanX}/58880-59135.pbf +0 -0
  240. /package/fonts/{IRANYekanX Regular → IRANYekanX}/59136-59391.pbf +0 -0
  241. /package/fonts/{IRANYekanX Regular → IRANYekanX}/59392-59647.pbf +0 -0
  242. /package/fonts/{IRANYekanX Regular → IRANYekanX}/59648-59903.pbf +0 -0
  243. /package/fonts/{IRANYekanX Regular → IRANYekanX}/59904-60159.pbf +0 -0
  244. /package/fonts/{IRANYekanX Regular → IRANYekanX}/60160-60415.pbf +0 -0
  245. /package/fonts/{IRANYekanX Regular → IRANYekanX}/60416-60671.pbf +0 -0
  246. /package/fonts/{IRANYekanX Regular → IRANYekanX}/60672-60927.pbf +0 -0
  247. /package/fonts/{IRANYekanX Regular → IRANYekanX}/60928-61183.pbf +0 -0
  248. /package/fonts/{IRANYekanX Regular → IRANYekanX}/61184-61439.pbf +0 -0
  249. /package/fonts/{IRANYekanX Regular → IRANYekanX}/6144-6399.pbf +0 -0
  250. /package/fonts/{IRANYekanX Regular → IRANYekanX}/61440-61695.pbf +0 -0
  251. /package/fonts/{IRANYekanX Regular → IRANYekanX}/61696-61951.pbf +0 -0
  252. /package/fonts/{IRANYekanX Regular → IRANYekanX}/61952-62207.pbf +0 -0
  253. /package/fonts/{IRANYekanX Regular → IRANYekanX}/62208-62463.pbf +0 -0
  254. /package/fonts/{IRANYekanX Regular → IRANYekanX}/62464-62719.pbf +0 -0
  255. /package/fonts/{IRANYekanX Regular → IRANYekanX}/62720-62975.pbf +0 -0
  256. /package/fonts/{IRANYekanX Regular → IRANYekanX}/62976-63231.pbf +0 -0
  257. /package/fonts/{IRANYekanX Regular → IRANYekanX}/63232-63487.pbf +0 -0
  258. /package/fonts/{IRANYekanX Regular → IRANYekanX}/63488-63743.pbf +0 -0
  259. /package/fonts/{IRANYekanX Regular → IRANYekanX}/63744-63999.pbf +0 -0
  260. /package/fonts/{IRANYekanX Regular → IRANYekanX}/6400-6655.pbf +0 -0
  261. /package/fonts/{IRANYekanX Regular → IRANYekanX}/64000-64255.pbf +0 -0
  262. /package/fonts/{IRANYekanX Regular → IRANYekanX}/64256-64511.pbf +0 -0
  263. /package/fonts/{IRANYekanX Regular → IRANYekanX}/64512-64767.pbf +0 -0
  264. /package/fonts/{IRANYekanX Regular → IRANYekanX}/64768-65023.pbf +0 -0
  265. /package/fonts/{IRANYekanX Regular → IRANYekanX}/65024-65279.pbf +0 -0
  266. /package/fonts/{IRANYekanX Regular → IRANYekanX}/65280-65535.pbf +0 -0
  267. /package/fonts/{IRANYekanX Regular → IRANYekanX}/6656-6911.pbf +0 -0
  268. /package/fonts/{IRANYekanX Regular → IRANYekanX}/6912-7167.pbf +0 -0
  269. /package/fonts/{IRANYekanX Regular → IRANYekanX}/7168-7423.pbf +0 -0
  270. /package/fonts/{IRANYekanX Regular → IRANYekanX}/7424-7679.pbf +0 -0
  271. /package/fonts/{IRANYekanX Regular → IRANYekanX}/768-1023.pbf +0 -0
  272. /package/fonts/{IRANYekanX Regular → IRANYekanX}/7680-7935.pbf +0 -0
  273. /package/fonts/{IRANYekanX Regular → IRANYekanX}/7936-8191.pbf +0 -0
  274. /package/fonts/{IRANYekanX Regular → IRANYekanX}/8192-8447.pbf +0 -0
  275. /package/fonts/{IRANYekanX Regular → IRANYekanX}/8448-8703.pbf +0 -0
  276. /package/fonts/{IRANYekanX Regular → IRANYekanX}/8704-8959.pbf +0 -0
  277. /package/fonts/{IRANYekanX Regular → IRANYekanX}/8960-9215.pbf +0 -0
  278. /package/fonts/{IRANYekanX Regular → IRANYekanX}/9216-9471.pbf +0 -0
  279. /package/fonts/{IRANYekanX Regular → IRANYekanX}/9472-9727.pbf +0 -0
  280. /package/fonts/{IRANYekanX Regular → IRANYekanX}/9728-9983.pbf +0 -0
  281. /package/fonts/{IRANYekanX Regular → IRANYekanX}/9984-10239.pbf +0 -0
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  MapLibre location picker as a publish-ready npm library. React-only (`@amir83nasr/map`) + Vite demo. Persian RTL, mobile-first, vector tiles.
4
4
 
5
- > Agent handbook: [`docs/USAGE.md`](../docs/USAGE.md) — copy-paste install, worker setup, recipes, callbacks, troubleshooting.
5
+ > Agent handbook: [`docs/USAGE.md`](./docs/USAGE.md) — copy-paste install, worker setup, recipes, callbacks, troubleshooting.
6
6
 
7
7
  ## Install
8
8
 
@@ -31,7 +31,7 @@ import { LocationPickerView } from '@amir83nasr/map';
31
31
  />;
32
32
  ```
33
33
 
34
- 41 Qom neighborhood suggestions ship as the package default — no `search.suggestions` needed. Pass your own array to replace them, or `suggestions: []` to disable.
34
+ 52 Qom neighborhood suggestions ship as the package default — no `search.suggestions` needed. Pass your own array to replace them, or `suggestions: []` to disable.
35
35
 
36
36
  The component calls `destroy()` in its own `useEffect` cleanup — no manual init/destroy. Give it a height (default `480px` via `style`); without one the map renders empty.
37
37
 
@@ -52,19 +52,19 @@ Public surface: one component (`LocationPickerView`), its props type (`QomPickPr
52
52
 
53
53
  Props of `LocationPickerView` (`QomPickProps` = engine options minus `container`, plus `className`/`style`; callbacks are props):
54
54
 
55
- | Key | Type | Default | Notes |
56
- | ---------------------------------------- | ----------------------------------------------------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------- |
57
- | `map.center/zoom/minZoom/maxZoom/bounds` | — | Qom `34.6416,50.8764`, z14 | — |
58
- | `map.style` | URL \| StyleSpecification | Snapp-like OpenFreeMap | vector style only (never raster) |
59
- | `map.glyphs` | string | jsDelivr CDN (bundled IRANYekanX PBFs) | relative paths resolve against page base; self-host by copying `fonts/` |
60
- | `controls` | `{gps, confirmButton, searchTrigger, developers}` | all true except developers | `developers` opens the in-map developer docs |
61
- | `search` | `{enabled, placeholder, suggestions, minLength, debounceMs, limit}` | 41 Qom neighborhoods; `3 / 350ms / 5` | Nominatim, Qom viewbox; custom array replaces, `[]` disables; `limit` also caps local suggestions |
62
- | `sheet` | `{enabled}` | true | — |
63
- | `behavior` | `{snapToRoad, resolveOnMove, resolveDelayMs, settleDelayMs, snapDelayMs, pickZoom, locateZoom}` | `400/250/900/15/18` | snap waits longer than settle; pinch-zoom never snaps |
64
- | `markers` | `Venue[]` | `[]` (off) | generic pins, demo enables Qom data |
65
- | `i18n` | `{labels}` | Persian (`fa`), always RTL | full label override |
66
- | callbacks | `onLocationChange/onAddressResolved/onSearchResults/onPick/onConfirm/onLocate/onError` | — | props |
67
- | `className/style` | — | height `480` | pass a height, otherwise the map is empty |
55
+ | Key | Type | Default | Notes |
56
+ | ---------------------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------- |
57
+ | `map.center/zoom/minZoom/maxZoom/bounds` | — | Qom`34.6416,50.8764`, z14 | — |
58
+ | `map.style` | URL\| StyleSpecification | Snapp-like OpenFreeMap | vector style only (never raster) |
59
+ | `map.glyphs` | string | jsDelivr CDN (bundled IRANYekanX PBFs) | relative paths resolve against page base; self-host by copying`fonts/` |
60
+ | `controls` | `{gps, confirmButton, searchTrigger, developers}` | all true except developers | `developers` opens the in-map developer docs |
61
+ | `search` | `{enabled, placeholder, suggestions, minLength, debounceMs, limit}` | 52 Qom neighborhoods (all shown);`3 / 350ms / 5` | Nominatim, Qom viewbox; custom array replaces,`[]` disables; `limit` caps remote results only |
62
+ | `sheet` | `{enabled}` | true | — |
63
+ | `behavior` | `{snapToRoad, resolveOnMove, resolveDelayMs, settleDelayMs, snapDelayMs, pickZoom, locateZoom}` | `400/250/900/15/18` | snap waits longer than settle; pinch-zoom never snaps |
64
+ | `markers` | `Venue[]` | `[]` (off) | generic pins, demo enables Qom data |
65
+ | `i18n` | `{labels}` | Persian (`fa`), always RTL | full label override |
66
+ | callbacks | `onLocationChange/onAddressResolved/onSearchResults/onPick/onConfirm/onLocate/onError` | — | props |
67
+ | `className/style` | — | height`480` | pass a height, otherwise the map is empty |
68
68
 
69
69
  Types (`PickerLocation`, `Venue`, `SearchSuggestion`, `QomPickProps`, …) are re-exported from `@amir83nasr/map`.
70
70
 
@@ -99,20 +99,21 @@ Default basemap is vector (OpenFreeMap + OpenMapTiles); raster styles are not su
99
99
 
100
100
  ## In-map developer docs
101
101
 
102
- Pass `controls={{ developers: true }}` to show a «توسعه‌دهندگان» button on the map. It opens Persian docs inside the map (`.qp-docs`): intro, install, React quick start including worker setup, key settings, appearance, project structure, two copyable prompts (new project / existing project), and FAQ (empty map, missing Persian map labels / glyphs, explicit MapLibre worker failure, maplibre v6 peer, Next.js).
102
+ Pass `controls={{ developers: true }}` to show a «توسعه‌دهندگان» button on the map. It opens numbered Persian docs inside the map (`.qp-docs`) with a section nav: 2-line quick start, mandatory worker setup (Vite / Next.js), props with defaults, callbacks table, theming vars, mount-only `key` rule, FAQ, and two copyable LLM prompts. Every code block has its own copy button (`.qp-code` + `.qp-code-copy`).
103
103
 
104
104
  ## Project structure
105
105
 
106
106
  ```text
107
107
  package/ # npm package `@amir83nasr/map`
108
- src/index.tsx # public: LocationPickerView + types
109
- src/picker.ts # internal engine (not exported)
110
- src/*.ts # helpers (geocode, snap, format, i18n, …)
111
- src/styles.css # ships as dist/qompick-react.css (import as `@amir83nasr/map/styles.css`)
112
- fonts/ # IRANYekanX woff2 + map glyph PBFs (published in the tarball)
113
- test/helpers.test.ts # vitest
114
- demo/ # Vite demo (vector map, port 5500); ships MapLibre worker files into dist
115
- docs/ # ARCHITECTURE.md + CHANGELOG.md + USAGE.md (agent handbook)
108
+ src/index.tsx # public re-export only
109
+ src/react/ # LocationPickerView + setupQomPickWorker
110
+ src/engine/ # internal picker/emitter/snap (not exported)
111
+ src/core/ # types, defaults, i18n, format, geocode, icons
112
+ src/style/ # map-style, colors, styles.css → dist/styles.css
113
+ src/*/*.test.ts # colocated vitest per folder
114
+ fonts/ # IRANYekanX woff2 + IRANYekanX/*.pbf glyphs (published)
115
+ demo/ # Vite demo (vector map, port 5500); USE_DIST=1 builds vs dist
116
+ CONTRIBUTING.md SECURITY.md LICENSE.md
116
117
  ```
117
118
 
118
119
  ## Scripts
@@ -132,7 +133,7 @@ cd package && pnpm build && pnpm pack --dry-run # inspect tarball
132
133
  pnpm publish --filter @amir83nasr/map --access public
133
134
  ```
134
135
 
135
- Versioning: semver, currently `1.0.4`.
136
+ Versioning: semver, currently `1.1.1`.
136
137
 
137
138
  ## Limitations
138
139
 
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { EventHandler, PickerEvent } from './types.js';
1
+ import { EventHandler, PickerEvent } from '../core/types.js';
2
2
  export declare class Emitter {
3
3
  private map;
4
4
  on(ev: PickerEvent, fn: EventHandler): () => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { EventHandler, LocationPickerOptions, PickerEvent, PickerLocation } from './types.js';
1
+ import { EventHandler, LocationPickerOptions, PickerEvent, PickerLocation } from '../core/types.js';
2
2
  export declare function isMapLibreWorkerError(value: unknown): boolean;
3
3
  export declare class LocationPicker {
4
4
  private opts;
@@ -54,7 +54,10 @@ export declare class LocationPicker {
54
54
  private devDocsHtml;
55
55
  private openDocs;
56
56
  private closeDocs;
57
+ private copyDone;
58
+ private copyText;
57
59
  private copyPrompt;
60
+ private copyCode;
58
61
  private fallbackCopy;
59
62
  private openSearch;
60
63
  private closeSearch;
package/dist/index.cjs ADDED
@@ -0,0 +1,88 @@
1
+ "use strict";var ne=Object.defineProperty;var le=(a,e,t)=>e in a?ne(a,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):a[e]=t;var d=(a,e,t)=>le(a,typeof e!="symbol"?e+"":e,t);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ce=require("react/jsx-runtime"),P=require("react"),z=require("maplibre-gl"),de={searchPlaceholder:"جست‌وجوی موقعیت...",searchTitle:"جستجوی موقعیت",suggestedPlaces:"مکان‌های پیشنهادی",searching:"در حال جستجو...",noResults:"نتیجه‌ای پیدا نشد؛ عبارت دیگری امتحان کنید",searchError:"خطا در جستجو؛ اتصال را بررسی کنید",confirmLocation:"تایید موقعیت",confirm:"تایید",editOnMap:"ویرایش روی نقشه",chosenAddress:"آدرس انتخابی",coordsToServer:"مختصات ارسالی به سرور",close:"بستن",clearSearch:"پاک کردن جستجو",currentLocation:"موقعیت فعلی",locating:"در حال پیدا کردن آدرس...",resolving:"در حال پیدا کردن آدرس...",registered:"موقعیت ثبت شد",gpsUnsupported:"GPS در این مرورگر پشتیبانی نمی‌شود",locateTimeout:"دریافت موقعیت طول کشید؛ دستی انتخاب کنید",locateUnavailable:"موقعیت در دسترس نیست؛ دستی انتخاب کنید",geoTitle:"دسترسی به موقعیت مکانی",geoText:"برای انتخاب موقعیت فعلی شما، لازم است دسترسی موقعیت مکانی را فعال کنید.",geoBlocked:"مرورگر قبلاً دسترسی را بسته است. از تنظیمات سایت مرورگر، دسترسی Location را مجاز کنید.",enableAccess:"فعال کردن دسترسی",developers:"توسعه‌دهندگان",backToMap:"بازگشت به نقشه",copy:"کپی",copied:"کپی شد",submitting:"در حال ثبت..."},re=[{name:"۱۹ دی",addr:"شهر قم، خیابان ۱۹ دی",lat:34.6457,lng:50.8851},{name:"۷۲ تن",addr:"شهر قم، میدان ۷۲ تن",lat:34.6753,lng:50.8922},{name:"آبشار",addr:"شهر قم، بوستان آبشار",lat:34.6869,lng:50.8899},{name:"آذر",addr:"شهر قم، بوستان شهدای آذر",lat:34.6341,lng:50.906},{name:"ارم",addr:"شهر قم، محله ارم",lat:34.6424,lng:50.8804},{name:"امام حسین",addr:"شهر قم، میدان امام حسین",lat:34.6426,lng:50.8491},{name:"امام خمینی",addr:"شهر قم، خیابان امام خمینی",lat:34.6633,lng:50.8759},{name:"انسجام",addr:"شهر قم، محله انسجام",lat:34.6081,lng:50.8783},{name:"انقلاب",addr:"شهر قم، خیابان انقلاب",lat:34.6354,lng:50.8906},{name:"باجک",addr:"شهر قم، محله باجک",lat:34.6496,lng:50.8906},{name:"بلوار امین",addr:"شهر قم، بلوار امین",lat:34.6335,lng:50.8676},{name:"بلوار الغدیر",addr:"شهر قم، بلوار الغدیر",lat:34.5956,lng:50.8209},{name:"بلوار جمهوری اسلامی",addr:"شهر قم، بلوار جمهوری اسلامی",lat:34.6056,lng:50.8866},{name:"بلوار پیامبر اعظم",addr:"شهر قم، بلوار پیامبر اعظم",lat:34.6113,lng:50.8973},{name:"بنیاد",addr:"شهر قم، محله بنیاد",lat:34.5944,lng:50.8768},{name:"پردیسان",addr:"شهر قم، شهرک پردیسان",lat:34.5588,lng:50.8331},{name:"توحید",addr:"شهر قم، میدان توحید",lat:34.6436,lng:50.8628},{name:"جمکران",addr:"شهر قم، مسجد مقدس جمکران",lat:34.5841,lng:50.9146},{name:"چهارمردان",addr:"شهر قم، محله چهارمردان",lat:34.6335,lng:50.889},{name:"حافظ",addr:"شهر قم، خیابان حافظ",lat:34.6494,lng:50.8611},{name:"حرم",addr:"شهر قم، حرم حضرت معصومه",lat:34.6419,lng:50.8787},{name:"خاکفرج",addr:"شهر قم، محله خاکفرج",lat:34.6517,lng:50.8853},{name:"دروازه ری",addr:"شهر قم، محله دروازه ری",lat:34.6446,lng:50.9023},{name:"دورشهر",addr:"شهر قم، محله دورشهر",lat:34.6296,lng:50.8705},{name:"زاویه",addr:"شهر قم، محله زاویه",lat:34.6214,lng:50.9078},{name:"زنبیل‌آباد",addr:"شهر قم، محله زنبیل‌آباد",lat:34.6075,lng:50.862},{name:"سالاریه",addr:"شهر قم، محله سالاریه",lat:34.6116,lng:50.8471},{name:"سعیدی",addr:"شهر قم، میدان سعیدی",lat:34.65,lng:50.878},{name:"سمیه",addr:"شهر قم، خیابان سمیه",lat:34.632,lng:50.8826},{name:"شهدا",addr:"شهر قم، خیابان شهدا",lat:34.6362,lng:50.872},{name:"شهرک امام حسن",addr:"شهر قم، شهرک امام حسن",lat:34.6782,lng:50.88},{name:"شهرک صنعتی شکوهیه",addr:"شهر قم، شهرک صنعتی شکوهیه",lat:34.7956,lng:50.8177},{name:"شهرک فاطمیه",addr:"شهر قم، شهرک فاطمیه",lat:34.6746,lng:50.8521},{name:"شهرک قدس",addr:"شهر قم، شهرک قدس",lat:34.5969,lng:50.8426},{name:"شهرک مهدیه",addr:"شهر قم، شهرک مهدیه",lat:34.5823,lng:50.8238},{name:"شیخ‌آباد",addr:"شهر قم، محله شیخ‌آباد",lat:34.6474,lng:50.8344},{name:"صدوق",addr:"شهر قم، محله صدوق",lat:34.6313,lng:50.8743},{name:"صفائیه",addr:"شهر قم، محله صفائیه",lat:34.6362,lng:50.8721},{name:"طالقانی",addr:"شهر قم، خیابان طالقانی",lat:34.6734,lng:50.8704},{name:"عطاران",addr:"شهر قم، محله عطاران",lat:34.624,lng:50.8714},{name:"علی‌بن‌جعفر",addr:"شهر قم، آستان علی‌بن‌جعفر",lat:34.6313,lng:50.8973},{name:"فرهنگیان",addr:"شهر قم، محله فرهنگیان",lat:34.6682,lng:50.8984},{name:"کشاورز",addr:"شهر قم، خیابان کشاورز",lat:34.656,lng:50.8446},{name:"کلهری",addr:"شهر قم، منطقه کلهری",lat:34.6257,lng:50.9034},{name:"کیوانفر",addr:"شهر قم، بلوار شهید کیوانفر",lat:34.6582,lng:50.8821},{name:"مطهری",addr:"شهر قم، خیابان مطهری",lat:34.646,lng:50.8486},{name:"معلم",addr:"شهر قم، میدان معلم",lat:34.6328,lng:50.8848},{name:"نوبهار",addr:"شهر قم، محله نوبهار",lat:34.6409,lng:50.9053},{name:"نیروگاه",addr:"شهر قم، محله نیروگاه",lat:34.6487,lng:50.8587},{name:"هفت‌تیر",addr:"شهر قم، خیابان هفت‌تیر",lat:34.6571,lng:50.8848},{name:"هنرستان",addr:"شهر قم، محله هنرستان",lat:34.628,lng:50.8878},{name:"یزدانشهر",addr:"شهر قم، محله یزدانشهر",lat:34.6154,lng:50.8824}],$={lat:34.6416,lng:50.8764},pe=14;function he(a){return{...de,...(a==null?void 0:a.labels)??{}}}function ue(){return"rtl"}function me(a){const e=a??{};return{container:e.container,map:{center:{...$},zoom:pe,minZoom:11,maxZoom:19,bounds:[[34.15,50.35],[35.05,51.45]],...e.map??{}},controls:{gps:!0,confirmButton:!0,searchTrigger:!0,developers:!1,...e.controls??{}},search:{enabled:!0,suggestions:re,minLength:3,debounceMs:350,limit:5,...e.search??{}},sheet:{enabled:!0,...e.sheet??{}},behavior:{snapToRoad:!0,resolveOnMove:!0,resolveDelayMs:400,settleDelayMs:250,snapDelayMs:900,pickZoom:15,locateZoom:18,...e.behavior??{}},i18n:{labels:he(e.i18n)},markers:e.markers??[]}}const ge="#e9ebee",ye="#e9ebee",G="#a9e29b",fe="#9ed894",be="#b5e8a6",ve="#d3ddd0",we="#e9dfc0",qe="#b9d9f2",ke="#cfe4f7",j="#a9cdf0",U="#4e6e94",V="#dfe3e9",xe="#e9ebee",O="#ffffff",Se="#d9dde2",k="#ffffff",A="#d5dae0",Le="#cdbfa8",Ee="#e9ebee",H="#c6ccd4",N="#b9bdc4",Q="#a7aab3",Y="#5b6067",_="#2f3338",f="#f7f8f9",D="#565b62",Te=["coalesce",["get","name:fa"],["get","name:nonlatin"],["get","name"],["get","name:latin"]],Me=["0","۰","1","۱","2","۲","3","۳","4","۴","5","۵","6","۶","7","۷","8","۸","9","۹","٠","۰","١","۱","٢","۲","٣","۳","٤","۴","٥","۵","٦","۶","٧","۷","٨","۸","٩","۹"];function Re(a,e=40){const t=["coalesce",a,""],o=["split",["to-string",t],""],r=["length",o],i=[];for(let s=0;s<e;s++){const n=["at",s,o];i.push(["case",[">",r,s],["match",n,...Me,n],""])}return i.push(["slice",["to-string",t],e]),["format",["concat",...i],{}]}const b=Re(Te),x=["IRANYekanX"],I=["IRANYekanX"],q=["LineString","MultiLineString"],Ae=["MultiPoint","Point"];function y(a){return["interpolate",["exponential",1.2],["zoom"],...a]}const X=["interpolate",["exponential",1.2],["zoom"],12.5,0,13,1.5,14,2.5,20,11.5],_e=["interpolate",["exponential",1.2],["zoom"],12,.5,13,1,14,4,20,15],Ce=[{id:"background",type:"background",paint:{"background-color":ge}},{id:"landuse-residential",type:"fill",source:"openmaptiles","source-layer":"landuse",filter:["match",["get","class"],["neighbourhood","residential"],!0,!1],paint:{"fill-color":ye}},{id:"landuse-cemetery",type:"fill",source:"openmaptiles","source-layer":"landuse",filter:["==",["get","class"],"cemetery"],paint:{"fill-color":ve}},{id:"landcover-wood",type:"fill",source:"openmaptiles","source-layer":"landcover",filter:["==",["get","class"],"wood"],paint:{"fill-color":fe}},{id:"landcover-grass",type:"fill",source:"openmaptiles","source-layer":"landcover",filter:["==",["get","class"],"grass"],paint:{"fill-color":be}},{id:"landcover-grass-park",type:"fill",source:"openmaptiles","source-layer":"park",paint:{"fill-color":G}},{id:"park",type:"fill",source:"openmaptiles","source-layer":"park",filter:["match",["geometry-type"],["MultiPolygon","Polygon"],!0,!1],paint:{"fill-color":G}},{id:"landcover-sand",type:"fill",source:"openmaptiles","source-layer":"landcover",filter:["==",["get","class"],"sand"],paint:{"fill-color":we}},{id:"water",type:"fill",source:"openmaptiles","source-layer":"water",filter:["all",["!=",["get","intermittent"],1],["!=",["get","brunnel"],"tunnel"]],paint:{"fill-color":qe}},{id:"water-intermittent",type:"fill",source:"openmaptiles","source-layer":"water",filter:["all",["==",["get","intermittent"],1],["!=",["get","brunnel"],"tunnel"]],paint:{"fill-color":ke,"fill-opacity":.8}},{id:"waterway-other",type:"line",source:"openmaptiles","source-layer":"waterway",filter:["all",["match",["get","class"],["canal","river","stream"],!1,!0],["==",["get","intermittent"],0]],paint:{"line-color":j,"line-width":["interpolate",["exponential",1.3],["zoom"],13,.5,20,2]}},{id:"waterway-stream-canal",type:"line",source:"openmaptiles","source-layer":"waterway",filter:["all",["match",["get","class"],["canal","stream"],!0,!1],["!=",["get","brunnel"],"tunnel"],["==",["get","intermittent"],0]],paint:{"line-color":j,"line-width":["interpolate",["exponential",1.3],["zoom"],13,.5,20,6]}},{id:"waterway-river",type:"line",source:"openmaptiles","source-layer":"waterway",filter:["all",["==",["get","class"],"river"],["!=",["get","brunnel"],"tunnel"],["!=",["get","intermittent"],1]],paint:{"line-color":j,"line-width":["interpolate",["exponential",1.2],["zoom"],10,.8,20,6]}},{id:"building",type:"fill",source:"openmaptiles","source-layer":"building",paint:{"fill-antialias":!0,"fill-color":V}},{id:"building-top",type:"fill",source:"openmaptiles","source-layer":"building",paint:{"fill-color":xe,"fill-opacity":["interpolate",["linear"],["zoom"],13,0,16,1],"fill-outline-color":V,"fill-translate":["interpolate",["linear"],["zoom"],14,["literal",[0,0]],16,["literal",[-2,-2]]]}},{id:"aeroway-area",type:"fill",source:"openmaptiles","source-layer":"aeroway",paint:{"fill-color":Ee,"fill-opacity":["interpolate",["linear"],["zoom"],13,0,14,1]}},{id:"aeroway-taxiway-casing",type:"line",source:"openmaptiles","source-layer":"aeroway",filter:["==",["get","class"],"taxiway"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":H,"line-width":["interpolate",["exponential",1.5],["zoom"],11,2,17,12]}},{id:"aeroway-taxiway",type:"line",source:"openmaptiles","source-layer":"aeroway",filter:["==",["get","class"],"taxiway"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":O,"line-width":["interpolate",["exponential",1.5],["zoom"],11,1,17,10]}},{id:"aeroway-runway-casing",type:"line",source:"openmaptiles","source-layer":"aeroway",filter:["==",["get","class"],"runway"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":H,"line-width":["interpolate",["exponential",1.5],["zoom"],11,5,17,55]}},{id:"aeroway-runway",type:"line",source:"openmaptiles","source-layer":"aeroway",filter:["==",["get","class"],"runway"],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":O,"line-width":["interpolate",["exponential",1.5],["zoom"],11,4,17,50]}},{id:"highway-minor-casing",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["!=",["get","brunnel"],"tunnel"],["match",["get","class"],["minor","service","track"],!0,!1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":Se,"line-opacity":["interpolate",["linear"],["zoom"],12,0,12.5,1],"line-width":_e}},{id:"highway-link-casing",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:13,filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["primary","secondary","tertiary","trunk"],!0,!1],["==",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":A,"line-width":y([12,1,13,3,14,4,20,15])}},{id:"highway-secondary-tertiary-casing",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["secondary","tertiary"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":A,"line-width":y([8,1.5,20,17])}},{id:"highway-primary-casing",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:5,filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["primary"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":A,"line-opacity":["interpolate",["linear"],["zoom"],7,0,8,1],"line-width":y([7,0,8,.6,9,1.5,20,22])}},{id:"highway-trunk-casing",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:5,filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["trunk"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":A,"line-opacity":["interpolate",["linear"],["zoom"],5,0,6,1],"line-width":y([5,0,6,.6,7,1.5,20,22])}},{id:"highway-motorway-casing",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:4,filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["==",["get","class"],"motorway"],["!=",["get","ramp"],1]],layout:{"line-cap":"butt","line-join":"round"},paint:{"line-color":A,"line-opacity":["interpolate",["linear"],["zoom"],4,0,5,1],"line-width":y([4,0,5,.4,6,.6,7,1.5,20,22])}},{id:"highway-path",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["==",["get","class"],"path"]],paint:{"line-color":Le,"line-dasharray":[1.5,.75],"line-width":y([15,1.2,20,4])}},{id:"highway-link",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:13,filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["primary","secondary","tertiary","trunk"],!0,!1],["==",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([12.5,0,13,1.5,14,2.5,20,11.5])}},{id:"highway-minor",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["!=",["get","brunnel"],"tunnel"],["match",["get","class"],["minor","service","track"],!0,!1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":O,"line-width":X}},{id:"highway-secondary-tertiary",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["secondary","tertiary"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,8,.5,20,13])}},{id:"highway-primary",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["primary"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([8.5,0,9,.5,20,18])}},{id:"highway-trunk",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["match",["get","class"],["trunk"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,7,.5,20,18])}},{id:"highway-motorway",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:5,filter:["all",["match",["geometry-type"],q,!0,!1],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["==",["get","class"],"motorway"],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,7,.5,20,18])}},{id:"bridge-link",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:13,filter:["all",["==",["get","brunnel"],"bridge"],["match",["get","class"],["primary","secondary","tertiary","trunk"],!0,!1],["==",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([12.5,0,13,1.5,14,2.5,20,11.5])}},{id:"bridge-minor",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["==",["get","brunnel"],"bridge"],["match",["get","class"],["minor","service","track"],!0,!1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":O,"line-width":X}},{id:"bridge-secondary-tertiary",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["==",["get","brunnel"],"bridge"],["match",["get","class"],["secondary","tertiary"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,8,.5,20,13])}},{id:"bridge-trunk-primary",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["==",["get","brunnel"],"bridge"],["match",["get","class"],["primary","trunk"],!0,!1],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,7,.5,20,18])}},{id:"bridge-motorway",type:"line",source:"openmaptiles","source-layer":"transportation",minzoom:5,filter:["all",["==",["get","brunnel"],"bridge"],["==",["get","class"],"motorway"],["!=",["get","ramp"],1]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":k,"line-width":y([6.5,0,7,.5,20,18])}},{id:"railway-transit",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["==",["get","class"],"transit"],["match",["get","brunnel"],["tunnel"],!1,!0]],paint:{"line-color":N,"line-width":["interpolate",["exponential",1.4],["zoom"],14,.4,20,1]}},{id:"railway-service",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["has","service"],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["==",["get","class"],"rail"]],paint:{"line-color":N,"line-width":["interpolate",["exponential",1.4],["zoom"],14,.4,20,1]}},{id:"railway",type:"line",source:"openmaptiles","source-layer":"transportation",filter:["all",["match",["geometry-type"],q,!0,!1],["!",["has","service"]],["match",["get","brunnel"],["bridge","tunnel"],!1,!0],["==",["get","class"],"rail"]],paint:{"line-color":N,"line-width":["interpolate",["exponential",1.4],["zoom"],14,.4,15,.75,20,2]}},{id:"boundary_3",type:"line",source:"openmaptiles","source-layer":"boundary",filter:["all",["==",["get","admin_level"],3],["!=",["get","maritime"],1]],paint:{"line-color":Q,"line-dasharray":[1,1],"line-width":["interpolate",["linear"],["zoom"],7,1,11,2]}},{id:"boundary_2",type:"line",source:"openmaptiles","source-layer":"boundary",filter:["all",["==",["get","admin_level"],2],["!=",["get","maritime"],1],["!=",["get","disputed"],1],["!",["has","claimed_by"]]],layout:{"line-cap":"round","line-join":"round"},paint:{"line-color":Q,"line-opacity":["interpolate",["linear"],["zoom"],0,.4,4,1],"line-width":["interpolate",["linear"],["zoom"],3,1,5,1.2,12,3]}},{id:"waterway_line_label",type:"symbol",source:"openmaptiles","source-layer":"waterway",layout:{"symbol-placement":"line","symbol-spacing":350,"text-field":b,"text-font":x,"text-size":13},paint:{"text-color":U,"text-halo-color":f,"text-halo-width":1.5}},{id:"water_name_label",type:"symbol",source:"openmaptiles","source-layer":"water_name",layout:{"text-field":b,"text-font":x,"text-max-width":8,"text-size":12},paint:{"text-color":U,"text-halo-color":f,"text-halo-width":1.5}},{id:"poi_worship_school",type:"symbol",source:"openmaptiles","source-layer":"poi",minzoom:14,filter:["match",["get","class"],["place_of_worship","school","college","library","hospital","park"],!0,!1],layout:{"icon-image":["match",["get","class"],["place_of_worship"],"place_of_worship",["school"],"school",["college"],"school",["library"],"school",["hospital"],"hospital",["park"],"park",""],"icon-size":1.1,"text-anchor":"top","text-field":b,"text-font":x,"text-max-width":8,"text-offset":[0,1],"text-size":12},paint:{"text-color":D,"text-halo-color":f,"text-halo-width":1.5}},{id:"poi_shops",type:"symbol",source:"openmaptiles","source-layer":"poi",minzoom:15.5,filter:["match",["get","class"],["shop","grocery","restaurant","cafe","fast_food","pharmacy","bank","fuel"],!0,!1],layout:{"icon-image":["match",["get","class"],["grocery"],"grocery",["restaurant"],"restaurant",["cafe"],"cafe",["fast_food"],"restaurant",["pharmacy"],"pharmacy",["bank"],"bank",["fuel"],"fuel","shop"],"icon-size":1,"text-anchor":"top","text-field":b,"text-font":x,"text-max-width":8,"text-offset":[0,1],"text-size":12},paint:{"text-color":D,"text-halo-color":f,"text-halo-width":1.5}},{id:"poi_r1",type:"symbol",source:"openmaptiles","source-layer":"poi",minzoom:16,filter:["all",["match",["geometry-type"],Ae,!0,!1],[">=",["get","rank"],1],["<",["get","rank"],7]],layout:{"icon-image":["match",["get","subclass"],["florist","furniture"],["get","subclass"],["get","class"]],"icon-size":.8,"text-anchor":"top","text-field":b,"text-font":x,"text-max-width":8,"text-offset":[0,.8],"text-size":12},paint:{"text-color":D,"text-halo-color":f,"text-halo-width":1.5}},{id:"airport",type:"symbol",source:"openmaptiles","source-layer":"aerodrome_label",minzoom:10,filter:["all",["has","iata"]],layout:{"icon-image":"airport_11","icon-size":1,"text-anchor":"top","text-field":b,"text-font":x,"text-max-width":8,"text-offset":[0,.8],"text-size":12},paint:{"text-color":D,"text-halo-color":f,"text-halo-width":1.5}},{id:"highway-name-minor",type:"symbol",source:"openmaptiles","source-layer":"transportation_name",minzoom:14,filter:["all",["match",["geometry-type"],q,!0,!1],["match",["get","class"],["minor","service","track"],!0,!1]],layout:{"symbol-placement":"line","text-field":b,"text-font":x,"text-rotation-alignment":"map","text-size":["interpolate",["linear"],["zoom"],14,11,17,12]},paint:{"text-color":Y,"text-halo-color":f,"text-halo-width":1.5}},{id:"highway-name-major",type:"symbol",source:"openmaptiles","source-layer":"transportation_name",minzoom:11,filter:["match",["get","class"],["primary","secondary","tertiary","trunk","motorway"],!0,!1],layout:{"symbol-placement":"line","text-field":b,"text-font":I,"text-rotation-alignment":"map","text-size":["interpolate",["linear"],["zoom"],11,11,15,13]},paint:{"text-color":Y,"text-halo-color":f,"text-halo-width":1.5}},{id:"label_village",type:"symbol",source:"openmaptiles","source-layer":"place",minzoom:9,filter:["==",["get","class"],"village"],layout:{"text-field":b,"text-font":x,"text-max-width":8,"text-size":["interpolate",["exponential",1.2],["zoom"],9,11,12,13]},paint:{"text-color":_,"text-halo-color":f,"text-halo-width":1.5}},{id:"label_town",type:"symbol",source:"openmaptiles","source-layer":"place",minzoom:6,filter:["==",["get","class"],"town"],layout:{"text-field":b,"text-font":I,"text-max-width":8,"text-size":["interpolate",["exponential",1.2],["zoom"],7,12,11,14]},paint:{"text-color":_,"text-halo-color":f,"text-halo-width":1.5}},{id:"label_other",type:"symbol",source:"openmaptiles","source-layer":"place",minzoom:8,filter:["match",["get","class"],["city","continent","country","state","town","village"],!1,!0],layout:{"text-field":b,"text-font":x,"text-max-width":8,"text-size":["interpolate",["linear"],["zoom"],8,10,12,12]},paint:{"text-color":_,"text-halo-color":f,"text-halo-width":1.5}},{id:"label_city",type:"symbol",source:"openmaptiles","source-layer":"place",minzoom:3,filter:["all",["==",["get","class"],"city"],["!=",["get","capital"],2]],layout:{"text-field":b,"text-font":I,"text-max-width":8,"text-size":["interpolate",["exponential",1.2],["zoom"],4,11,7,13,11,16]},paint:{"text-color":_,"text-halo-color":f,"text-halo-width":1.5}},{id:"label_city_capital",type:"symbol",source:"openmaptiles","source-layer":"place",minzoom:3,filter:["all",["==",["get","class"],"city"],["==",["get","capital"],2]],layout:{"text-field":b,"text-font":I,"text-max-width":8,"text-size":["interpolate",["exponential",1.2],["zoom"],4,12,7,14,11,18]},paint:{"text-color":_,"text-halo-color":f,"text-halo-width":1.5}}],ze="https://tiles.openfreemap.org/planet",$e={version:8,name:"snapp-like",glyphs:"https://cdn.jsdelivr.net/npm/@amir83nasr/map@1/fonts/{fontstack}/{range}.pbf",sprite:"https://tiles.openfreemap.org/sprites/ofm_f384/ofm",sources:{openmaptiles:{type:"vector",url:ze}},layers:Ce};class Pe{constructor(){d(this,"map",new Map)}on(e,t){let o=this.map.get(e);return o||this.map.set(e,o=new Set),o.add(t),()=>this.off(e,t)}off(e,t){var o;(o=this.map.get(e))==null||o.delete(t)}emit(e,t){for(const o of this.map.get(e)??[])try{o(t)}catch{}}}function C(a){return`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${a}</svg>`}const v={locate:C('<line x1="2" x2="5" y1="12" y2="12"/><line x1="19" x2="22" y1="12" y2="12"/><line x1="12" x2="12" y1="2" y2="5"/><line x1="12" x2="12" y1="19" y2="22"/><circle cx="12" cy="12" r="7"/><circle cx="12" cy="12" r="3"/>'),pin:C('<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/><circle cx="12" cy="10" r="3"/>'),search:C('<circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/>'),star:C('<polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" fill="currentColor" stroke="none"/>'),x:C('<path d="M18 6 6 18"/><path d="m6 6 12 12"/>')},K="۰۱۲۳۴۵۶۷۸۹";function S(a){return String(a).replace(/\d/g,e=>K[Number(e)]).replace(/[٠-٩]/g,e=>K["٠١٢٣٤٥٦٧٨٩".indexOf(e)])}function J(a,e=5){return S(Number(a).toFixed(e))}function M(a){return String(a).replace(/[۰-۹]/g,e=>String("۰۱۲۳۴۵۶۷۸۹".indexOf(e))).replace(/[٠-٩]/g,e=>String("٠١٢٣٤٥٦٧٨٩".indexOf(e)))}function ee(a){if(!a)return"";const e=String(a).split(",").map(o=>o.trim()).filter(Boolean),t=o=>!!(/^(ایران|Iran)$/i.test(o)||/^استان\b/.test(o)||/^شهرستان\b/.test(o)||/^بخش\b/.test(o)||/^[\d\s\-–—]+$/.test(M(o)));return e.filter(o=>!t(o)).slice(0,4).reverse().join(", ")}function Oe(a,e){return Number.isFinite(a)&&Number.isFinite(e)&&a>=-90&&a<=90&&e>=-180&&e<=180}const De="50.35,35.05,51.45,34.15",W=new Map,F=new Map;function ie(a,e){a.size>e&&a.delete(a.keys().next().value)}async function Ie(a,e,t){const o=`${a.toFixed(4)},${e.toFixed(4)}`,r=W.get(o);if(r)return r;const i=await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${a}&lon=${e}&accept-language=fa`,{headers:{Accept:"application/json"},signal:t==null?void 0:t.signal});if(!i.ok)throw new Error(`http ${i.status}`);const s=await i.json();if(!s.display_name)throw new Error("empty result");return W.set(o,s.display_name),ie(W,200),s.display_name}async function je(a,e=5,t){const o=`${M(a).trim().toLowerCase()}|${e}`,r=F.get(o);if(r)return r;const i=await fetch(`https://nominatim.openstreetmap.org/search?format=jsonv2&accept-language=fa&limit=${e}&viewbox=${De}&bounded=1&q=${encodeURIComponent(M(a))}`,{headers:{Accept:"application/json"},signal:t==null?void 0:t.signal});if(!i.ok)throw new Error(`http ${i.status}`);const s=await i.json();return F.set(o,s),ie(F,50),s}const Ne=["highway-minor","highway-link","highway-secondary-tertiary","highway-primary","highway-trunk","highway-motorway","bridge-minor","bridge-link","bridge-secondary-tertiary","bridge-trunk-primary","bridge-motorway"],T=64,We=15,te=2;function Fe(a,e,t,o,r,i){const s=r-t,n=i-o,l=s*s+n*n,g=l===0?0:((a-t)*s+(e-o)*n)/l,m=Math.max(0,Math.min(1,g)),p=t+m*s,h=o+m*n;return{x:p,y:h,d2:(a-p)*(a-p)+(e-h)*(e-h)}}function Ze(a,e,t){if(a.getZoom()<We)return null;const o=a.project([t,e]);let r;try{const l=[[o.x-T,o.y-T],[o.x+T,o.y+T]];r=a.queryRenderedFeatures(l,{layers:Ne})}catch{return null}let i=null,s=T*T;for(const l of r){const g=l.geometry,m=g.type==="LineString"?[g.coordinates]:g.type==="MultiLineString"?g.coordinates:[];for(const p of m){let h=null;for(const L of p){const c=a.project(L);if(h){const u=Fe(o.x,o.y,h.x,h.y,c.x,c.y);u.d2<s&&(s=u.d2,i={x:u.x,y:u.y})}h={x:c.x,y:c.y}}}}if(!i||s<te*te)return null;const n=a.unproject([i.x,i.y]);return{lat:n.lat,lng:n.lng}}const oe=3,Be="Vite: import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url'; سپس setupQomPickWorker(workerUrl) را قبل از mount صدا بزنید. Next.js/webpack: هر دو فایل worker و shared را کپی کنید.",Ge="qompick: MapLibre worker failed to load. Call setupQomPickWorker(workerUrl) from @amir83nasr/map before mounting LocationPickerView. Vite: use maplibre-gl-worker.mjs?worker&url. Next.js/webpack: copy maplibre-gl-worker.mjs and maplibre-gl-shared.mjs.";let Z=!1;function Ue(a){const e=globalThis.Worker;if(typeof e!="function")return()=>{};class t extends e{constructor(r,i){super(r,i),Z=!1,this.addEventListener("error",()=>{Z=!0,a()})}}return globalThis.Worker=t,()=>{globalThis.Worker=e}}function Ve(a){const e=a,t=[e==null?void 0:e.message,e==null?void 0:e.filename,e==null?void 0:e.url,a].filter(o=>typeof o=="string").join(" ").toLowerCase();return/maplibre-gl-(worker|shared)(?:-dev)?\.mjs/.test(t)||/failed to fetch worker script/.test(t)||/worker/.test(t)&&/failed to load|cannot load|dynamically imported module/.test(t)}const B="من می‌خواهم با پکیج قم‌پیک (@amir83nasr/map) یک نقشه انتخاب موقعیت (LocationPickerView) از صفر در پروژه React/Next.js بسازم. این پکیج کاملاً متن‌باز و رایگان است و روی MapLibre GL ساخته شده و فقط نسخه React دارد. لطفاً قدم‌به‌قدم و به ترتیب راهنمایی‌ام کن: ۱) نصب — دستور نصب @amir83nasr/map و maplibre-gl نسخه ۶ (که peer dependency است و باید جدا نصب شود)؛ ۲) راه‌اندازی پایه — ایمپورت @amir83nasr/map/styles.css (شامل CSS مپ‌لایبر، فقط یک import CSS) و رندر کامپوننت LocationPickerView با ارتفاع مشخص (مثلاً 480px، چون بدون ارتفاع نقشه خالی دیده می‌شود) و center و zoom اولیه؛ ۳) جستجو — استفاده از پیشنهادهای پیش‌فرض محله‌های قم، یا جایگزینی آن‌ها با search.suggestions شامل name و addr و lat و lng؛۴) مارکرها — نمایش مارکر مکان‌ها با markers؛ ۵) دریافت نتیجه — گرفتن مختصات و آدرس تاییدشده کاربر با onConfirm؛ ۶) پاک‌سازی — کامپوننت LocationPickerView خودش destroy را در cleanup صدا می‌زند. کد کامل و قابل اجرا بده شامل همه importها و cssها، بگو هر بخش چه می‌کند، و در پایان خروجی مورد انتظار را توصیف کن: نقشه فارسی راست‌چین (RTL) و موبایل‌فرست با پین وسط، دکمه GPS، جستجو و دکمه تایید موقعیت. اگر چیزی از پروژه من لازم داری (نسخه React/Next.js، نسخه پکیج‌ها) اول بپرس.",ae="پروژه React/Next.js من از قبل وجود دارد و می‌خواهم نقشه انتخاب موقعیت قم‌پیک (@amir83nasr/map) را به آن اضافه کنم بدون این‌که چیز دیگری خراب شود. این پکیج کاملاً متن‌باز و رایگان است و روی MapLibre GL ساخته شده و فقط نسخه React دارد. لطفاً قدم‌به‌قدم و به ترتیب راهنمایی‌ام کن: ۱) نصب — دستور نصب @amir83nasr/map و maplibre-gl نسخه ۶ (که peer dependency است و باید جدا نصب شود)، با توجه به این‌که بقیه dependencyهای پروژه نباید به‌هم بخورد؛ ۲) ایمپورت css — اضافه کردن @amir83nasr/map/styles.css (شامل CSS مپ‌لایبر؛ فقط یک import CSS) طوری که با استایل‌های فعلی پروژه تداخل نکند (همه کلاس‌ها و متغیرهای قم‌پیک با qp- شروع می‌شوند)؛ ۳) کانتینر — رندر LocationPickerView با ارتفاع مشخص (مثلاً 480px، چون بدون ارتفاع نقشه خالی دیده می‌شود) در جای مناسب صفحه فعلی؛ ۴) اتصال — دادن center و zoom، استفاده یا جایگزینی پیشنهادهای پیش‌فرض search، نمایش markers، و گرفتن مختصات و آدرس تاییدشده با onConfirm؛۵) پاک‌سازی — کامپوننت LocationPickerView خودش destroy را در cleanup صدا می‌زند. کد کامل و قابل اجرا بده شامل همه importها، بگو هر بخش چه می‌کند، و در پایان خروجی مورد انتظار را توصیف کن: نقشه فارسی راست‌چین (RTL) و موبایل‌فرست با پین وسط، دکمه GPS، جستجو و دکمه تایید موقعیت. اگر چیزی از پروژه من لازم داری (نسخه React/Next.js، نسخه پکیج‌ها، ساختار فایل‌ها) اول بپرس.",He={zero:B,existing:ae};function w(a){const e=document.createElement("template");return e.innerHTML=a.trim(),e.content.firstElementChild}class Qe{constructor(e){d(this,"opts");d(this,"emitter",new Pe);d(this,"root");d(this,"map");d(this,"myMarker",null);d(this,"venueMarkers",[]);d(this,"labelEl");d(this,"toastEl");d(this,"overlay");d(this,"resolveT",0);d(this,"searchT",0);d(this,"toastT",0);d(this,"settleT",0);d(this,"confirmT",0);d(this,"venueT",[]);d(this,"revSeq",0);d(this,"searchSeq",0);d(this,"revAbort",null);d(this,"searchAbort",null);d(this,"destroyed",!1);d(this,"workerFailed",!1);d(this,"boundsSaved",null);d(this,"lat",$.lat);d(this,"lng",$.lng);d(this,"address","");d(this,"resolving",!1);d(this,"onKey",e=>{e.key==="Escape"&&(this.overlay.hidden?this.isHidden(".qp-docs")?this.isHidden(".qp-confirm")?this.isHidden(".qp-geo")||this.closeModal("qp-geo"):this.closeModal("qp-confirm"):this.closeDocs():this.closeSearch())});var o,r;const t=typeof e.container=="string"?document.querySelector(e.container):e.container;if(!t)throw new Error("qompick: container not found");this.opts=me(e);for(const[i,s]of[["onLocationChange","locationChange"],["onAddressResolved","addressResolved"],["onSearchResults","searchResults"],["onPick","pick"],["onConfirm","confirm"],["onLocate","locate"],["onError","error"]]){const n=e[i];typeof n=="function"&&this.emitter.on(s,n)}this.build(t),this.initMap(),this.opts.markers.length&&this.addVenues(this.opts.markers),this.setLocation(((o=this.opts.map.center)==null?void 0:o.lat)??$.lat,((r=this.opts.map.center)==null?void 0:r.lng)??$.lng,{resolve:!0}),this.emitter.emit("ready",this.getLocation())}isHidden(e){var t;return((t=this.root.querySelector(e))==null?void 0:t.hidden)??!0}on(e,t){return this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}getLocation(){return{lat:this.lat,lng:this.lng,address:this.address}}setLocation(e,t,o={}){if(!Oe(e,t)){this.fail(new Error("invalid coordinates"));return}this.lat=e,this.lng=t;const r=this.getLocation();if(this.emitter.emit("locationChange",r),o.moveMap&&this.map){const i=o.zoom??Math.max(this.map.getZoom(),this.opts.behavior.pickZoom??15);this.map.flyTo({center:[t,e],zoom:i,duration:450})}o.resolve!==!1&&this.opts.behavior.resolveOnMove!==!1?this.scheduleResolve(e,t):this.renderLabel()}locate(){if(!navigator.geolocation){this.toast(this.t("gpsUnsupported")),this.fail(new Error("geolocate: unsupported"));return}const e=this.root.querySelector(".qp-gps");if(!window.isSecureContext){this.openModal("qp-geo"),this.fail(new Error("geolocate: insecure-context"));return}e==null||e.classList.add("is-locating"),navigator.geolocation.getCurrentPosition(t=>{if(e==null||e.classList.remove("is-locating"),!this.boundsSaved){const o=this.map.getMaxBounds();o&&(this.boundsSaved={sw:o.getSouthWest().toArray(),ne:o.getNorthEast().toArray()})}this.map.setMaxBounds(null),this.showMyPos(t.coords.latitude,t.coords.longitude),this.setLocation(t.coords.latitude,t.coords.longitude,{moveMap:!0,zoom:this.opts.behavior.locateZoom??18}),this.boundsSaved&&(this.map.setMaxBounds([this.boundsSaved.sw,this.boundsSaved.ne]),this.boundsSaved=null),this.emitter.emit("locate",this.getLocation())},t=>{e==null||e.classList.remove("is-locating"),(t==null?void 0:t.code)===t.PERMISSION_DENIED?this.openModal("qp-geo"):(this.toast((t==null?void 0:t.code)===t.TIMEOUT?this.t("locateTimeout"):this.t("locateUnavailable")),this.scheduleResolve(this.lat,this.lng,100)),this.fail(new Error(`geolocate: ${t==null?void 0:t.code}`))},{timeout:1e4})}confirm(e){const t={lat:this.lat,lng:this.lng,address:e??this.address};return this.emitter.emit("confirm",t),t}destroy(){var e,t,o,r;this.destroyed=!0,document.removeEventListener("keydown",this.onKey),window.clearTimeout(this.resolveT),window.clearTimeout(this.searchT),window.clearTimeout(this.toastT),window.clearTimeout(this.settleT),window.clearTimeout(this.confirmT),this.venueT.forEach(i=>window.clearTimeout(i)),(e=this.revAbort)==null||e.abort(),(t=this.searchAbort)==null||t.abort(),this.venueMarkers.forEach(i=>i.remove()),(o=this.myMarker)==null||o.remove(),(r=this.map)==null||r.remove(),this.root.remove()}t(e){return this.opts.i18n.labels[e]}build(e){const t=this.opts,o=ue(),r=(t.search.placeholder??this.t("searchPlaceholder")).replace(/&/g,"&amp;").replace(/"/g,"&quot;").replace(/</g,"&lt;").replace(/>/g,"&gt;");this.root=w(`<div class="qp qp-app" dir="${o}"></div>`);const i='<div class="qp-pin" aria-hidden="true"><div class="qp-pin-body"><div class="qp-pin-head"><div class="qp-pin-hole"></div></div><div class="qp-pin-stem"></div><div class="qp-pin-foot"></div></div><div class="qp-pin-shadow"></div></div>';this.root.innerHTML=`
2
+ <div class="qp-layout">
3
+ <main class="qp-map-wrap"><div class="qp-map"></div>${i}
4
+ ${t.controls.gps?`<button class="qp-gps" type="button" aria-label="${this.t("currentLocation")}">${v.locate}</button>`:""}
5
+ ${t.controls.developers?`<button class="qp-dev" type="button">${this.t("developers")}</button>`:""}
6
+ </main>
7
+ ${t.sheet.enabled?`<section class="qp-sheet"><div class="qp-grab"></div>
8
+ ${t.controls.searchTrigger&&t.search.enabled?`<div class="qp-search"><button class="qp-search-trigger" type="button"><span class="qp-sic">${v.search}</span><span class="qp-search-label"></span></button></div>`:""}
9
+ <div class="qp-desk">
10
+ <div class="qp-search-bar"><div class="qp-field"><input class="qp-desk-input" type="search" placeholder="${r}" autocomplete="off" aria-label="${this.t("searchTitle")}"/><button class="qp-clear qp-desk-clear" hidden aria-label="${this.t("clearSearch")}">${v.x}</button><span class="qp-sic">${v.search}</span></div></div>
11
+ <div class="qp-desk-body"><div class="qp-desk-home"><h3 class="qp-sec-t">${this.t("suggestedPlaces")}</h3><div class="qp-suggest-desk"></div></div><div class="qp-results-desk"></div></div>
12
+ </div>
13
+ <div class="qp-sheet-row">${t.controls.confirmButton?`<button class="qp-cta">${this.t("confirmLocation")}</button>`:""}</div>
14
+ </section>`:""}
15
+ </div>
16
+ ${t.search.enabled?`<div class="qp-overlay" hidden><div class="qp-ov-head"><h2>${this.t("searchTitle")}</h2><button class="qp-ov-close" type="button" aria-label="${this.t("close")}">${v.x}</button></div>
17
+ <div class="qp-search-bar"><div class="qp-field"><input type="search" placeholder="${r}" autocomplete="off"/><button class="qp-clear" hidden aria-label="${this.t("clearSearch")}">${v.x}</button><span class="qp-sic">${v.search}</span></div></div>
18
+ <div class="qp-ov-body"><div class="qp-home"><h3 class="qp-sec-t">${this.t("suggestedPlaces")}</h3><div class="qp-suggest"></div></div><div class="qp-results"></div></div>
19
+ </div>`:""}
20
+ <div class="qp-modal qp-geo" hidden><div class="qp-modal-card"><div class="qp-modal-head"><h2>${this.t("geoTitle")}</h2><button class="qp-x" type="button" aria-label="${this.t("close")}">${v.x}</button></div><p>${this.t("geoText")}</p><p class="qp-modal-sub">${this.t("geoBlocked")}</p><div class="qp-modal-row"><button class="qp-cta qp-geo-retry" type="button">${this.t("enableAccess")}</button></div></div></div>
21
+ <div class="qp-modal qp-confirm" hidden><div class="qp-modal-card"><div class="qp-modal-head"><h2>${this.t("confirmLocation")}</h2><button class="qp-x" type="button" aria-label="${this.t("close")}">${v.x}</button></div><label>${this.t("chosenAddress")}</label><textarea class="qp-addr" rows="3"></textarea><div>${this.t("coordsToServer")}</div><div class="qp-coords" dir="ltr"></div><div class="qp-modal-row"><button class="qp-cta qp-final" type="button">${this.t("confirm")}</button><button class="qp-ghost qp-edit" type="button">${this.t("editOnMap")}</button></div></div></div>
22
+ ${t.controls.developers?this.devDocsHtml():""}
23
+ <div class="qp-toast" role="status"></div>`,e.appendChild(this.root),this.labelEl=this.root.querySelector(".qp-search-label")??w("<span></span>"),this.toastEl=this.root.querySelector(".qp-toast"),this.overlay=this.root.querySelector(".qp-overlay")??w("<div></div>"),this.wire(),requestAnimationFrame(()=>this.root.classList.add("is-ready"))}wire(){var o,r,i,s,n,l,g,m,p,h,L;(o=this.root.querySelector(".qp-gps"))==null||o.addEventListener("click",()=>this.locate()),(r=this.root.querySelector(".qp-search-trigger"))==null||r.addEventListener("click",()=>this.openSearch()),(i=this.root.querySelector(".qp-ov-close"))==null||i.addEventListener("click",()=>this.closeSearch()),(s=this.root.querySelector(".qp-cta"))==null||s.addEventListener("click",()=>this.openConfirm()),(n=this.root.querySelector(".qp-final"))==null||n.addEventListener("click",()=>this.finishConfirm()),(l=this.root.querySelector(".qp-edit"))==null||l.addEventListener("click",()=>this.closeModal("qp-confirm")),(g=this.root.querySelector(".qp-geo-retry"))==null||g.addEventListener("click",()=>{this.closeModal("qp-geo"),this.locate()}),this.root.querySelectorAll(".qp-modal").forEach(c=>c.addEventListener("click",u=>{u.target===c&&(c.hidden=!0)})),this.root.querySelectorAll(".qp-modal .qp-x").forEach(c=>c.addEventListener("click",()=>{var u;(u=c.closest(".qp-modal"))==null||u.setAttribute("hidden","")})),(m=this.root.querySelector(".qp-docs .qp-x"))==null||m.addEventListener("click",()=>this.closeDocs()),document.addEventListener("keydown",this.onKey),(p=this.root.querySelector(".qp-dev"))==null||p.addEventListener("click",()=>this.openDocs()),(h=this.root.querySelector(".qp-back"))==null||h.addEventListener("click",()=>this.closeDocs()),(L=this.root.querySelector(".qp-docs"))==null||L.addEventListener("click",c=>{c.target===this.root.querySelector(".qp-docs")&&this.closeDocs()}),this.root.querySelectorAll(".qp-copy").forEach(c=>c.addEventListener("click",u=>{this.copyPrompt(u.currentTarget)})),this.root.querySelectorAll(".qp-code-copy").forEach(c=>c.addEventListener("click",u=>{this.copyCode(u.currentTarget)}));const e=this.root.querySelector(".qp-overlay .qp-field input");if(e){const c=this.root.querySelector(".qp-overlay .qp-clear"),u=()=>{c&&(c.hidden=e.value.length===0)};e.addEventListener("input",()=>{u(),this.onQuery(e.value)}),e.addEventListener("keydown",R=>{R.key==="Enter"&&this.runSearch(e.value.trim())}),c==null||c.addEventListener("click",()=>{e.value="",u(),this.renderSuggest(""),e.focus()}),this.renderSuggest("")}const t=this.root.querySelector(".qp-desk-input");if(t){const c=this.root.querySelector(".qp-desk-clear"),u=()=>{c&&(c.hidden=t.value.length===0)};t.addEventListener("input",()=>{u(),this.onDeskQuery(t.value)}),t.addEventListener("keydown",R=>{R.key==="Enter"&&this.runRemoteSearch(t.value.trim(),".qp-results-desk",".qp-desk-home")}),c==null||c.addEventListener("click",()=>{t.value="",u(),this.renderDeskSuggest(""),t.focus()}),this.renderDeskSuggest("")}}initMap(){const e=this.opts,t=this.root.querySelector(".qp-map"),o=typeof e.map.style=="object"&&e.map.style!==null?{...e.map.style}:{...$e},r=e.map.glyphs?{...o,glyphs:e.map.glyphs}:o;if(typeof r.glyphs=="string"&&!/^(https?:|data:|blob:|\/)/.test(r.glyphs)){const p=document.baseURI,h=p.endsWith("/")?p:p.slice(0,p.lastIndexOf("/")+1);r.glyphs=h+r.glyphs}const i=e.map.bounds,s=Ue(()=>this.showWorkerError());try{this.map=new z.Map({container:t,style:r,center:[e.map.center.lng,e.map.center.lat],zoom:e.map.zoom,minZoom:e.map.minZoom,maxZoom:e.map.maxZoom,attributionControl:!1,renderWorldCopies:!1,fadeDuration:100,crossSourceCollisions:!1,scrollZoom:{around:"center"},dragRotate:!1,touchPitch:!1,clickTolerance:5,maxCanvasSize:[8192,8192],maxBounds:[[i[0][1],i[0][0]],[i[1][1],i[1][0]]]})}finally{s()}Z&&this.showWorkerError(),this.map.on("error",p=>{if(Ve(p.error)){this.showWorkerError();return}console.error(p.error),this.fail(p.error)}),requestAnimationFrame(()=>this.map.resize());const n=this.root.querySelector(".qp-map-wrap");let l=null,g=this.map.getZoom(),m=this.map.getCenter();this.map.on("movestart",()=>{n.classList.add("is-moving"),window.clearTimeout(this.settleT),g=this.map.getZoom(),m=this.map.getCenter()}),this.map.on("move",()=>{const p=this.map.getCenter();this.lat=p.lat,this.lng=p.lng}),this.map.on("moveend",p=>{n.classList.remove("is-moving");const h=this.map.getCenter();if(window.clearTimeout(this.settleT),l&&Math.abs(h.lat-l.lat)<1e-7&&Math.abs(h.lng-l.lng)<1e-7){l=null;return}if(!p.originalEvent){this.setLocation(h.lat,h.lng);return}const L=Math.hypot(h.lat-m.lat,h.lng-m.lng)*111320,c=this.map.getZoom(),u=Math.abs(c-g)>1&&L<10,R=u?0:this.opts.behavior.snapDelayMs??this.opts.behavior.settleDelayMs;this.settleT=window.setTimeout(()=>{if(!this.destroyed){if(this.opts.behavior.snapToRoad&&!u)try{const E=Ze(this.map,h.lat,h.lng);if(E){l=E,this.map.easeTo({center:[E.lng,E.lat],duration:400}),this.setLocation(E.lat,E.lng);return}}catch{}this.setLocation(h.lat,h.lng)}},R)})}showWorkerError(){var s;if(this.destroyed||this.workerFailed)return;this.workerFailed=!0;const e=new Error(Ge);console.warn(e.message),this.fail(e);const t=w('<div class="qp-err qp-map-err" role="alert"></div>'),o=w("<strong></strong>");o.textContent="ورکر MapLibre بارگذاری نشد؛ نقشه قابل استفاده نیست.";const r=w("<span></span>");r.textContent="راه‌حل: ";const i=w('<code dir="ltr"></code>');i.textContent=Be,r.appendChild(i),t.append(o,r),(s=this.root.querySelector(".qp-map-wrap"))==null||s.appendChild(t)}showMyPos(e,t){if(this.myMarker){this.myMarker.setLngLat([t,e]);return}const o=w('<div class="qp-my-wrap"><div class="qp-my-dot"></div></div>');this.myMarker=new z.Marker({element:o}).setLngLat([t,e]).addTo(this.map)}addVenues(e){for(const t of e){const o=document.createElement("button");o.type="button",o.className="qp-venue",o.setAttribute("aria-label",t.name),o.innerHTML=v.star,o.addEventListener("click",()=>{this.setLocation(t.lat,t.lng,{moveMap:!0,zoom:this.opts.behavior.pickZoom}),this.emitter.emit("pick",this.getLocation())});const r=w('<div class="qp-venue-pop"><span class="qp-venue-dot"></span><span></span></div>');r.lastElementChild.textContent=t.name;const i=new z.Popup({offset:26,anchor:"top",closeButton:!1,className:"qp-venue-pop-wrap"}).setDOMContent(r),s=new z.Marker({element:o}).setLngLat([t.lng,t.lat]).setPopup(i).addTo(this.map);let n=0;i.on("open",()=>{window.clearTimeout(n),n=window.setTimeout(()=>i.remove(),4e3),this.venueT.push(n)}),i.on("close",()=>window.clearTimeout(n)),this.venueMarkers.push(s)}}scheduleResolve(e,t,o){window.clearTimeout(this.resolveT);const r=o??this.opts.behavior.resolveDelayMs??600;this.resolveT=window.setTimeout(()=>void this.resolveAddress(e,t),r)}async resolveAddress(e,t){var r;(r=this.revAbort)==null||r.abort(),this.revAbort=new AbortController;const o=++this.revSeq;this.resolving=!0,this.labelEl.textContent=this.t("resolving");try{const i=await Ie(e,t,{signal:this.revAbort.signal});if(o!==this.revSeq||this.destroyed)return;this.address=ee(i),this.emitter.emit("addressResolved",this.getLocation())}catch(i){if(i instanceof DOMException&&i.name==="AbortError"||o!==this.revSeq)return;this.address="",this.fail(i)}finally{if(o!==this.revSeq)return;this.resolving=!1,this.renderLabel()}}renderLabel(){this.labelEl.textContent=this.address?S(this.address):this.t("searchTitle")}devDocsHtml(){const e=this.t("copy"),t=o=>`<div class="qp-code" dir="ltr"><pre>${o}</pre><button class="qp-ghost qp-code-copy" type="button">${e}</button></div>`;return`<div class="qp-docs" hidden><div class="qp-docs-card">
24
+ <div class="qp-modal-head"><h2>${this.t("developers")}</h2><button class="qp-x" type="button" aria-label="${this.t("close")}">${v.x}</button></div>
25
+ <p class="qp-note">قم‌پیک (@amir83nasr/map) — نقشه انتخاب موقعیت روی MapLibre، فقط React، کاملاً متن‌باز و رایگان. نقشه همیشه VECTOR است (نه raster)؛ فارسی راست‌چین (RTL) و موبایل‌فرست.</p>
26
+ <nav class="qp-docs-nav">
27
+ <a href="#qp-d-install">نصب</a><a href="#qp-d-quick">شروع سریع</a><a href="#qp-d-worker">ورکر</a><a href="#qp-d-props">تنظیمات</a><a href="#qp-d-cb">کال‌بک‌ها</a><a href="#qp-d-style">ظاهر</a><a href="#qp-d-faq">خطاها</a><a href="#qp-d-prompts">پرامپت‌ها</a>
28
+ </nav>
29
+ <section id="qp-d-install"><h3>۱) نصب</h3>${t("pnpm add @amir83nasr/map maplibre-gl")}
30
+ <p class="qp-note">نکته: maplibre-gl نسخه ۶ و react/react-dom‏ peer dependency هستند و باید جدا نصب شوند.</p></section>
31
+ <section id="qp-d-quick"><h3>۲) شروع سریع — ۲ خط</h3>${t(`import '@amir83nasr/map/styles.css';
32
+ import { LocationPickerView } from '@amir83nasr/map';`)}${t(`&lt;LocationPickerView
33
+ style={{ height: 480 }}
34
+ onConfirm={(loc) =&gt; console.log(loc.lat, loc.lng, loc.address)}
35
+ /&gt;;`)}
36
+ <p class="qp-note">نکته: همین یک import کافی است (CSS مپ‌لایبر + فونت IRANYekanX داخلش است). بدون <code dir="ltr">height</code> نقشه خالی دیده می‌شود (پیش‌فرض <code dir="ltr">480px</code>). کامپوننت خودش init/destroy می‌کند — دستی صدا نزنید.</p>
37
+ <p class="qp-note">نکته Next.js App Router: کامپوننت client است؛ با <code dir="ltr">dynamic(..., { ssr: false })</code> لود کنید.</p></section>
38
+ <section id="qp-d-worker"><h3>۳) ورکر MapLibre — قبل از mount (اجباری)</h3>
39
+ <p class="qp-note">پکیج نمی‌تواند ورکر را برای شما باندل کند. علامت خرابی: نقشه خاکستری + باکس <code dir="ltr">.qp-map-err</code> + یک <code dir="ltr">console.warn</code> + کال <code dir="ltr">onError</code>.</p>
40
+ <p class="qp-note">Vite:</p>${t(`import { setupQomPickWorker } from '@amir83nasr/map';
41
+ import workerUrl from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&amp;url';
42
+ setupQomPickWorker(workerUrl);`)}
43
+ <p class="qp-note">Next.js/webpack: هر دو فایل <code dir="ltr">maplibre-gl-worker.mjs</code> و <code dir="ltr">maplibre-gl-shared.mjs</code> را در خروجی public کپی کنید و URL عمومی ورکر را به <code dir="ltr">setupQomPickWorker()</code> بدهید (ال‌یاس <code dir="ltr">setupMapWorker</code> یکسان است).</p></section>
44
+ <section id="qp-d-props"><h3>۴) تنظیمات مهم</h3><ul class="qp-list">
45
+ <li><code dir="ltr">map</code> — مرکز/زوم/محدوده (<code dir="ltr">center / zoom / minZoom / maxZoom / bounds</code>)؛ پیش‌فرض قم <code dir="ltr">34.6416,50.8764</code> زوم ۱۴. استایل سفارشی فقط برداری (<code dir="ltr">style</code>)؛ <code dir="ltr">glyphs</code> برای self-host فونت نقشه.</li>
46
+ <li><code dir="ltr">search</code> — پیش‌فرض ۵۲ محله قم (همه نمایش، بدون سقف): <code dir="ltr">enabled / placeholder / suggestions / minLength(3) / debounceMs(350) / limit(5)</code>. آرایه سفارشی جایگزین می‌شود؛ <code dir="ltr">[]</code> غیرفعال می‌کند. <code dir="ltr">limit</code> فقط نتایج ریموت (Nominatim) است.</li>
47
+ <li><code dir="ltr">markers</code> — پین‌ها با <code dir="ltr">name / lat / lng</code>؛ کلیک → پرواز تا <code dir="ltr">pickZoom</code> + کال <code dir="ltr">onPick</code>.</li>
48
+ <li><code dir="ltr">controls</code> — <code dir="ltr">gps / confirmButton / searchTrigger / developers</code>.</li>
49
+ <li><code dir="ltr">behavior</code> — <code dir="ltr">snapToRoad / resolveOnMove / resolveDelayMs(400) / settleDelayMs(250) / snapDelayMs(900) / pickZoom(15) / locateZoom(18)</code>. اسنپ فقط حرکت دستی، زوم ≥ ۱۵؛ پینچ‌زوم و حرکات کد هرگز اسنپ نمی‌شوند.</li>
50
+ <li><code dir="ltr">i18n.labels</code> — بازنویسی متن‌ها؛ چیدمان همیشه RTL است.</li></ul>
51
+ ${t(`&lt;LocationPickerView
52
+ map={{ center: { lat: 34.64, lng: 50.87 }, zoom: 15 }}
53
+ search={{ minLength: 3, limit: 5 }}
54
+ markers={[{ name: 'فروشگاه', lat: 34.63, lng: 50.87 }]}
55
+ controls={{ gps: true, developers: true }}
56
+ onConfirm={(loc) =&gt; console.log(loc)}
57
+ /&gt;;`)}
58
+ <p class="qp-note">تنظیمات engine فقط موقع mount اعمال می‌شوند؛ برای اعمال جدید با <code dir="ltr">key</code> ریمانت کنید — فقط کال‌بک‌ها زنده می‌مانند: <code dir="ltr">&lt;LocationPickerView key={cityId} ... /&gt;</code>.</p></section>
59
+ <section id="qp-d-cb"><h3>۵) کال‌بک‌ها — کدام برای چه</h3><ul class="qp-list">
60
+ <li><code dir="ltr">onConfirm</code> — دکمه تایید در مودال → <b>ذخیره نتیجه</b> (فرم/سرور).</li>
61
+ <li><code dir="ltr">onPick</code> — کلیک پین/پیشنهاد → واکنش، نه ذخیره.</li>
62
+ <li><code dir="ltr">onLocationChange</code> — هر حرکت مرکز (پرتکرار).</li>
63
+ <li><code dir="ltr">onAddressResolved</code> — پایان ژئوکد معکوس.</li>
64
+ <li><code dir="ltr">onSearchResults</code> — پایان جستجوی ریموت.</li>
65
+ <li><code dir="ltr">onLocate</code> — موفقیت GPS. <code dir="ltr">onError</code> — هر خطا از جمله ورکر.</li></ul></section>
66
+ <section id="qp-d-style"><h3>۶) سفارشی‌سازی ظاهر</h3><p class="qp-note">prop تم نیست؛ همه کلاس‌ها/متغیرها با <code dir="ltr">qp-</code> شروع می‌شوند و با پروژه تداخل نمی‌کنند:</p>
67
+ ${t(".qp { --qp-brand: #16a34a; --qp-ink: #111; --qp-radius: 16px; }")}
68
+ <p class="qp-note">متغیرها: <code dir="ltr">--qp-brand --qp-brand-dark --qp-bg --qp-card --qp-ink --qp-muted --qp-line --qp-radius --qp-shadow --qp-font</code>.</p></section>
69
+ <section><h3>۷) ساختار پروژه</h3><ul class="qp-list">
70
+ <li><code dir="ltr">package/src/index.tsx</code> — API عمومی (re-export از <code dir="ltr">react/ + core/</code>).</li>
71
+ <li><code dir="ltr">package/src/react/</code> — کامپوننت <code dir="ltr">LocationPickerView</code> + هلپر <code dir="ltr">setupQomPickWorker</code>.</li>
72
+ <li><code dir="ltr">package/src/engine/</code> — engine داخلی (<code dir="ltr">picker</code>، در exports عمومی نیست).</li>
73
+ <li><code dir="ltr">package/src/core/ + style/</code> — تایپ‌ها و helperها + استایل و basemap.</li>
74
+ <li><code dir="ltr">dist/styles.css</code> — ایمپورت: <code dir="ltr">@amir83nasr/map/styles.css</code>.</li>
75
+ <li><code dir="ltr">package/fonts/</code> — فونت IRANYekanX‏ (woff2) و PBFهای glyph نقشه؛ داخل tarball منتشر می‌شود.</li></ul></section>
76
+ <section id="qp-d-faq"><h3>۸) سوالات پرتکرار</h3><ul class="qp-list">
77
+ <li>نقشه خالی/خاکستری بدون خطا؟ ارتفاع بدهید (<code dir="ltr">style={{ height: 480 }}</code>).</li>
78
+ <li>باکس قرمز ورکر؟ بخش ۳ (ورکر) — نه چیز دیگر.</li>
79
+ <li>لیبل فارسی نقشه نیست؟ CDN glyph مسدود است؛ <code dir="ltr">map.glyphs</code> را به کپی محلی <code dir="ltr">fonts/</code> بدهید.</li>
80
+ <li>پراپ جدید اثر ندارد؟ mount-only است؛ <code dir="ltr">key</code> بدهید.</li>
81
+ <li>کرش Next.js‏ (<code dir="ltr">window/document</code>)؟ <code dir="ltr">'use client' + ssr: false</code>.</li>
82
+ <li>کدام نسخه maplibre؟ ۶ (peer). رایگان؟ بله، متن‌باز.</li></ul></section>
83
+ <section id="qp-d-prompts"><h3>پرامپت شروع از صفر</h3><div class="qp-prompt">${B}</div>
84
+ <div class="qp-modal-row"><button class="qp-ghost qp-copy" type="button" data-prompt="zero">${this.t("copy")}</button></div></section>
85
+ <section><h3>پرامپت افزودن به پروژه موجود</h3><div class="qp-prompt">${ae}</div>
86
+ <div class="qp-modal-row"><button class="qp-ghost qp-copy" type="button" data-prompt="existing">${this.t("copy")}</button></div></section>
87
+ <div class="qp-modal-row"><button class="qp-cta qp-back" type="button">${this.t("backToMap")}</button></div>
88
+ </div></div>`}openDocs(){var e;(e=this.root.querySelector(".qp-docs"))==null||e.removeAttribute("hidden")}closeDocs(){const e=this.root.querySelector(".qp-docs");e&&(e.hidden=!0)}copyDone(e){const t=e.textContent??"";e.textContent=this.t("copied"),window.setTimeout(()=>{e.textContent=t},1500)}copyText(e,t){var r;const o=()=>this.copyDone(t);if((r=navigator.clipboard)!=null&&r.writeText){navigator.clipboard.writeText(e).then(o,()=>this.fallbackCopy(e,o));return}this.fallbackCopy(e,o)}copyPrompt(e){const t=e.dataset.prompt??"zero";this.copyText(He[t]??B,e)}copyCode(e){var o;const t=(o=e.closest(".qp-code"))==null?void 0:o.querySelector("pre");t&&this.copyText(t.textContent??"",e)}fallbackCopy(e,t){const o=document.createElement("textarea");o.value=e,o.style.position="fixed",o.style.opacity="0",document.body.appendChild(o),o.select();try{document.execCommand("copy")}catch{}o.remove(),t()}openSearch(){this.overlay.hidden=!1;const e=this.root.querySelector(".qp-overlay .qp-field input");e&&(e.value="",this.renderSuggest(""),window.setTimeout(()=>e.focus(),50))}closeSearch(){this.overlay.hidden=!0;const e=this.root.querySelector(".qp-overlay .qp-field input");e&&e.blur()}pickSuggestion(e){this.setLocation(e.lat,e.lng,{moveMap:!0,zoom:this.opts.behavior.pickZoom}),this.emitter.emit("pick",this.getLocation()),this.closeSearch()}pickResult(e,t){this.searchSeq++,this.setLocation(parseFloat(e),parseFloat(t),{moveMap:!0,zoom:this.opts.behavior.pickZoom});const o=this.getLocation();this.emitter.emit("pick",o),this.closeSearch()}suggestionRow(e){const t=w(`<button class="qp-row" type="button"><span class="qp-ric">${v.pin}</span><span class="qp-t"><b></b><small></small></span></button>`);return t.querySelector("b").textContent=S(e.name),t.querySelector("small").textContent=S(e.addr),t.addEventListener("click",()=>this.pickSuggestion(e)),t}resultRow(e,t,o){const r=w(`<button class="qp-card" type="button"><span class="qp-ric">${v.pin}</span><span><b></b><small></small></span></button>`);return r.querySelector("b").textContent=S(String(e).split(",")[0]),r.querySelector("small").textContent=S(ee(e)),r.addEventListener("click",()=>this.pickResult(t,o)),r}filteredSuggestions(e){const t=M(e).trim();return this.suggestions().filter(o=>!t||M(o.name).includes(t)||M(o.addr).includes(t)).sort((o,r)=>o.name.localeCompare(r.name,"fa"))}suggestions(){return this.opts.search.suggestions??[]}renderSuggest(e){const t=this.root.querySelector(".qp-suggest"),o=this.root.querySelector(".qp-home"),r=this.root.querySelector(".qp-results");if(t){t.innerHTML="";for(const i of this.filteredSuggestions(e))t.appendChild(this.suggestionRow(i));o&&(o.hidden=!1),r&&(r.innerHTML="")}}renderDeskSuggest(e){const t=this.root.querySelector(".qp-suggest-desk"),o=this.root.querySelector(".qp-desk-home"),r=this.root.querySelector(".qp-results-desk");if(t){t.innerHTML="";for(const i of this.filteredSuggestions(e))t.appendChild(this.suggestionRow(i));o&&(o.hidden=!1),r&&(r.innerHTML="")}}onQuery(e){this.onQueryShared(e,t=>this.renderSuggest(t),t=>void this.runSearch(t))}onQueryShared(e,t,o){this.searchSeq++;const r=this.searchSeq;window.clearTimeout(this.searchT);const i=e.trim(),s=this.opts.search.minLength??oe;if(i.length<1){t("");return}if(i.length<s){t(i);return}this.searchT=window.setTimeout(()=>{r===this.searchSeq&&o(i)},this.opts.search.debounceMs??350)}async runSearch(e){await this.runRemoteSearch(e,".qp-results",".qp-home")}onDeskQuery(e){this.onQueryShared(e,t=>this.renderDeskSuggest(t),t=>void this.runRemoteSearch(t,".qp-results-desk",".qp-desk-home"))}async runRemoteSearch(e,t,o){var g;const r=e.trim(),i=this.root.querySelector(t),s=this.root.querySelector(o);if(!i)return;if(!r){t.includes("desk")?this.renderDeskSuggest(""):this.renderSuggest("");return}const n=this.opts.search.minLength??oe;if(r.length<n){t.includes("desk")?this.renderDeskSuggest(r):this.renderSuggest(r);return}const l=++this.searchSeq;(g=this.searchAbort)==null||g.abort(),this.searchAbort=new AbortController,s&&(s.hidden=!0),i.innerHTML=`<div class="qp-err">${this.t("searching")}</div>`;try{const m=await je(r,this.opts.search.limit??5,{signal:this.searchAbort.signal});if(l!==this.searchSeq)return;if(this.emitter.emit("searchResults",m),!m.length){i.innerHTML=`<div class="qp-err">${this.t("noResults")}</div>`;return}i.innerHTML="";for(const p of m)i.appendChild(this.resultRow(p.display_name,p.lat,p.lon))}catch(m){if(m instanceof DOMException&&m.name==="AbortError"||l!==this.searchSeq)return;i.innerHTML=`<div class="qp-err">${this.t("searchError")}</div>`,this.fail(m)}}openModal(e){var t;(t=this.root.querySelector(`.${e}`))==null||t.removeAttribute("hidden")}closeModal(e){const t=this.root.querySelector(`.${e}`);t&&(t.hidden=!0)}openConfirm(){!this.address&&!this.resolving&&this.scheduleResolve(this.lat,this.lng,100),this.root.querySelector(".qp-addr").value=this.address?S(this.address):"",this.root.querySelector(".qp-coords").textContent=`${Number(this.lat).toFixed(6)}, ${Number(this.lng).toFixed(6)}`,this.openModal("qp-confirm")}finishConfirm(){const e=this.root.querySelector(".qp-final"),t=this.root.querySelector(".qp-addr").value;e.disabled=!0;const o=e.textContent??"";e.textContent=this.t("submitting"),window.clearTimeout(this.confirmT),this.confirmT=window.setTimeout(()=>{if(this.destroyed)return;e.disabled=!1,e.textContent=o;const r=this.confirm(t);this.closeModal("qp-confirm"),this.toast(`${this.t("registered")} (${J(Number(r.lat))}, ${J(Number(r.lng))})`)},800)}toast(e){this.toastEl.textContent=e,this.toastEl.classList.add("show"),window.clearTimeout(this.toastT),this.toastT=window.setTimeout(()=>this.toastEl.classList.remove("show"),2600)}fail(e){const t=e instanceof Error?e:new Error(String(e));this.emitter.emit("error",t)}}function se(a){z.setWorkerUrl(a)}const Ye=se;function Xe({className:a,style:e,...t}){const o=P.useRef(null),r=P.useRef(t);return P.useEffect(()=>{r.current=t}),P.useEffect(()=>{if(!o.current)return;const i=new Qe({...r.current,container:o.current,onLocationChange:s=>{var n,l;return(l=(n=r.current).onLocationChange)==null?void 0:l.call(n,s)},onAddressResolved:s=>{var n,l;return(l=(n=r.current).onAddressResolved)==null?void 0:l.call(n,s)},onSearchResults:s=>{var n,l;return(l=(n=r.current).onSearchResults)==null?void 0:l.call(n,s)},onPick:s=>{var n,l;return(l=(n=r.current).onPick)==null?void 0:l.call(n,s)},onConfirm:s=>{var n,l;return(l=(n=r.current).onConfirm)==null?void 0:l.call(n,s)},onLocate:s=>{var n,l;return(l=(n=r.current).onLocate)==null?void 0:l.call(n,s)},onError:s=>{var n,l;return(l=(n=r.current).onError)==null?void 0:l.call(n,s)}});return()=>i.destroy()},[]),ce.jsx("div",{ref:o,className:a,style:{height:480,...e}})}exports.LocationPickerView=Xe;exports.QOM_SUGGESTIONS=re;exports.setupMapWorker=Ye;exports.setupQomPickWorker=se;
@@ -0,0 +1,4 @@
1
+ export { LocationPickerView, setupMapWorker, setupQomPickWorker, } from './react/LocationPickerView.js';
2
+ export type { QomPickProps } from './react/LocationPickerView.js';
3
+ export type * from './core/types.js';
4
+ export { QOM_SUGGESTIONS } from './core/defaults.js';
package/dist/index.d.ts CHANGED
@@ -1,18 +1,4 @@
1
- import { LocationPickerOptions } from './types.js';
2
- /** Public props: engine options minus `container` (React owns the element) + layout. */
3
- export type QomPickProps = Omit<LocationPickerOptions, 'container'> & {
4
- className?: string;
5
- style?: React.CSSProperties;
6
- };
7
- /**
8
- * Set MapLibre's worker URL before mounting `LocationPickerView`.
9
- * Worker files are bundler-specific — the package cannot ship them for you.
10
- * Vite: `import url from 'maplibre-gl/dist/maplibre-gl-worker.mjs?worker&url'`.
11
- * Next.js/webpack: copy both `maplibre-gl-worker.mjs` and `maplibre-gl-shared.mjs`.
12
- */
13
- export declare function setupQomPickWorker(workerUrl: string): void;
14
- /** Alias matching the package name; identical to `setupQomPickWorker`. */
15
- export declare const setupMapWorker: typeof setupQomPickWorker;
16
- export declare function LocationPickerView({ className, style, ...opts }: QomPickProps): React.JSX.Element;
17
- export type * from './types.js';
18
- export { QOM_SUGGESTIONS } from './defaults.js';
1
+ export { LocationPickerView, setupMapWorker, setupQomPickWorker, } from './react/LocationPickerView.js';
2
+ export type { QomPickProps } from './react/LocationPickerView.js';
3
+ export type * from './core/types.js';
4
+ export { QOM_SUGGESTIONS } from './core/defaults.js';