@onairos/react-native 3.7.2 → 3.7.4

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 (237) hide show
  1. package/lib/commonjs/api/index.js +219 -9
  2. package/lib/commonjs/components/BodyText.js +27 -9
  3. package/lib/commonjs/components/BrandMark.js +111 -10
  4. package/lib/commonjs/components/CodeInput.js +120 -9
  5. package/lib/commonjs/components/EmailInput.js +30 -8
  6. package/lib/commonjs/components/GoogleButton.js +56 -9
  7. package/lib/commonjs/components/HeadingGroup.js +43 -9
  8. package/lib/commonjs/components/LLMDataInputModal.js +664 -14
  9. package/lib/commonjs/components/ModalHeader.js +99 -9
  10. package/lib/commonjs/components/ModalSheet.js +47 -9
  11. package/lib/commonjs/components/Onairos.js +380 -14
  12. package/lib/commonjs/components/OnairosButton.js +313 -13
  13. package/lib/commonjs/components/OnairosSignInButton.js +130 -12
  14. package/lib/commonjs/components/Overlay.js +465 -13
  15. package/lib/commonjs/components/PersonaImage.js +137 -10
  16. package/lib/commonjs/components/PersonaLoadingScreen.js +318 -12
  17. package/lib/commonjs/components/PersonalizationConsentScreen.js +467 -13
  18. package/lib/commonjs/components/PinCreationScreen.js +403 -12
  19. package/lib/commonjs/components/PinInput.js +464 -9
  20. package/lib/commonjs/components/PlatformConnectorsStep.js +1311 -23
  21. package/lib/commonjs/components/PlatformList.js +137 -10
  22. package/lib/commonjs/components/PlatformToggle.js +180 -9
  23. package/lib/commonjs/components/PrimaryButton.js +180 -10
  24. package/lib/commonjs/components/SignInMatchAnimation.js +197 -9
  25. package/lib/commonjs/components/SignInStep.js +345 -12
  26. package/lib/commonjs/components/UniversalOnboarding.js +2780 -30
  27. package/lib/commonjs/components/VerificationStep.js +176 -11
  28. package/lib/commonjs/components/WelcomeScreen.js +461 -22
  29. package/lib/commonjs/components/icons/Basicproficon.js +37 -8
  30. package/lib/commonjs/components/icons/Basicprofile.js +21 -8
  31. package/lib/commonjs/components/icons/Checkbox.js +21 -8
  32. package/lib/commonjs/components/icons/Checkmark.js +27 -8
  33. package/lib/commonjs/components/icons/Contentanalysis.js +21 -8
  34. package/lib/commonjs/components/icons/Contenticon.js +39 -8
  35. package/lib/commonjs/components/icons/EnochE.js +41 -8
  36. package/lib/commonjs/components/icons/Personalityicon.js +30 -8
  37. package/lib/commonjs/components/icons/Personalityprofile.js +21 -8
  38. package/lib/commonjs/components/icons/Personalitytraits.js +21 -8
  39. package/lib/commonjs/components/icons/Userpreferences.js +21 -8
  40. package/lib/commonjs/components/icons/index.js +84 -17
  41. package/lib/commonjs/components/onboarding/OAuthWebView.js +1754 -18
  42. package/lib/commonjs/components/onboarding/OnboardingHeader.js +74 -10
  43. package/lib/commonjs/components/onboarding/PinInput.js +283 -10
  44. package/lib/commonjs/components/onboarding/PlatformConnector.js +249 -11
  45. package/lib/commonjs/config/PLATFORM_APIS.md +849 -0
  46. package/lib/commonjs/config/api.js +56 -7
  47. package/lib/commonjs/constants/index.js +120 -7
  48. package/lib/commonjs/context/AuthContext.js +345 -10
  49. package/lib/commonjs/hooks/useConnectedAccounts.js +111 -9
  50. package/lib/commonjs/hooks/useConnections.js +102 -8
  51. package/lib/commonjs/hooks/useCredentials.js +178 -10
  52. package/lib/commonjs/hooks/useUserConnections.js +148 -10
  53. package/lib/commonjs/index.js +439 -34
  54. package/lib/commonjs/services/apiClient.js +298 -8
  55. package/lib/commonjs/services/biometricPinService.js +180 -8
  56. package/lib/commonjs/services/chatGPTConversationExtractor.js +155 -8
  57. package/lib/commonjs/services/chatGPTConversationService.js +275 -9
  58. package/lib/commonjs/services/claudeConversationExtractor.js +103 -8
  59. package/lib/commonjs/services/claudeConversationService.js +158 -9
  60. package/lib/commonjs/services/connectedAccountsService.js +310 -10
  61. package/lib/commonjs/services/googleAuthService.js +252 -11
  62. package/lib/commonjs/services/hingeDataExtractor.js +105 -8
  63. package/lib/commonjs/services/hingeDataService.js +150 -9
  64. package/lib/commonjs/services/imageCompressionService.js +260 -7
  65. package/lib/commonjs/services/instagramDataExtractor.js +126 -8
  66. package/lib/commonjs/services/instagramDataService.js +163 -9
  67. package/lib/commonjs/services/jwtStorageService.js +276 -7
  68. package/lib/commonjs/services/linkedinDOMExtractor.js +245 -7
  69. package/lib/commonjs/services/linkedinProfileService.js +222 -9
  70. package/lib/commonjs/services/linkedinScrapingService.js +230 -8
  71. package/lib/commonjs/services/llmDataStorage.js +294 -8
  72. package/lib/commonjs/services/mobileTrainingService.js +186 -8
  73. package/lib/commonjs/services/netflixDataExtractor.js +120 -8
  74. package/lib/commonjs/services/netflixDataService.js +198 -9
  75. package/lib/commonjs/services/pinEncryptionService.js +84 -8
  76. package/lib/commonjs/services/pinStorageUtils.js +105 -7
  77. package/lib/commonjs/services/platformAuthService.js +1484 -12
  78. package/lib/commonjs/services/sephoraDataExtractor.js +140 -8
  79. package/lib/commonjs/services/sephoraDataService.js +200 -9
  80. package/lib/commonjs/services/spotifyDataExtractor.js +148 -8
  81. package/lib/commonjs/services/spotifyDataService.js +241 -9
  82. package/lib/commonjs/services/storageService.js +404 -8
  83. package/lib/commonjs/services/telegramDataExtractor.js +115 -8
  84. package/lib/commonjs/services/telegramDataService.js +499 -9
  85. package/lib/commonjs/services/trainingApiHelpers.js +73 -7
  86. package/lib/commonjs/services/userConnectionsService.js +340 -10
  87. package/lib/commonjs/services/youtubeMigrationService.js +416 -10
  88. package/lib/commonjs/theme/index.js +250 -7
  89. package/lib/commonjs/types/ambient.d.js +2 -1
  90. package/lib/commonjs/types/declarations.d.js +2 -1
  91. package/lib/commonjs/types/index.js +6 -1
  92. package/lib/commonjs/types/node-fix.d.js +2 -1
  93. package/lib/commonjs/types/node-override.d.js +2 -1
  94. package/lib/commonjs/types/opacity.d.js +2 -1
  95. package/lib/commonjs/types.js +14 -1
  96. package/lib/commonjs/utils/Portal.js +98 -8
  97. package/lib/commonjs/utils/api.js +130 -9
  98. package/lib/commonjs/utils/assetRegistry.js +210 -35
  99. package/lib/commonjs/utils/auth.js +112 -9
  100. package/lib/commonjs/utils/connectorTests.js +613 -29
  101. package/lib/commonjs/utils/crypto.js +62 -8
  102. package/lib/commonjs/utils/debugHelper.js +64 -1
  103. package/lib/commonjs/utils/encryption.js +76 -7
  104. package/lib/commonjs/utils/eventUtils.js +288 -1
  105. package/lib/commonjs/utils/haptics.js +66 -9
  106. package/lib/commonjs/utils/imagePreloader.js +6 -1
  107. package/lib/commonjs/utils/networkDiagnostics.js +226 -8
  108. package/lib/commonjs/utils/onairosApi.js +350 -9
  109. package/lib/commonjs/utils/programmaticFlow.js +117 -9
  110. package/lib/commonjs/utils/retryHelper.js +220 -1
  111. package/lib/commonjs/utils/secureStorage.js +349 -10
  112. package/lib/commonjs/utils/webviewScripts/chatgpt.js +551 -1
  113. package/lib/commonjs/utils/webviewScripts/claude.js +376 -1
  114. package/lib/commonjs/utils/webviewScripts/hinge.js +411 -1
  115. package/lib/commonjs/utils/webviewScripts/index.js +698 -15
  116. package/lib/commonjs/utils/webviewScripts/instagram.js +454 -1
  117. package/lib/commonjs/utils/webviewScripts/linkedin.js +880 -1
  118. package/lib/commonjs/utils/webviewScripts/netflix.js +382 -1
  119. package/lib/commonjs/utils/webviewScripts/sephora.js +516 -1
  120. package/lib/commonjs/utils/webviewScripts/spotify.js +419 -1
  121. package/lib/commonjs/utils/webviewScripts/telegram.js +678 -1
  122. package/lib/module/api/index.js +211 -1
  123. package/lib/module/components/BodyText.js +20 -1
  124. package/lib/module/components/BrandMark.js +104 -1
  125. package/lib/module/components/CodeInput.js +113 -1
  126. package/lib/module/components/EmailInput.js +23 -1
  127. package/lib/module/components/GoogleButton.js +49 -1
  128. package/lib/module/components/HeadingGroup.js +36 -1
  129. package/lib/module/components/LLMDataInputModal.js +656 -7
  130. package/lib/module/components/ModalHeader.js +92 -1
  131. package/lib/module/components/ModalSheet.js +39 -1
  132. package/lib/module/components/Onairos.js +373 -1
  133. package/lib/module/components/OnairosButton.js +305 -1
  134. package/lib/module/components/OnairosSignInButton.js +121 -1
  135. package/lib/module/components/Overlay.js +456 -1
  136. package/lib/module/components/PersonaImage.js +129 -1
  137. package/lib/module/components/PersonaLoadingScreen.js +310 -1
  138. package/lib/module/components/PersonalizationConsentScreen.js +460 -1
  139. package/lib/module/components/PinCreationScreen.js +396 -1
  140. package/lib/module/components/PinInput.js +456 -1
  141. package/lib/module/components/PlatformConnectorsStep.js +1302 -6
  142. package/lib/module/components/PlatformList.js +129 -1
  143. package/lib/module/components/PlatformToggle.js +173 -1
  144. package/lib/module/components/PrimaryButton.js +172 -1
  145. package/lib/module/components/SignInMatchAnimation.js +189 -1
  146. package/lib/module/components/SignInStep.js +338 -1
  147. package/lib/module/components/UniversalOnboarding.js +2770 -1
  148. package/lib/module/components/VerificationStep.js +168 -1
  149. package/lib/module/components/WelcomeScreen.js +453 -1
  150. package/lib/module/components/icons/Basicproficon.js +30 -1
  151. package/lib/module/components/icons/Basicprofile.js +14 -1
  152. package/lib/module/components/icons/Checkbox.js +14 -1
  153. package/lib/module/components/icons/Checkmark.js +20 -1
  154. package/lib/module/components/icons/Contentanalysis.js +14 -1
  155. package/lib/module/components/icons/Contenticon.js +32 -1
  156. package/lib/module/components/icons/EnochE.js +34 -1
  157. package/lib/module/components/icons/Personalityicon.js +23 -1
  158. package/lib/module/components/icons/Personalityprofile.js +14 -1
  159. package/lib/module/components/icons/Personalitytraits.js +14 -1
  160. package/lib/module/components/icons/Userpreferences.js +14 -1
  161. package/lib/module/components/icons/index.js +13 -1
  162. package/lib/module/components/onboarding/OAuthWebView.js +1746 -1
  163. package/lib/module/components/onboarding/OnboardingHeader.js +66 -1
  164. package/lib/module/components/onboarding/PinInput.js +274 -1
  165. package/lib/module/components/onboarding/PlatformConnector.js +240 -1
  166. package/lib/module/config/PLATFORM_APIS.md +849 -0
  167. package/lib/module/config/api.js +47 -1
  168. package/lib/module/constants/index.js +114 -1
  169. package/lib/module/context/AuthContext.js +335 -1
  170. package/lib/module/hooks/useConnectedAccounts.js +106 -1
  171. package/lib/module/hooks/useConnections.js +95 -1
  172. package/lib/module/hooks/useCredentials.js +171 -6
  173. package/lib/module/hooks/useUserConnections.js +140 -1
  174. package/lib/module/index.js +172 -1
  175. package/lib/module/services/apiClient.js +295 -1
  176. package/lib/module/services/biometricPinService.js +169 -1
  177. package/lib/module/services/chatGPTConversationExtractor.js +149 -1
  178. package/lib/module/services/chatGPTConversationService.js +268 -1
  179. package/lib/module/services/claudeConversationExtractor.js +97 -1
  180. package/lib/module/services/claudeConversationService.js +151 -1
  181. package/lib/module/services/connectedAccountsService.js +293 -1
  182. package/lib/module/services/googleAuthService.js +241 -1
  183. package/lib/module/services/hingeDataExtractor.js +99 -1
  184. package/lib/module/services/hingeDataService.js +143 -1
  185. package/lib/module/services/imageCompressionService.js +250 -1
  186. package/lib/module/services/instagramDataExtractor.js +120 -1
  187. package/lib/module/services/instagramDataService.js +156 -1
  188. package/lib/module/services/jwtStorageService.js +257 -1
  189. package/lib/module/services/linkedinDOMExtractor.js +234 -1
  190. package/lib/module/services/linkedinProfileService.js +210 -1
  191. package/lib/module/services/linkedinScrapingService.js +219 -1
  192. package/lib/module/services/llmDataStorage.js +277 -1
  193. package/lib/module/services/mobileTrainingService.js +173 -1
  194. package/lib/module/services/netflixDataExtractor.js +114 -1
  195. package/lib/module/services/netflixDataService.js +191 -1
  196. package/lib/module/services/pinEncryptionService.js +74 -6
  197. package/lib/module/services/pinStorageUtils.js +93 -1
  198. package/lib/module/services/platformAuthService.js +1461 -1
  199. package/lib/module/services/sephoraDataExtractor.js +134 -1
  200. package/lib/module/services/sephoraDataService.js +193 -1
  201. package/lib/module/services/spotifyDataExtractor.js +142 -1
  202. package/lib/module/services/spotifyDataService.js +234 -1
  203. package/lib/module/services/storageService.js +383 -1
  204. package/lib/module/services/telegramDataExtractor.js +109 -1
  205. package/lib/module/services/telegramDataService.js +493 -1
  206. package/lib/module/services/trainingApiHelpers.js +67 -1
  207. package/lib/module/services/userConnectionsService.js +329 -1
  208. package/lib/module/services/youtubeMigrationService.js +405 -1
  209. package/lib/module/theme/index.js +245 -1
  210. package/lib/module/types.js +10 -1
  211. package/lib/module/utils/Portal.js +90 -1
  212. package/lib/module/utils/api.js +118 -1
  213. package/lib/module/utils/assetRegistry.js +200 -34
  214. package/lib/module/utils/auth.js +100 -1
  215. package/lib/module/utils/connectorTests.js +600 -27
  216. package/lib/module/utils/crypto.js +54 -1
  217. package/lib/module/utils/debugHelper.js +54 -1
  218. package/lib/module/utils/encryption.js +67 -1
  219. package/lib/module/utils/eventUtils.js +270 -1
  220. package/lib/module/utils/haptics.js +59 -8
  221. package/lib/module/utils/imagePreloader.js +3 -1
  222. package/lib/module/utils/networkDiagnostics.js +217 -1
  223. package/lib/module/utils/onairosApi.js +333 -1
  224. package/lib/module/utils/programmaticFlow.js +111 -1
  225. package/lib/module/utils/retryHelper.js +211 -1
  226. package/lib/module/utils/secureStorage.js +330 -6
  227. package/lib/module/utils/webviewScripts/chatgpt.js +545 -1
  228. package/lib/module/utils/webviewScripts/claude.js +370 -1
  229. package/lib/module/utils/webviewScripts/hinge.js +405 -1
  230. package/lib/module/utils/webviewScripts/index.js +434 -1
  231. package/lib/module/utils/webviewScripts/instagram.js +448 -1
  232. package/lib/module/utils/webviewScripts/linkedin.js +874 -1
  233. package/lib/module/utils/webviewScripts/netflix.js +376 -1
  234. package/lib/module/utils/webviewScripts/sephora.js +510 -1
  235. package/lib/module/utils/webviewScripts/spotify.js +413 -1
  236. package/lib/module/utils/webviewScripts/telegram.js +672 -1
  237. package/package.json +2 -2
