@swiftbrowser/swift 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (400) hide show
  1. package/Package.swift +214 -0
  2. package/README.md +10 -2
  3. package/Sources/AVFoundation/AVFoundation.swift +131 -0
  4. package/Sources/AVFoundation/Asset.swift +487 -0
  5. package/Sources/AVFoundation/AudioSession.swift +144 -0
  6. package/Sources/AVFoundation/CMTime.swift +303 -0
  7. package/Sources/AVFoundation/Capture.swift +688 -0
  8. package/Sources/AVFoundation/Player.swift +749 -0
  9. package/Sources/AVFoundation/PlayerView.swift +117 -0
  10. package/Sources/AVKit/AVKit.swift +132 -0
  11. package/Sources/Accelerate/Accelerate.swift +122 -0
  12. package/Sources/AppIntents/AppIntents.swift +144 -0
  13. package/Sources/AppIntents/Parameters.swift +220 -0
  14. package/Sources/AppIntents/Shortcuts.swift +159 -0
  15. package/Sources/AudioToolbox/AudioToolbox.swift +55 -0
  16. package/Sources/AuthenticationServices/AuthenticationServices.swift +257 -0
  17. package/Sources/AuthenticationServices/Authorization.swift +251 -0
  18. package/Sources/Charts/Charts.swift +61 -0
  19. package/Sources/Combine/AnyCancellable.swift +65 -0
  20. package/Sources/Combine/AnyPublisher.swift +148 -0
  21. package/Sources/Combine/AnySubscriber.swift +230 -0
  22. package/Sources/Combine/Cancellable.swift +35 -0
  23. package/Sources/Combine/Codable.swift +29 -0
  24. package/Sources/Combine/CombineIdentifier.swift +45 -0
  25. package/Sources/Combine/Concurrency/ConcurrencyHelpers.swift +24 -0
  26. package/Sources/Combine/Concurrency/Future+Concurrency.swift +136 -0
  27. package/Sources/Combine/Concurrency/GENERATED-Publisher+Concurrency.swift +397 -0
  28. package/Sources/Combine/CurrentValueSubject.swift +252 -0
  29. package/Sources/Combine/CustomCombineIdentifierConvertible.swift +28 -0
  30. package/Sources/Combine/Future.swift +228 -0
  31. package/Sources/Combine/GENERATED-RootProtocols.swift +426 -0
  32. package/Sources/Combine/Helpers/ConduitBase.swift +40 -0
  33. package/Sources/Combine/Helpers/ConduitList.swift +59 -0
  34. package/Sources/Combine/Helpers/DebugHook.swift +177 -0
  35. package/Sources/Combine/Helpers/FilterProducer.swift +174 -0
  36. package/Sources/Combine/Helpers/Locking.swift +30 -0
  37. package/Sources/Combine/Helpers/PartialCompletion.swift +26 -0
  38. package/Sources/Combine/Helpers/ReduceProducer.swift +249 -0
  39. package/Sources/Combine/Helpers/SubjectSubscriber.swift +96 -0
  40. package/Sources/Combine/Helpers/SubscriberTap.swift +69 -0
  41. package/Sources/Combine/Helpers/SubscriptionStatus.swift +33 -0
  42. package/Sources/Combine/Helpers/SubscriptionTap.swift +33 -0
  43. package/Sources/Combine/Helpers/Utils.swift +30 -0
  44. package/Sources/Combine/Helpers/Violations.swift +33 -0
  45. package/Sources/Combine/ImmediateScheduler.swift +178 -0
  46. package/Sources/Combine/LICENSE +21 -0
  47. package/Sources/Combine/NotificationPublisher.swift +48 -0
  48. package/Sources/Combine/ObjectWillChange.swift +46 -0
  49. package/Sources/Combine/PassthroughSubject.swift +222 -0
  50. package/Sources/Combine/Publisher+Subscribe.swift +53 -0
  51. package/Sources/Combine/Publishers/Deferred.swift +48 -0
  52. package/Sources/Combine/Publishers/Empty.swift +54 -0
  53. package/Sources/Combine/Publishers/Fail.swift +42 -0
  54. package/Sources/Combine/Publishers/GENERATED-Publishers.Catch.swift +673 -0
  55. package/Sources/Combine/Publishers/GENERATED-Publishers.Encode.swift +388 -0
  56. package/Sources/Combine/Publishers/GENERATED-Publishers.MapKeyPath.swift +384 -0
  57. package/Sources/Combine/Publishers/Just.swift +313 -0
  58. package/Sources/Combine/Publishers/Optional.Publisher.swift +315 -0
  59. package/Sources/Combine/Publishers/Publishers.AllSatisfy.swift +217 -0
  60. package/Sources/Combine/Publishers/Publishers.AssertNoFailure.swift +158 -0
  61. package/Sources/Combine/Publishers/Publishers.Autoconnect.swift +193 -0
  62. package/Sources/Combine/Publishers/Publishers.Breakpoint.swift +231 -0
  63. package/Sources/Combine/Publishers/Publishers.Buffer.swift +356 -0
  64. package/Sources/Combine/Publishers/Publishers.Collect.swift +102 -0
  65. package/Sources/Combine/Publishers/Publishers.CollectByCount.swift +195 -0
  66. package/Sources/Combine/Publishers/Publishers.CompactMap.swift +241 -0
  67. package/Sources/Combine/Publishers/Publishers.Comparison.swift +371 -0
  68. package/Sources/Combine/Publishers/Publishers.Concatenate.swift +474 -0
  69. package/Sources/Combine/Publishers/Publishers.Contains.swift +293 -0
  70. package/Sources/Combine/Publishers/Publishers.Count.swift +87 -0
  71. package/Sources/Combine/Publishers/Publishers.Debounce.swift +332 -0
  72. package/Sources/Combine/Publishers/Publishers.Delay.swift +269 -0
  73. package/Sources/Combine/Publishers/Publishers.Drop.swift +155 -0
  74. package/Sources/Combine/Publishers/Publishers.DropUntilOutput.swift +283 -0
  75. package/Sources/Combine/Publishers/Publishers.DropWhile.swift +378 -0
  76. package/Sources/Combine/Publishers/Publishers.Filter.swift +248 -0
  77. package/Sources/Combine/Publishers/Publishers.First.swift +261 -0
  78. package/Sources/Combine/Publishers/Publishers.FlatMap.swift +533 -0
  79. package/Sources/Combine/Publishers/Publishers.HandleEvents.swift +260 -0
  80. package/Sources/Combine/Publishers/Publishers.IgnoreOutput.swift +109 -0
  81. package/Sources/Combine/Publishers/Publishers.Last.swift +252 -0
  82. package/Sources/Combine/Publishers/Publishers.MakeConnectable.swift +82 -0
  83. package/Sources/Combine/Publishers/Publishers.Map.swift +351 -0
  84. package/Sources/Combine/Publishers/Publishers.MapError.swift +140 -0
  85. package/Sources/Combine/Publishers/Publishers.MeasureInterval.swift +187 -0
  86. package/Sources/Combine/Publishers/Publishers.Multicast.swift +284 -0
  87. package/Sources/Combine/Publishers/Publishers.Output.swift +241 -0
  88. package/Sources/Combine/Publishers/Publishers.PrefixUntilOutput.swift +197 -0
  89. package/Sources/Combine/Publishers/Publishers.PrefixWhile.swift +176 -0
  90. package/Sources/Combine/Publishers/Publishers.Print.swift +206 -0
  91. package/Sources/Combine/Publishers/Publishers.ReceiveOn.swift +227 -0
  92. package/Sources/Combine/Publishers/Publishers.Reduce.swift +204 -0
  93. package/Sources/Combine/Publishers/Publishers.RemoveDuplicates.swift +264 -0
  94. package/Sources/Combine/Publishers/Publishers.ReplaceEmpty.swift +201 -0
  95. package/Sources/Combine/Publishers/Publishers.ReplaceError.swift +211 -0
  96. package/Sources/Combine/Publishers/Publishers.Retry.swift +274 -0
  97. package/Sources/Combine/Publishers/Publishers.Scan.swift +331 -0
  98. package/Sources/Combine/Publishers/Publishers.Sequence.swift +437 -0
  99. package/Sources/Combine/Publishers/Publishers.SetFailureType.swift +120 -0
  100. package/Sources/Combine/Publishers/Publishers.Share.swift +104 -0
  101. package/Sources/Combine/Publishers/Publishers.SubscribeOn.swift +197 -0
  102. package/Sources/Combine/Publishers/Publishers.SwitchToLatest.swift +444 -0
  103. package/Sources/Combine/Publishers/Publishers.Throttle.swift +359 -0
  104. package/Sources/Combine/Publishers/Publishers.Timeout.swift +301 -0
  105. package/Sources/Combine/Publishers/Publishers.Zip.swift +720 -0
  106. package/Sources/Combine/Publishers/Publishers.swift +13 -0
  107. package/Sources/Combine/Publishers/Record.swift +237 -0
  108. package/Sources/Combine/Publishers/Result.Publisher.swift +337 -0
  109. package/Sources/Combine/Result.swift +46 -0
  110. package/Sources/Combine/Scheduler.swift +89 -0
  111. package/Sources/Combine/Schedulers.swift +211 -0
  112. package/Sources/Combine/Subject+Void.swift +17 -0
  113. package/Sources/Combine/Subscriber+Void.swift +20 -0
  114. package/Sources/Combine/Subscribers/Subscribers.Assign.swift +175 -0
  115. package/Sources/Combine/Subscribers/Subscribers.Completion.swift +90 -0
  116. package/Sources/Combine/Subscribers/Subscribers.Demand.swift +476 -0
  117. package/Sources/Combine/Subscribers/Subscribers.Sink.swift +206 -0
  118. package/Sources/Combine/Subscribers/Subscribers.swift +9 -0
  119. package/Sources/Combine/Subscription.swift +22 -0
  120. package/Sources/Combine/Subscriptions.swift +42 -0
  121. package/Sources/Combine/SwiftUIObservation.swift +10 -0
  122. package/Sources/Combine/_Introspection.swift +107 -0
  123. package/Sources/CommonCrypto/CommonCrypto.swift +80 -0
  124. package/Sources/Compression/Compression.swift +365 -0
  125. package/Sources/Compression/Deflate.swift +407 -0
  126. package/Sources/Compression/Zlib.swift +179 -0
  127. package/Sources/CoreFoundationTypes/CoreFoundationTypes.swift +101 -0
  128. package/Sources/CoreGraphics/CoreGraphics.swift +411 -0
  129. package/Sources/CoreGraphics/ProjectionTransforms.swift +28 -0
  130. package/Sources/CoreHaptics/CoreHaptics.swift +399 -0
  131. package/Sources/CoreImage/CIColor.swift +41 -0
  132. package/Sources/CoreImage/CIContext.swift +31 -0
  133. package/Sources/CoreImage/CIDetector.swift +57 -0
  134. package/Sources/CoreImage/CIFilter.swift +243 -0
  135. package/Sources/CoreImage/CIFilterBuiltins.swift +136 -0
  136. package/Sources/CoreImage/CIImage.swift +162 -0
  137. package/Sources/CoreImage/QRCode.swift +393 -0
  138. package/Sources/CoreLocation/Coordinate.swift +30 -0
  139. package/Sources/CoreLocation/Location.swift +65 -0
  140. package/Sources/CoreML/Evaluation.swift +414 -0
  141. package/Sources/CoreML/FeatureValue.swift +266 -0
  142. package/Sources/CoreML/Model.swift +269 -0
  143. package/Sources/CoreML/MultiArray.swift +92 -0
  144. package/Sources/CoreML/Specification.swift +233 -0
  145. package/Sources/CoreText/CoreText.swift +64 -0
  146. package/Sources/CoreTransferable/CoreTransferable.swift +606 -0
  147. package/Sources/CryptoKit/ChaChaPoly.swift +258 -0
  148. package/Sources/CryptoKit/CryptoKit.swift +375 -0
  149. package/Sources/CryptoKit/Curve25519.swift +317 -0
  150. package/Sources/CryptoKit/P256.swift +321 -0
  151. package/Sources/FoundationBridge/AppStorage.swift +165 -0
  152. package/Sources/FoundationBridge/AssetResources.swift +90 -0
  153. package/Sources/FoundationBridge/AsyncBytes.swift +128 -0
  154. package/Sources/FoundationBridge/AsyncImage.swift +116 -0
  155. package/Sources/FoundationBridge/AttributedStrings.swift +16 -0
  156. package/Sources/FoundationBridge/Bundle.swift +119 -0
  157. package/Sources/FoundationBridge/CombineExports.swift +8 -0
  158. package/Sources/FoundationBridge/CoreFoundation.swift +77 -0
  159. package/Sources/FoundationBridge/Dispatch.swift +458 -0
  160. package/Sources/FoundationBridge/EnvironmentFoundation.swift +41 -0
  161. package/Sources/FoundationBridge/FileImporter.swift +128 -0
  162. package/Sources/FoundationBridge/FileSystem.swift +68 -0
  163. package/Sources/FoundationBridge/FoundationBridge.swift +29 -0
  164. package/Sources/FoundationBridge/HostResolution.swift +31 -0
  165. package/Sources/FoundationBridge/ItemProvider.swift +655 -0
  166. package/Sources/FoundationBridge/KeyValueObserving.swift +138 -0
  167. package/Sources/FoundationBridge/Links.swift +127 -0
  168. package/Sources/FoundationBridge/ListFormatter.swift +32 -0
  169. package/Sources/FoundationBridge/Locale.swift +86 -0
  170. package/Sources/FoundationBridge/Localization.swift +149 -0
  171. package/Sources/FoundationBridge/Locks.swift +50 -0
  172. package/Sources/FoundationBridge/Markdown.swift +527 -0
  173. package/Sources/FoundationBridge/MeasurementFormat.swift +95 -0
  174. package/Sources/FoundationBridge/NotificationCenter.swift +154 -0
  175. package/Sources/FoundationBridge/OpenURLHandlers.swift +60 -0
  176. package/Sources/FoundationBridge/Operation.swift +195 -0
  177. package/Sources/FoundationBridge/ProcessInfo.swift +32 -0
  178. package/Sources/FoundationBridge/RelativeDateTimeFormatter.swift +136 -0
  179. package/Sources/FoundationBridge/SceneStorage.swift +78 -0
  180. package/Sources/FoundationBridge/SecurityExports.swift +8 -0
  181. package/Sources/FoundationBridge/Selector.swift +226 -0
  182. package/Sources/FoundationBridge/StringComparators.swift +17 -0
  183. package/Sources/FoundationBridge/Table.swift +211 -0
  184. package/Sources/FoundationBridge/TextAttributes.swift +42 -0
  185. package/Sources/FoundationBridge/Timer.swift +53 -0
  186. package/Sources/FoundationBridge/UITextChecker.swift +30 -0
  187. package/Sources/FoundationBridge/URLSession.swift +718 -0
  188. package/Sources/FoundationBridge/UserDefaults.swift +183 -0
  189. package/Sources/FoundationBridge/WebAuthRedirects.swift +227 -0
  190. package/Sources/FoundationBridge/WebSocket.swift +187 -0
  191. package/Sources/FoundationModels/FoundationModels.swift +1098 -0
  192. package/Sources/ImageIO/GIF.swift +72 -0
  193. package/Sources/ImageIO/ImageIO.swift +248 -0
  194. package/Sources/ImageIO/ImageTypes.swift +28 -0
  195. package/Sources/LinkPresentation/LinkPresentation.swift +249 -0
  196. package/Sources/LocalAuthentication/LAContext.swift +86 -0
  197. package/Sources/MapKit/Geometry.swift +223 -0
  198. package/Sources/MapKit/Map.swift +638 -0
  199. package/Sources/MapKit/MapView.swift +229 -0
  200. package/Sources/MobileCoreServices/MobileCoreServices.swift +28 -0
  201. package/Sources/NaturalLanguage/LanguageIdentifier.swift +317 -0
  202. package/Sources/NaturalLanguage/NaturalLanguage.swift +135 -0
  203. package/Sources/OSLog/OSLog.swift +6 -0
  204. package/Sources/Photos/Photos.swift +572 -0
  205. package/Sources/PhotosUI/PhotosPicker.swift +248 -0
  206. package/Sources/PhotosUI/PhotosPickerItem.swift +261 -0
  207. package/Sources/QuickLook/QuickLook.swift +168 -0
  208. package/Sources/SafariServices/SafariServices.swift +106 -0
  209. package/Sources/Security/Security.swift +332 -0
  210. package/Sources/StoreKit/AppStore.swift +207 -0
  211. package/Sources/StoreKit/Products.swift +280 -0
  212. package/Sources/StoreKit/RequestReview.swift +28 -0
  213. package/Sources/StoreKit/StoreKit1.swift +486 -0
  214. package/Sources/StoreKit/StoreViews.swift +428 -0
  215. package/Sources/StoreKit/Transactions.swift +197 -0
  216. package/Sources/SwiftData/Macros.swift +58 -0
  217. package/Sources/SwiftData/ModelActor.swift +38 -0
  218. package/Sources/SwiftData/ModelContainer.swift +129 -0
  219. package/Sources/SwiftData/ModelContext.swift +451 -0
  220. package/Sources/SwiftData/PersistentModel.swift +238 -0
  221. package/Sources/SwiftData/Properties.swift +261 -0
  222. package/Sources/SwiftData/Query.swift +256 -0
  223. package/Sources/SwiftData/Schema.swift +192 -0
  224. package/Sources/SwiftData/Store.swift +146 -0
  225. package/Sources/SwiftData/StringPredicates.swift +125 -0
  226. package/Sources/SwiftDataMacros/EntryMacro.swift +82 -0
  227. package/Sources/SwiftDataMacros/GenerableMacro.swift +183 -0
  228. package/Sources/SwiftDataMacros/ModelActorMacro.swift +46 -0
  229. package/Sources/SwiftDataMacros/ModelMacro.swift +260 -0
  230. package/Sources/SwiftDataMacros/Plugin.swift +18 -0
  231. package/Sources/SwiftDataMacros/PredicateMacro.swift +1244 -0
  232. package/Sources/SwiftUI/API/Accessibility.swift +181 -0
  233. package/Sources/SwiftUI/API/AccessibilityExtras.swift +33 -0
  234. package/Sources/SwiftUI/API/AccessibilityFocus.swift +63 -0
  235. package/Sources/SwiftUI/API/Alert.swift +221 -0
  236. package/Sources/SwiftUI/API/AlignmentGuides.swift +65 -0
  237. package/Sources/SwiftUI/API/Animation.swift +285 -0
  238. package/Sources/SwiftUI/API/App.swift +87 -0
  239. package/Sources/SwiftUI/API/BindingCollections.swift +35 -0
  240. package/Sources/SwiftUI/API/BindingForEach.swift +27 -0
  241. package/Sources/SwiftUI/API/Bitmaps.swift +254 -0
  242. package/Sources/SwiftUI/API/ButtonStyles.swift +96 -0
  243. package/Sources/SwiftUI/API/Canvas.swift +337 -0
  244. package/Sources/SwiftUI/API/Color.swift +237 -0
  245. package/Sources/SwiftUI/API/ColorEffects.swift +52 -0
  246. package/Sources/SwiftUI/API/ColorPickerAndLabeledContent.swift +138 -0
  247. package/Sources/SwiftUI/API/ColorSpaces.swift +161 -0
  248. package/Sources/SwiftUI/API/Commands.swift +106 -0
  249. package/Sources/SwiftUI/API/ContainerBackground.swift +28 -0
  250. package/Sources/SwiftUI/API/ContentShape.swift +33 -0
  251. package/Sources/SwiftUI/API/ContentSizeCategory.swift +35 -0
  252. package/Sources/SwiftUI/API/ContentUnavailable.swift +101 -0
  253. package/Sources/SwiftUI/API/Controls.swift +300 -0
  254. package/Sources/SwiftUI/API/CustomLayout.swift +442 -0
  255. package/Sources/SwiftUI/API/CustomToolbarContent.swift +46 -0
  256. package/Sources/SwiftUI/API/Decorations.swift +92 -0
  257. package/Sources/SwiftUI/API/EditMode.swift +212 -0
  258. package/Sources/SwiftUI/API/Effects.swift +388 -0
  259. package/Sources/SwiftUI/API/Entry.swift +8 -0
  260. package/Sources/SwiftUI/API/Environment.swift +439 -0
  261. package/Sources/SwiftUI/API/EnvironmentSendable.swift +6 -0
  262. package/Sources/SwiftUI/API/Focus.swift +137 -0
  263. package/Sources/SwiftUI/API/Font.swift +131 -0
  264. package/Sources/SwiftUI/API/Gauge.swift +290 -0
  265. package/Sources/SwiftUI/API/Geometry.swift +89 -0
  266. package/Sources/SwiftUI/API/GeometryEffects.swift +232 -0
  267. package/Sources/SwiftUI/API/GeometryReader.swift +135 -0
  268. package/Sources/SwiftUI/API/GestureState.swift +65 -0
  269. package/Sources/SwiftUI/API/Gestures.swift +342 -0
  270. package/Sources/SwiftUI/API/Glass.swift +127 -0
  271. package/Sources/SwiftUI/API/Grid.swift +188 -0
  272. package/Sources/SwiftUI/API/GroupBoxAndControlGroup.swift +130 -0
  273. package/Sources/SwiftUI/API/KeyPress.swift +54 -0
  274. package/Sources/SwiftUI/API/LabelStyle.swift +124 -0
  275. package/Sources/SwiftUI/API/Layout.swift +220 -0
  276. package/Sources/SwiftUI/API/LazyStacks.swift +49 -0
  277. package/Sources/SwiftUI/API/LegacyAlert.swift +97 -0
  278. package/Sources/SwiftUI/API/Lists.swift +331 -0
  279. package/Sources/SwiftUI/API/Menu.swift +58 -0
  280. package/Sources/SwiftUI/API/Modifiers.swift +313 -0
  281. package/Sources/SwiftUI/API/MoreModifiers.swift +100 -0
  282. package/Sources/SwiftUI/API/Namespace.swift +44 -0
  283. package/Sources/SwiftUI/API/Navigation.swift +386 -0
  284. package/Sources/SwiftUI/API/NavigationDestinationBindings.swift +55 -0
  285. package/Sources/SwiftUI/API/ObservableObject.swift +293 -0
  286. package/Sources/SwiftUI/API/OnChange.swift +48 -0
  287. package/Sources/SwiftUI/API/Path.swift +543 -0
  288. package/Sources/SwiftUI/API/Phase8Controls.swift +411 -0
  289. package/Sources/SwiftUI/API/PhaseAnimator.swift +130 -0
  290. package/Sources/SwiftUI/API/Picker.swift +185 -0
  291. package/Sources/SwiftUI/API/PointerAndKeyboard.swift +77 -0
  292. package/Sources/SwiftUI/API/Popover.swift +41 -0
  293. package/Sources/SwiftUI/API/Preferences.swift +262 -0
  294. package/Sources/SwiftUI/API/Presentation.swift +122 -0
  295. package/Sources/SwiftUI/API/PresentationExtras.swift +60 -0
  296. package/Sources/SwiftUI/API/Primitives.swift +517 -0
  297. package/Sources/SwiftUI/API/Publishers.swift +107 -0
  298. package/Sources/SwiftUI/API/Redaction.swift +75 -0
  299. package/Sources/SwiftUI/API/RowActions.swift +84 -0
  300. package/Sources/SwiftUI/API/Scenes.swift +131 -0
  301. package/Sources/SwiftUI/API/ScrollModifiers.swift +132 -0
  302. package/Sources/SwiftUI/API/ScrollTargets.swift +104 -0
  303. package/Sources/SwiftUI/API/ScrollViewReader.swift +144 -0
  304. package/Sources/SwiftUI/API/SectionSupplements.swift +96 -0
  305. package/Sources/SwiftUI/API/Shape.swift +214 -0
  306. package/Sources/SwiftUI/API/ShapeStyle.swift +409 -0
  307. package/Sources/SwiftUI/API/ShapeTrim.swift +78 -0
  308. package/Sources/SwiftUI/API/Sharing.swift +193 -0
  309. package/Sources/SwiftUI/API/StackLayouts.swift +199 -0
  310. package/Sources/SwiftUI/API/State.swift +144 -0
  311. package/Sources/SwiftUI/API/StatusGaps.swift +121 -0
  312. package/Sources/SwiftUI/API/StrokeStyle.swift +30 -0
  313. package/Sources/SwiftUI/API/SymbolEffects.swift +203 -0
  314. package/Sources/SwiftUI/API/TabContent.swift +841 -0
  315. package/Sources/SwiftUI/API/Table.swift +382 -0
  316. package/Sources/SwiftUI/API/Tabs.swift +263 -0
  317. package/Sources/SwiftUI/API/Tasks.swift +35 -0
  318. package/Sources/SwiftUI/API/Text.swift +386 -0
  319. package/Sources/SwiftUI/API/TextDates.swift +61 -0
  320. package/Sources/SwiftUI/API/TextDecorations.swift +52 -0
  321. package/Sources/SwiftUI/API/TextFieldAxis.swift +103 -0
  322. package/Sources/SwiftUI/API/TextFieldCommit.swift +52 -0
  323. package/Sources/SwiftUI/API/Timeline.swift +212 -0
  324. package/Sources/SwiftUI/API/Toolbar.swift +251 -0
  325. package/Sources/SwiftUI/API/Transfer.swift +145 -0
  326. package/Sources/SwiftUI/API/UnevenRoundedRectangle.swift +66 -0
  327. package/Sources/SwiftUI/API/Video.swift +64 -0
  328. package/Sources/SwiftUI/API/View.swift +215 -0
  329. package/Sources/SwiftUI/API/ViewModifier.swift +43 -0
  330. package/Sources/SwiftUI/API/VisualEffect.swift +155 -0
  331. package/Sources/SwiftUI/API/Windows.swift +25 -0
  332. package/Sources/SwiftUI/Charts/Axis.swift +325 -0
  333. package/Sources/SwiftUI/Charts/AxisFormatsAndRanges.swift +68 -0
  334. package/Sources/SwiftUI/Charts/Chart.swift +660 -0
  335. package/Sources/SwiftUI/Charts/ChartContent.swift +376 -0
  336. package/Sources/SwiftUI/Charts/ChartProxy.swift +57 -0
  337. package/Sources/SwiftUI/Charts/Marks.swift +204 -0
  338. package/Sources/SwiftUI/Charts/Plottable.swift +99 -0
  339. package/Sources/SwiftUI/Charts/Scales.swift +326 -0
  340. package/Sources/SwiftUI/Localization/Localization.swift +498 -0
  341. package/Sources/SwiftUI/Localization/PluralRules.swift +127 -0
  342. package/Sources/SwiftUI/Runtime/Executor.swift +85 -0
  343. package/Sources/SwiftUI/Runtime/Exports.swift +101 -0
  344. package/Sources/SwiftUI/Runtime/ImageSource.swift +310 -0
  345. package/Sources/SwiftUI/Runtime/JSON.swift +143 -0
  346. package/Sources/SwiftUI/Runtime/JSONParser.swift +443 -0
  347. package/Sources/SwiftUI/Runtime/LazyRows.swift +99 -0
  348. package/Sources/SwiftUI/Runtime/Measurements.swift +140 -0
  349. package/Sources/SwiftUI/Runtime/Ops.swift +152 -0
  350. package/Sources/SwiftUI/Runtime/Reconciler.swift +219 -0
  351. package/Sources/SwiftUI/Runtime/Replay.swift +382 -0
  352. package/Sources/SwiftUI/Runtime/Runtime.swift +2146 -0
  353. package/Sources/SwiftUI/Runtime/Sameness.swift +152 -0
  354. package/Sources/SwiftUI/Runtime/ViewPath.swift +89 -0
  355. package/Sources/SwiftUI/Runtime/ViewTraits.swift +175 -0
  356. package/Sources/SwiftUI/Runtime/WebAuthHeadless.swift +49 -0
  357. package/Sources/Symbols/Symbols.swift +25 -0
  358. package/Sources/Translation/Translation.swift +423 -0
  359. package/Sources/UIKit/Activity.swift +213 -0
  360. package/Sources/UIKit/Alerts.swift +69 -0
  361. package/Sources/UIKit/AppDelegate.swift +222 -0
  362. package/Sources/UIKit/Appearance.swift +84 -0
  363. package/Sources/UIKit/ColorConversions.swift +70 -0
  364. package/Sources/UIKit/Controls.swift +225 -0
  365. package/Sources/UIKit/Device.swift +200 -0
  366. package/Sources/UIKit/Feedback.swift +65 -0
  367. package/Sources/UIKit/Font.swift +307 -0
  368. package/Sources/UIKit/Graphics.swift +204 -0
  369. package/Sources/UIKit/HostingController.swift +185 -0
  370. package/Sources/UIKit/Identity.swift +24 -0
  371. package/Sources/UIKit/Introspectable.swift +510 -0
  372. package/Sources/UIKit/Pasteboard.swift +363 -0
  373. package/Sources/UIKit/PhotoAlbum.swift +81 -0
  374. package/Sources/UIKit/RemoteNotifications.swift +15 -0
  375. package/Sources/UIKit/Representable.swift +288 -0
  376. package/Sources/UIKit/SafeArea.swift +12 -0
  377. package/Sources/UIKit/SceneDelegates.swift +132 -0
  378. package/Sources/UIKit/Scenes.swift +40 -0
  379. package/Sources/UIKit/ScrollView.swift +157 -0
  380. package/Sources/UIKit/ShortcutItems.swift +67 -0
  381. package/Sources/UIKit/SymbolConfiguration.swift +124 -0
  382. package/Sources/UIKit/TargetAction.swift +123 -0
  383. package/Sources/UIKit/TextPaste.swift +161 -0
  384. package/Sources/UIKit/TextView.swift +538 -0
  385. package/Sources/UIKit/UIKit.swift +292 -0
  386. package/Sources/UIKit/UIView.swift +855 -0
  387. package/Sources/UIKit/ViewTranslation.swift +311 -0
  388. package/Sources/UniformTypeIdentifiers/UTType.swift +196 -0
  389. package/Sources/UserNotifications/Content.swift +370 -0
  390. package/Sources/UserNotifications/NotificationCenter.swift +309 -0
  391. package/Sources/WeatherKit/WeatherKit.swift +228 -0
  392. package/Sources/WebKit/WebKit.swift +245 -0
  393. package/Sources/os/os.swift +376 -0
  394. package/Sources/zlib/zlib.swift +6 -0
  395. package/index.d.ts +2 -0
  396. package/index.mjs +16 -0
  397. package/manifest.d.mts +2 -0
  398. package/manifest.mjs +39 -0
  399. package/package.json +30 -4
  400. package/sync-sources.mjs +33 -0
