react-native-unistyles 2.0.0-alpha.9 → 2.0.0-beta.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (228) hide show
  1. package/android/CMakeLists.txt +28 -0
  2. package/android/build.gradle +40 -0
  3. package/android/src/main/cxx/cpp-adapter.cpp +108 -0
  4. package/android/src/main/java/com/unistyles/UnistylesModule.kt +159 -0
  5. package/android/src/main/java/com/unistyles/UnistylesPackage.kt +18 -0
  6. package/cxx/UnistylesRuntime.cpp +55 -2
  7. package/cxx/UnistylesRuntime.h +15 -9
  8. package/ios/UnistylesModule.mm +16 -6
  9. package/lib/commonjs/common.js +30 -16
  10. package/lib/commonjs/common.js.map +1 -1
  11. package/lib/commonjs/core/UnistyleRegistry.js +65 -3
  12. package/lib/commonjs/core/UnistyleRegistry.js.map +1 -1
  13. package/lib/commonjs/core/Unistyles.js +1 -1
  14. package/lib/commonjs/core/Unistyles.js.map +1 -1
  15. package/lib/commonjs/core/UnistylesModule.web.js +187 -0
  16. package/lib/commonjs/core/UnistylesModule.web.js.map +1 -0
  17. package/lib/commonjs/core/UnistylesRuntime.js +15 -16
  18. package/lib/commonjs/core/UnistylesRuntime.js.map +1 -1
  19. package/lib/commonjs/createStyleSheet.js +1 -6
  20. package/lib/commonjs/createStyleSheet.js.map +1 -1
  21. package/lib/commonjs/hooks/index.js +7 -0
  22. package/lib/commonjs/hooks/index.js.map +1 -1
  23. package/lib/commonjs/hooks/useUnistyles.js +12 -9
  24. package/lib/commonjs/hooks/useUnistyles.js.map +1 -1
  25. package/lib/commonjs/hooks/useVariants.js +14 -0
  26. package/lib/commonjs/hooks/useVariants.js.map +1 -0
  27. package/lib/commonjs/index.js.map +1 -1
  28. package/lib/commonjs/plugins/index.js +38 -0
  29. package/lib/commonjs/plugins/index.js.map +1 -0
  30. package/lib/commonjs/plugins/normalizeWebStylesPlugin.js +12 -0
  31. package/lib/commonjs/plugins/normalizeWebStylesPlugin.js.map +1 -0
  32. package/lib/commonjs/plugins/normalizer/index.js +32 -0
  33. package/lib/commonjs/plugins/normalizer/index.js.map +1 -0
  34. package/lib/commonjs/plugins/normalizer/module.d.js.map +1 -0
  35. package/lib/commonjs/{utils/normalizeStyles.web.js → plugins/normalizer/normalizeStyle.js} +5 -5
  36. package/lib/commonjs/plugins/normalizer/normalizeStyle.js.map +1 -0
  37. package/lib/commonjs/{utils → plugins/normalizer}/normalizer.js +1 -1
  38. package/lib/commonjs/plugins/normalizer/normalizer.js.map +1 -0
  39. package/lib/commonjs/types/{mq.js → plugin.js} +1 -1
  40. package/lib/commonjs/types/{mq.js.map → plugin.js.map} +1 -1
  41. package/lib/commonjs/types/stylesheet.js +6 -0
  42. package/lib/commonjs/types/stylesheet.js.map +1 -0
  43. package/lib/commonjs/types/variants.js +2 -0
  44. package/lib/commonjs/{utils/module.d.js.map → types/variants.js.map} +1 -1
  45. package/lib/commonjs/useStyles.js +10 -20
  46. package/lib/commonjs/useStyles.js.map +1 -1
  47. package/lib/commonjs/utils/breakpoints.js +13 -59
  48. package/lib/commonjs/utils/breakpoints.js.map +1 -1
  49. package/lib/commonjs/utils/index.js +13 -51
  50. package/lib/commonjs/utils/index.js.map +1 -1
  51. package/lib/commonjs/utils/mq.js +36 -68
  52. package/lib/commonjs/utils/mq.js.map +1 -1
  53. package/lib/commonjs/utils/mqParser.js +4 -1
  54. package/lib/commonjs/utils/mqParser.js.map +1 -1
  55. package/lib/commonjs/utils/styles.js +35 -20
  56. package/lib/commonjs/utils/styles.js.map +1 -1
  57. package/lib/commonjs/utils/withPlugins.js +15 -0
  58. package/lib/commonjs/utils/withPlugins.js.map +1 -0
  59. package/lib/module/common.js +28 -17
  60. package/lib/module/common.js.map +1 -1
  61. package/lib/module/core/UnistyleRegistry.js +65 -3
  62. package/lib/module/core/UnistyleRegistry.js.map +1 -1
  63. package/lib/module/core/Unistyles.js +2 -2
  64. package/lib/module/core/Unistyles.js.map +1 -1
  65. package/lib/module/core/UnistylesModule.web.js +180 -0
  66. package/lib/module/core/UnistylesModule.web.js.map +1 -0
  67. package/lib/module/core/UnistylesRuntime.js +15 -16
  68. package/lib/module/core/UnistylesRuntime.js.map +1 -1
  69. package/lib/module/createStyleSheet.js +1 -6
  70. package/lib/module/createStyleSheet.js.map +1 -1
  71. package/lib/module/hooks/index.js +1 -0
  72. package/lib/module/hooks/index.js.map +1 -1
  73. package/lib/module/hooks/useUnistyles.js +13 -10
  74. package/lib/module/hooks/useUnistyles.js.map +1 -1
  75. package/lib/module/hooks/useVariants.js +7 -0
  76. package/lib/module/hooks/useVariants.js.map +1 -0
  77. package/lib/module/index.js.map +1 -1
  78. package/lib/module/plugins/index.js +3 -0
  79. package/lib/module/plugins/index.js.map +1 -0
  80. package/lib/module/plugins/normalizeWebStylesPlugin.js +6 -0
  81. package/lib/module/plugins/normalizeWebStylesPlugin.js.map +1 -0
  82. package/lib/module/plugins/normalizer/index.js +3 -0
  83. package/lib/module/plugins/normalizer/index.js.map +1 -0
  84. package/lib/module/plugins/normalizer/module.d.js.map +1 -0
  85. package/lib/module/{utils/normalizeStyles.web.js → plugins/normalizer/normalizeStyle.js} +3 -3
  86. package/lib/module/plugins/normalizer/normalizeStyle.js.map +1 -0
  87. package/lib/module/{utils → plugins/normalizer}/normalizer.js +1 -1
  88. package/lib/module/plugins/normalizer/normalizer.js.map +1 -0
  89. package/lib/module/types/plugin.js +2 -0
  90. package/lib/module/types/{mq.js.map → plugin.js.map} +1 -1
  91. package/lib/module/types/stylesheet.js +2 -0
  92. package/lib/module/types/stylesheet.js.map +1 -0
  93. package/lib/module/types/variants.js +2 -0
  94. package/lib/module/{utils/module.d.js.map → types/variants.js.map} +1 -1
  95. package/lib/module/useStyles.js +12 -22
  96. package/lib/module/useStyles.js.map +1 -1
  97. package/lib/module/utils/breakpoints.js +12 -56
  98. package/lib/module/utils/breakpoints.js.map +1 -1
  99. package/lib/module/utils/index.js +4 -6
  100. package/lib/module/utils/index.js.map +1 -1
  101. package/lib/module/utils/mq.js +35 -67
  102. package/lib/module/utils/mq.js.map +1 -1
  103. package/lib/module/utils/mqParser.js +3 -3
  104. package/lib/module/utils/mqParser.js.map +1 -1
  105. package/lib/module/utils/styles.js +35 -20
  106. package/lib/module/utils/styles.js.map +1 -1
  107. package/lib/module/utils/withPlugins.js +8 -0
  108. package/lib/module/utils/withPlugins.js.map +1 -0
  109. package/lib/typescript/src/common.d.ts +23 -12
  110. package/lib/typescript/src/common.d.ts.map +1 -1
  111. package/lib/typescript/src/core/UnistyleRegistry.d.ts +45 -4
  112. package/lib/typescript/src/core/UnistyleRegistry.d.ts.map +1 -1
  113. package/lib/typescript/src/core/UnistylesModule.web.d.ts +19 -0
  114. package/lib/typescript/src/core/UnistylesModule.web.d.ts.map +1 -0
  115. package/lib/typescript/src/core/UnistylesRuntime.d.ts +8 -9
  116. package/lib/typescript/src/core/UnistylesRuntime.d.ts.map +1 -1
  117. package/lib/typescript/src/core/index.d.ts +1 -0
  118. package/lib/typescript/src/core/index.d.ts.map +1 -1
  119. package/lib/typescript/src/createStyleSheet.d.ts +2 -2
  120. package/lib/typescript/src/createStyleSheet.d.ts.map +1 -1
  121. package/lib/typescript/src/global.d.ts.map +1 -1
  122. package/lib/typescript/src/hooks/index.d.ts +1 -0
  123. package/lib/typescript/src/hooks/index.d.ts.map +1 -1
  124. package/lib/typescript/src/hooks/useUnistyles.d.ts +2 -1
  125. package/lib/typescript/src/hooks/useUnistyles.d.ts.map +1 -1
  126. package/lib/typescript/src/hooks/useVariants.d.ts +3 -0
  127. package/lib/typescript/src/hooks/useVariants.d.ts.map +1 -0
  128. package/lib/typescript/src/index.d.ts +51 -5
  129. package/lib/typescript/src/index.d.ts.map +1 -1
  130. package/lib/typescript/src/plugins/index.d.ts +3 -0
  131. package/lib/typescript/src/plugins/index.d.ts.map +1 -0
  132. package/lib/typescript/src/plugins/normalizeWebStylesPlugin.d.ts +3 -0
  133. package/lib/typescript/src/plugins/normalizeWebStylesPlugin.d.ts.map +1 -0
  134. package/lib/typescript/src/plugins/normalizer/index.d.ts +3 -0
  135. package/lib/typescript/src/plugins/normalizer/index.d.ts.map +1 -0
  136. package/lib/typescript/src/plugins/normalizer/normalizeStyle.d.ts +3 -0
  137. package/lib/typescript/src/plugins/normalizer/normalizeStyle.d.ts.map +1 -0
  138. package/lib/typescript/src/{utils → plugins/normalizer}/normalizer.d.ts +1 -1
  139. package/lib/typescript/src/plugins/normalizer/normalizer.d.ts.map +1 -0
  140. package/lib/typescript/src/types/breakpoints.d.ts +25 -12
  141. package/lib/typescript/src/types/breakpoints.d.ts.map +1 -1
  142. package/lib/typescript/src/types/core.d.ts +6 -27
  143. package/lib/typescript/src/types/core.d.ts.map +1 -1
  144. package/lib/typescript/src/types/index.d.ts +4 -2
  145. package/lib/typescript/src/types/index.d.ts.map +1 -1
  146. package/lib/typescript/src/types/plugin.d.ts +7 -0
  147. package/lib/typescript/src/types/plugin.d.ts.map +1 -0
  148. package/lib/typescript/src/types/stylesheet.d.ts +40 -0
  149. package/lib/typescript/src/types/stylesheet.d.ts.map +1 -0
  150. package/lib/typescript/src/types/unistyles.d.ts +16 -11
  151. package/lib/typescript/src/types/unistyles.d.ts.map +1 -1
  152. package/lib/typescript/src/types/variants.d.ts +14 -0
  153. package/lib/typescript/src/types/variants.d.ts.map +1 -0
  154. package/lib/typescript/src/useStyles.d.ts +3 -3
  155. package/lib/typescript/src/useStyles.d.ts.map +1 -1
  156. package/lib/typescript/src/utils/breakpoints.d.ts +2 -5
  157. package/lib/typescript/src/utils/breakpoints.d.ts.map +1 -1
  158. package/lib/typescript/src/utils/index.d.ts +4 -6
  159. package/lib/typescript/src/utils/index.d.ts.map +1 -1
  160. package/lib/typescript/src/utils/mq.d.ts +15 -14
  161. package/lib/typescript/src/utils/mq.d.ts.map +1 -1
  162. package/lib/typescript/src/utils/mqParser.d.ts +14 -2
  163. package/lib/typescript/src/utils/mqParser.d.ts.map +1 -1
  164. package/lib/typescript/src/utils/styles.d.ts +3 -4
  165. package/lib/typescript/src/utils/styles.d.ts.map +1 -1
  166. package/lib/typescript/src/utils/withPlugins.d.ts +3 -0
  167. package/lib/typescript/src/utils/withPlugins.d.ts.map +1 -0
  168. package/package.json +19 -16
  169. package/src/__tests__/mocks.ts +24 -0
  170. package/src/common.ts +30 -14
  171. package/src/core/UnistyleRegistry.ts +66 -4
  172. package/src/core/Unistyles.ts +2 -2
  173. package/src/core/UnistylesModule.web.ts +214 -0
  174. package/src/core/UnistylesRuntime.ts +18 -20
  175. package/src/core/index.ts +1 -0
  176. package/src/createStyleSheet.ts +2 -8
  177. package/src/global.ts +1 -0
  178. package/src/hooks/index.ts +1 -0
  179. package/src/hooks/useUnistyles.ts +12 -10
  180. package/src/hooks/useVariants.ts +10 -0
  181. package/src/index.ts +3 -1
  182. package/src/plugins/index.ts +2 -0
  183. package/src/plugins/normalizeWebStylesPlugin.ts +7 -0
  184. package/src/plugins/normalizer/index.ts +2 -0
  185. package/src/{utils/normalizeStyles.web.ts → plugins/normalizer/normalizeStyle.ts} +3 -3
  186. package/src/{utils → plugins/normalizer}/normalizer.ts +3 -3
  187. package/src/types/breakpoints.ts +57 -25
  188. package/src/types/core.ts +9 -43
  189. package/src/types/index.ts +11 -2
  190. package/src/types/plugin.ts +7 -0
  191. package/src/types/stylesheet.ts +49 -0
  192. package/src/types/unistyles.ts +18 -13
  193. package/src/types/variants.ts +19 -0
  194. package/src/useStyles.ts +18 -25
  195. package/src/utils/breakpoints.ts +11 -67
  196. package/src/utils/index.ts +4 -6
  197. package/src/utils/mq.ts +31 -84
  198. package/src/utils/mqParser.ts +5 -5
  199. package/src/utils/styles.ts +44 -50
  200. package/src/utils/withPlugins.ts +13 -0
  201. package/lib/commonjs/utils/common.js +0 -25
  202. package/lib/commonjs/utils/common.js.map +0 -1
  203. package/lib/commonjs/utils/normalizeStyles.js +0 -10
  204. package/lib/commonjs/utils/normalizeStyles.js.map +0 -1
  205. package/lib/commonjs/utils/normalizeStyles.web.js.map +0 -1
  206. package/lib/commonjs/utils/normalizer.js.map +0 -1
  207. package/lib/module/types/mq.js +0 -2
  208. package/lib/module/utils/common.js +0 -17
  209. package/lib/module/utils/common.js.map +0 -1
  210. package/lib/module/utils/normalizeStyles.js +0 -3
  211. package/lib/module/utils/normalizeStyles.js.map +0 -1
  212. package/lib/module/utils/normalizeStyles.web.js.map +0 -1
  213. package/lib/module/utils/normalizer.js.map +0 -1
  214. package/lib/typescript/src/types/mq.d.ts +0 -3
  215. package/lib/typescript/src/types/mq.d.ts.map +0 -1
  216. package/lib/typescript/src/utils/common.d.ts +0 -12
  217. package/lib/typescript/src/utils/common.d.ts.map +0 -1
  218. package/lib/typescript/src/utils/normalizeStyles.d.ts +0 -2
  219. package/lib/typescript/src/utils/normalizeStyles.d.ts.map +0 -1
  220. package/lib/typescript/src/utils/normalizeStyles.web.d.ts +0 -5
  221. package/lib/typescript/src/utils/normalizeStyles.web.d.ts.map +0 -1
  222. package/lib/typescript/src/utils/normalizer.d.ts.map +0 -1
  223. package/src/types/mq.ts +0 -3
  224. package/src/utils/common.ts +0 -20
  225. package/src/utils/normalizeStyles.ts +0 -2
  226. /package/lib/commonjs/{utils → plugins/normalizer}/module.d.js +0 -0
  227. /package/lib/module/{utils → plugins/normalizer}/module.d.js +0 -0
  228. /package/src/{utils → plugins/normalizer}/module.d.ts +0 -0