@@ -1 +1,874 @@
1
- function _0x4b52(_0x1f54d2,_0x4b529c){_0x1f54d2=_0x1f54d2-0x0;const _0x4748aa=_0x1f54();let _0x5c5c42=_0x4748aa[_0x1f54d2];return _0x5c5c42;}export const LINKEDIN_APP_BLOCKER_SCRIPT=_0x4b52(0x0);export const LINKEDIN_PROFILE_EXTRACTOR_SCRIPT=_0x4b52(0x1);export const LINKEDIN_NAVIGATE_TO_PROFILE_SCRIPT=_0x4b52(0x2);export const LINKEDIN_PROFILE_CONSENT_POPUP_SCRIPT='\x0a(function()\x20{\x0a\x20\x20\x20\x20try\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20existing\x20=\x20document.getElementById(\x27onairos-linkedin-consent-overlay\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(existing)\x20existing.remove();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20overlay\x20=\x20document.createElement(\x27div\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20overlay.id\x20=\x20\x27onairos-linkedin-consent-overlay\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20overlay.style.cssText\x20=\x20`\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20position:\x20fixed;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20top:\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20left:\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20width:\x20100%;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20height:\x20100%;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background:\x20rgba(0,\x200,\x200,\x200.7);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20z-index:\x20999999;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20display:\x20flex;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20align-items:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20justify-content:\x20center;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-family:\x20-apple-system,\x20BlinkMacSystemFont,\x20\x27Segoe\x20UI\x27,\x20Roboto,\x20sans-serif;\x0a\x20\x20\x20\x20\x20\x20\x20\x20`;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20popup\x20=\x20document.createElement(\x27div\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20popup.style.cssText\x20=\x20`\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background:\x20white;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2032px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20max-width:\x20400px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20width:\x2090%;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20box-shadow:\x200\x2020px\x2060px\x20rgba(0,\x200,\x200,\x200.3);\x0a\x20\x20\x20\x20\x20\x20\x20\x20`;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20popup.innerHTML\x20=\x20`\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22text-align:\x20center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22font-size:\x2048px;\x20margin-bottom:\x2016px;\x22>💼</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<h2\x20style=\x22margin:\x200\x200\x2012px\x200;\x20font-size:\x2024px;\x20color:\x20#1a1a1a;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Import\x20LinkedIn\x20Profile?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</h2>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<p\x20style=\x22margin:\x200\x200\x2024px\x200;\x20color:\x20#666;\x20font-size:\x2016px;\x20line-height:\x201.5;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20Allow\x20Onairos\x20to\x20import\x20your\x20LinkedIn\x20profile\x20data\x20including\x20bio,\x20work\x20history,\x20education,\x20and\x20skills?\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</p>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<div\x20style=\x22display:\x20flex;\x20gap:\x2012px;\x20justify-content:\x20center;\x22>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20id=\x22onairos-linkedin-deny\x22\x20style=\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20flex:\x201;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2014px\x2024px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:\x202px\x20solid\x20#e0e0e0;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background:\x20white;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20#666;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20600;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22>Deny</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20<button\x20id=\x22onairos-linkedin-allow\x22\x20style=\x22\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20flex:\x201;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20padding:\x2014px\x2024px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border:\x20none;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20background:\x20#0077B5;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20color:\x20white;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20border-radius:\x208px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-size:\x2016px;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20font-weight:\x20600;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20cursor:\x20pointer;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22>Allow</button>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20</div>\x0a`;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20overlay.appendChild(popup);\x0a\x20\x20\x20\x20\x20\x20\x20\x20document.body.appendChild(overlay);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20document.getElementById(\x27onairos-linkedin-deny\x27).onclick\x20=\x20()\x20=>\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20overlay.remove();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_CONSENT\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27denied\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20document.getElementById(\x27onairos-linkedin-allow\x27).onclick\x20=\x20()\x20=>\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.getElementById(\x27onairos-linkedin-allow\x27).innerHTML\x20=\x20\x27⏳\x20Extracting...\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.getElementById(\x27onairos-linkedin-allow\x27).disabled\x20=\x20true;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_CONSENT\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27allowed\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20setTimeout(()\x20=>\x20overlay.remove(),\x20500);\x0a\x20\x20\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20}\x20catch\x20(error)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_CONSENT\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27error\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20error.message\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20}\x0a})();\x0atrue;\x0a';export const LINKEDIN_PROFILE_SCRAPER_SCRIPT=_0x4b52(0x3);function _0x1f54(){const _0x438dbc=['\x0a(function()\x20{\x0a\x20\x20try\x20{\x0a\x20\x20\x20\x20//\x20CRITICAL:\x20Block\x20ALL\x20LinkedIn\x20app\x20deep\x20link\x20schemes\x0a\x20\x20\x20\x20var\x20blockedSchemes\x20=\x20[\x27linkedin://\x27,\x20\x27linkedinapp://\x27,\x20\x27linkedinssl://\x27,\x20\x27linkedin-mobile://\x27];\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20function\x20isBlockedUrl(url)\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(!url\x20||\x20typeof\x20url\x20!==\x20\x27string\x27)\x20return\x20false;\x0a\x20\x20\x20\x20\x20\x20var\x20urlLower\x20=\x20url.toLowerCase();\x0a\x20\x20\x20\x20\x20\x20return\x20blockedSchemes.some(function(scheme)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20return\x20urlLower.startsWith(scheme);\x0a\x20\x20\x20\x20\x20\x20})\x20||\x20(urlLower.startsWith(\x27intent://\x27)\x20&&\x20urlLower.includes(\x27linkedin\x27));\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Block\x20app\x20deep\x20links\x20by\x20intercepting\x20link\x20clicks\x20(capture\x20phase\x20-\x20earliest\x20possible)\x0a\x20\x20\x20\x20document.addEventListener(\x27click\x27,\x20function(e)\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20target\x20=\x20e.target;\x0a\x20\x20\x20\x20\x20\x20//\x20Traverse\x20up\x20DOM\x20to\x20find\x20anchor\x20tag\x0a\x20\x20\x20\x20\x20\x20while\x20(target\x20&&\x20target.tagName\x20!==\x20\x27A\x27\x20&&\x20target.tagName\x20!==\x20\x27BUTTON\x27)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20target\x20=\x20target.parentElement;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20if\x20(target)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20href\x20=\x20target.href\x20||\x20target.getAttribute(\x27href\x27)\x20||\x20target.getAttribute(\x27data-href\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(href\x20&&\x20isBlockedUrl(href))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20e.preventDefault();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20e.stopPropagation();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20e.stopImmediatePropagation();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20app\x20deep\x20link\x20click:\x27,\x20href);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20false;\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20},\x20true);\x20//\x20Capture\x20phase\x20-\x20intercept\x20before\x20any\x20other\x20handlers\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Override\x20window.open\x20to\x20prevent\x20app\x20opening\x0a\x20\x20\x20\x20var\x20originalOpen\x20=\x20window.open;\x0a\x20\x20\x20\x20window.open\x20=\x20function(url,\x20target,\x20features)\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(url))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20window.open\x20app\x20link:\x27,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20return\x20originalOpen.apply(this,\x20arguments);\x0a\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Block\x20location.href\x20changes\x20to\x20app\x20URLs\x0a\x20\x20\x20\x20var\x20originalLocation\x20=\x20window.location;\x0a\x20\x20\x20\x20try\x20{\x0a\x20\x20\x20\x20\x20\x20Object.defineProperty(window,\x20\x27location\x27,\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20set:\x20function(url)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(url))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20location.href\x20change\x20to\x20app\x20URL:\x27,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20originalLocation.href\x20=\x20url;\x0a\x20\x20\x20\x20\x20\x20\x20\x20},\x0a\x20\x20\x20\x20\x20\x20\x20\x20get:\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20originalLocation;\x0a\x20\x20\x20\x20\x20\x20\x20\x20},\x0a\x20\x20\x20\x20\x20\x20\x20\x20configurable:\x20true\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20}\x20catch\x20(e)\x20{\x0a\x20\x20\x20\x20\x20\x20//\x20Fallback:\x20Override\x20location.href\x20directly\x0a\x20\x20\x20\x20\x20\x20var\x20originalHref\x20=\x20Object.getOwnPropertyDescriptor(window.location,\x20\x27href\x27);\x0a\x20\x20\x20\x20\x20\x20if\x20(originalHref\x20&&\x20originalHref.set)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20Object.defineProperty(window.location,\x20\x27href\x27,\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20set:\x20function(url)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(url))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20location.href\x20setter\x20to\x20app\x20URL:\x27,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20originalHref.set.call(window.location,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20},\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20get:\x20originalHref.get,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20configurable:\x20true\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Block\x20location.replace\x20and\x20location.assign\x0a\x20\x20\x20\x20var\x20originalReplace\x20=\x20window.location.replace;\x0a\x20\x20\x20\x20window.location.replace\x20=\x20function(url)\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(url))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20location.replace\x20to\x20app\x20URL:\x27,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20return\x20originalReplace.call(window.location,\x20url);\x0a\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20var\x20originalAssign\x20=\x20window.location.assign;\x0a\x20\x20\x20\x20window.location.assign\x20=\x20function(url)\x20{\x0a\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(url))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Blocked\x20location.assign\x20to\x20app\x20URL:\x27,\x20url);\x0a\x20\x20\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20return\x20originalAssign.call(window.location,\x20url);\x0a\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Intercept\x20meta\x20refresh\x20tags\x0a\x20\x20\x20\x20var\x20observer\x20=\x20new\x20MutationObserver(function(mutations)\x20{\x0a\x20\x20\x20\x20\x20\x20mutations.forEach(function(mutation)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20mutation.addedNodes.forEach(function(node)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(node.nodeType\x20===\x201)\x20{\x20//\x20Element\x20node\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(node.tagName\x20===\x20\x27META\x27\x20&&\x20node.httpEquiv\x20&&\x20node.httpEquiv.toLowerCase()\x20===\x20\x27refresh\x27)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20content\x20=\x20node.content\x20||\x20node.getAttribute(\x27content\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(content\x20&&\x20isBlockedUrl(content))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20node.remove();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Removed\x20meta\x20refresh\x20to\x20app\x20URL\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Check\x20all\x20links\x20in\x20added\x20nodes\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20links\x20=\x20node.querySelectorAll\x20?\x20node.querySelectorAll(\x27a[href]\x27)\x20:\x20[];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20links.forEach(function(link)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(isBlockedUrl(link.href))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20link.href\x20=\x20\x27#\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20link.onclick\x20=\x20function(e)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20e.preventDefault();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20e.stopPropagation();\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20false;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🚫\x20[LINKEDIN-JS]\x20Neutralized\x20app\x20deep\x20link\x20in\x20added\x20node\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20});\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Start\x20observing\x20when\x20DOM\x20is\x20ready\x0a\x20\x20\x20\x20if\x20(document.body)\x20{\x0a\x20\x20\x20\x20\x20\x20observer.observe(document.body,\x20{\x20childList:\x20true,\x20subtree:\x20true\x20});\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20document.addEventListener(\x27DOMContentLoaded\x27,\x20function()\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20observer.observe(document.body,\x20{\x20childList:\x20true,\x20subtree:\x20true\x20});\x0a\x20\x20\x20\x20\x20\x20});\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20console.log(\x27✅\x20[LINKEDIN-JS]\x20App\x20deep\x20link\x20blocker\x20installed\x20(comprehensive)\x27);\x0a\x20\x20}\x20catch\x20(e)\x20{\x0a\x20\x20\x20\x20console.error(\x27❌\x20[LINKEDIN-JS]\x20App\x20blocker\x20error:\x27,\x20e);\x0a\x20\x20}\x0a})();\x0atrue;\x0a','\x0a(function()\x20{\x0a\x20\x20try\x20{\x0a\x20\x20\x20\x20if\x20(!document.body)\x20{\x0a\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27error\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Page\x20not\x20ready\x27\x0a\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20return;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20//\x205\x20EXTRACTION\x20METHODS\x20(from\x20iOS)\x0a\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20/**\x0a\x20\x20\x20\x20\x20*\x20Method\x201:\x20Check\x20current\x20URL\x20for\x20/in/\x20pattern\x0a\x20\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20function\x20extractFromCurrentUrl()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20currentUrl\x20=\x20window.location.href;\x0a\x20\x20\x20\x20\x20\x20var\x20inMatch\x20=\x20currentUrl.match(/linkedin\x5c.com\x5c/in\x5c/([^\x5c/\x5c?]+)/);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20if\x20(inMatch)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20return\x20\x27https://www.linkedin.com/in/\x27\x20+\x20inMatch[1];\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20/**\x0a\x20\x20\x20\x20\x20*\x20Method\x202:\x20Search\x20all\x20links\x20for\x20/in/\x20pattern\x0a\x20\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20function\x20extractFromLinks()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20allLinks\x20=\x20document.querySelectorAll(\x27a[href*=\x22/in/\x22]\x27);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20allLinks.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20href\x20=\x20allLinks[i].getAttribute(\x27href\x27)\x20||\x20allLinks[i].href;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(href\x20&&\x20href.includes(\x27/in/\x27)\x20&&\x20!href.includes(\x27/me\x27))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20match\x20=\x20href.match(/https?:\x5c/\x5c/[^\x5c/]+\x5c/in\x5c/([^\x5c/\x5c?]+)/);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(match)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20\x27https://www.linkedin.com/in/\x27\x20+\x20match[1];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20/**\x0a\x20\x20\x20\x20\x20*\x20Method\x203:\x20Check\x20meta\x20tags\x0a\x20\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20function\x20extractFromMetaTags()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20metaTags\x20=\x20document.querySelectorAll(\x27meta\x27);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20metaTags.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20content\x20=\x20metaTags[i].getAttribute(\x27content\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20metaTags[i].getAttribute(\x27property\x27)\x20||\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(content\x20&&\x20content.includes(\x27/in/\x27))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20match\x20=\x20content.match(/https?:\x5c/\x5c/[^\x5c/]+\x5c/in\x5c/([^\x5c/\x5c?]+)/);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(match)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20\x27https://www.linkedin.com/in/\x27\x20+\x20match[1];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20/**\x0a\x20\x20\x20\x20\x20*\x20Method\x204:\x20Check\x20scripts\x20for\x20embedded\x20URLs\x0a\x20\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20function\x20extractFromScripts()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20scripts\x20=\x20document.querySelectorAll(\x27script\x27);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20scripts.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20scriptText\x20=\x20scripts[i].textContent\x20||\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20match\x20=\x20scriptText.match(/https?:\x5c/\x5c/[^\x5c/]+\x5c/in\x5c/([^\x5c/\x5c?\x22\x27]+)/);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(match\x20&&\x20!match[0].includes(\x27/me\x27))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20\x27https://www.linkedin.com/in/\x27\x20+\x20match[1];\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20/**\x0a\x20\x20\x20\x20\x20*\x20Method\x205:\x20Check\x20data\x20attributes\x0a\x20\x20\x20\x20\x20*/\x0a\x20\x20\x20\x20function\x20extractFromDataAttributes()\x20{\x0a\x20\x20\x20\x20\x20\x20var\x20dataElems\x20=\x20document.querySelectorAll(\x27[data-profile-url],\x20[data-entity-urn]\x27);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20for\x20(var\x20i\x20=\x200;\x20i\x20<\x20dataElems.length;\x20i++)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20var\x20dataUrl\x20=\x20dataElems[i].getAttribute(\x27data-profile-url\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20dataElems[i].getAttribute(\x27href\x27)\x20||\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(dataUrl\x20&&\x20dataUrl.includes(\x27/in/\x27))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20var\x20match\x20=\x20dataUrl.match(/https?:\x5c/\x5c/[^\x5c/]+\x5c/in\x5c/([^\x5c/\x5c?]+)/);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(match)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20\x27https://www.linkedin.com/in/\x27\x20+\x20match[1];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20return\x20null;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20//\x20EXECUTE\x20EXTRACTION\x0a\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20console.log(\x27🔍\x20Starting\x20LinkedIn\x20profile\x20URL\x20extraction...\x27);\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Try\x20all\x205\x20methods\x20in\x20order\x0a\x20\x20\x20\x20var\x20profileUrl\x20=\x20extractFromCurrentUrl()\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20extractFromLinks()\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20extractFromMetaTags()\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20extractFromScripts()\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20extractFromDataAttributes();\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20if\x20(profileUrl)\x20{\x0a\x20\x20\x20\x20\x20\x20console.log(\x27✅\x20Profile\x20URL\x20extracted:\x27,\x20profileUrl);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20//\x20Send\x20success\x20to\x20React\x20Native\x0a\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27success\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20profileUrl:\x20profileUrl\x0a\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20}\x20else\x20{\x0a\x20\x20\x20\x20\x20\x20console.warn(\x27⚠️\x20Could\x20not\x20find\x20LinkedIn\x20profile\x20URL\x27);\x0a\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20//\x20Send\x20error\x20to\x20React\x20Native\x0a\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27error\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Could\x20not\x20find\x20LinkedIn\x20profile\x20URL.\x20Please\x20navigate\x20to\x20your\x20profile\x20page.\x27\x0a\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x0a\x20\x20}\x20catch\x20(error)\x20{\x0a\x20\x20\x20\x20console.error(\x27❌\x20Error\x20extracting\x20profile\x20URL:\x27,\x20error);\x0a\x20\x20\x20\x20\x0a\x20\x20\x20\x20//\x20Send\x20error\x20to\x20React\x20Native\x0a\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20status:\x20\x27error\x27,\x0a\x20\x20\x20\x20\x20\x20message:\x20\x27JavaScript\x20error:\x20\x27\x20+\x20(error.message\x20||\x20String(error))\x0a\x20\x20\x20\x20}));\x0a\x20\x20}\x0a})();\x0atrue;\x20//\x20Required\x20for\x20iOS\x20compatibility\x0a','\x0a(function()\x20{\x0a\x20\x20try\x20{\x0a\x20\x20\x20\x20//\x20Try\x20clicking\x20the\x20\x22Me\x22\x20menu\x20item\x20or\x20profile\x20link\x0a\x20\x20\x20\x20var\x20meLink\x20=\x20document.querySelector(\x27a[href*=\x22/me\x22]\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27a[href*=\x22/in/\x22][href*=\x22profile\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27[data-control-name=\x22identity_welcome_message\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27a[aria-label*=\x22Profile\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27a[aria-label*=\x22Me\x22]\x27);\x0a\x20\x20\x20\x20if\x20(meLink)\x20{\x0a\x20\x20\x20\x20\x20\x20console.log(\x27[LINKEDIN]\x20Found\x20profile\x20link,\x20clicking...\x27);\x0a\x20\x20\x20\x20\x20\x20meLink.click();\x0a\x20\x20\x20\x20\x20\x20return\x20true;\x0a\x20\x20\x20\x20}\x0a\x20\x20\x20\x20//\x20Fallback:\x20navigate\x20directly\x0a\x20\x20\x20\x20console.log(\x27[LINKEDIN]\x20No\x20profile\x20link\x20found,\x20navigating\x20directly\x20to\x20/me\x27);\x0a\x20\x20\x20\x20window.location.href\x20=\x20\x27https://www.linkedin.com/me\x27;\x0a\x20\x20\x20\x20return\x20false;\x0a\x20\x20}\x20catch\x20(e)\x20{\x0a\x20\x20\x20\x20console.error(\x27[LINKEDIN]\x20Navigation\x20error:\x27,\x20e);\x0a\x20\x20\x20\x20window.location.href\x20=\x20\x27https://www.linkedin.com/me\x27;\x0a\x20\x20\x20\x20return\x20false;\x0a\x20\x20}\x0a})();\x0atrue;\x0a','\x0a(function()\x20{\x0a\x20\x20\x20\x20try\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🔍\x20[LINKEDIN]\x20Starting\x20profile\x20DOM\x20extraction...\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27starting\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x205,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Starting\x20profile\x20extraction...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20HELPER\x20FUNCTIONS\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20function\x20getTextContent(selector,\x20parent\x20=\x20document)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20el\x20=\x20parent.querySelector(selector);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20el\x20?\x20el.textContent.trim()\x20:\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20function\x20getAllTextContent(selector,\x20parent\x20=\x20document)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20elements\x20=\x20parent.querySelectorAll(selector);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20Array.from(elements).map(el\x20=>\x20el.textContent.trim()).filter(t\x20=>\x20t);\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20function\x20cleanText(text)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(!text)\x20return\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20return\x20text.replace(/\x5cs+/g,\x20\x27\x20\x27).trim();\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20BASIC\x20INFO\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27basic_info\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2010,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extracting\x20basic\x20info...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Name\x20-\x20try\x20multiple\x20selectors\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20fullName\x20=\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20nameSelectors\x20=\x20[\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27h1\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.text-heading-xlarge\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27[data-anonymize=\x22person-name\x22]\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.pv-text-details__left-panel\x20h1\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.profile-topcard-person-entity__name\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20];\x0a\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20sel\x20of\x20nameSelectors)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20name\x20=\x20getTextContent(sel);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(name\x20&&\x20name.length\x20>\x201\x20&&\x20name.length\x20<\x20100)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fullName\x20=\x20cleanText(name);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20break;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27📛\x20[LINKEDIN]\x20Name:\x27,\x20fullName);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Headline\x20-\x20try\x20multiple\x20selectors\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20headline\x20=\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20headlineSelectors\x20=\x20[\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.text-body-medium.break-words\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27[data-anonymize=\x22headline\x22]\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.pv-text-details__left-panel\x20.text-body-medium\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.profile-topcard__summary-position-title\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20];\x0a\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20sel\x20of\x20headlineSelectors)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20h\x20=\x20getTextContent(sel);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(h\x20&&\x20h.length\x20>\x203)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20headline\x20=\x20cleanText(h);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20break;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27📋\x20[LINKEDIN]\x20Headline:\x27,\x20headline);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Location\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20location\x20=\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20locationSelectors\x20=\x20[\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.text-body-small.inline.t-black--light.break-words\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.pv-text-details__left-panel\x20.text-body-small\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27[data-anonymize=\x22location\x22]\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.profile-topcard__location-data\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20];\x0a\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20sel\x20of\x20locationSelectors)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20loc\x20=\x20getTextContent(sel);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(loc\x20&&\x20loc.length\x20>\x202\x20&&\x20!loc.includes(\x27connections\x27)\x20&&\x20!loc.includes(\x27followers\x27))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location\x20=\x20cleanText(loc);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20break;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27📍\x20[LINKEDIN]\x20Location:\x27,\x20location);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Profile\x20URL\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20profileUrl\x20=\x20window.location.href.split(\x27?\x27)[0];\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🔗\x20[LINKEDIN]\x20Profile\x20URL:\x27,\x20profileUrl);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20ABOUT\x20SECTION\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27about\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2025,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extracting\x20about\x20section...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20about\x20=\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Try\x20to\x20find\x20About\x20section\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20aboutSection\x20=\x20document.querySelector(\x27#about\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27[id*=\x22about\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27section:has(>\x20div\x20>\x20div\x20>\x20span:contains(\x22About\x22))\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(aboutSection)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Look\x20for\x20the\x20about\x20text\x20within\x20the\x20section\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20aboutTextSelectors\x20=\x20[\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.display-flex.ph5.pv3\x20span[aria-hidden=\x22true\x22]\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.pv-shared-text-with-see-more\x20span\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.inline-show-more-text\x20span\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27span[aria-hidden=\x22true\x22]\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x27.full-width\x20span\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20sel\x20of\x20aboutTextSelectors)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20texts\x20=\x20aboutSection.querySelectorAll(sel);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(texts.length\x20>\x200)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20about\x20=\x20cleanText(Array.from(texts).map(t\x20=>\x20t.textContent).join(\x27\x20\x27));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(about.length\x20>\x2020)\x20break;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Alternative:\x20look\x20for\x20about\x20text\x20near\x20\x22About\x22\x20heading\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(!about)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20allSpans\x20=\x20document.querySelectorAll(\x27span\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20let\x20foundAboutHeading\x20=\x20false;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20span\x20of\x20allSpans)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(span.textContent.trim()\x20===\x20\x27About\x27)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20foundAboutHeading\x20=\x20true;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20continue;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(foundAboutHeading\x20&&\x20span.textContent.length\x20>\x2050)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20about\x20=\x20cleanText(span.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20break;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27📝\x20[LINKEDIN]\x20About\x20(preview):\x27,\x20about.substring(0,\x20100)\x20+\x20\x27...\x27);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20EXPERIENCE\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27experience\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2040,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extracting\x20work\x20experience...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20experience\x20=\x20[];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Find\x20experience\x20section\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20expSection\x20=\x20document.querySelector(\x27#experience\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27[id*=\x22experience\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27section.experience-section\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(expSection)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Look\x20for\x20experience\x20entries\x20-\x20LinkedIn\x20uses\x20list\x20items\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20expItems\x20=\x20expSection.querySelectorAll(\x27li.artdeco-list__item,\x20li[class*=\x22experience-item\x22],\x20ul\x20>\x20li\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20item\x20of\x20expItems)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20entry\x20=\x20{};\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Title\x20-\x20usually\x20the\x20first/main\x20heading\x20in\x20the\x20item\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20titleEl\x20=\x20item.querySelector(\x27.t-bold\x20span,\x20.mr1.t-bold\x20span,\x20[data-anonymize=\x22job-title\x22]\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(titleEl)\x20entry.title\x20=\x20cleanText(titleEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Company\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20companyEl\x20=\x20item.querySelector(\x27.t-normal\x20span,\x20.t-14.t-normal\x20span,\x20[data-anonymize=\x22company-name\x22]\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(companyEl)\x20entry.company\x20=\x20cleanText(companyEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Duration/dates\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20dateEl\x20=\x20item.querySelector(\x27.t-black--light\x20span,\x20.pvs-entity__caption-wrapper\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(dateEl)\x20entry.duration\x20=\x20cleanText(dateEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Description\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20descEl\x20=\x20item.querySelector(\x27.display-flex.align-items-center\x20span[aria-hidden=\x22true\x22],\x20.inline-show-more-text\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(descEl)\x20entry.description\x20=\x20cleanText(descEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Location\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20locEl\x20=\x20item.querySelector(\x27.t-black--light.t-normal\x20span:last-child\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(locEl)\x20entry.location\x20=\x20cleanText(locEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(entry.title\x20||\x20entry.company)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20experience.push(entry);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27💼\x20[LINKEDIN]\x20Experience\x20entries:\x27,\x20experience.length);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20EDUCATION\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27education\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2060,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extracting\x20education...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20education\x20=\x20[];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Find\x20education\x20section\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20eduSection\x20=\x20document.querySelector(\x27#education\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27[id*=\x22education\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27section.education-section\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(eduSection)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20eduItems\x20=\x20eduSection.querySelectorAll(\x27li.artdeco-list__item,\x20li[class*=\x22education-item\x22],\x20ul\x20>\x20li\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20item\x20of\x20eduItems)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20entry\x20=\x20{};\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20School\x20name\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20schoolEl\x20=\x20item.querySelector(\x27.t-bold\x20span,\x20.mr1.t-bold\x20span,\x20[data-anonymize=\x22school-name\x22]\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(schoolEl)\x20entry.school\x20=\x20cleanText(schoolEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Degree\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20degreeEl\x20=\x20item.querySelector(\x27.t-normal\x20span,\x20.t-14.t-normal\x20span\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(degreeEl)\x20entry.degree\x20=\x20cleanText(degreeEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Field\x20of\x20study\x20(sometimes\x20combined\x20with\x20degree)\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20fieldEl\x20=\x20item.querySelector(\x27.pv-entity__comma-item\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(fieldEl)\x20entry.fieldOfStudy\x20=\x20cleanText(fieldEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Years\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20yearsEl\x20=\x20item.querySelector(\x27.t-black--light\x20span,\x20.pvs-entity__caption-wrapper\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(yearsEl)\x20entry.years\x20=\x20cleanText(yearsEl.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(entry.school)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20education.push(entry);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🎓\x20[LINKEDIN]\x20Education\x20entries:\x27,\x20education.length);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20SKILLS\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27skills\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2080,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extracting\x20skills...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20skills\x20=\x20[];\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Find\x20skills\x20section\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20skillsSection\x20=\x20document.querySelector(\x27#skills\x27)\x20||\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27[id*=\x22skills\x22]\x27)\x20||\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20document.querySelector(\x27section.skills-section\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(skillsSection)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20skillItems\x20=\x20skillsSection.querySelectorAll(\x27.t-bold\x20span,\x20[data-anonymize=\x22skill-name\x22],\x20.pv-skill-category-entity__name-text\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20item\x20of\x20skillItems)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20skill\x20=\x20cleanText(item.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(skill\x20&&\x20skill.length\x20>\x201\x20&&\x20skill.length\x20<\x20100\x20&&\x20!skills.includes(skill))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20skills.push(skill);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Also\x20check\x20for\x20skills\x20in\x20\x22Top\x20skills\x22\x20section\x20on\x20profile\x20card\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20topSkillsSection\x20=\x20document.querySelector(\x27.pv-skill-category-list\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(topSkillsSection)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20topSkillItems\x20=\x20topSkillsSection.querySelectorAll(\x27span\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20for\x20(const\x20item\x20of\x20topSkillItems)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20skill\x20=\x20cleanText(item.textContent);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(skill\x20&&\x20skill.length\x20>\x201\x20&&\x20skill.length\x20<\x20100\x20&&\x20!skills.includes(skill))\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20skills.push(skill);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27🛠️\x20[LINKEDIN]\x20Skills:\x27,\x20skills.length);\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20EXTRACT\x20ADDITIONAL\x20INFO\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Connections\x20count\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20connections\x20=\x200;\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20connectionsEl\x20=\x20document.querySelector(\x27.t-bold:has(+\x20span:contains(\x22connections\x22)),\x20.pv-top-card--list-bullet\x20span\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(connectionsEl)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20connText\x20=\x20connectionsEl.textContent;\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20const\x20connMatch\x20=\x20connText.match(/([\x5cd,]+)\x5c+?\x5cs*connections?/i);\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20if\x20(connMatch)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20connections\x20=\x20parseInt(connMatch[1].replace(/,/g,\x20\x27\x27));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20Profile\x20picture\x20URL\x0a\x20\x20\x20\x20\x20\x20\x20\x20let\x20profilePicture\x20=\x20\x27\x27;\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20imgEl\x20=\x20document.querySelector(\x27.pv-top-card-profile-picture__image,\x20.profile-photo-edit__preview,\x20img[data-anonymize=\x22headshot-photo\x22]\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20if\x20(imgEl\x20&&\x20imgEl.src)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20profilePicture\x20=\x20imgEl.src;\x0a\x20\x20\x20\x20\x20\x20\x20\x20}\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20BUILD\x20RESULT\x20OBJECT\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_PROGRESS\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20stage:\x20\x27finalizing\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20progress:\x2095,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Finalizing\x20extraction...\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20const\x20profileData\x20=\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Basic\x20Info\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20fullName:\x20fullName,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20headline:\x20headline,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20location:\x20location,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20about:\x20about,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20profileUrl:\x20profileUrl,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Profile\x20Details\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20profilePicture:\x20profilePicture,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Professional\x20Info\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20experience:\x20experience,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20education:\x20education,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20skills:\x20skills,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Additional\x20Info\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20connections:\x20connections,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20//\x20Metadata\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20scrapedAt:\x20new\x20Date().toISOString(),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20extractionMethod:\x20\x27dom_scraper\x27\x0a\x20\x20\x20\x20\x20\x20\x20\x20};\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27✅\x20[LINKEDIN]\x20Profile\x20extraction\x20complete!\x27);\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.log(\x27📊\x20[LINKEDIN]\x20Summary:\x27,\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20name:\x20fullName,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20headline:\x20headline.substring(0,\x2050),\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20experienceCount:\x20experience.length,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20educationCount:\x20education.length,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20skillsCount:\x20skills.length\x0a\x20\x20\x20\x20\x20\x20\x20\x20});\x0a\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20SEND\x20RESULT\x20TO\x20REACT\x20NATIVE\x0a\x20\x20\x20\x20\x20\x20\x20\x20//\x20========================================\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_EXPORT_COMPLETE\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27success\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20data:\x20profileData,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20success:\x20true\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x0a\x20\x20\x20\x20}\x20catch\x20(error)\x20{\x0a\x20\x20\x20\x20\x20\x20\x20\x20console.error(\x27❌\x20[LINKEDIN]\x20Profile\x20extraction\x20error:\x27,\x20error);\x0a\x20\x20\x20\x20\x20\x20\x20\x20window.ReactNativeWebView.postMessage(JSON.stringify({\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20type:\x20\x27LINKEDIN_PROFILE_EXPORT_ERROR\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20status:\x20\x27error\x27,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20message:\x20\x27Extraction\x20failed:\x20\x27\x20+\x20error.message,\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20success:\x20false\x0a\x20\x20\x20\x20\x20\x20\x20\x20}));\x0a\x20\x20\x20\x20}\x0a})();\x0atrue;\x0a','\x0a(function()\x20{\x0a\x20\x20\x20\x20console.log(\x27✅\x20LinkedIn\x20profile\x20export\x20successful!\x27);\x0a})();\x0atrue;\x0a','\x0a(function()\x20{\x0a\x20\x20\x20\x20console.log(\x27❌\x20LinkedIn\x20profile\x20export\x20failed!\x27);\x0a})();\x0atrue;\x0a'];_0x1f54=function(){return _0x438dbc;};return _0x1f54();}export const LINKEDIN_PROFILE_SUCCESS_SCRIPT=_0x4b52(0x4);export const LINKEDIN_PROFILE_ERROR_SCRIPT=_0x4b52(0x5);
1
+ /**
2
+ * LinkedIn WebView Injection Scripts
3
+ *
4
+ * Used for LinkedIn profile URL extraction and anti-detection
5
+ * Ported from iOS WKWebView implementation (LinkedInConnectorView.swift)
6
+ */
7
+
8
+ /**
9
+ * LinkedIn App Deep Link Blocker
10
+ * Prevents LinkedIn from opening the native app - keeps everything in WebView
11
+ * Intercepts link clicks and navigation attempts
12
+ */
13
+ export const LINKEDIN_APP_BLOCKER_SCRIPT = `
14
+ (function() {
15
+ try {
16
+ // CRITICAL: Block ALL LinkedIn app deep link schemes
17
+ var blockedSchemes = ['linkedin://', 'linkedinapp://', 'linkedinssl://', 'linkedin-mobile://'];
18
+
19
+ function isBlockedUrl(url) {
20
+ if (!url || typeof url !== 'string') return false;
21
+ var urlLower = url.toLowerCase();
22
+ return blockedSchemes.some(function(scheme) {
23
+ return urlLower.startsWith(scheme);
24
+ }) || (urlLower.startsWith('intent://') && urlLower.includes('linkedin'));
25
+ }
26
+
27
+ // Block app deep links by intercepting link clicks (capture phase - earliest possible)
28
+ document.addEventListener('click', function(e) {
29
+ var target = e.target;
30
+ // Traverse up DOM to find anchor tag
31
+ while (target && target.tagName !== 'A' && target.tagName !== 'BUTTON') {
32
+ target = target.parentElement;
33
+ }
34
+
35
+ if (target) {
36
+ var href = target.href || target.getAttribute('href') || target.getAttribute('data-href');
37
+ if (href && isBlockedUrl(href)) {
38
+ e.preventDefault();
39
+ e.stopPropagation();
40
+ e.stopImmediatePropagation();
41
+ console.log('🚫 [LINKEDIN-JS] Blocked app deep link click:', href);
42
+ return false;
43
+ }
44
+ }
45
+ }, true); // Capture phase - intercept before any other handlers
46
+
47
+ // Override window.open to prevent app opening
48
+ var originalOpen = window.open;
49
+ window.open = function(url, target, features) {
50
+ if (isBlockedUrl(url)) {
51
+ console.log('🚫 [LINKEDIN-JS] Blocked window.open app link:', url);
52
+ return null;
53
+ }
54
+ return originalOpen.apply(this, arguments);
55
+ };
56
+
57
+ // Block location.href changes to app URLs
58
+ var originalLocation = window.location;
59
+ try {
60
+ Object.defineProperty(window, 'location', {
61
+ set: function(url) {
62
+ if (isBlockedUrl(url)) {
63
+ console.log('🚫 [LINKEDIN-JS] Blocked location.href change to app URL:', url);
64
+ return;
65
+ }
66
+ originalLocation.href = url;
67
+ },
68
+ get: function() {
69
+ return originalLocation;
70
+ },
71
+ configurable: true
72
+ });
73
+ } catch (e) {
74
+ // Fallback: Override location.href directly
75
+ var originalHref = Object.getOwnPropertyDescriptor(window.location, 'href');
76
+ if (originalHref && originalHref.set) {
77
+ Object.defineProperty(window.location, 'href', {
78
+ set: function(url) {
79
+ if (isBlockedUrl(url)) {
80
+ console.log('🚫 [LINKEDIN-JS] Blocked location.href setter to app URL:', url);
81
+ return;
82
+ }
83
+ originalHref.set.call(window.location, url);
84
+ },
85
+ get: originalHref.get,
86
+ configurable: true
87
+ });
88
+ }
89
+ }
90
+
91
+ // Block location.replace and location.assign
92
+ var originalReplace = window.location.replace;
93
+ window.location.replace = function(url) {
94
+ if (isBlockedUrl(url)) {
95
+ console.log('🚫 [LINKEDIN-JS] Blocked location.replace to app URL:', url);
96
+ return;
97
+ }
98
+ return originalReplace.call(window.location, url);
99
+ };
100
+
101
+ var originalAssign = window.location.assign;
102
+ window.location.assign = function(url) {
103
+ if (isBlockedUrl(url)) {
104
+ console.log('🚫 [LINKEDIN-JS] Blocked location.assign to app URL:', url);
105
+ return;
106
+ }
107
+ return originalAssign.call(window.location, url);
108
+ };
109
+
110
+ // Intercept meta refresh tags
111
+ var observer = new MutationObserver(function(mutations) {
112
+ mutations.forEach(function(mutation) {
113
+ mutation.addedNodes.forEach(function(node) {
114
+ if (node.nodeType === 1) { // Element node
115
+ if (node.tagName === 'META' && node.httpEquiv && node.httpEquiv.toLowerCase() === 'refresh') {
116
+ var content = node.content || node.getAttribute('content');
117
+ if (content && isBlockedUrl(content)) {
118
+ node.remove();
119
+ console.log('🚫 [LINKEDIN-JS] Removed meta refresh to app URL');
120
+ }
121
+ }
122
+ // Check all links in added nodes
123
+ var links = node.querySelectorAll ? node.querySelectorAll('a[href]') : [];
124
+ links.forEach(function(link) {
125
+ if (isBlockedUrl(link.href)) {
126
+ link.href = '#';
127
+ link.onclick = function(e) {
128
+ e.preventDefault();
129
+ e.stopPropagation();
130
+ return false;
131
+ };
132
+ console.log('🚫 [LINKEDIN-JS] Neutralized app deep link in added node');
133
+ }
134
+ });
135
+ }
136
+ });
137
+ });
138
+ });
139
+
140
+ // Start observing when DOM is ready
141
+ if (document.body) {
142
+ observer.observe(document.body, { childList: true, subtree: true });
143
+ } else {
144
+ document.addEventListener('DOMContentLoaded', function() {
145
+ observer.observe(document.body, { childList: true, subtree: true });
146
+ });
147
+ }
148
+
149
+ console.log('✅ [LINKEDIN-JS] App deep link blocker installed (comprehensive)');
150
+ } catch (e) {
151
+ console.error('❌ [LINKEDIN-JS] App blocker error:', e);
152
+ }
153
+ })();
154
+ true;
155
+ `;
156
+
157
+ /**
158
+ * LinkedIn Profile URL Extraction Script
159
+ * Injected ON DEMAND when user is on their profile page
160
+ * Uses 5 extraction methods for robustness (from iOS implementation)
161
+ * Based on iOS implementation: LinkedInConnectorView.swift lines 224-339
162
+ */
163
+ export const LINKEDIN_PROFILE_EXTRACTOR_SCRIPT = `
164
+ (function() {
165
+ try {
166
+ if (!document.body) {
167
+ window.ReactNativeWebView.postMessage(JSON.stringify({
168
+ status: 'error',
169
+ message: 'Page not ready'
170
+ }));
171
+ return;
172
+ }
173
+
174
+ // ========================================
175
+ // 5 EXTRACTION METHODS (from iOS)
176
+ // ========================================
177
+
178
+ /**
179
+ * Method 1: Check current URL for /in/ pattern
180
+ */
181
+ function extractFromCurrentUrl() {
182
+ var currentUrl = window.location.href;
183
+ var inMatch = currentUrl.match(/linkedin\\.com\\/in\\/([^\\/\\?]+)/);
184
+
185
+ if (inMatch) {
186
+ return 'https://www.linkedin.com/in/' + inMatch[1];
187
+ }
188
+
189
+ return null;
190
+ }
191
+
192
+ /**
193
+ * Method 2: Search all links for /in/ pattern
194
+ */
195
+ function extractFromLinks() {
196
+ var allLinks = document.querySelectorAll('a[href*="/in/"]');
197
+
198
+ for (var i = 0; i < allLinks.length; i++) {
199
+ var href = allLinks[i].getAttribute('href') || allLinks[i].href;
200
+
201
+ if (href && href.includes('/in/') && !href.includes('/me')) {
202
+ var match = href.match(/https?:\\/\\/[^\\/]+\\/in\\/([^\\/\\?]+)/);
203
+ if (match) {
204
+ return 'https://www.linkedin.com/in/' + match[1];
205
+ }
206
+ }
207
+ }
208
+
209
+ return null;
210
+ }
211
+
212
+ /**
213
+ * Method 3: Check meta tags
214
+ */
215
+ function extractFromMetaTags() {
216
+ var metaTags = document.querySelectorAll('meta');
217
+
218
+ for (var i = 0; i < metaTags.length; i++) {
219
+ var content = metaTags[i].getAttribute('content') ||
220
+ metaTags[i].getAttribute('property') || '';
221
+
222
+ if (content && content.includes('/in/')) {
223
+ var match = content.match(/https?:\\/\\/[^\\/]+\\/in\\/([^\\/\\?]+)/);
224
+ if (match) {
225
+ return 'https://www.linkedin.com/in/' + match[1];
226
+ }
227
+ }
228
+ }
229
+
230
+ return null;
231
+ }
232
+
233
+ /**
234
+ * Method 4: Check scripts for embedded URLs
235
+ */
236
+ function extractFromScripts() {
237
+ var scripts = document.querySelectorAll('script');
238
+
239
+ for (var i = 0; i < scripts.length; i++) {
240
+ var scriptText = scripts[i].textContent || '';
241
+ var match = scriptText.match(/https?:\\/\\/[^\\/]+\\/in\\/([^\\/\\?"']+)/);
242
+
243
+ if (match && !match[0].includes('/me')) {
244
+ return 'https://www.linkedin.com/in/' + match[1];
245
+ }
246
+ }
247
+
248
+ return null;
249
+ }
250
+
251
+ /**
252
+ * Method 5: Check data attributes
253
+ */
254
+ function extractFromDataAttributes() {
255
+ var dataElems = document.querySelectorAll('[data-profile-url], [data-entity-urn]');
256
+
257
+ for (var i = 0; i < dataElems.length; i++) {
258
+ var dataUrl = dataElems[i].getAttribute('data-profile-url') ||
259
+ dataElems[i].getAttribute('href') || '';
260
+
261
+ if (dataUrl && dataUrl.includes('/in/')) {
262
+ var match = dataUrl.match(/https?:\\/\\/[^\\/]+\\/in\\/([^\\/\\?]+)/);
263
+ if (match) {
264
+ return 'https://www.linkedin.com/in/' + match[1];
265
+ }
266
+ }
267
+ }
268
+
269
+ return null;
270
+ }
271
+
272
+ // ========================================
273
+ // EXECUTE EXTRACTION
274
+ // ========================================
275
+
276
+ console.log('🔍 Starting LinkedIn profile URL extraction...');
277
+
278
+ // Try all 5 methods in order
279
+ var profileUrl = extractFromCurrentUrl() ||
280
+ extractFromLinks() ||
281
+ extractFromMetaTags() ||
282
+ extractFromScripts() ||
283
+ extractFromDataAttributes();
284
+
285
+ if (profileUrl) {
286
+ console.log('✅ Profile URL extracted:', profileUrl);
287
+
288
+ // Send success to React Native
289
+ window.ReactNativeWebView.postMessage(JSON.stringify({
290
+ status: 'success',
291
+ profileUrl: profileUrl
292
+ }));
293
+ } else {
294
+ console.warn('⚠️ Could not find LinkedIn profile URL');
295
+
296
+ // Send error to React Native
297
+ window.ReactNativeWebView.postMessage(JSON.stringify({
298
+ status: 'error',
299
+ message: 'Could not find LinkedIn profile URL. Please navigate to your profile page.'
300
+ }));
301
+ }
302
+
303
+ } catch (error) {
304
+ console.error('❌ Error extracting profile URL:', error);
305
+
306
+ // Send error to React Native
307
+ window.ReactNativeWebView.postMessage(JSON.stringify({
308
+ status: 'error',
309
+ message: 'JavaScript error: ' + (error.message || String(error))
310
+ }));
311
+ }
312
+ })();
313
+ true; // Required for iOS compatibility
314
+ `;
315
+
316
+ /**
317
+ * LinkedIn navigation script to go to user's profile page
318
+ * Used after OAuth callback to navigate to /me
319
+ */
320
+ export const LINKEDIN_NAVIGATE_TO_PROFILE_SCRIPT = `
321
+ (function() {
322
+ try {
323
+ // Try clicking the "Me" menu item or profile link
324
+ var meLink = document.querySelector('a[href*="/me"]') ||
325
+ document.querySelector('a[href*="/in/"][href*="profile"]') ||
326
+ document.querySelector('[data-control-name="identity_welcome_message"]') ||
327
+ document.querySelector('a[aria-label*="Profile"]') ||
328
+ document.querySelector('a[aria-label*="Me"]');
329
+ if (meLink) {
330
+ console.log('[LINKEDIN] Found profile link, clicking...');
331
+ meLink.click();
332
+ return true;
333
+ }
334
+ // Fallback: navigate directly
335
+ console.log('[LINKEDIN] No profile link found, navigating directly to /me');
336
+ window.location.href = 'https://www.linkedin.com/me';
337
+ return false;
338
+ } catch (e) {
339
+ console.error('[LINKEDIN] Navigation error:', e);
340
+ window.location.href = 'https://www.linkedin.com/me';
341
+ return false;
342
+ }
343
+ })();
344
+ true;
345
+ `;
346
+
347
+ /**
348
+ * LinkedIn Profile Data Consent Popup Script
349
+ * Shows user consent UI before extracting profile data from DOM
350
+ * Based on ChatGPT consent popup pattern
351
+ */
352
+ export const LINKEDIN_PROFILE_CONSENT_POPUP_SCRIPT = `
353
+ (function() {
354
+ try {
355
+ const existing = document.getElementById('onairos-linkedin-consent-overlay');
356
+ if (existing) existing.remove();
357
+
358
+ const overlay = document.createElement('div');
359
+ overlay.id = 'onairos-linkedin-consent-overlay';
360
+ overlay.style.cssText = \`
361
+ position: fixed;
362
+ top: 0;
363
+ left: 0;
364
+ width: 100%;
365
+ height: 100%;
366
+ background: rgba(0, 0, 0, 0.7);
367
+ z-index: 999999;
368
+ display: flex;
369
+ align-items: center;
370
+ justify-content: center;
371
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
372
+ \`;
373
+
374
+ const popup = document.createElement('div');
375
+ popup.style.cssText = \`
376
+ background: white;
377
+ border-radius: 16px;
378
+ padding: 32px;
379
+ max-width: 400px;
380
+ width: 90%;
381
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
382
+ \`;
383
+
384
+ popup.innerHTML = \`
385
+ <div style="text-align: center;">
386
+ <div style="font-size: 48px; margin-bottom: 16px;">💼</div>
387
+ <h2 style="margin: 0 0 12px 0; font-size: 24px; color: #1a1a1a;">
388
+ Import LinkedIn Profile?
389
+ </h2>
390
+ <p style="margin: 0 0 24px 0; color: #666; font-size: 16px; line-height: 1.5;">
391
+ Allow Onairos to import your LinkedIn profile data including bio, work history, education, and skills?
392
+ </p>
393
+ <div style="display: flex; gap: 12px; justify-content: center;">
394
+ <button id="onairos-linkedin-deny" style="
395
+ flex: 1;
396
+ padding: 14px 24px;
397
+ border: 2px solid #e0e0e0;
398
+ background: white;
399
+ color: #666;
400
+ border-radius: 8px;
401
+ font-size: 16px;
402
+ font-weight: 600;
403
+ cursor: pointer;
404
+ ">Deny</button>
405
+ <button id="onairos-linkedin-allow" style="
406
+ flex: 1;
407
+ padding: 14px 24px;
408
+ border: none;
409
+ background: #0077B5;
410
+ color: white;
411
+ border-radius: 8px;
412
+ font-size: 16px;
413
+ font-weight: 600;
414
+ cursor: pointer;
415
+ ">Allow</button>
416
+ </div>
417
+ </div>
418
+ \`;
419
+
420
+ overlay.appendChild(popup);
421
+ document.body.appendChild(overlay);
422
+
423
+ document.getElementById('onairos-linkedin-deny').onclick = () => {
424
+ overlay.remove();
425
+ window.ReactNativeWebView.postMessage(JSON.stringify({
426
+ type: 'LINKEDIN_PROFILE_CONSENT',
427
+ status: 'denied'
428
+ }));
429
+ };
430
+
431
+ document.getElementById('onairos-linkedin-allow').onclick = () => {
432
+ document.getElementById('onairos-linkedin-allow').innerHTML = '⏳ Extracting...';
433
+ document.getElementById('onairos-linkedin-allow').disabled = true;
434
+
435
+ window.ReactNativeWebView.postMessage(JSON.stringify({
436
+ type: 'LINKEDIN_PROFILE_CONSENT',
437
+ status: 'allowed'
438
+ }));
439
+
440
+ setTimeout(() => overlay.remove(), 500);
441
+ };
442
+ } catch (error) {
443
+ window.ReactNativeWebView.postMessage(JSON.stringify({
444
+ type: 'LINKEDIN_PROFILE_CONSENT',
445
+ status: 'error',
446
+ message: error.message
447
+ }));
448
+ }
449
+ })();
450
+ true;
451
+ `;
452
+
453
+ /**
454
+ * LinkedIn Profile DOM Scraper Script
455
+ * Extracts profile data directly from the LinkedIn profile page DOM
456
+ *
457
+ * This script extracts:
458
+ * - Basic info (name, headline, location, about)
459
+ * - Profile URL
460
+ * - Work experience
461
+ * - Education
462
+ * - Skills
463
+ *
464
+ * NOTE: LinkedIn's DOM structure changes frequently.
465
+ * If extraction fails, inspect the page and update selectors.
466
+ *
467
+ * Common selector patterns for LinkedIn profile pages:
468
+ * - Name: h1, .text-heading-xlarge, [data-anonymize="person-name"]
469
+ * - Headline: .text-body-medium, [data-anonymize="headline"]
470
+ * - Location: .text-body-small, span with location text
471
+ * - About: section with id="about" or class containing "about"
472
+ * - Experience: section with id="experience"
473
+ * - Education: section with id="education"
474
+ * - Skills: section with id="skills"
475
+ */
476
+ export const LINKEDIN_PROFILE_SCRAPER_SCRIPT = `
477
+ (function() {
478
+ try {
479
+ console.log('🔍 [LINKEDIN] Starting profile DOM extraction...');
480
+
481
+ window.ReactNativeWebView.postMessage(JSON.stringify({
482
+ type: 'LINKEDIN_PROFILE_PROGRESS',
483
+ stage: 'starting',
484
+ progress: 5,
485
+ message: 'Starting profile extraction...'
486
+ }));
487
+
488
+ // ========================================
489
+ // HELPER FUNCTIONS
490
+ // ========================================
491
+
492
+ function getTextContent(selector, parent = document) {
493
+ const el = parent.querySelector(selector);
494
+ return el ? el.textContent.trim() : '';
495
+ }
496
+
497
+ function getAllTextContent(selector, parent = document) {
498
+ const elements = parent.querySelectorAll(selector);
499
+ return Array.from(elements).map(el => el.textContent.trim()).filter(t => t);
500
+ }
501
+
502
+ function cleanText(text) {
503
+ if (!text) return '';
504
+ return text.replace(/\\s+/g, ' ').trim();
505
+ }
506
+
507
+ // ========================================
508
+ // EXTRACT BASIC INFO
509
+ // ========================================
510
+
511
+ window.ReactNativeWebView.postMessage(JSON.stringify({
512
+ type: 'LINKEDIN_PROFILE_PROGRESS',
513
+ stage: 'basic_info',
514
+ progress: 10,
515
+ message: 'Extracting basic info...'
516
+ }));
517
+
518
+ // Name - try multiple selectors
519
+ let fullName = '';
520
+ const nameSelectors = [
521
+ 'h1',
522
+ '.text-heading-xlarge',
523
+ '[data-anonymize="person-name"]',
524
+ '.pv-text-details__left-panel h1',
525
+ '.profile-topcard-person-entity__name'
526
+ ];
527
+ for (const sel of nameSelectors) {
528
+ const name = getTextContent(sel);
529
+ if (name && name.length > 1 && name.length < 100) {
530
+ fullName = cleanText(name);
531
+ break;
532
+ }
533
+ }
534
+ console.log('📛 [LINKEDIN] Name:', fullName);
535
+
536
+ // Headline - try multiple selectors
537
+ let headline = '';
538
+ const headlineSelectors = [
539
+ '.text-body-medium.break-words',
540
+ '[data-anonymize="headline"]',
541
+ '.pv-text-details__left-panel .text-body-medium',
542
+ '.profile-topcard__summary-position-title'
543
+ ];
544
+ for (const sel of headlineSelectors) {
545
+ const h = getTextContent(sel);
546
+ if (h && h.length > 3) {
547
+ headline = cleanText(h);
548
+ break;
549
+ }
550
+ }
551
+ console.log('📋 [LINKEDIN] Headline:', headline);
552
+
553
+ // Location
554
+ let location = '';
555
+ const locationSelectors = [
556
+ '.text-body-small.inline.t-black--light.break-words',
557
+ '.pv-text-details__left-panel .text-body-small',
558
+ '[data-anonymize="location"]',
559
+ '.profile-topcard__location-data'
560
+ ];
561
+ for (const sel of locationSelectors) {
562
+ const loc = getTextContent(sel);
563
+ if (loc && loc.length > 2 && !loc.includes('connections') && !loc.includes('followers')) {
564
+ location = cleanText(loc);
565
+ break;
566
+ }
567
+ }
568
+ console.log('📍 [LINKEDIN] Location:', location);
569
+
570
+ // Profile URL
571
+ const profileUrl = window.location.href.split('?')[0];
572
+ console.log('🔗 [LINKEDIN] Profile URL:', profileUrl);
573
+
574
+ // ========================================
575
+ // EXTRACT ABOUT SECTION
576
+ // ========================================
577
+
578
+ window.ReactNativeWebView.postMessage(JSON.stringify({
579
+ type: 'LINKEDIN_PROFILE_PROGRESS',
580
+ stage: 'about',
581
+ progress: 25,
582
+ message: 'Extracting about section...'
583
+ }));
584
+
585
+ let about = '';
586
+
587
+ // Try to find About section
588
+ const aboutSection = document.querySelector('#about') ||
589
+ document.querySelector('[id*="about"]') ||
590
+ document.querySelector('section:has(> div > div > span:contains("About"))');
591
+
592
+ if (aboutSection) {
593
+ // Look for the about text within the section
594
+ const aboutTextSelectors = [
595
+ '.display-flex.ph5.pv3 span[aria-hidden="true"]',
596
+ '.pv-shared-text-with-see-more span',
597
+ '.inline-show-more-text span',
598
+ 'span[aria-hidden="true"]',
599
+ '.full-width span'
600
+ ];
601
+
602
+ for (const sel of aboutTextSelectors) {
603
+ const texts = aboutSection.querySelectorAll(sel);
604
+ if (texts.length > 0) {
605
+ about = cleanText(Array.from(texts).map(t => t.textContent).join(' '));
606
+ if (about.length > 20) break;
607
+ }
608
+ }
609
+ }
610
+
611
+ // Alternative: look for about text near "About" heading
612
+ if (!about) {
613
+ const allSpans = document.querySelectorAll('span');
614
+ let foundAboutHeading = false;
615
+ for (const span of allSpans) {
616
+ if (span.textContent.trim() === 'About') {
617
+ foundAboutHeading = true;
618
+ continue;
619
+ }
620
+ if (foundAboutHeading && span.textContent.length > 50) {
621
+ about = cleanText(span.textContent);
622
+ break;
623
+ }
624
+ }
625
+ }
626
+ console.log('📝 [LINKEDIN] About (preview):', about.substring(0, 100) + '...');
627
+
628
+ // ========================================
629
+ // EXTRACT EXPERIENCE
630
+ // ========================================
631
+
632
+ window.ReactNativeWebView.postMessage(JSON.stringify({
633
+ type: 'LINKEDIN_PROFILE_PROGRESS',
634
+ stage: 'experience',
635
+ progress: 40,
636
+ message: 'Extracting work experience...'
637
+ }));
638
+
639
+ const experience = [];
640
+
641
+ // Find experience section
642
+ const expSection = document.querySelector('#experience') ||
643
+ document.querySelector('[id*="experience"]') ||
644
+ document.querySelector('section.experience-section');
645
+
646
+ if (expSection) {
647
+ // Look for experience entries - LinkedIn uses list items
648
+ const expItems = expSection.querySelectorAll('li.artdeco-list__item, li[class*="experience-item"], ul > li');
649
+
650
+ for (const item of expItems) {
651
+ const entry = {};
652
+
653
+ // Title - usually the first/main heading in the item
654
+ const titleEl = item.querySelector('.t-bold span, .mr1.t-bold span, [data-anonymize="job-title"]');
655
+ if (titleEl) entry.title = cleanText(titleEl.textContent);
656
+
657
+ // Company
658
+ const companyEl = item.querySelector('.t-normal span, .t-14.t-normal span, [data-anonymize="company-name"]');
659
+ if (companyEl) entry.company = cleanText(companyEl.textContent);
660
+
661
+ // Duration/dates
662
+ const dateEl = item.querySelector('.t-black--light span, .pvs-entity__caption-wrapper');
663
+ if (dateEl) entry.duration = cleanText(dateEl.textContent);
664
+
665
+ // Description
666
+ const descEl = item.querySelector('.display-flex.align-items-center span[aria-hidden="true"], .inline-show-more-text');
667
+ if (descEl) entry.description = cleanText(descEl.textContent);
668
+
669
+ // Location
670
+ const locEl = item.querySelector('.t-black--light.t-normal span:last-child');
671
+ if (locEl) entry.location = cleanText(locEl.textContent);
672
+
673
+ if (entry.title || entry.company) {
674
+ experience.push(entry);
675
+ }
676
+ }
677
+ }
678
+ console.log('💼 [LINKEDIN] Experience entries:', experience.length);
679
+
680
+ // ========================================
681
+ // EXTRACT EDUCATION
682
+ // ========================================
683
+
684
+ window.ReactNativeWebView.postMessage(JSON.stringify({
685
+ type: 'LINKEDIN_PROFILE_PROGRESS',
686
+ stage: 'education',
687
+ progress: 60,
688
+ message: 'Extracting education...'
689
+ }));
690
+
691
+ const education = [];
692
+
693
+ // Find education section
694
+ const eduSection = document.querySelector('#education') ||
695
+ document.querySelector('[id*="education"]') ||
696
+ document.querySelector('section.education-section');
697
+
698
+ if (eduSection) {
699
+ const eduItems = eduSection.querySelectorAll('li.artdeco-list__item, li[class*="education-item"], ul > li');
700
+
701
+ for (const item of eduItems) {
702
+ const entry = {};
703
+
704
+ // School name
705
+ const schoolEl = item.querySelector('.t-bold span, .mr1.t-bold span, [data-anonymize="school-name"]');
706
+ if (schoolEl) entry.school = cleanText(schoolEl.textContent);
707
+
708
+ // Degree
709
+ const degreeEl = item.querySelector('.t-normal span, .t-14.t-normal span');
710
+ if (degreeEl) entry.degree = cleanText(degreeEl.textContent);
711
+
712
+ // Field of study (sometimes combined with degree)
713
+ const fieldEl = item.querySelector('.pv-entity__comma-item');
714
+ if (fieldEl) entry.fieldOfStudy = cleanText(fieldEl.textContent);
715
+
716
+ // Years
717
+ const yearsEl = item.querySelector('.t-black--light span, .pvs-entity__caption-wrapper');
718
+ if (yearsEl) entry.years = cleanText(yearsEl.textContent);
719
+
720
+ if (entry.school) {
721
+ education.push(entry);
722
+ }
723
+ }
724
+ }
725
+ console.log('🎓 [LINKEDIN] Education entries:', education.length);
726
+
727
+ // ========================================
728
+ // EXTRACT SKILLS
729
+ // ========================================
730
+
731
+ window.ReactNativeWebView.postMessage(JSON.stringify({
732
+ type: 'LINKEDIN_PROFILE_PROGRESS',
733
+ stage: 'skills',
734
+ progress: 80,
735
+ message: 'Extracting skills...'
736
+ }));
737
+
738
+ const skills = [];
739
+
740
+ // Find skills section
741
+ const skillsSection = document.querySelector('#skills') ||
742
+ document.querySelector('[id*="skills"]') ||
743
+ document.querySelector('section.skills-section');
744
+
745
+ if (skillsSection) {
746
+ const skillItems = skillsSection.querySelectorAll('.t-bold span, [data-anonymize="skill-name"], .pv-skill-category-entity__name-text');
747
+
748
+ for (const item of skillItems) {
749
+ const skill = cleanText(item.textContent);
750
+ if (skill && skill.length > 1 && skill.length < 100 && !skills.includes(skill)) {
751
+ skills.push(skill);
752
+ }
753
+ }
754
+ }
755
+
756
+ // Also check for skills in "Top skills" section on profile card
757
+ const topSkillsSection = document.querySelector('.pv-skill-category-list');
758
+ if (topSkillsSection) {
759
+ const topSkillItems = topSkillsSection.querySelectorAll('span');
760
+ for (const item of topSkillItems) {
761
+ const skill = cleanText(item.textContent);
762
+ if (skill && skill.length > 1 && skill.length < 100 && !skills.includes(skill)) {
763
+ skills.push(skill);
764
+ }
765
+ }
766
+ }
767
+ console.log('🛠️ [LINKEDIN] Skills:', skills.length);
768
+
769
+ // ========================================
770
+ // EXTRACT ADDITIONAL INFO
771
+ // ========================================
772
+
773
+ // Connections count
774
+ let connections = 0;
775
+ const connectionsEl = document.querySelector('.t-bold:has(+ span:contains("connections")), .pv-top-card--list-bullet span');
776
+ if (connectionsEl) {
777
+ const connText = connectionsEl.textContent;
778
+ const connMatch = connText.match(/([\\d,]+)\\+?\\s*connections?/i);
779
+ if (connMatch) {
780
+ connections = parseInt(connMatch[1].replace(/,/g, ''));
781
+ }
782
+ }
783
+
784
+ // Profile picture URL
785
+ let profilePicture = '';
786
+ const imgEl = document.querySelector('.pv-top-card-profile-picture__image, .profile-photo-edit__preview, img[data-anonymize="headshot-photo"]');
787
+ if (imgEl && imgEl.src) {
788
+ profilePicture = imgEl.src;
789
+ }
790
+
791
+ // ========================================
792
+ // BUILD RESULT OBJECT
793
+ // ========================================
794
+
795
+ window.ReactNativeWebView.postMessage(JSON.stringify({
796
+ type: 'LINKEDIN_PROFILE_PROGRESS',
797
+ stage: 'finalizing',
798
+ progress: 95,
799
+ message: 'Finalizing extraction...'
800
+ }));
801
+
802
+ const profileData = {
803
+ // Basic Info
804
+ fullName: fullName,
805
+ headline: headline,
806
+ location: location,
807
+ about: about,
808
+ profileUrl: profileUrl,
809
+
810
+ // Profile Details
811
+ profilePicture: profilePicture,
812
+
813
+ // Professional Info
814
+ experience: experience,
815
+ education: education,
816
+ skills: skills,
817
+
818
+ // Additional Info
819
+ connections: connections,
820
+
821
+ // Metadata
822
+ scrapedAt: new Date().toISOString(),
823
+ extractionMethod: 'dom_scraper'
824
+ };
825
+
826
+ console.log('✅ [LINKEDIN] Profile extraction complete!');
827
+ console.log('📊 [LINKEDIN] Summary:', {
828
+ name: fullName,
829
+ headline: headline.substring(0, 50),
830
+ experienceCount: experience.length,
831
+ educationCount: education.length,
832
+ skillsCount: skills.length
833
+ });
834
+
835
+ // ========================================
836
+ // SEND RESULT TO REACT NATIVE
837
+ // ========================================
838
+
839
+ window.ReactNativeWebView.postMessage(JSON.stringify({
840
+ type: 'LINKEDIN_PROFILE_EXPORT_COMPLETE',
841
+ status: 'success',
842
+ data: profileData,
843
+ success: true
844
+ }));
845
+
846
+ } catch (error) {
847
+ console.error('❌ [LINKEDIN] Profile extraction error:', error);
848
+ window.ReactNativeWebView.postMessage(JSON.stringify({
849
+ type: 'LINKEDIN_PROFILE_EXPORT_ERROR',
850
+ status: 'error',
851
+ message: 'Extraction failed: ' + error.message,
852
+ success: false
853
+ }));
854
+ }
855
+ })();
856
+ true;
857
+ `;
858
+
859
+ /**
860
+ * Success/Error notification scripts for LinkedIn
861
+ */
862
+ export const LINKEDIN_PROFILE_SUCCESS_SCRIPT = `
863
+ (function() {
864
+ console.log('✅ LinkedIn profile export successful!');
865
+ })();
866
+ true;
867
+ `;
868
+ export const LINKEDIN_PROFILE_ERROR_SCRIPT = `
869
+ (function() {
870
+ console.log('❌ LinkedIn profile export failed!');
871
+ })();
872
+ true;
873
+ `;
874
+ //# sourceMappingURL=linkedin.js.map