@vibelabsdotto/featurama-rn-expo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (312) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -0
  3. package/android/build.gradle +26 -0
  4. package/android/src/main/AndroidManifest.xml +3 -0
  5. package/android/src/main/java/com/featurama/reactnative/FeaturamaInsetsModule.kt +58 -0
  6. package/android/src/main/java/com/featurama/reactnative/FeaturamaInsetsPackage.kt +28 -0
  7. package/featurama-rn-expo.podspec +23 -0
  8. package/ios/FeaturamaInsets.h +11 -0
  9. package/ios/FeaturamaInsets.mm +101 -0
  10. package/lib/commonjs/NativeFeaturamaInsets.js +9 -0
  11. package/lib/commonjs/NativeFeaturamaInsets.js.map +1 -0
  12. package/lib/commonjs/client.js +230 -0
  13. package/lib/commonjs/client.js.map +1 -0
  14. package/lib/commonjs/context/FeaturamaProvider.js +35 -0
  15. package/lib/commonjs/context/FeaturamaProvider.js.map +1 -0
  16. package/lib/commonjs/deviceInfo.js +66 -0
  17. package/lib/commonjs/deviceInfo.js.map +1 -0
  18. package/lib/commonjs/errors.js +102 -0
  19. package/lib/commonjs/errors.js.map +1 -0
  20. package/lib/commonjs/hooks/useFeaturama.js +40 -0
  21. package/lib/commonjs/hooks/useFeaturama.js.map +1 -0
  22. package/lib/commonjs/hooks/useRequests.js +110 -0
  23. package/lib/commonjs/hooks/useRequests.js.map +1 -0
  24. package/lib/commonjs/index.js +73 -0
  25. package/lib/commonjs/index.js.map +1 -0
  26. package/lib/commonjs/types/index.js +68 -0
  27. package/lib/commonjs/types/index.js.map +1 -0
  28. package/lib/commonjs/ui/FeatureRequestsScreen.js +239 -0
  29. package/lib/commonjs/ui/FeatureRequestsScreen.js.map +1 -0
  30. package/lib/commonjs/ui/components/AddCommentForm.js +84 -0
  31. package/lib/commonjs/ui/components/AddCommentForm.js.map +1 -0
  32. package/lib/commonjs/ui/components/Branding.js +62 -0
  33. package/lib/commonjs/ui/components/Branding.js.map +1 -0
  34. package/lib/commonjs/ui/components/CommentItem.js +124 -0
  35. package/lib/commonjs/ui/components/CommentItem.js.map +1 -0
  36. package/lib/commonjs/ui/components/CreateRequestForm.js +199 -0
  37. package/lib/commonjs/ui/components/CreateRequestForm.js.map +1 -0
  38. package/lib/commonjs/ui/components/Fab.js +46 -0
  39. package/lib/commonjs/ui/components/Fab.js.map +1 -0
  40. package/lib/commonjs/ui/components/FilterTabs.js +79 -0
  41. package/lib/commonjs/ui/components/FilterTabs.js.map +1 -0
  42. package/lib/commonjs/ui/components/Header.js +59 -0
  43. package/lib/commonjs/ui/components/Header.js.map +1 -0
  44. package/lib/commonjs/ui/components/RequestCard.js +156 -0
  45. package/lib/commonjs/ui/components/RequestCard.js.map +1 -0
  46. package/lib/commonjs/ui/components/RequestDetailView.js +259 -0
  47. package/lib/commonjs/ui/components/RequestDetailView.js.map +1 -0
  48. package/lib/commonjs/ui/components/RequestList.js +119 -0
  49. package/lib/commonjs/ui/components/RequestList.js.map +1 -0
  50. package/lib/commonjs/ui/icons/FeaturamaLogoIcon.js +43 -0
  51. package/lib/commonjs/ui/icons/FeaturamaLogoIcon.js.map +1 -0
  52. package/lib/commonjs/ui/icons/SvgIcon.js +32 -0
  53. package/lib/commonjs/ui/icons/SvgIcon.js.map +1 -0
  54. package/lib/commonjs/ui/icons/index.js +74 -0
  55. package/lib/commonjs/ui/icons/index.js.map +1 -0
  56. package/lib/commonjs/ui/icons/paths.js +21 -0
  57. package/lib/commonjs/ui/icons/paths.js.map +1 -0
  58. package/lib/commonjs/ui/strings/de.js +39 -0
  59. package/lib/commonjs/ui/strings/de.js.map +1 -0
  60. package/lib/commonjs/ui/strings/en.js +39 -0
  61. package/lib/commonjs/ui/strings/en.js.map +1 -0
  62. package/lib/commonjs/ui/strings/es.js +39 -0
  63. package/lib/commonjs/ui/strings/es.js.map +1 -0
  64. package/lib/commonjs/ui/strings/fr.js +39 -0
  65. package/lib/commonjs/ui/strings/fr.js.map +1 -0
  66. package/lib/commonjs/ui/strings/index.js +40 -0
  67. package/lib/commonjs/ui/strings/index.js.map +1 -0
  68. package/lib/commonjs/ui/strings/it.js +39 -0
  69. package/lib/commonjs/ui/strings/it.js.map +1 -0
  70. package/lib/commonjs/ui/strings/ja.js +39 -0
  71. package/lib/commonjs/ui/strings/ja.js.map +1 -0
  72. package/lib/commonjs/ui/strings/ko.js +39 -0
  73. package/lib/commonjs/ui/strings/ko.js.map +1 -0
  74. package/lib/commonjs/ui/strings/nl.js +39 -0
  75. package/lib/commonjs/ui/strings/nl.js.map +1 -0
  76. package/lib/commonjs/ui/strings/pl.js +39 -0
  77. package/lib/commonjs/ui/strings/pl.js.map +1 -0
  78. package/lib/commonjs/ui/strings/pt.js +39 -0
  79. package/lib/commonjs/ui/strings/pt.js.map +1 -0
  80. package/lib/commonjs/ui/strings/zh.js +39 -0
  81. package/lib/commonjs/ui/strings/zh.js.map +1 -0
  82. package/lib/commonjs/ui/theme/ThemeContext.js +17 -0
  83. package/lib/commonjs/ui/theme/ThemeContext.js.map +1 -0
  84. package/lib/commonjs/ui/theme/createTheme.js +92 -0
  85. package/lib/commonjs/ui/theme/createTheme.js.map +1 -0
  86. package/lib/commonjs/ui/theme/types.js +2 -0
  87. package/lib/commonjs/ui/theme/types.js.map +1 -0
  88. package/lib/commonjs/ui/types.js +6 -0
  89. package/lib/commonjs/ui/types.js.map +1 -0
  90. package/lib/commonjs/ui/utils/locale.js +67 -0
  91. package/lib/commonjs/ui/utils/locale.js.map +1 -0
  92. package/lib/commonjs/ui/utils/useAutoInsets.js +35 -0
  93. package/lib/commonjs/ui/utils/useAutoInsets.js.map +1 -0
  94. package/lib/commonjs/ui/utils/voterId.js +24 -0
  95. package/lib/commonjs/ui/utils/voterId.js.map +1 -0
  96. package/lib/module/NativeFeaturamaInsets.js +3 -0
  97. package/lib/module/NativeFeaturamaInsets.js.map +1 -0
  98. package/lib/module/client.js +223 -0
  99. package/lib/module/client.js.map +1 -0
  100. package/lib/module/context/FeaturamaProvider.js +28 -0
  101. package/lib/module/context/FeaturamaProvider.js.map +1 -0
  102. package/lib/module/deviceInfo.js +60 -0
  103. package/lib/module/deviceInfo.js.map +1 -0
  104. package/lib/module/errors.js +96 -0
  105. package/lib/module/errors.js.map +1 -0
  106. package/lib/module/hooks/useFeaturama.js +34 -0
  107. package/lib/module/hooks/useFeaturama.js.map +1 -0
  108. package/lib/module/hooks/useRequests.js +104 -0
  109. package/lib/module/hooks/useRequests.js.map +1 -0
  110. package/lib/module/index.js +17 -0
  111. package/lib/module/index.js.map +1 -0
  112. package/lib/module/types/index.js +77 -0
  113. package/lib/module/types/index.js.map +1 -0
  114. package/lib/module/ui/FeatureRequestsScreen.js +233 -0
  115. package/lib/module/ui/FeatureRequestsScreen.js.map +1 -0
  116. package/lib/module/ui/components/AddCommentForm.js +78 -0
  117. package/lib/module/ui/components/AddCommentForm.js.map +1 -0
  118. package/lib/module/ui/components/Branding.js +56 -0
  119. package/lib/module/ui/components/Branding.js.map +1 -0
  120. package/lib/module/ui/components/CommentItem.js +118 -0
  121. package/lib/module/ui/components/CommentItem.js.map +1 -0
  122. package/lib/module/ui/components/CreateRequestForm.js +193 -0
  123. package/lib/module/ui/components/CreateRequestForm.js.map +1 -0
  124. package/lib/module/ui/components/Fab.js +40 -0
  125. package/lib/module/ui/components/Fab.js.map +1 -0
  126. package/lib/module/ui/components/FilterTabs.js +73 -0
  127. package/lib/module/ui/components/FilterTabs.js.map +1 -0
  128. package/lib/module/ui/components/Header.js +53 -0
  129. package/lib/module/ui/components/Header.js.map +1 -0
  130. package/lib/module/ui/components/RequestCard.js +150 -0
  131. package/lib/module/ui/components/RequestCard.js.map +1 -0
  132. package/lib/module/ui/components/RequestDetailView.js +253 -0
  133. package/lib/module/ui/components/RequestDetailView.js.map +1 -0
  134. package/lib/module/ui/components/RequestList.js +113 -0
  135. package/lib/module/ui/components/RequestList.js.map +1 -0
  136. package/lib/module/ui/icons/FeaturamaLogoIcon.js +37 -0
  137. package/lib/module/ui/icons/FeaturamaLogoIcon.js.map +1 -0
  138. package/lib/module/ui/icons/SvgIcon.js +26 -0
  139. package/lib/module/ui/icons/SvgIcon.js.map +1 -0
  140. package/lib/module/ui/icons/index.js +63 -0
  141. package/lib/module/ui/icons/index.js.map +1 -0
  142. package/lib/module/ui/icons/paths.js +15 -0
  143. package/lib/module/ui/icons/paths.js.map +1 -0
  144. package/lib/module/ui/strings/de.js +33 -0
  145. package/lib/module/ui/strings/de.js.map +1 -0
  146. package/lib/module/ui/strings/en.js +33 -0
  147. package/lib/module/ui/strings/en.js.map +1 -0
  148. package/lib/module/ui/strings/es.js +33 -0
  149. package/lib/module/ui/strings/es.js.map +1 -0
  150. package/lib/module/ui/strings/fr.js +33 -0
  151. package/lib/module/ui/strings/fr.js.map +1 -0
  152. package/lib/module/ui/strings/index.js +29 -0
  153. package/lib/module/ui/strings/index.js.map +1 -0
  154. package/lib/module/ui/strings/it.js +33 -0
  155. package/lib/module/ui/strings/it.js.map +1 -0
  156. package/lib/module/ui/strings/ja.js +33 -0
  157. package/lib/module/ui/strings/ja.js.map +1 -0
  158. package/lib/module/ui/strings/ko.js +33 -0
  159. package/lib/module/ui/strings/ko.js.map +1 -0
  160. package/lib/module/ui/strings/nl.js +33 -0
  161. package/lib/module/ui/strings/nl.js.map +1 -0
  162. package/lib/module/ui/strings/pl.js +33 -0
  163. package/lib/module/ui/strings/pl.js.map +1 -0
  164. package/lib/module/ui/strings/pt.js +33 -0
  165. package/lib/module/ui/strings/pt.js.map +1 -0
  166. package/lib/module/ui/strings/zh.js +33 -0
  167. package/lib/module/ui/strings/zh.js.map +1 -0
  168. package/lib/module/ui/theme/ThemeContext.js +10 -0
  169. package/lib/module/ui/theme/ThemeContext.js.map +1 -0
  170. package/lib/module/ui/theme/createTheme.js +86 -0
  171. package/lib/module/ui/theme/createTheme.js.map +1 -0
  172. package/lib/module/ui/theme/types.js +2 -0
  173. package/lib/module/ui/theme/types.js.map +1 -0
  174. package/lib/module/ui/types.js +2 -0
  175. package/lib/module/ui/types.js.map +1 -0
  176. package/lib/module/ui/utils/locale.js +61 -0
  177. package/lib/module/ui/utils/locale.js.map +1 -0
  178. package/lib/module/ui/utils/useAutoInsets.js +28 -0
  179. package/lib/module/ui/utils/useAutoInsets.js.map +1 -0
  180. package/lib/module/ui/utils/voterId.js +18 -0
  181. package/lib/module/ui/utils/voterId.js.map +1 -0
  182. package/lib/typescript/NativeFeaturamaInsets.d.ts +16 -0
  183. package/lib/typescript/NativeFeaturamaInsets.d.ts.map +1 -0
  184. package/lib/typescript/client.d.ts +70 -0
  185. package/lib/typescript/client.d.ts.map +1 -0
  186. package/lib/typescript/context/FeaturamaProvider.d.ts +27 -0
  187. package/lib/typescript/context/FeaturamaProvider.d.ts.map +1 -0
  188. package/lib/typescript/deviceInfo.d.ts +7 -0
  189. package/lib/typescript/deviceInfo.d.ts.map +1 -0
  190. package/lib/typescript/errors.d.ts +40 -0
  191. package/lib/typescript/errors.d.ts.map +1 -0
  192. package/lib/typescript/hooks/useFeaturama.d.ts +27 -0
  193. package/lib/typescript/hooks/useFeaturama.d.ts.map +1 -0
  194. package/lib/typescript/hooks/useRequests.d.ts +30 -0
  195. package/lib/typescript/hooks/useRequests.d.ts.map +1 -0
  196. package/lib/typescript/index.d.ts +12 -0
  197. package/lib/typescript/index.d.ts.map +1 -0
  198. package/lib/typescript/types/index.d.ts +161 -0
  199. package/lib/typescript/types/index.d.ts.map +1 -0
  200. package/lib/typescript/ui/FeatureRequestsScreen.d.ts +4 -0
  201. package/lib/typescript/ui/FeatureRequestsScreen.d.ts.map +1 -0
  202. package/lib/typescript/ui/components/AddCommentForm.d.ts +11 -0
  203. package/lib/typescript/ui/components/AddCommentForm.d.ts.map +1 -0
  204. package/lib/typescript/ui/components/Branding.d.ts +7 -0
  205. package/lib/typescript/ui/components/Branding.d.ts.map +1 -0
  206. package/lib/typescript/ui/components/CommentItem.d.ts +12 -0
  207. package/lib/typescript/ui/components/CommentItem.d.ts.map +1 -0
  208. package/lib/typescript/ui/components/CreateRequestForm.d.ts +14 -0
  209. package/lib/typescript/ui/components/CreateRequestForm.d.ts.map +1 -0
  210. package/lib/typescript/ui/components/Fab.d.ts +8 -0
  211. package/lib/typescript/ui/components/Fab.d.ts.map +1 -0
  212. package/lib/typescript/ui/components/FilterTabs.d.ts +11 -0
  213. package/lib/typescript/ui/components/FilterTabs.d.ts.map +1 -0
  214. package/lib/typescript/ui/components/Header.d.ts +10 -0
  215. package/lib/typescript/ui/components/Header.d.ts.map +1 -0
  216. package/lib/typescript/ui/components/RequestCard.d.ts +13 -0
  217. package/lib/typescript/ui/components/RequestCard.d.ts.map +1 -0
  218. package/lib/typescript/ui/components/RequestDetailView.d.ts +22 -0
  219. package/lib/typescript/ui/components/RequestDetailView.d.ts.map +1 -0
  220. package/lib/typescript/ui/components/RequestList.d.ts +17 -0
  221. package/lib/typescript/ui/components/RequestList.d.ts.map +1 -0
  222. package/lib/typescript/ui/icons/FeaturamaLogoIcon.d.ts +8 -0
  223. package/lib/typescript/ui/icons/FeaturamaLogoIcon.d.ts.map +1 -0
  224. package/lib/typescript/ui/icons/SvgIcon.d.ts +10 -0
  225. package/lib/typescript/ui/icons/SvgIcon.d.ts.map +1 -0
  226. package/lib/typescript/ui/icons/index.d.ts +13 -0
  227. package/lib/typescript/ui/icons/index.d.ts.map +1 -0
  228. package/lib/typescript/ui/icons/paths.d.ts +15 -0
  229. package/lib/typescript/ui/icons/paths.d.ts.map +1 -0
  230. package/lib/typescript/ui/strings/de.d.ts +3 -0
  231. package/lib/typescript/ui/strings/de.d.ts.map +1 -0
  232. package/lib/typescript/ui/strings/en.d.ts +34 -0
  233. package/lib/typescript/ui/strings/en.d.ts.map +1 -0
  234. package/lib/typescript/ui/strings/es.d.ts +3 -0
  235. package/lib/typescript/ui/strings/es.d.ts.map +1 -0
  236. package/lib/typescript/ui/strings/fr.d.ts +3 -0
  237. package/lib/typescript/ui/strings/fr.d.ts.map +1 -0
  238. package/lib/typescript/ui/strings/index.d.ts +7 -0
  239. package/lib/typescript/ui/strings/index.d.ts.map +1 -0
  240. package/lib/typescript/ui/strings/it.d.ts +3 -0
  241. package/lib/typescript/ui/strings/it.d.ts.map +1 -0
  242. package/lib/typescript/ui/strings/ja.d.ts +3 -0
  243. package/lib/typescript/ui/strings/ja.d.ts.map +1 -0
  244. package/lib/typescript/ui/strings/ko.d.ts +3 -0
  245. package/lib/typescript/ui/strings/ko.d.ts.map +1 -0
  246. package/lib/typescript/ui/strings/nl.d.ts +3 -0
  247. package/lib/typescript/ui/strings/nl.d.ts.map +1 -0
  248. package/lib/typescript/ui/strings/pl.d.ts +3 -0
  249. package/lib/typescript/ui/strings/pl.d.ts.map +1 -0
  250. package/lib/typescript/ui/strings/pt.d.ts +3 -0
  251. package/lib/typescript/ui/strings/pt.d.ts.map +1 -0
  252. package/lib/typescript/ui/strings/zh.d.ts +3 -0
  253. package/lib/typescript/ui/strings/zh.d.ts.map +1 -0
  254. package/lib/typescript/ui/theme/ThemeContext.d.ts +4 -0
  255. package/lib/typescript/ui/theme/ThemeContext.d.ts.map +1 -0
  256. package/lib/typescript/ui/theme/createTheme.d.ts +3 -0
  257. package/lib/typescript/ui/theme/createTheme.d.ts.map +1 -0
  258. package/lib/typescript/ui/theme/types.d.ts +17 -0
  259. package/lib/typescript/ui/theme/types.d.ts.map +1 -0
  260. package/lib/typescript/ui/types.d.ts +24 -0
  261. package/lib/typescript/ui/types.d.ts.map +1 -0
  262. package/lib/typescript/ui/utils/locale.d.ts +10 -0
  263. package/lib/typescript/ui/utils/locale.d.ts.map +1 -0
  264. package/lib/typescript/ui/utils/useAutoInsets.d.ts +5 -0
  265. package/lib/typescript/ui/utils/useAutoInsets.d.ts.map +1 -0
  266. package/lib/typescript/ui/utils/voterId.d.ts +2 -0
  267. package/lib/typescript/ui/utils/voterId.d.ts.map +1 -0
  268. package/package.json +56 -0
  269. package/react-native.config.js +8 -0
  270. package/src/NativeFeaturamaInsets.ts +19 -0
  271. package/src/client.ts +292 -0
  272. package/src/context/FeaturamaProvider.tsx +52 -0
  273. package/src/deviceInfo.ts +69 -0
  274. package/src/errors.ts +117 -0
  275. package/src/hooks/useFeaturama.ts +40 -0
  276. package/src/hooks/useRequests.ts +115 -0
  277. package/src/index.ts +41 -0
  278. package/src/types/index.ts +175 -0
  279. package/src/ui/FeatureRequestsScreen.tsx +264 -0
  280. package/src/ui/components/AddCommentForm.tsx +78 -0
  281. package/src/ui/components/Branding.tsx +53 -0
  282. package/src/ui/components/CommentItem.tsx +114 -0
  283. package/src/ui/components/CreateRequestForm.tsx +227 -0
  284. package/src/ui/components/Fab.tsx +40 -0
  285. package/src/ui/components/FilterTabs.tsx +78 -0
  286. package/src/ui/components/Header.tsx +52 -0
  287. package/src/ui/components/RequestCard.tsx +146 -0
  288. package/src/ui/components/RequestDetailView.tsx +260 -0
  289. package/src/ui/components/RequestList.tsx +116 -0
  290. package/src/ui/icons/FeaturamaLogoIcon.tsx +38 -0
  291. package/src/ui/icons/SvgIcon.tsx +31 -0
  292. package/src/ui/icons/index.tsx +34 -0
  293. package/src/ui/icons/paths.ts +32 -0
  294. package/src/ui/strings/de.ts +34 -0
  295. package/src/ui/strings/en.ts +65 -0
  296. package/src/ui/strings/es.ts +34 -0
  297. package/src/ui/strings/fr.ts +34 -0
  298. package/src/ui/strings/index.ts +34 -0
  299. package/src/ui/strings/it.ts +34 -0
  300. package/src/ui/strings/ja.ts +34 -0
  301. package/src/ui/strings/ko.ts +34 -0
  302. package/src/ui/strings/nl.ts +34 -0
  303. package/src/ui/strings/pl.ts +34 -0
  304. package/src/ui/strings/pt.ts +34 -0
  305. package/src/ui/strings/zh.ts +34 -0
  306. package/src/ui/theme/ThemeContext.tsx +12 -0
  307. package/src/ui/theme/createTheme.ts +115 -0
  308. package/src/ui/theme/types.ts +27 -0
  309. package/src/ui/types.ts +24 -0
  310. package/src/ui/utils/locale.ts +68 -0
  311. package/src/ui/utils/useAutoInsets.ts +28 -0
  312. package/src/ui/utils/voterId.ts +20 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VibeLabs
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,45 @@
1
+ # @vibelabsdotto/featurama-rn-expo
2
+
3
+ Featurama feature-request UI and client for React Native and Expo. One SDK for Expo Go, development builds, and native React Native apps. The optional native safe-area module is not required in Expo Go; pass `safeAreaTop`/`safeAreaBottom` when embedding the screen in a modal.
4
+
5
+ ## Install
6
+
7
+ ```sh
8
+ npm install @vibelabsdotto/featurama-rn-expo @react-native-async-storage/async-storage react-native-svg
9
+ ```
10
+
11
+ For Expo apps also install the compatible optional localization module with `npx expo install expo-localization`. Provide your **project API key** (`fm_live_…`), not a developer PAT (`fm_dev_…`). Project keys are intended for client apps and are restricted to a project; do not treat them as admin credentials.
12
+
13
+ ```tsx
14
+ import { FeaturamaProvider, FeatureRequestsScreen } from '@vibelabsdotto/featurama-rn-expo';
15
+
16
+ export function Requests() {
17
+ return (
18
+ <FeaturamaProvider config={{ apiKey: 'fm_live_…' }}>
19
+ <FeatureRequestsScreen />
20
+ </FeaturamaProvider>
21
+ );
22
+ }
23
+ ```
24
+
25
+ The SDK defaults to `https://api.featurama.app`. For the new Preview, set `baseUrl: 'https://newapi.featurama.app'` and use a project key created **in that Preview**. The two instances do not share projects or API keys.
26
+
27
+ ## Local example
28
+
29
+ `example/` is an Expo SDK 54 app linked to the package source. Copy `example/.env.example` to `example/.env.local`, insert a Preview project API key, then:
30
+
31
+ ```sh
32
+ npm ci
33
+ cd example
34
+ npm ci
35
+ npm run typecheck
36
+ npm run ios
37
+ ```
38
+
39
+ Run `npm run typecheck` and `npm run prepare` in the package root to verify the library and build distributable JS/types. Do not commit `example/.env.local` or real keys.
40
+
41
+ ## API
42
+
43
+ `FeaturamaClient` exposes `getConfig`, `getRequests`, `createRequest`, `updateRequest`, `toggleVote`, `getComments`, `addComment`, and comment-voting methods. The bundled `FeatureRequestsScreen` provides the end-user UI. Consult `src/types/index.ts` for input/output types.
44
+
45
+ MIT © VibeLabs.
@@ -0,0 +1,26 @@
1
+ apply plugin: 'com.android.library'
2
+ apply plugin: 'org.jetbrains.kotlin.android'
3
+ apply plugin: 'com.facebook.react'
4
+
5
+ def safeExtGet(prop, fallback) {
6
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
7
+ }
8
+
9
+ android {
10
+ compileSdkVersion safeExtGet('compileSdkVersion', 34)
11
+ namespace "com.featurama.reactnative"
12
+
13
+ defaultConfig {
14
+ minSdkVersion safeExtGet('minSdkVersion', 21)
15
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
16
+ }
17
+
18
+ buildFeatures {
19
+ buildConfig true
20
+ }
21
+ }
22
+
23
+ dependencies {
24
+ implementation "com.facebook.react:react-android"
25
+ implementation "androidx.core:core-ktx:1.12.0"
26
+ }
@@ -0,0 +1,3 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
2
+ package="com.featurama.reactnative">
3
+ </manifest>
@@ -0,0 +1,58 @@
1
+ package com.featurama.reactnative
2
+
3
+ import androidx.core.view.ViewCompat
4
+ import androidx.core.view.WindowInsetsCompat
5
+ import com.facebook.react.bridge.Arguments
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.bridge.WritableMap
8
+ import com.facebook.react.module.annotations.ReactModule
9
+
10
+ @ReactModule(name = FeaturamaInsetsModule.NAME)
11
+ class FeaturamaInsetsModule(
12
+ reactContext: ReactApplicationContext
13
+ ) : NativeFeaturamaInsetsSpec(reactContext) {
14
+
15
+ companion object {
16
+ const val NAME = "FeaturamaInsets"
17
+ }
18
+
19
+ override fun getName(): String = NAME
20
+
21
+ override fun getSafeAreaInsets(): WritableMap {
22
+ val result = Arguments.createMap()
23
+ val activity = currentActivity
24
+ if (activity == null) {
25
+ result.putDouble("top", 0.0)
26
+ result.putDouble("right", 0.0)
27
+ result.putDouble("bottom", 0.0)
28
+ result.putDouble("left", 0.0)
29
+ return result
30
+ }
31
+
32
+ val rootView = activity.window.decorView
33
+ val windowInsets = ViewCompat.getRootWindowInsets(rootView)
34
+ val density = reactApplicationContext.resources.displayMetrics.density
35
+
36
+ if (windowInsets != null) {
37
+ val insets = windowInsets.getInsets(
38
+ WindowInsetsCompat.Type.systemBars()
39
+ or WindowInsetsCompat.Type.displayCutout()
40
+ )
41
+ result.putDouble("top", (insets.top / density).toDouble())
42
+ result.putDouble("right", (insets.right / density).toDouble())
43
+ result.putDouble("bottom", (insets.bottom / density).toDouble())
44
+ result.putDouble("left", (insets.left / density).toDouble())
45
+ } else {
46
+ result.putDouble("top", 0.0)
47
+ result.putDouble("right", 0.0)
48
+ result.putDouble("bottom", 0.0)
49
+ result.putDouble("left", 0.0)
50
+ }
51
+ return result
52
+ }
53
+
54
+ override fun getTypedExportedConstants(): Map<String, Any> {
55
+ val insets = getSafeAreaInsets()
56
+ return mapOf("initialInsets" to insets.toHashMap())
57
+ }
58
+ }
@@ -0,0 +1,28 @@
1
+ package com.featurama.reactnative
2
+
3
+ import com.facebook.react.BaseReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+
9
+ class FeaturamaInsetsPackage : BaseReactPackage() {
10
+ override fun getModule(
11
+ name: String,
12
+ reactContext: ReactApplicationContext
13
+ ): NativeModule? =
14
+ if (name == FeaturamaInsetsModule.NAME) FeaturamaInsetsModule(reactContext) else null
15
+
16
+ override fun getReactModuleInfoProvider() = ReactModuleInfoProvider {
17
+ mapOf(
18
+ FeaturamaInsetsModule.NAME to ReactModuleInfo(
19
+ name = FeaturamaInsetsModule.NAME,
20
+ className = FeaturamaInsetsModule.NAME,
21
+ canOverrideExistingModule = false,
22
+ needsEagerInit = false,
23
+ isCxxModule = false,
24
+ isTurboModule = true
25
+ )
26
+ )
27
+ }
28
+ }
@@ -0,0 +1,23 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "featurama-rn-expo"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+ s.source = { :git => package["repository"]["url"], :tag => "v#{s.version}" }
13
+
14
+ s.ios.deployment_target = "13.4"
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,cpp}"
17
+
18
+ if respond_to?(:install_modules_dependencies, true)
19
+ install_modules_dependencies(s)
20
+ else
21
+ s.dependency "React-Core"
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ #ifdef RCT_NEW_ARCH_ENABLED
2
+ #import <FeaturamaInsetsSpec/FeaturamaInsetsSpec.h>
3
+
4
+ @interface FeaturamaInsets : NSObject <NativeFeaturamaInsetsSpec>
5
+ #else
6
+ #import <React/RCTBridgeModule.h>
7
+
8
+ @interface FeaturamaInsets : NSObject <RCTBridgeModule>
9
+ #endif
10
+
11
+ @end
@@ -0,0 +1,101 @@
1
+ #import "FeaturamaInsets.h"
2
+
3
+ #if TARGET_OS_IPHONE
4
+ #import <UIKit/UIKit.h>
5
+ #endif
6
+
7
+ #ifdef RCT_NEW_ARCH_ENABLED
8
+ #import <FeaturamaInsetsSpec/FeaturamaInsetsSpec.h>
9
+ #endif
10
+
11
+ @implementation FeaturamaInsets {
12
+ NSDictionary *_cachedInsets;
13
+ }
14
+
15
+ RCT_EXPORT_MODULE(FeaturamaInsets)
16
+
17
+ + (BOOL)requiresMainQueueSetup
18
+ {
19
+ return YES;
20
+ }
21
+
22
+ - (instancetype)init
23
+ {
24
+ self = [super init];
25
+ if (self) {
26
+ _cachedInsets = [self readSafeAreaInsets];
27
+ }
28
+ return self;
29
+ }
30
+
31
+ #pragma mark - Window Helpers
32
+
33
+ + (UIWindow *)keyWindow
34
+ {
35
+ #if TARGET_OS_IPHONE
36
+ if (@available(iOS 15.0, *)) {
37
+ for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
38
+ if ([scene isKindOfClass:[UIWindowScene class]]) {
39
+ UIWindow *kw = ((UIWindowScene *)scene).keyWindow;
40
+ if (kw) return kw;
41
+ }
42
+ }
43
+ }
44
+
45
+ for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) {
46
+ if (scene.activationState == UISceneActivationStateForegroundActive &&
47
+ [scene isKindOfClass:[UIWindowScene class]]) {
48
+ for (UIWindow *w in ((UIWindowScene *)scene).windows) {
49
+ if (w.isKeyWindow) return w;
50
+ }
51
+ }
52
+ }
53
+ #endif
54
+ return nil;
55
+ }
56
+
57
+ #pragma mark - Inset Reading
58
+
59
+ - (NSDictionary *)readSafeAreaInsets
60
+ {
61
+ #if TARGET_OS_IPHONE
62
+ UIWindow *window = [FeaturamaInsets keyWindow];
63
+ if (!window) {
64
+ return @{@"top": @(0), @"right": @(0), @"bottom": @(0), @"left": @(0)};
65
+ }
66
+
67
+ UIEdgeInsets insets = window.safeAreaInsets;
68
+ return @{
69
+ @"top": @(insets.top),
70
+ @"right": @(insets.right),
71
+ @"bottom": @(insets.bottom),
72
+ @"left": @(insets.left),
73
+ };
74
+ #else
75
+ return @{@"top": @(0), @"right": @(0), @"bottom": @(0), @"left": @(0)};
76
+ #endif
77
+ }
78
+
79
+ #pragma mark - TurboModule Methods
80
+
81
+ RCT_EXPORT_SYNCHRONOUS_TYPED_METHOD(NSDictionary *, getSafeAreaInsets)
82
+ {
83
+ // Runs on JS thread — return cached values (populated on main thread during init)
84
+ return _cachedInsets ?: @{@"top": @(0), @"right": @(0), @"bottom": @(0), @"left": @(0)};
85
+ }
86
+
87
+ - (NSDictionary *)getConstants
88
+ {
89
+ // Runs on main thread (requiresMainQueueSetup = YES) during module init
90
+ return @{@"initialInsets": _cachedInsets ?: @{@"top": @(0), @"right": @(0), @"bottom": @(0), @"left": @(0)}};
91
+ }
92
+
93
+ #ifdef RCT_NEW_ARCH_ENABLED
94
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
95
+ (const facebook::react::ObjCTurboModule::InitParams &)params
96
+ {
97
+ return std::make_shared<facebook::react::NativeFeaturamaInsetsSpecJSI>(params);
98
+ }
99
+ #endif
100
+
101
+ @end
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _reactNative = require("react-native");
8
+ var _default = exports.default = _reactNative.TurboModuleRegistry.get('FeaturamaInsets');
9
+ //# sourceMappingURL=NativeFeaturamaInsets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","_default","exports","default","TurboModuleRegistry","get"],"sourceRoot":"../../src","sources":["NativeFeaturamaInsets.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAAmD,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAiBpCC,gCAAmB,CAACC,GAAG,CAAO,iBAAiB,CAAC","ignoreList":[]}
@@ -0,0 +1,230 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FeaturamaClient = void 0;
7
+ var _errors = require("./errors");
8
+ var _deviceInfo = require("./deviceInfo");
9
+ const DEFAULT_BASE_URL = 'https://api.featurama.app';
10
+ const DEFAULT_TIMEOUT = 10000;
11
+ const API_KEY_PREFIX = 'fm_live_';
12
+
13
+ /**
14
+ * Featurama API client for interacting with the public SDK endpoints
15
+ */
16
+ class FeaturamaClient {
17
+ constructor(config) {
18
+ if (!config.apiKey || !config.apiKey.startsWith(API_KEY_PREFIX)) {
19
+ throw _errors.FeaturamaError.invalidApiKey();
20
+ }
21
+ this.apiKey = config.apiKey;
22
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL;
23
+ this.timeout = config.timeout || DEFAULT_TIMEOUT;
24
+ this.appVersion = config.appVersion;
25
+ this.appBuild = config.appBuild;
26
+ }
27
+
28
+ /**
29
+ * Make an authenticated request to the API
30
+ */
31
+ async request(method, path, body) {
32
+ const url = `${this.baseUrl}${path}`;
33
+ const controller = new AbortController();
34
+ const timeoutId = setTimeout(() => controller.abort(), this.timeout);
35
+ try {
36
+ const response = await fetch(url, {
37
+ method,
38
+ headers: {
39
+ 'Content-Type': 'application/json',
40
+ 'X-Api-Key': this.apiKey
41
+ },
42
+ body: body ? JSON.stringify(body) : undefined,
43
+ signal: controller.signal
44
+ });
45
+ clearTimeout(timeoutId);
46
+ if (!response.ok) {
47
+ throw await _errors.FeaturamaError.fromResponse(response);
48
+ }
49
+ return await response.json();
50
+ } catch (error) {
51
+ clearTimeout(timeoutId);
52
+ if (error instanceof _errors.FeaturamaError) {
53
+ throw error;
54
+ }
55
+ if (error instanceof Error) {
56
+ if (error.name === 'AbortError') {
57
+ throw _errors.FeaturamaError.timeout(this.timeout);
58
+ }
59
+ throw _errors.FeaturamaError.networkError(error);
60
+ }
61
+ throw _errors.FeaturamaError.networkError();
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Get project configuration (status labels, branding settings)
67
+ */
68
+ async getConfig() {
69
+ return this.request('GET', '/api/public/config');
70
+ }
71
+
72
+ /**
73
+ * Get paginated list of feature requests
74
+ */
75
+ async getRequests(options = {}) {
76
+ const {
77
+ page = 1,
78
+ pageSize = 20,
79
+ filter,
80
+ submitterIdentifier
81
+ } = options;
82
+ const queryParams = new URLSearchParams({
83
+ page: page.toString(),
84
+ pageSize: pageSize.toString()
85
+ });
86
+ if (filter) {
87
+ queryParams.set('filter', filter);
88
+ }
89
+ if (submitterIdentifier) {
90
+ queryParams.set('submitterIdentifier', submitterIdentifier);
91
+ }
92
+ return this.request('GET', `/api/public/requests?${queryParams}`);
93
+ }
94
+
95
+ /**
96
+ * Create a new feature request
97
+ */
98
+ async createRequest(input) {
99
+ const deviceInfo = (0, _deviceInfo.collectDeviceInfo)();
100
+ if (this.appVersion) deviceInfo.appVersion = this.appVersion;
101
+ if (this.appBuild) deviceInfo.appBuild = this.appBuild;
102
+ return this.request('POST', '/api/public/requests', {
103
+ title: input.title,
104
+ description: input.description,
105
+ submitterIdentifier: input.submitterIdentifier,
106
+ ...(input.email ? {
107
+ email: input.email
108
+ } : {}),
109
+ deviceInfo
110
+ });
111
+ }
112
+
113
+ /**
114
+ * Update an existing feature request (only allowed by the original submitter)
115
+ */
116
+ async updateRequest(id, input, submitterIdentifier) {
117
+ const queryParams = new URLSearchParams({
118
+ submitterIdentifier
119
+ });
120
+ return this.request('PUT', `/api/public/requests/${id}?${queryParams}`, {
121
+ title: input.title,
122
+ description: input.description
123
+ });
124
+ }
125
+
126
+ /**
127
+ * Vote for a feature request
128
+ */
129
+ async vote(requestId, voterIdentifier) {
130
+ return this.request('POST', `/api/public/requests/${requestId}/vote`, {
131
+ voterIdentifier
132
+ });
133
+ }
134
+
135
+ /**
136
+ * Remove vote from a feature request
137
+ */
138
+ async removeVote(requestId, voterIdentifier) {
139
+ return this.request('DELETE', `/api/public/requests/${requestId}/vote`, {
140
+ voterIdentifier
141
+ });
142
+ }
143
+
144
+ /**
145
+ * Toggle vote on a feature request
146
+ * If already voted, removes the vote. If not voted, adds a vote.
147
+ * Returns the updated request and whether the user is now voting.
148
+ */
149
+ async toggleVote(requestId, voterIdentifier) {
150
+ try {
151
+ const request = await this.vote(requestId, voterIdentifier);
152
+ return {
153
+ request,
154
+ isVoting: true
155
+ };
156
+ } catch (error) {
157
+ if (error instanceof _errors.FeaturamaError && error.code === 'CONFLICT') {
158
+ // Already voted, so remove the vote
159
+ const request = await this.removeVote(requestId, voterIdentifier);
160
+ return {
161
+ request,
162
+ isVoting: false
163
+ };
164
+ }
165
+ throw error;
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Get comments for a feature request
171
+ */
172
+ async getComments(requestId) {
173
+ return this.request('GET', `/api/public/requests/${requestId}/comments`);
174
+ }
175
+
176
+ /**
177
+ * Add a comment to a feature request
178
+ */
179
+ async addComment(requestId, input) {
180
+ return this.request('POST', `/api/public/requests/${requestId}/comments`, {
181
+ content: input.content,
182
+ authorIdentifier: input.authorIdentifier,
183
+ ...(input.authorName ? {
184
+ authorName: input.authorName
185
+ } : {})
186
+ });
187
+ }
188
+
189
+ /**
190
+ * Vote on a comment
191
+ */
192
+ async voteComment(requestId, commentId, voterIdentifier) {
193
+ return this.request('POST', `/api/public/requests/${requestId}/comments/${commentId}/vote`, {
194
+ voterIdentifier
195
+ });
196
+ }
197
+
198
+ /**
199
+ * Remove vote from a comment
200
+ */
201
+ async removeCommentVote(requestId, commentId, voterIdentifier) {
202
+ return this.request('DELETE', `/api/public/requests/${requestId}/comments/${commentId}/vote`, {
203
+ voterIdentifier
204
+ });
205
+ }
206
+
207
+ /**
208
+ * Toggle vote on a comment
209
+ */
210
+ async toggleCommentVote(requestId, commentId, voterIdentifier) {
211
+ try {
212
+ const comment = await this.voteComment(requestId, commentId, voterIdentifier);
213
+ return {
214
+ comment,
215
+ isVoting: true
216
+ };
217
+ } catch (error) {
218
+ if (error instanceof _errors.FeaturamaError && error.code === 'CONFLICT') {
219
+ const comment = await this.removeCommentVote(requestId, commentId, voterIdentifier);
220
+ return {
221
+ comment,
222
+ isVoting: false
223
+ };
224
+ }
225
+ throw error;
226
+ }
227
+ }
228
+ }
229
+ exports.FeaturamaClient = FeaturamaClient;
230
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_errors","require","_deviceInfo","DEFAULT_BASE_URL","DEFAULT_TIMEOUT","API_KEY_PREFIX","FeaturamaClient","constructor","config","apiKey","startsWith","FeaturamaError","invalidApiKey","baseUrl","timeout","appVersion","appBuild","request","method","path","body","url","controller","AbortController","timeoutId","setTimeout","abort","response","fetch","headers","JSON","stringify","undefined","signal","clearTimeout","ok","fromResponse","json","error","Error","name","networkError","getConfig","getRequests","options","page","pageSize","filter","submitterIdentifier","queryParams","URLSearchParams","toString","set","createRequest","input","deviceInfo","collectDeviceInfo","title","description","email","updateRequest","id","vote","requestId","voterIdentifier","removeVote","toggleVote","isVoting","code","getComments","addComment","content","authorIdentifier","authorName","voteComment","commentId","removeCommentVote","toggleCommentVote","comment","exports"],"sourceRoot":"../../src","sources":["client.ts"],"mappings":"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","ignoreList":[]}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.FeaturamaContext = void 0;
7
+ exports.FeaturamaProvider = FeaturamaProvider;
8
+ var _react = require("react");
9
+ var _client = require("../client");
10
+ const FeaturamaContext = exports.FeaturamaContext = /*#__PURE__*/(0, _react.createContext)(null);
11
+ /**
12
+ * Provider component that initializes the Featurama client and makes it available
13
+ * to all child components via React context.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <FeaturamaProvider config={{ apiKey: 'fm_live_...' }}>
18
+ * <App />
19
+ * </FeaturamaProvider>
20
+ * ```
21
+ */
22
+ function FeaturamaProvider({
23
+ config,
24
+ children
25
+ }) {
26
+ const client = (0, _react.useMemo)(() => new _client.FeaturamaClient(config), [config.apiKey, config.baseUrl, config.timeout, config.appVersion, config.appBuild]);
27
+ const value = (0, _react.useMemo)(() => ({
28
+ client,
29
+ isInitialized: true
30
+ }), [client]);
31
+ return /*#__PURE__*/React.createElement(FeaturamaContext.Provider, {
32
+ value: value
33
+ }, children);
34
+ }
35
+ //# sourceMappingURL=FeaturamaProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_client","FeaturamaContext","exports","createContext","FeaturamaProvider","config","children","client","useMemo","FeaturamaClient","apiKey","baseUrl","timeout","appVersion","appBuild","value","isInitialized","React","createElement","Provider"],"sourceRoot":"../../../src","sources":["context/FeaturamaProvider.tsx"],"mappings":";;;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,OAAA,GAAAD,OAAA;AAGO,MAAME,gBAAgB,GAAAC,OAAA,CAAAD,gBAAA,gBAAG,IAAAE,oBAAa,EAA+B,IAAI,CAAC;AAajF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,iBAAiBA,CAAC;EAChCC,MAAM;EACNC;AACsB,CAAC,EAAe;EACtC,MAAMC,MAAM,GAAG,IAAAC,cAAO,EACpB,MAAM,IAAIC,uBAAe,CAACJ,MAAM,CAAC,EACjC,CAACA,MAAM,CAACK,MAAM,EAAEL,MAAM,CAACM,OAAO,EAAEN,MAAM,CAACO,OAAO,EAAEP,MAAM,CAACQ,UAAU,EAAER,MAAM,CAACS,QAAQ,CACpF,CAAC;EAED,MAAMC,KAAK,GAAG,IAAAP,cAAO,EACnB,OAAO;IACLD,MAAM;IACNS,aAAa,EAAE;EACjB,CAAC,CAAC,EACF,CAACT,MAAM,CACT,CAAC;EAED,oBACEU,KAAA,CAAAC,aAAA,CAACjB,gBAAgB,CAACkB,QAAQ;IAACJ,KAAK,EAAEA;EAAM,GACrCT,QACwB,CAAC;AAEhC","ignoreList":[]}