@@ -0,0 +1,28 @@
1
+ cmake_minimum_required(VERSION 3.9.0)
2
+
3
+ project(unistyles)
4
+
5
+ add_library(unistyles
6
+ SHARED
7
+ ../cxx/UnistylesRuntime.cpp
8
+ ./src/main/cxx/cpp-adapter.cpp
9
+ ../node_modules/react-native/ReactCommon/jsi/jsi/jsi.cpp
10
+ )
11
+
12
+ include_directories(
13
+ ../cxx
14
+ ../node_modules/react-native/React
15
+ ../node_modules/react-native/React/Base
16
+ ../node_modules/react-native/ReactCommon/jsi
17
+ )
18
+
19
+ set_target_properties(unistyles PROPERTIES
20
+ CXX_STANDARD 17
21
+ CXX_STANDARD_REQUIRED ON
22
+ CXX_EXTENSIONS OFF
23
+ POSITION_INDEPENDENT_CODE ON
24
+ )
25
+
26
+ target_link_libraries(unistyles
27
+ android
28
+ )
@@ -0,0 +1,40 @@
1
+ buildscript {
2
+ ext.safeExtGet = {prop, fallback ->
3
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
4
+ }
5
+ repositories {
6
+ google()
7
+ gradlePluginPortal()
8
+ }
9
+ dependencies {
10
+ classpath("com.android.tools.build:gradle:7.3.1")
11
+ classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.7.22")
12
+ }
13
+ }
14
+
15
+ apply plugin: 'com.android.library'
16
+ apply plugin: 'org.jetbrains.kotlin.android'
17
+
18
+ android {
19
+ compileSdkVersion safeExtGet('compileSdkVersion', 33)
20
+ namespace "com.unistyles"
21
+
22
+ defaultConfig {
23
+ minSdkVersion safeExtGet('minSdkVersion', 21)
24
+ }
25
+
26
+ externalNativeBuild {
27
+ cmake {
28
+ path "CMakeLists.txt"
29
+ }
30
+ }
31
+ }
32
+
33
+ repositories {
34
+ mavenCentral()
35
+ google()
36
+ }
37
+
38
+ dependencies {
39
+ implementation 'com.facebook.react:react-native'
40
+ }
@@ -0,0 +1,108 @@
1
+ #include <jni.h>
2
+ #include <jsi/jsi.h>
3
+ #include "UnistylesRuntime.h"
4
+
5
+ using namespace facebook;
6
+
7
+ static jobject unistylesModule = nullptr;
8
+ std::shared_ptr<UnistylesRuntime> unistylesRuntime = nullptr;
9
+
10
+ void throwKotlinException(
11
+ JNIEnv *env,
12
+ const char *message
13
+ ) {
14
+ jclass runtimeExceptionClass = env->FindClass("java/lang/RuntimeException");
15
+
16
+ if (runtimeExceptionClass != nullptr) {
17
+ env->ThrowNew(runtimeExceptionClass, message);
18
+ env->DeleteLocalRef(runtimeExceptionClass);
19
+ }
20
+ }
21
+
22
+ extern "C"
23
+ JNIEXPORT void JNICALL
24
+ Java_com_unistyles_UnistylesModule_nativeInstall(
25
+ JNIEnv *env,
26
+ jobject thiz,
27
+ jlong jsi,
28
+ jint screenWidth,
29
+ jint screenHeight,
30
+ jstring colorScheme
31
+ ) {
32
+ auto runtime = reinterpret_cast<facebook::jsi::Runtime *>(jsi);
33
+
34
+ if (unistylesModule == nullptr) {
35
+ unistylesModule = env->NewGlobalRef(thiz);
36
+ }
37
+
38
+ if (runtime == nullptr || unistylesModule == nullptr) {
39
+ return throwKotlinException(env, "Something went wrong while initializing UnistylesModule");
40
+ }
41
+
42
+ const char *colorSchemeChars = env->GetStringUTFChars(colorScheme, nullptr);
43
+ std::string colorSchemeStr(colorSchemeChars);
44
+ env->ReleaseStringUTFChars(colorScheme, colorSchemeChars);
45
+
46
+ unistylesRuntime = std::make_shared<UnistylesRuntime>(
47
+ screenWidth,
48
+ screenHeight,
49
+ colorSchemeStr
50
+ );
51
+
52
+ unistylesRuntime->onThemeChange([=](const std::string &theme) {
53
+ jstring themeStr = env->NewStringUTF(theme.c_str());
54
+ jclass cls = env->GetObjectClass(unistylesModule);
55
+ jmethodID methodId = env->GetMethodID(cls, "onThemeChange", "(Ljava/lang/String;)V");
56
+
57
+ env->CallVoidMethod(unistylesModule, methodId, themeStr);
58
+ env->DeleteLocalRef(themeStr);
59
+ env->DeleteLocalRef(cls);
60
+ });
61
+
62
+ unistylesRuntime->onLayoutChange([=](const std::string &breakpoint, const std::string &orientation, int width, int height) {
63
+ jstring breakpointStr = env->NewStringUTF(breakpoint.c_str());
64
+ jstring orientationStr = env->NewStringUTF(orientation.c_str());
65
+ jclass cls = env->GetObjectClass(unistylesModule);
66
+ jmethodID methodId = env->GetMethodID(cls, "onLayoutChange", "(Ljava/lang/String;Ljava/lang/String;II)V");
67
+
68
+ env->CallVoidMethod(unistylesModule, methodId, breakpointStr, orientationStr, width, height);
69
+ env->DeleteLocalRef(breakpointStr);
70
+ env->DeleteLocalRef(orientationStr);
71
+ env->DeleteLocalRef(cls);
72
+ });
73
+
74
+ unistylesRuntime->onPluginChange([=]() {
75
+ jclass cls = env->GetObjectClass(unistylesModule);
76
+ jmethodID methodId = env->GetMethodID(cls, "onPluginChange", "()V");
77
+
78
+ env->CallVoidMethod(unistylesModule, methodId);
79
+ env->DeleteLocalRef(cls);
80
+ });
81
+
82
+ jsi::Object hostObject = jsi::Object::createFromHostObject(*runtime, unistylesRuntime);
83
+
84
+ runtime->global().setProperty(*runtime, "__UNISTYLES__", std::move(hostObject));
85
+ }
86
+
87
+ extern "C"
88
+ JNIEXPORT void JNICALL
89
+ Java_com_unistyles_UnistylesModule_nativeDestroy(JNIEnv *env, jobject thiz) {
90
+ unistylesRuntime.reset();
91
+ env->DeleteGlobalRef(unistylesModule);
92
+ }
93
+
94
+ extern "C"
95
+ JNIEXPORT void JNICALL
96
+ Java_com_unistyles_UnistylesModule_nativeOnOrientationChange(JNIEnv *env, jobject thiz, jint width, jint height) {
97
+ if (unistylesRuntime != nullptr) {
98
+ unistylesRuntime->handleScreenSizeChange(width, height);
99
+ }
100
+ }
101
+
102
+ extern "C"
103
+ JNIEXPORT void JNICALL
104
+ Java_com_unistyles_UnistylesModule_nativeOnAppearanceChange(JNIEnv *env, jobject thiz, jstring colorScheme) {
105
+ if (unistylesRuntime != nullptr) {
106
+ unistylesRuntime->handleAppearanceChange(env->GetStringUTFChars(colorScheme, nullptr));
107
+ }
108
+ }
@@ -0,0 +1,159 @@
1
+ package com.unistyles
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import android.content.IntentFilter
7
+ import android.content.res.Configuration
8
+ import android.os.Handler
9
+ import android.os.Looper
10
+ import android.util.Log
11
+ import com.facebook.react.bridge.Arguments
12
+ import com.facebook.react.bridge.LifecycleEventListener
13
+ import com.facebook.react.bridge.ReactApplicationContext
14
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
15
+ import com.facebook.react.bridge.ReactMethod
16
+ import com.facebook.react.modules.core.DeviceEventManagerModule
17
+
18
+ class UnistylesModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener {
19
+ private val configurationChangeReceiver = object : BroadcastReceiver() {
20
+ override fun onReceive(context: Context, intent: Intent) {
21
+ if (intent.action == Intent.ACTION_CONFIGURATION_CHANGED) {
22
+ Handler(Looper.getMainLooper()).postDelayed({
23
+ this@UnistylesModule.onConfigChange()
24
+ }, 10)
25
+ }
26
+ }
27
+ }
28
+
29
+ override fun getName() = NAME
30
+ companion object {
31
+ const val NAME = "Unistyles"
32
+ }
33
+
34
+ //region Lifecycle
35
+ init {
36
+ reactApplicationContext.registerReceiver(configurationChangeReceiver, IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED))
37
+ }
38
+
39
+ override fun onCatalystInstanceDestroy() {
40
+ reactApplicationContext.unregisterReceiver(configurationChangeReceiver)
41
+ this.nativeDestroy()
42
+ }
43
+
44
+ //endregion
45
+ //region Event handlers
46
+ private fun onConfigChange() {
47
+ val config = this.getConfig()
48
+
49
+ reactApplicationContext.runOnJSQueueThread {
50
+ this.nativeOnOrientationChange(
51
+ config["width"] as Int,
52
+ config["height"] as Int
53
+ )
54
+ this.nativeOnAppearanceChange(
55
+ config["colorScheme"] as String
56
+ )
57
+ }
58
+ }
59
+
60
+ private fun getConfig(): Map<String, Any> {
61
+ val displayMetrics = reactApplicationContext.resources.displayMetrics
62
+ val colorScheme = when (reactApplicationContext.resources.configuration.uiMode.and(Configuration.UI_MODE_NIGHT_MASK)) {
63
+ Configuration.UI_MODE_NIGHT_YES -> "dark"
64
+ Configuration.UI_MODE_NIGHT_NO -> "light"
65
+ else -> "unspecified"
66
+ }
67
+
68
+ return mapOf(
69
+ "width" to (displayMetrics.widthPixels / displayMetrics.density).toInt(),
70
+ "height" to (displayMetrics.heightPixels / displayMetrics.density).toInt(),
71
+ "colorScheme" to colorScheme
72
+ )
73
+ }
74
+
75
+ //endregion
76
+ //region Core
77
+ @ReactMethod(isBlockingSynchronousMethod = true)
78
+ fun install(): Boolean {
79
+ return try {
80
+ System.loadLibrary("unistyles")
81
+ val config = this.getConfig()
82
+
83
+ this.nativeInstall(
84
+ this.reactApplicationContext.javaScriptContextHolder.get(),
85
+ config["width"] as Int,
86
+ config["height"] as Int,
87
+ config["colorScheme"] as String
88
+ )
89
+
90
+ Log.i(NAME, "Installed Unistyles \uD83E\uDD84!")
91
+
92
+ true
93
+ } catch (e: Exception) {
94
+ false
95
+ }
96
+ }
97
+
98
+ private external fun nativeInstall(jsi: Long, width: Int, height: Int, colorScheme: String)
99
+ private external fun nativeDestroy()
100
+ private external fun nativeOnOrientationChange(width: Int, height: Int)
101
+ private external fun nativeOnAppearanceChange(colorScheme: String)
102
+
103
+ //endregion
104
+ //region Event emitter
105
+ private fun onLayoutChange(breakpoint: String, orientation: String, width: Int, height: Int) {
106
+ val body = Arguments.createMap().apply {
107
+ putString("type", "layout")
108
+ putMap("payload", Arguments.createMap().apply {
109
+ putString("breakpoint", breakpoint)
110
+ putString("orientation", orientation)
111
+ putMap("screen", Arguments.createMap().apply {
112
+ putInt("width", width)
113
+ putInt("height", height)
114
+ })
115
+ })
116
+ }
117
+
118
+ reactApplicationContext
119
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
120
+ .emit("__unistylesOnChange", body)
121
+ }
122
+
123
+ private fun onThemeChange(themeName: String) {
124
+ val body = Arguments.createMap().apply {
125
+ putString("type", "theme")
126
+ putMap("payload", Arguments.createMap().apply {
127
+ putString("themeName", themeName)
128
+ })
129
+ }
130
+
131
+ reactApplicationContext
132
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
133
+ .emit("__unistylesOnChange", body)
134
+ }
135
+
136
+ private fun onPluginChange() {
137
+ val body = Arguments.createMap().apply {
138
+ putString("type", "plugin")
139
+ }
140
+
141
+ reactApplicationContext
142
+ .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
143
+ .emit("__unistylesOnChange", body)
144
+ }
145
+
146
+ @ReactMethod
147
+ fun addListener(eventName: String?) = Unit
148
+
149
+ @ReactMethod
150
+ fun removeListeners(count: Double) = Unit
151
+ override fun onHostResume() {
152
+ this.onConfigChange()
153
+ }
154
+
155
+ override fun onHostPause() {}
156
+
157
+ override fun onHostDestroy() {}
158
+ //endregion
159
+ }
@@ -0,0 +1,18 @@
1
+ package com.unistyles
2
+
3
+ import android.view.View
4
+ import com.facebook.react.ReactPackage
5
+ import com.facebook.react.bridge.NativeModule
6
+ import com.facebook.react.bridge.ReactApplicationContext
7
+ import com.facebook.react.uimanager.ReactShadowNode
8
+ import com.facebook.react.uimanager.ViewManager
9
+
10
+ class UnistylesPackage: ReactPackage {
11
+ override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule> {
12
+ return mutableListOf(UnistylesModule(reactContext))
13
+ }
14
+
15
+ override fun createViewManagers(reactContext: ReactApplicationContext): MutableList<ViewManager<View, ReactShadowNode<*>>> {
16
+ return mutableListOf()
17
+ }
18
+ }
@@ -19,6 +19,9 @@ std::vector<jsi::PropNameID> UnistylesRuntime::getPropertyNames(jsi::Runtime& ru
19
19
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("useBreakpoints")));
20
20
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("useTheme")));
21
21
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("useAdaptiveThemes")));
22
+ properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("addPlugin")));
23
+ properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("removePlugin")));
24
+ properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("enabledPlugins")));
22
25
 