@@ -0,0 +1,660 @@
1
+ // `Chart`: kind `chart`, props `{marks, xAxis, yAxis, legend}` in unit
2
+ // coordinates (x left → right, y top → bottom), children `chartitem`s for
3
+ // annotations and view axis labels. See docs/ops-protocol.md, Phase 7.
4
+
5
+ // MARK: - Chart
6
+
7
+ public struct Chart<Content: ChartContent> {
8
+ let content: Content
9
+
10
+ public init(@ChartContentBuilder content: () -> Content) {
11
+ self.content = content()
12
+ }
13
+ }
14
+
15
+ extension Chart {
16
+ public init<Data: RandomAccessCollection, C: ChartContent>(
17
+ _ data: Data, @ChartContentBuilder content: @escaping (Data.Element) -> C
18
+ ) where Data.Element: Identifiable, Content == ForEach<Data, Data.Element.ID, C> {
19
+ self.content = ForEach(data, content: content)
20
+ }
21
+
22
+ public init<Data: RandomAccessCollection, ID: Hashable, C: ChartContent>(
23
+ _ data: Data, id: KeyPath<Data.Element, ID>, @ChartContentBuilder content: @escaping (Data.Element) -> C
24
+ ) where Content == ForEach<Data, ID, C> {
25
+ self.content = ForEach(data, id: id, content: content)
26
+ }
27
+ }
28
+
29
+ extension Chart: _PrimitiveView {}
30
+ extension Chart: _HostView {
31
+ var _kind: String { "chart" }
32
+
33
+ func _props(in environment: EnvironmentValues) -> _JSON {
34
+ _resolveChart(content, config: environment._chartConfig).props
35
+ }
36
+
37
+ var _content: [any View] {
38
+ // `_content` has no environment; the group reads the chart config
39
+ // itself and contributes the annotation and label views.
40
+ [_ChartItems(content: AnyChartContent(content))]
41
+ }
42
+ }
43
+
44
+ /// Contributes the chart's `chartitem` children, resolved with the chart
45
+ /// configuration from the environment.
46
+ struct _ChartItems {
47
+ let content: AnyChartContent
48
+ @Environment(\._chartConfig) private var config
49
+
50
+ init(content: AnyChartContent) { self.content = content }
51
+ }
52
+ extension _ChartItems: _PrimitiveView {}
53
+ extension _ChartItems: _GroupView {
54
+ var _children: [any View] { _resolveChart(content, config: config).items }
55
+ }
56
+
57
+ /// An annotation or a view axis label. Kind `chartitem`.
58
+ struct _ChartItemView {
59
+ let role: String
60
+ let x0: Double
61
+ let x1: Double
62
+ let y0: Double
63
+ let y1: Double
64
+ let position: String
65
+ let alignment: Alignment
66
+ let spacing: Double
67
+ let content: any View
68
+ }
69
+ extension _ChartItemView: _PrimitiveView {}
70
+ extension _ChartItemView: _HostView {
71
+ var _kind: String { "chartitem" }
72
+
73
+ func _props(in environment: EnvironmentValues) -> _JSON {
74
+ .object([
75
+ "role": .string(role),
76
+ "x0": .number(_unit(x0)), "x1": .number(_unit(x1)),
77
+ "y0": .number(_unit(y0)), "y1": .number(_unit(y1)),
78
+ "position": .string(position),
79
+ "alignment": .string(alignment._name),
80
+ "spacing": .number(spacing),
81
+ ])
82
+ }
83
+
84
+ var _content: [any View] { [content] }
85
+ }
86
+
87
+ // MARK: - Scales
88
+
89
+ /// A resolved scale: categories (band) or a continuous domain.
90
+ struct _ChartScale {
91
+ enum Kind {
92
+ case band([String])
93
+ case continuous(lower: Double, upper: Double, isDate: Bool)
94
+ }
95
+ var kind: Kind
96
+ var reversed = false
97
+
98
+ var isBand: Bool { if case .band = kind { true } else { false } }
99
+ var isDate: Bool { if case .continuous(_, _, let isDate) = kind { isDate } else { false } }
100
+
101
+ /// 0…1 from the lower bound (or first category's center) to the upper.
102
+ func unit(_ value: _PlottableValue) -> Double? {
103
+ let raw: Double?
104
+ switch kind {
105
+ case .band(let categories):
106
+ guard case .string(let s) = value, let index = categories.firstIndex(of: s) else { return nil }
107
+ raw = (Double(index) + 0.5) / Double(categories.count)
108
+ case .continuous(let lower, let upper, _):
109
+ guard let v = value.continuous else { return nil }
110
+ raw = upper > lower ? (v - lower) / (upper - lower) : 0.5
111
+ }
112
+ return raw.map { reversed ? 1 - $0 : $0 }
113
+ }
114
+
115
+ /// The band of a category, `nil` on a continuous scale.
116
+ func band(_ value: _PlottableValue) -> (Double, Double)? {
117
+ guard case .band(let categories) = kind, case .string(let s) = value,
118
+ let index = categories.firstIndex(of: s) else { return nil }
119
+ let n = Double(categories.count)
120
+ let band = (Double(index) / n, Double(index + 1) / n)
121
+ return reversed ? (1 - band.1, 1 - band.0) : band
122
+ }
123
+
124
+ /// The band width when every value gets one band.
125
+ var bandWidth: Double {
126
+ if case .band(let categories) = kind { return 1 / Double(max(categories.count, 1)) }
127
+ return 1
128
+ }
129
+ }
130
+
131
+ /// The ticks of one `AxisMarks`, as values.
132
+ struct _AxisTicks {
133
+ var marks: AxisMarks
134
+ var values: [_PlottableValue]
135
+ }
136
+
137
+ struct _ResolvedAxis {
138
+ var scale: _ChartScale
139
+ var ticks: [_AxisTicks]
140
+ var dateFormat: _DateFormat
141
+ }
142
+
143
+ /// Builds the scale and ticks of one axis from the values the marks put on it.
144
+ func _resolveAxis(values: [_PlottableValue], domain: _ScaleDomainSpec, axis: _AxisSpec,
145
+ includesZeroByDefault: Bool) -> _ResolvedAxis {
146
+ var reversed = false
147
+ var includesZero: Bool? = nil
148
+ var explicitDomain: [_PlottableValue]? = nil
149
+ switch domain {
150
+ case .automatic(let zero, let rev):
151
+ includesZero = zero
152
+ reversed = rev
153
+ case .values(let domainValues):
154
+ explicitDomain = domainValues
155
+ }
156
+
157
+ let allValues = explicitDomain ?? values
158
+ let axisMarks = axis.marks.isEmpty ? [AxisMarks()] : axis.marks
159
+
160
+ // Categories: a band scale.
161
+ if allValues.contains(where: \.isString) {
162
+ var categories: [String] = []
163
+ for value in allValues {
164
+ if case .string(let s) = value, !categories.contains(s) { categories.append(s) }
165
+ }
166
+ let scale = _ChartScale(kind: .band(categories), reversed: reversed)
167
+ let ticks = axisMarks.map { marks -> _AxisTicks in
168
+ if case .explicit(let explicit) = marks.values.spec {
169
+ return _AxisTicks(marks: marks, values: explicit.filter { value in
170
+ if case .string(let s) = value { return categories.contains(s) }
171
+ return false
172
+ })
173
+ }
174
+ return _AxisTicks(marks: marks, values: categories.map { .string($0) })
175
+ }
176
+ return _ResolvedAxis(scale: scale, ticks: ticks, dateFormat: .dayMonth)
177
+ }
178
+
179
+ // Continuous: numbers or dates.
180
+ let isDate = allValues.contains(where: \.isDate)
181
+ let numbers = allValues.compactMap(\.continuous)
182
+ var lower = numbers.min() ?? 0
183
+ var upper = numbers.max() ?? (isDate ? lower + _secondsPerDay : 1)
184
+ if explicitDomain == nil, includesZero ?? includesZeroByDefault, !isDate {
185
+ lower = min(lower, 0)
186
+ upper = max(upper, 0)
187
+ }
188
+ if upper <= lower {
189
+ if isDate {
190
+ lower -= 12 * 3600
191
+ upper += 12 * 3600
192
+ } else if lower == 0 {
193
+ upper = 1
194
+ } else {
195
+ let pad = abs(lower) * 0.1
196
+ lower -= pad
197
+ upper += pad
198
+ }
199
+ }
200
+
201
+ // Ticks per `AxisMarks`, rounding the domain to them when asked.
202
+ var dateFormat = _DateFormat.dayMonth
203
+ var tickValues: [[Double]] = []
204
+ for marks in axisMarks {
205
+ switch marks.values.spec {
206
+ case .automatic(let options):
207
+ var ticks: [Double]
208
+ if isDate {
209
+ let dated = _niceDateTicks(lower: lower, upper: upper, options: options)
210
+ ticks = dated.ticks
211
+ dateFormat = dated.format
212
+ } else {
213
+ ticks = _niceTicks(lower: lower, upper: upper, options: options)
214
+ }
215
+ if explicitDomain == nil, let first = ticks.first, options.roundLowerBound { lower = min(lower, first) }
216
+ if explicitDomain == nil, let last = ticks.last, options.roundUpperBound { upper = max(upper, last) }
217
+ tickValues.append(ticks)
218
+ case .stride(let step, let roundLower, let roundUpper):
219
+ var ticks: [Double] = []
220
+ guard step > 0 else { tickValues.append([]); continue }
221
+ var tick = (lower / step).rounded(.down) * step
222
+ let last = (upper / step).rounded(.up) * step
223
+ while tick <= last + step * 1e-9, ticks.count < 1000 {
224
+ ticks.append(_cleanTick(tick, step: step))
225
+ tick += step
226
+ }
227
+ if explicitDomain == nil, let first = ticks.first, roundLower { lower = min(lower, first) }
228
+ if explicitDomain == nil, let final = ticks.last, roundUpper { upper = max(upper, final) }
229
+ if isDate { dateFormat = _dateFormat(forValues: ticks) }
230
+ tickValues.append(ticks)
231
+ case .explicit(let explicit):
232
+ let ticks = explicit.compactMap(\.continuous)
233
+ if isDate { dateFormat = _dateFormat(forValues: ticks) }
234
+ tickValues.append(ticks)
235
+ }
236
+ }
237
+
238
+ // Drop the ticks that fall outside the (unrounded) domain.
239
+ let epsilon = (upper - lower) * 1e-9
240
+ let scale = _ChartScale(kind: .continuous(lower: lower, upper: upper, isDate: isDate), reversed: reversed)
241
+ let ticks = zip(axisMarks, tickValues).map { marks, values in
242
+ let kept: [Double]
243
+ if case .explicit = marks.values.spec {
244
+ kept = values
245
+ } else {
246
+ kept = values.filter { $0 >= lower - epsilon && $0 <= upper + epsilon }
247
+ }
248
+ return _AxisTicks(marks: marks, values: kept.map { isDate ? .date($0) : .number($0) })
249
+ }
250
+ return _ResolvedAxis(scale: scale, ticks: ticks, dateFormat: dateFormat)
251
+ }
252
+
253
+ // MARK: - Resolution
254
+
255
+ struct _ResolvedChart {
256
+ var props: _JSON
257
+ var items: [any View]
258
+ }
259
+
260
+ /// A mark after scaling, ready to serialize.
261
+ private struct _OutMark {
262
+ var json: [String: _JSON]
263
+ /// Line/area grouping key, `nil` for other kinds.
264
+ var groupKey: _PlottableValue?
265
+ var groupKind: _RawMarkKind?
266
+ var points: [[String: Double]] = []
267
+ var sortKeys: [Double] = []
268
+ }
269
+
270
+ private struct _ChartResolver {
271
+ let x: _ResolvedAxis
272
+ let y: _ResolvedAxis
273
+ /// Palette indices for `foregroundStyle(by:)` / `symbol(by:)` values.
274
+ var styleIndices: [_PlottableValue: Int] = [:]
275
+ var symbolIndices: [_PlottableValue: Int] = [:]
276
+ var styleOrder: [_LabelledValue] = []
277
+ var symbolOrder: [_LabelledValue] = []
278
+ /// The default bar width on a continuous x axis: the smallest gap between bars.
279
+ var continuousBarBand = 1.0
280
+
281
+ init(marks: [_RawMark], config: _ChartConfig) {
282
+ x = _resolveAxis(values: marks.flatMap(\.xValues), domain: config.xDomain, axis: config.xAxis,
283
+ includesZeroByDefault: false)
284
+ y = _resolveAxis(values: marks.flatMap(\.yValues), domain: config.yDomain, axis: config.yAxis,
285
+ includesZeroByDefault: true)
286
+ for mark in marks {
287
+ if let by = mark.modifiers.styleBy, styleIndices[by.value] == nil {
288
+ styleIndices[by.value] = styleOrder.count
289
+ styleOrder.append(by)
290
+ }
291
+ if let by = mark.modifiers.symbolBy, symbolIndices[by.value] == nil {
292
+ symbolIndices[by.value] = symbolOrder.count
293
+ symbolOrder.append(by)
294
+ }
295
+ }
296
+ if !x.scale.isBand {
297
+ let centers = Set(marks.filter { ($0.kind == .bar || $0.kind == .rectangle) && $0.x != nil }
298
+ .compactMap { $0.x.flatMap(x.scale.unit) }).sorted()
299
+ var gap = 1.0
300
+ for (a, b) in zip(centers, centers.dropFirst()) where b - a > 1e-9 { gap = min(gap, b - a) }
301
+ continuousBarBand = centers.count > 1 ? gap : 1
302
+ }
303
+ }
304
+
305
+ // Unit coordinates: x left → right, y top → bottom.
306
+ func ux(_ value: _PlottableValue) -> Double? { x.scale.unit(value) }
307
+ func uy(_ value: _PlottableValue) -> Double? { y.scale.unit(value).map { 1 - $0 } }
308
+
309
+ /// The unit position of 0 on the y axis (the bar baseline), clamped to the plot.
310
+ var yBaseline: Double {
311
+ if y.scale.isBand { return 1 }
312
+ return 1 - max(0, min(1, y.scale.unit(.number(0)) ?? 0))
313
+ }
314
+
315
+ var xBaseline: Double {
316
+ if x.scale.isBand { return 0 }
317
+ return max(0, min(1, x.scale.unit(.number(0)) ?? 0))
318
+ }
319
+
320
+ func style(for modifiers: _MarkModifiers) -> _JSON {
321
+ if let style = modifiers.style { return style._json }
322
+ if let by = modifiers.styleBy, let index = styleIndices[by.value] {
323
+ return _chartColorPalette[index % _chartColorPalette.count]._json
324
+ }
325
+ return Color.blue._json
326
+ }
327
+
328
+ func symbol(for modifiers: _MarkModifiers, defaultSymbol: String?) -> String? {
329
+ if let symbol = modifiers.symbol { return symbol }
330
+ if let by = modifiers.symbolBy, let index = symbolIndices[by.value] {
331
+ return _chartSymbolPalette[index % _chartSymbolPalette.count]
332
+ }
333
+ return defaultSymbol
334
+ }
335
+
336
+ /// The rectangle of a bar or rectangle mark.
337
+ func rect(of mark: _RawMark) -> (x0: Double, x1: Double, y0: Double, y1: Double, fixedWidth: Double?) {
338
+ var x0 = 0.0, x1 = 1.0, y0 = 0.0, y1 = 1.0
339
+ var fixedWidth: Double? = nil
340
+
341
+ if let start = mark.xStart, let end = mark.xEnd {
342
+ x0 = x.scale.band(start)?.0 ?? ux(start) ?? 0
343
+ x1 = x.scale.band(end)?.1 ?? ux(end) ?? 1
344
+ } else if let value = mark.x {
345
+ let center = ux(value) ?? 0.5
346
+ let band = x.scale.isBand ? x.scale.bandWidth : continuousBarBand
347
+ switch mark.width ?? .automatic {
348
+ case .fixed(let points):
349
+ fixedWidth = points
350
+ x0 = center
351
+ x1 = center
352
+ case .ratio(let ratio):
353
+ x0 = center - band * ratio / 2
354
+ x1 = center + band * ratio / 2
355
+ case .automatic, .inset:
356
+ x0 = center - band * 0.4
357
+ x1 = center + band * 0.4
358
+ }
359
+ }
360
+
361
+ if let start = mark.yStart, let end = mark.yEnd {
362
+ y0 = y.scale.band(start).map { 1 - $0.1 } ?? uy(start) ?? 0
363
+ y1 = y.scale.band(end).map { 1 - $0.0 } ?? uy(end) ?? 1
364
+ } else if let value = mark.y {
365
+ if let band = y.scale.band(value) {
366
+ let center = 1 - (band.0 + band.1) / 2
367
+ let width = y.scale.bandWidth
368
+ switch mark.height ?? .automatic {
369
+ case .fixed, .automatic, .inset:
370
+ y0 = center - width * 0.4
371
+ y1 = center + width * 0.4
372
+ case .ratio(let ratio):
373
+ y0 = center - width * ratio / 2
374
+ y1 = center + width * ratio / 2
375
+ }
376
+ } else if mark.xStart != nil, mark.xEnd != nil {
377
+ // A horizontal bar on a continuous y axis: a thin band around the value.
378
+ let center = uy(value) ?? 0.5
379
+ y0 = center - 0.04
380
+ y1 = center + 0.04
381
+ } else {
382
+ y0 = uy(value) ?? 0
383
+ y1 = yBaseline
384
+ }
385
+ }
386
+
387
+ return (min(x0, x1), max(x0, x1), min(y0, y1), max(y0, y1), fixedWidth)
388
+ }
389
+
390
+ /// Scales every mark; lines and areas with the same key become one mark.
391
+ func outMarks(_ marks: [_RawMark], includeMasks: Bool) -> [_OutMark] {
392
+ var out: [_OutMark] = []
393
+ var groupIndex: [String: Int] = [:]
394
+
395
+ for mark in marks {
396
+ let m = mark.modifiers
397
+ var json: [String: _JSON] = [
398
+ "style": style(for: m),
399
+ "opacity": .number(m.opacity),
400
+ ]
401
+ if includeMasks, let mask = m.mask, let maskJSON = resolveMask(mask) {
402
+ json["mask"] = maskJSON
403
+ }
404
+
405
+ switch mark.kind {
406
+ case .bar, .rectangle:
407
+ let r = rect(of: mark)
408
+ json["kind"] = .string("rect")
409
+ json["x0"] = .number(_unit(r.x0))
410
+ json["x1"] = .number(_unit(r.x1))
411
+ json["y0"] = .number(_unit(r.y0))
412
+ json["y1"] = .number(_unit(r.y1))
413
+ json["cornerRadius"] = .number(m.cornerRadius)
414
+ json["fixedWidth"] = r.fixedWidth.map { .number($0) } ?? .null
415
+ out.append(_OutMark(json: json))
416
+
417
+ case .point:
418
+ guard let px = mark.x.flatMap(ux), let py = mark.y.flatMap(uy) else { continue }
419
+ json["kind"] = .string("point")
420
+ json["x"] = .number(_unit(px))
421
+ json["y"] = .number(_unit(py))
422
+ json["symbol"] = .string(symbol(for: m, defaultSymbol: "circle") ?? "circle")
423
+ json["symbolSize"] = .number(m.symbolSize ?? 8)
424
+ out.append(_OutMark(json: json))
425
+
426
+ case .rule:
427
+ var x0 = 0.0, x1 = 1.0, y0 = 0.0, y1 = 1.0
428
+ if let start = mark.xStart, let end = mark.xEnd {
429
+ x0 = ux(start) ?? 0; x1 = ux(end) ?? 1
430
+ } else if let value = mark.x {
431
+ x0 = ux(value) ?? 0.5; x1 = x0
432
+ }
433
+ if let start = mark.yStart, let end = mark.yEnd {
434
+ y0 = uy(start) ?? 0; y1 = uy(end) ?? 1
435
+ } else if let value = mark.y {
436
+ y0 = uy(value) ?? 0.5; y1 = y0
437
+ }
438
+ json["kind"] = .string("rule")
439
+ json["x0"] = .number(_unit(x0))
440
+ json["x1"] = .number(_unit(x1))
441
+ json["y0"] = .number(_unit(y0))
442
+ json["y1"] = .number(_unit(y1))
443
+ json["lineWidth"] = .number(m.lineWidth ?? 1)
444
+ out.append(_OutMark(json: json))
445
+
446
+ case .line, .area:
447
+ guard let xValue = mark.x, let px = ux(xValue) else { continue }
448
+ let key = mark.series ?? m.styleBy?.value ?? m.symbolBy?.value
449
+ let keyName = "\(mark.kind):\(key.map { "\($0)" } ?? "")"
450
+ var point: [String: Double]
451
+ if mark.kind == .line {
452
+ guard let py = (mark.y ?? mark.yEnd).flatMap(uy) else { continue }
453
+ point = ["x": _unit(px), "y": _unit(py)]
454
+ } else {
455
+ let top: Double
456
+ let bottom: Double
457
+ if let start = mark.yStart, let end = mark.yEnd {
458
+ top = uy(end) ?? 0
459
+ bottom = uy(start) ?? yBaseline
460
+ } else if let value = mark.y {
461
+ top = uy(value) ?? 0
462
+ bottom = yBaseline
463
+ } else { continue }
464
+ point = ["x": _unit(px), "y0": _unit(min(top, bottom)), "y1": _unit(max(top, bottom))]
465
+ }
466
+ if let index = groupIndex[keyName] {
467
+ out[index].points.append(point)
468
+ out[index].sortKeys.append(px)
469
+ } else {
470
+ json["kind"] = .string(mark.kind == .line ? "line" : "area")
471
+ json["interpolation"] = .string(m.interpolation)
472
+ if mark.kind == .line {
473
+ json["lineWidth"] = .number(m.lineWidth ?? 2)
474
+ json["symbol"] = symbol(for: m, defaultSymbol: nil).map { .string($0) } ?? .null
475
+ json["symbolSize"] = .number(m.symbolSize ?? 8)
476
+ }
477
+ groupIndex[keyName] = out.count
478
+ out.append(_OutMark(json: json, groupKey: key, groupKind: mark.kind, points: [point], sortKeys: [px]))
479
+ }
480
+ }
481
+ }
482
+
483
+ // Lines and areas connect their points in x order.
484
+ for index in out.indices where out[index].groupKind != nil {
485
+ let order = out[index].sortKeys.indices.sorted {
486
+ let a = out[index].sortKeys[$0], b = out[index].sortKeys[$1]
487
+ return a == b ? $0 < $1 : a < b
488
+ }
489
+ let points = order.map { out[index].points[$0] }
490
+ out[index].json["points"] = .array(points.map { point in
491
+ .object(point.mapValues { .number($0) })
492
+ })
493
+ }
494
+ return out
495
+ }
496
+
497
+ /// The first area or rect mark of a mask's content, scaled like the chart.
498
+ func resolveMask(_ content: any ChartContent) -> _JSON? {
499
+ var collector = _ChartCollector()
500
+ content._collectAny(into: &collector, modifiers: _MarkModifiers())
501
+ let marks = outMarks(collector.marks, includeMasks: false)
502
+ guard let first = marks.first(where: {
503
+ if case .string(let kind)? = $0.json["kind"] { return kind == "area" || kind == "rect" }
504
+ return false
505
+ }) else { return nil }
506
+ return .object(first.json)
507
+ }
508
+
509
+ /// The anchor rectangle of a mark's annotations.
510
+ func annotationRect(of mark: _RawMark) -> (x0: Double, x1: Double, y0: Double, y1: Double) {
511
+ switch mark.kind {
512
+ case .bar, .rectangle:
513
+ let r = rect(of: mark)
514
+ return (r.x0, r.x1, r.y0, r.y1)
515
+ case .rule:
516
+ var x0 = 0.0, x1 = 1.0, y0 = 0.0, y1 = 1.0
517
+ if let value = mark.x { x0 = ux(value) ?? 0.5; x1 = x0 }
518
+ if let value = mark.y { y0 = uy(value) ?? 0.5; y1 = y0 }
519
+ return (x0, x1, y0, y1)
520
+ case .line, .area, .point:
521
+ let px = mark.x.flatMap(ux) ?? 0.5
522
+ let py = (mark.y ?? mark.yEnd).flatMap(uy) ?? 0.5
523
+ return (px, px, py, py)
524
+ }
525
+ }
526
+
527
+ func axisJSON(_ axis: _ResolvedAxis, spec: _AxisSpec, isX: Bool, items: inout [any View]) -> _JSON {
528
+ if spec.hidden { return .null }
529
+ let position = spec.marks.lazy.compactMap { $0.position._name }.first ?? (isX ? "bottom" : "trailing")
530
+ var gridLines: [_JSON] = []
531
+ var ticks: [_JSON] = []
532
+ var labels: [_JSON] = []
533
+ var views: [any View] = []
534
+
535
+ for set in axis.ticks {
536
+ let count = set.values.count
537
+ for (index, value) in set.values.enumerated() {
538
+ let scaled = axis.scale.unit(value)
539
+ // A value outside the scale's domain (a date bin that starts
540
+ // before the data) has no mark, as in Swift Charts.
541
+ if let scaled, scaled < -1e-9 || scaled > 1 + 1e-9 { continue }
542
+ let unit = scaled ?? 0
543
+ let at = _unit(isX ? unit : 1 - unit)
544
+ // A date's label starts at its tick, as Swift Charts places it;
545
+ // other values are centered on theirs.
546
+ func label(_ text: String) -> _JSON {
547
+ if isX, case .date = value {
548
+ return .object(["at": .number(at), "text": .string(text), "anchor": .string("leading")])
549
+ }
550
+ return .object(["at": .number(at), "text": .string(text)])
551
+ }
552
+ let marks = set.marks.content?(AxisValue(index: index, count: count, value: value))._items
553
+ ?? [.gridLine, .tick, .label(.automatic)]
554
+ for item in marks {
555
+ switch item {
556
+ case .gridLine:
557
+ gridLines.append(.number(at))
558
+ case .tick:
559
+ ticks.append(.number(at))
560
+ case .label(.automatic):
561
+ labels.append(label(defaultLabel(value, axis: axis)))
562
+ case .label(.text(let text)):
563
+ labels.append(label(text))
564
+ case .label(.formatted(let format)):
565
+ labels.append(label(format(value) ?? defaultLabel(value, axis: axis)))
566
+ case .label(.view(let view)):
567
+ let edge: Double = position == "top" || position == "leading" ? 0 : 1
568
+ views.append(_ChartItemView(
569
+ role: isX ? "xLabel" : "yLabel",
570
+ x0: isX ? at : edge, x1: isX ? at : edge,
571
+ y0: isX ? edge : at, y1: isX ? edge : at,
572
+ position: position, alignment: .center, spacing: 0, content: view
573
+ ))
574
+ }
575
+ }
576
+ }
577
+ }
578
+ items.append(contentsOf: views)
579
+ return .object([
580
+ "position": .string(position),
581
+ "gridLines": .array(gridLines),
582
+ "ticks": .array(ticks),
583
+ "labels": .array(labels),
584
+ ])
585
+ }
586
+
587
+ func defaultLabel(_ value: _PlottableValue, axis: _ResolvedAxis) -> String {
588
+ switch value {
589
+ case .date(let seconds): _formatChartDate(seconds, as: axis.dateFormat)
590
+ case .number(let n): _formatChartNumber(n)
591
+ case .string(let s): s
592
+ }
593
+ }
594
+
595
+ func legendJSON(config: _ChartConfig) -> _JSON {
596
+ guard !config.legendHidden, !styleOrder.isEmpty || !symbolOrder.isEmpty else { return .null }
597
+ var items: [_JSON] = []
598
+ var seen = Set<_PlottableValue>()
599
+ for by in styleOrder {
600
+ seen.insert(by.value)
601
+ let symbol = symbolIndices[by.value].map { _chartSymbolPalette[$0 % _chartSymbolPalette.count] }
602
+ items.append(.object([
603
+ "label": .string(by.value.text),
604
+ "style": _chartColorPalette[styleIndices[by.value]! % _chartColorPalette.count]._json,
605
+ "symbol": symbol.map { .string($0) } ?? .null,
606
+ ]))
607
+ }
608
+ for by in symbolOrder where !seen.contains(by.value) {
609
+ items.append(.object([
610
+ "label": .string(by.value.text),
611
+ "style": Color.blue._json,
612
+ "symbol": .string(_chartSymbolPalette[symbolIndices[by.value]! % _chartSymbolPalette.count]),
613
+ ]))
614
+ }
615
+ let position: String = switch config.legendPosition {
616
+ case .top, .topLeading, .topTrailing: "top"
617
+ case .leading: "leading"
618
+ case .trailing: "trailing"
619
+ default: "bottom"
620
+ }
621
+ return .object(["position": .string(position), "items": .array(items)])
622
+ }
623
+ }
624
+
625
+ func _resolveChart(_ content: any ChartContent, config: _ChartConfig) -> _ResolvedChart {
626
+ var collector = _ChartCollector()
627
+ content._collectAny(into: &collector, modifiers: _MarkModifiers())
628
+ let marks = collector.marks
629
+ let resolver = _ChartResolver(marks: marks, config: config)
630
+
631
+ var items: [any View] = []
632
+
633
+ // Annotations, in mark order.
634
+ for mark in marks where !mark.modifiers.annotations.isEmpty {
635
+ let r = resolver.annotationRect(of: mark)
636
+ for annotation in mark.modifiers.annotations {
637
+ let resolved = annotation.position._resolved
638
+ items.append(_ChartItemView(
639
+ role: "annotation",
640
+ x0: r.x0, x1: r.x1, y0: r.y0, y1: r.y1,
641
+ position: resolved.position,
642
+ alignment: resolved.alignment ?? annotation.alignment,
643
+ spacing: annotation.spacing,
644
+ content: annotation.content
645
+ ))
646
+ }
647
+ }
648
+
649
+ let markJSON = resolver.outMarks(marks, includeMasks: true).map { _JSON.object($0.json) }
650
+ let xAxis = resolver.axisJSON(resolver.x, spec: config.xAxis, isX: true, items: &items)
651
+ let yAxis = resolver.axisJSON(resolver.y, spec: config.yAxis, isX: false, items: &items)
652
+
653
+ let props: _JSON = .object([
654
+ "marks": .array(markJSON),
655
+ "xAxis": xAxis,
656
+ "yAxis": yAxis,
657
+ "legend": resolver.legendJSON(config: config),
658
+ ])
659
+ return _ResolvedChart(props: props, items: items)
660
+ }