23
26
  // setters
24
27
  properties.push_back(jsi::PropNameID::forUtf8(runtime, std::string("themes")));
@@ -26,7 +29,6 @@ std::vector<jsi::PropNameID> UnistylesRuntime::getPropertyNames(jsi::Runtime& ru
26
29
  return properties;
27
30
  }
28
31
 
29
-
30
32
  jsi::Value UnistylesRuntime::get(jsi::Runtime& runtime, const jsi::PropNameID& propNameId) {
31
33
  std::string propName = propNameId.utf8(runtime);
32
34
 
@@ -57,6 +59,16 @@ jsi::Value UnistylesRuntime::get(jsi::Runtime& runtime, const jsi::PropNameID& p
57
59
  if (propName == "colorScheme") {
58
60
  return jsi::Value(jsi::String::createFromUtf8(runtime, this->colorScheme));
59
61
  }
62
+
63
+ if (propName == "enabledPlugins") {
64
+ auto jsiArray = facebook::jsi::Array(runtime, this->pluginNames.size());
65
+
66
+ for (size_t i = 0; i < this->pluginNames.size(); i++) {
67
+ jsiArray.setValueAtIndex(runtime, i, facebook::jsi::String::createFromUtf8(runtime, this->pluginNames[i]));
68
+ }
69
+
70
+ return jsiArray;
71
+ }
60
72
 
61
73
  if (propName == "sortedBreakpointPairs") {
62
74
  std::unique_ptr<jsi::Array> sortedBreakpointEntriesArray = std::make_unique<jsi::Array>(runtime, this->sortedBreakpointPairs.size());
@@ -72,6 +84,47 @@ jsi::Value UnistylesRuntime::get(jsi::Runtime& runtime, const jsi::PropNameID& p
72
84
 
73
85
  return jsi::Value(runtime, *sortedBreakpointEntriesArray);
74
86
  }
87
+
88
+ if (propName == "addPlugin") {
89
+ return jsi::Function::createFromHostFunction(
90
+ runtime,
91
+ jsi::PropNameID::forAscii(runtime, "addPlugin"),
92
+ 1,
93
+ [this](jsi::Runtime &runtime, const jsi::Value &thisVal, const jsi::Value *arguments, size_t count) -> jsi::Value {
94
+ std::string pluginName = arguments[0].asString(runtime).utf8(runtime);
95
+ bool notify = arguments[1].asBool();
96
+
97
+ this->pluginNames.push_back(pluginName);
98
+
99
+ // registry enabled plugins won't notify listeners
100
+ if (notify) {
101
+ this->onPluginChangeCallback();
102
+ }
103
+
104
+ return jsi::Value::undefined();
105
+ }
106
+ );
107
+ }
108
+
109
+ if (propName == "removePlugin") {
110
+ return jsi::Function::createFromHostFunction(
111
+ runtime,
112
+ jsi::PropNameID::forAscii(runtime, "removePlugin"),
113
+ 1,
114
+ [this](jsi::Runtime &runtime, const jsi::Value &thisVal, const jsi::Value *arguments, size_t count) -> jsi::Value {
115
+ std::string pluginName = arguments[0].asString(runtime).utf8(runtime);
116
+
117
+ auto it = std::find(this->pluginNames.begin(), this->pluginNames.end(), pluginName);
118
+
119
+ if (it != this->pluginNames.end()) {
120
+ this->pluginNames.erase(it);
121
+ this->onPluginChangeCallback();
122
+ }
123
+
124
+ return jsi::Value::undefined();
125
+ }
126
+ );
127
+ }
75
128
 
76
129
  if (propName == "useBreakpoints") {
77
130
  return jsi::Function::createFromHostFunction(
@@ -218,7 +271,7 @@ void UnistylesRuntime::handleScreenSizeChange(int width, int height) {
218
271
  this->screenWidth = width;
219
272
  this->screenHeight = height;
220
273
 
221
- int orientation = width > height
274
+ std::string orientation = width > height
222
275
  ? UnistylesOrientationLandscape
223
276
  : UnistylesOrientationPortrait;
224
277
 
@@ -5,21 +5,22 @@
5
5
 
6
6
  using namespace facebook;
7
7
 
8
- const int UnistylesOrientationPortrait = 1;
9
- const int UnistylesOrientationLandscape = 2;
8
+ const std::string UnistylesOrientationPortrait = "portrait";
9
+ const std::string UnistylesOrientationLandscape = "landscape";
10
10
 
11
11
  const std::string UnistylesDarkScheme = "dark";
12
12
  const std::string UnistylesLightScheme = "light";
13
13
  const std::string UnistylesUnspecifiedScheme = "unspecified";
14
14
 
15
- const std::string UnistylesErrorBreakpointsCannotBeEmpty = "UNISTYLES_ERROR_BREAKPOINTS_CANNOT_BE_EMPTY'";
16
- const std::string UnistylesErrorBreakpointsMustStartFromZero = "UNISTYLES_ERROR_BREAKPOINTS_MUST_START_FROM_ZER0";
17
- const std::string UnistylesErrorThemesCannotBeEmpty = "UNISTYLES_ERROR_THEMES_CANNOT_BE_EMPTY";
15
+ const std::string UnistylesErrorBreakpointsCannotBeEmpty = "You are trying to register empty breakpoints object";
16
+ const std::string UnistylesErrorBreakpointsMustStartFromZero = "You are trying to register breakpoints that don't start from 0";
17
+ const std::string UnistylesErrorThemesCannotBeEmpty = "You are trying to register empty themes object";
18
18
 
19
19
  class JSI_EXPORT UnistylesRuntime : public jsi::HostObject {
20
20
  private:
21
21
  std::function<void(std::string)> onThemeChangeCallback;
22
- std::function<void(std::string breakpoint, int layout, int screenWidth, int screenHeight)> onLayoutChangeCallback;
22
+ std::function<void(std::string breakpoint, std::string orientation, int screenWidth, int screenHeight)> onLayoutChangeCallback;
23
+ std::function<void()> onPluginChangeCallback;
23
24
 
24
25
  int screenWidth;
25
26
  int screenHeight;
@@ -37,17 +38,22 @@ public:
37
38
 
38
39
  std::string themeName;
39
40
  std::string breakpoint;
41
+ std::vector<std::string> pluginNames;
40
42
  std::vector<std::string> themes;
41
43
  std::vector<std::pair<std::string, double>> sortedBreakpointPairs;
42
-
44
+
43
45
  void onThemeChange(std::function<void(std::string)> callback) {
44
46
  this->onThemeChangeCallback = callback;
45
47
  }
46
-
47
- void onLayoutChange(std::function<void(std::string breakpoint, int layout, int screenWidth, int screenHeight)> callback) {
48
+
49
+ void onLayoutChange(std::function<void(std::string breakpoint, std::string orientation, int screenWidth, int screenHeight)> callback) {
48
50
  this->onLayoutChangeCallback = callback;
49
51
  }
50
52
 
53
+ void onPluginChange(std::function<void()> callback) {
54
+ this->onPluginChangeCallback = callback;
55
+ }
56
+
51
57
  jsi::Value get(jsi::Runtime&, const jsi::PropNameID& name) override;
52
58
  void set(jsi::Runtime& runtime, const jsi::PropNameID& propNameId, const jsi::Value& value) override;
53
59
  std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime& runtime) override;
@@ -65,7 +65,7 @@ RCT_EXPORT_MODULE(Unistyles)
65
65
 
66
66
  #pragma mark - Event emitter
67
67
  - (NSArray<NSString *> *)supportedEvents {
68
- return @[@"onChange"];
68
+ return @[@"__unistylesOnChange"];
69
69
  }
70
70
 
71
71
  - (void)startObserving {
@@ -78,7 +78,7 @@ RCT_EXPORT_MODULE(Unistyles)
78
78
 
79
79
  - (void)emitEvent:(NSString *)eventName withBody:(NSDictionary *)body {
80
80
  if (self.hasListeners) {
81
- [self sendEventWithName:@"onChange" body:body];
81
+ [self sendEventWithName:@"__unistylesOnChange" body:body];
82
82
  }
83
83
  }
84
84
 
@@ -127,15 +127,15 @@ void registerUnistylesHostObject(jsi::Runtime &runtime, UnistylesModule* weakSel
127
127
  }
128
128
  };
129
129
 
130
- [weakSelf emitEvent:@"onChange" withBody:body];
130
+ [weakSelf emitEvent:@"__unistylesOnChange" withBody:body];
131
131
  });
132
132
 
133
- unistylesRuntime.get()->onLayoutChange([=](std::string breakpoint, int orientation, int width, int height) {
133
+ unistylesRuntime.get()->onLayoutChange([=](std::string breakpoint, std::string orientation, int width, int height) {
134
134
  NSDictionary *body = @{
135
135
  @"type": @"layout",
136
136
  @"payload": @{
137
137
  @"breakpoint": cxxStringToNSString(breakpoint),
138
- @"orientation": @(orientation),
138
+ @"orientation": cxxStringToNSString(orientation),
139
139
  @"screen": @{
140
140
  @"width": @(width),
141
141
  @"height": @(height)
@@ -143,7 +143,17 @@ void registerUnistylesHostObject(jsi::Runtime &runtime, UnistylesModule* weakSel
143
143
  }
144
144
  };
145
145
 
146
- [weakSelf emitEvent:@"onChange" withBody:body];
146
+ [weakSelf emitEvent:@"__unistylesOnChange" withBody:body];
147
+ });
148
+
149
+ unistylesRuntime.get()->onPluginChange([=]() {
150
+ NSDictionary *body = @{
151
+ @"type": @"plugin"
152
+ };
153
+
154
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
155
+ [weakSelf emitEvent:@"__unistylesOnChange" withBody:body];
156
+ });
147
157
  });
148
158
 
149
159
  weakSelf.unistylesRuntime = unistylesRuntime.get();
@@ -3,24 +3,38 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.UnistylesError = exports.ScreenOrientation = exports.CxxUnistylesEventTypes = void 0;
7
- let CxxUnistylesEventTypes = exports.CxxUnistylesEventTypes = /*#__PURE__*/function (CxxUnistylesEventTypes) {
8
- CxxUnistylesEventTypes["Theme"] = "theme";
9
- CxxUnistylesEventTypes["Layout"] = "layout";
10
- return CxxUnistylesEventTypes;
6
+ exports.warn = exports.isWeb = exports.isServer = exports.isMobile = exports.isIOS = exports.isAndroid = exports.UnistylesEventType = exports.UnistylesError = exports.ScreenOrientation = void 0;
7
+ var _reactNative = require("react-native");
8
+ const warn = message => {
9
+ console.warn(`🦄 [react-native-unistyles]: ${message}`);
10
+ };
11
+ exports.warn = warn;
12
+ const isWeb = exports.isWeb = _reactNative.Platform.OS === 'web';
13
+ const isIOS = exports.isIOS = _reactNative.Platform.OS === 'ios';
14
+ const isAndroid = exports.isAndroid = _reactNative.Platform.OS === 'android';
15
+ const isMobile = exports.isMobile = isIOS || isAndroid;
16
+ const isServer = exports.isServer = typeof window === 'undefined';
17
+ const ScreenOrientation = exports.ScreenOrientation = {
18
+ Landscape: 'landscape',
19
+ Portrait: 'portrait'
20
+ };
21
+ let UnistylesEventType = exports.UnistylesEventType = /*#__PURE__*/function (UnistylesEventType) {
22
+ UnistylesEventType["Theme"] = "theme";
23
+ UnistylesEventType["Layout"] = "layout";
24
+ UnistylesEventType["Plugin"] = "plugin";
25
+ return UnistylesEventType;
11
26
  }({});
12
27
  let UnistylesError = exports.UnistylesError = /*#__PURE__*/function (UnistylesError) {
13
- UnistylesError["RuntimeUnavailable"] = "UNISTYLES_ERROR_RUNTIME_UNAVAILABLE";
14
- UnistylesError["ThemeNotFound"] = "UNISTYLES_ERROR_THEME_NOT_FOUND";
15
- UnistylesError["ThemeNotRegistered"] = "UNISTYLES_ERROR_THEME_NOT_REGISTERED";
16
- UnistylesError["ThemesCannotBeEmpty"] = "UNISTYLES_ERROR_THEMES_CANNOT_BE_EMPTY";
17
- UnistylesError["BreakpointsCannotBeEmpty"] = "UNISTYLES_ERROR_BREAKPOINTS_CANNOT_BE_EMPTY";
18
- UnistylesError["BreakpointsMustStartFromZero"] = "UNISTYLES_ERROR_BREAKPOINTS_MUST_START_FROM_ZERO";
28
+ UnistylesError["RuntimeUnavailable"] = "Unistyles runtime is not available. Make sure you followed the installation instructions";
29
+ UnistylesError["ThemeNotFound"] = "You are trying to get a theme that is not registered with UnistylesRegistry";
30
+ UnistylesError["ThemeNotRegistered"] = "You are trying to set a theme that was not registered with UnistylesRegistry";
31
+ UnistylesError["ThemeNotSelected"] = "Your themes are registered, but you didn't select the initial theme";
32
+ UnistylesError["ThemesCannotBeEmpty"] = "You are trying to register empty themes object";
33
+ UnistylesError["BreakpointsCannotBeEmpty"] = "You are trying to register empty breakpoints object";
34
+ UnistylesError["BreakpointsMustStartFromZero"] = "You are trying to register breakpoints that don't start from 0";
35
+ UnistylesError["InvalidPluginName"] = "Plugin name can't start from reserved prefix __unistyles";
36
+ UnistylesError["DuplicatePluginName"] = "You are trying to register a plugin with a name that is already registered";
37
+ UnistylesError["CantRemoveInternalPlugin"] = "You are trying to remove an internal unistyles plugin";
19
38
  return UnistylesError;
20
- }({}); // todo to string?
21
- let ScreenOrientation = exports.ScreenOrientation = /*#__PURE__*/function (ScreenOrientation) {
22
- ScreenOrientation[ScreenOrientation["Portrait"] = 1] = "Portrait";
23
- ScreenOrientation[ScreenOrientation["Landscape"] = 2] = "Landscape";
24
- return ScreenOrientation;
25
39
  }({});
26
40
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"names":["CxxUnistylesEventTypes","exports","UnistylesError","ScreenOrientation"],"sourceRoot":"../../src","sources":["common.ts"],"mappings":";;;;;;IAAYA,sBAAsB,GAAAC,OAAA,CAAAD,sBAAA,0BAAtBA,sBAAsB;EAAtBA,sBAAsB;EAAtBA,sBAAsB;EAAA,OAAtBA,sBAAsB;AAAA;AAAA,IAKtBE,cAAc,GAAAD,OAAA,CAAAC,cAAA,0BAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA,OAS1B;AAAA,IACYC,iBAAiB,GAAAF,OAAA,CAAAE,iBAAA,0BAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAjBA,iBAAiB,CAAjBA,iBAAiB;EAAA,OAAjBA,iBAAiB;AAAA"}
1
+ {"version":3,"names":["_reactNative","require","warn","message","console","exports","isWeb","Platform","OS","isIOS","isAndroid","isMobile","isServer","window","ScreenOrientation","Landscape","Portrait","UnistylesEventType","UnistylesError"],"sourceRoot":"../../src","sources":["common.ts"],"mappings":";;;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAEO,MAAMC,IAAI,GAAIC,OAAe,IAAK;EACrCC,OAAO,CAACF,IAAI,CAAE,gCAA+BC,OAAQ,EAAC,CAAC;AAC3D,CAAC;AAAAE,OAAA,CAAAH,IAAA,GAAAA,IAAA;AAEM,MAAMI,KAAK,GAAAD,OAAA,CAAAC,KAAA,GAAGC,qBAAQ,CAACC,EAAE,KAAK,KAAK;AACnC,MAAMC,KAAK,GAAAJ,OAAA,CAAAI,KAAA,GAAGF,qBAAQ,CAACC,EAAE,KAAK,KAAK;AACnC,MAAME,SAAS,GAAAL,OAAA,CAAAK,SAAA,GAAGH,qBAAQ,CAACC,EAAE,KAAK,SAAS;AAC3C,MAAMG,QAAQ,GAAAN,OAAA,CAAAM,QAAA,GAAGF,KAAK,IAAIC,SAAS;AACnC,MAAME,QAAQ,GAAAP,OAAA,CAAAO,QAAA,GAAG,OAAOC,MAAM,KAAK,WAAW;AAE9C,MAAMC,iBAAiB,GAAAT,OAAA,CAAAS,iBAAA,GAAG;EAC7BC,SAAS,EAAE,WAAW;EACtBC,QAAQ,EAAE;AACd,CAAU;AAAA,IAEEC,kBAAkB,GAAAZ,OAAA,CAAAY,kBAAA,0BAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAlBA,kBAAkB;EAAA,OAAlBA,kBAAkB;AAAA;AAAA,IAMlBC,cAAc,GAAAb,OAAA,CAAAa,cAAA,0BAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAdA,cAAc;EAAA,OAAdA,cAAc;AAAA"}