diff --git a/BHTwitter.xcodeproj/project.pbxproj b/BHTwitter.xcodeproj/project.pbxproj index ef3e33c5..a99db9fd 100644 --- a/BHTwitter.xcodeproj/project.pbxproj +++ b/BHTwitter.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 52; objects = { /* Begin PBXBuildFile section */ @@ -23,31 +23,6 @@ 5020A8D824E759190080F292 /* TWHeaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A8D524E759190080F292 /* TWHeaders.h */; }; 5020A8D924E759190080F292 /* BHTManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020A8D624E759190080F292 /* BHTManager.h */; }; 5020A8DA24E759190080F292 /* BHTManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020A8D724E759190080F292 /* BHTManager.m */; }; - 5020AA4324E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA2924E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.m */; }; - 5020AA4424E759390080F292 /* JGProgressHUDErrorIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA2A24E759390080F292 /* JGProgressHUDErrorIndicatorView.m */; }; - 5020AA4524E759390080F292 /* JGProgressHUDAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA2B24E759390080F292 /* JGProgressHUDAnimation.m */; }; - 5020AA4624E759390080F292 /* JGProgressHUDSuccessIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA2D24E759390080F292 /* JGProgressHUDSuccessIndicatorView.h */; }; - 5020AA4724E759390080F292 /* JGProgressHUDImageIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA2E24E759390080F292 /* JGProgressHUDImageIndicatorView.h */; }; - 5020AA4824E759390080F292 /* JGProgressHUDIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA2F24E759390080F292 /* JGProgressHUDIndicatorView.h */; }; - 5020AA4924E759390080F292 /* JGProgressHUD.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3024E759390080F292 /* JGProgressHUD.h */; }; - 5020AA4A24E759390080F292 /* JGProgressHUDShadow.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3124E759390080F292 /* JGProgressHUDShadow.h */; }; - 5020AA4B24E759390080F292 /* JGProgressHUDPieIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3224E759390080F292 /* JGProgressHUDPieIndicatorView.h */; }; - 5020AA4C24E759390080F292 /* JGProgressHUDRingIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3324E759390080F292 /* JGProgressHUDRingIndicatorView.h */; }; - 5020AA4D24E759390080F292 /* JGProgressHUDFadeAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3424E759390080F292 /* JGProgressHUDFadeAnimation.h */; }; - 5020AA4E24E759390080F292 /* JGProgressHUD-Defines.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3524E759390080F292 /* JGProgressHUD-Defines.h */; }; - 5020AA4F24E759390080F292 /* JGProgressHUDAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3624E759390080F292 /* JGProgressHUDAnimation.h */; }; - 5020AA5024E759390080F292 /* JGProgressHUDErrorIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3724E759390080F292 /* JGProgressHUDErrorIndicatorView.h */; }; - 5020AA5124E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3824E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.h */; }; - 5020AA5224E759390080F292 /* JGProgressHUDFadeZoomAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA3924E759390080F292 /* JGProgressHUDFadeZoomAnimation.h */; }; - 5020AA5324E759390080F292 /* JGProgressHUDFadeZoomAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3A24E759390080F292 /* JGProgressHUDFadeZoomAnimation.m */; }; - 5020AA5424E759390080F292 /* JGProgressHUDImageIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3B24E759390080F292 /* JGProgressHUDImageIndicatorView.m */; }; - 5020AA5524E759390080F292 /* JGProgressHUDSuccessIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3C24E759390080F292 /* JGProgressHUDSuccessIndicatorView.m */; }; - 5020AA5624E759390080F292 /* JGProgressHUDIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3D24E759390080F292 /* JGProgressHUDIndicatorView.m */; }; - 5020AA5724E759390080F292 /* JGProgressHUD.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3E24E759390080F292 /* JGProgressHUD.m */; }; - 5020AA5824E759390080F292 /* JGProgressHUDFadeAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA3F24E759390080F292 /* JGProgressHUDFadeAnimation.m */; }; - 5020AA5924E759390080F292 /* JGProgressHUDRingIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA4024E759390080F292 /* JGProgressHUDRingIndicatorView.m */; }; - 5020AA5A24E759390080F292 /* JGProgressHUDPieIndicatorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA4124E759390080F292 /* JGProgressHUDPieIndicatorView.m */; }; - 5020AA5B24E759390080F292 /* JGProgressHUDShadow.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA4224E759390080F292 /* JGProgressHUDShadow.m */; }; 5020AA6424E759590080F292 /* Colours.h in Headers */ = {isa = PBXBuildFile; fileRef = 5020AA5E24E759590080F292 /* Colours.h */; }; 5020AA6624E759590080F292 /* Colours.m in Sources */ = {isa = PBXBuildFile; fileRef = 5020AA6024E759590080F292 /* Colours.m */; }; 5020AA6924E759700080F292 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5020AA6824E759700080F292 /* Accelerate.framework */; }; @@ -61,418 +36,6 @@ 5020AA7924E759960080F292 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5020AA7824E759960080F292 /* SafariServices.framework */; }; 5020AA7B24E7599B0080F292 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5020AA7A24E7599B0080F292 /* Security.framework */; }; 5020AA7D24E759A20080F292 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5020AA7C24E759A20080F292 /* QuartzCore.framework */; }; - 503FA8362753F04B00BBB92A /* FLEX-Runtime.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA66E2753F04A00BBB92A /* FLEX-Runtime.h */; }; - 503FA8372753F04B00BBB92A /* FLEXTableViewSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6702753F04A00BBB92A /* FLEXTableViewSection.h */; }; - 503FA8382753F04B00BBB92A /* FLEXSingleRowSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6712753F04A00BBB92A /* FLEXSingleRowSection.m */; }; - 503FA8392753F04B00BBB92A /* FLEXTableViewSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6722753F04A00BBB92A /* FLEXTableViewSection.m */; }; - 503FA83A2753F04B00BBB92A /* FLEXTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6742753F04A00BBB92A /* FLEXTableViewController.m */; }; - 503FA83B2753F04B00BBB92A /* FLEXNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6752753F04A00BBB92A /* FLEXNavigationController.m */; }; - 503FA83C2753F04B00BBB92A /* FLEXFilteringTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6762753F04A00BBB92A /* FLEXFilteringTableViewController.h */; }; - 503FA83D2753F04B00BBB92A /* FLEXNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6772753F04A00BBB92A /* FLEXNavigationController.h */; }; - 503FA83E2753F04B00BBB92A /* FLEXTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6782753F04A00BBB92A /* FLEXTableViewController.h */; }; - 503FA83F2753F04B00BBB92A /* FLEXFilteringTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6792753F04A00BBB92A /* FLEXFilteringTableViewController.m */; }; - 503FA8402753F04B00BBB92A /* FLEXCodeFontCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA67C2753F04A00BBB92A /* FLEXCodeFontCell.h */; }; - 503FA8412753F04B00BBB92A /* FLEXKeyValueTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA67D2753F04A00BBB92A /* FLEXKeyValueTableViewCell.m */; }; - 503FA8422753F04B00BBB92A /* FLEXSubtitleTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA67E2753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */; }; - 503FA8432753F04B00BBB92A /* FLEXTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA67F2753F04A00BBB92A /* FLEXTableViewCell.h */; }; - 503FA8442753F04B00BBB92A /* FLEXMultilineTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6802753F04A00BBB92A /* FLEXMultilineTableViewCell.h */; }; - 503FA8452753F04B00BBB92A /* FLEXKeyValueTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6812753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */; }; - 503FA8462753F04B00BBB92A /* FLEXCodeFontCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6822753F04A00BBB92A /* FLEXCodeFontCell.m */; }; - 503FA8472753F04B00BBB92A /* FLEXSubtitleTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6832753F04A00BBB92A /* FLEXSubtitleTableViewCell.m */; }; - 503FA8482753F04B00BBB92A /* FLEXMultilineTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6842753F04A00BBB92A /* FLEXMultilineTableViewCell.m */; }; - 503FA8492753F04B00BBB92A /* FLEXTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6852753F04A00BBB92A /* FLEXTableViewCell.m */; }; - 503FA84A2753F04B00BBB92A /* FLEXTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6862753F04A00BBB92A /* FLEXTableView.h */; }; - 503FA84B2753F04B00BBB92A /* FLEXCarouselCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6882753F04A00BBB92A /* FLEXCarouselCell.h */; }; - 503FA84C2753F04B00BBB92A /* FLEXScopeCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6892753F04A00BBB92A /* FLEXScopeCarousel.m */; }; - 503FA84D2753F04B00BBB92A /* FLEXScopeCarousel.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA68A2753F04A00BBB92A /* FLEXScopeCarousel.h */; }; - 503FA84E2753F04B00BBB92A /* FLEXCarouselCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA68B2753F04A00BBB92A /* FLEXCarouselCell.m */; }; - 503FA84F2753F04B00BBB92A /* FLEXTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA68C2753F04A00BBB92A /* FLEXTableView.m */; }; - 503FA8502753F04B00BBB92A /* FLEXSingleRowSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA68D2753F04A00BBB92A /* FLEXSingleRowSection.h */; }; - 503FA8512753F04B00BBB92A /* FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA68E2753F04A00BBB92A /* FLEX.h */; }; - 503FA8522753F04B00BBB92A /* FLEXObjectExplorerFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6902753F04A00BBB92A /* FLEXObjectExplorerFactory.m */; }; - 503FA8532753F04B00BBB92A /* FLEXColorPreviewSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6922753F04A00BBB92A /* FLEXColorPreviewSection.h */; }; - 503FA8542753F04B00BBB92A /* FLEXCollectionContentSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6932753F04A00BBB92A /* FLEXCollectionContentSection.h */; }; - 503FA8552753F04B00BBB92A /* FLEXDefaultsContentSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6942753F04A00BBB92A /* FLEXDefaultsContentSection.m */; }; - 503FA8562753F04B00BBB92A /* FLEXMutableListSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6952753F04A00BBB92A /* FLEXMutableListSection.m */; }; - 503FA8572753F04B00BBB92A /* FLEXMetadataSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6962753F04A00BBB92A /* FLEXMetadataSection.h */; }; - 503FA8582753F04B00BBB92A /* FLEXCollectionContentSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6972753F04A00BBB92A /* FLEXCollectionContentSection.m */; }; - 503FA8592753F04B00BBB92A /* FLEXColorPreviewSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6982753F04A00BBB92A /* FLEXColorPreviewSection.m */; }; - 503FA85A2753F04B00BBB92A /* FLEXDefaultsContentSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6992753F04A00BBB92A /* FLEXDefaultsContentSection.h */; }; - 503FA85B2753F04B00BBB92A /* FLEXBundleShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA69B2753F04A00BBB92A /* FLEXBundleShortcuts.h */; }; - 503FA85C2753F04B00BBB92A /* FLEXShortcutsSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA69C2753F04A00BBB92A /* FLEXShortcutsSection.m */; }; - 503FA85D2753F04B00BBB92A /* FLEXViewShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA69D2753F04A00BBB92A /* FLEXViewShortcuts.h */; }; - 503FA85E2753F04B00BBB92A /* FLEXNSStringShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA69E2753F04A00BBB92A /* FLEXNSStringShortcuts.h */; }; - 503FA85F2753F04B00BBB92A /* FLEXBlockShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA69F2753F04A00BBB92A /* FLEXBlockShortcuts.m */; }; - 503FA8602753F04B00BBB92A /* FLEXClassShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6A02753F04A00BBB92A /* FLEXClassShortcuts.m */; }; - 503FA8612753F04B00BBB92A /* FLEXShortcutsFactory+Defaults.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.h */; }; - 503FA8622753F04B00BBB92A /* FLEXUIAppShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A22753F04A00BBB92A /* FLEXUIAppShortcuts.h */; }; - 503FA8632753F04B00BBB92A /* FLEXLayerShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A32753F04A00BBB92A /* FLEXLayerShortcuts.h */; }; - 503FA8642753F04B00BBB92A /* FLEXImageShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6A42753F04A00BBB92A /* FLEXImageShortcuts.m */; }; - 503FA8652753F04B00BBB92A /* FLEXNSDataShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A52753F04A00BBB92A /* FLEXNSDataShortcuts.h */; }; - 503FA8662753F04B00BBB92A /* FLEXViewControllerShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A62753F04A00BBB92A /* FLEXViewControllerShortcuts.h */; }; - 503FA8672753F04B00BBB92A /* FLEXShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A72753F04A00BBB92A /* FLEXShortcut.h */; }; - 503FA8682753F04B00BBB92A /* FLEXViewShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6A82753F04A00BBB92A /* FLEXViewShortcuts.m */; }; - 503FA8692753F04B00BBB92A /* FLEXShortcutsSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6A92753F04A00BBB92A /* FLEXShortcutsSection.h */; }; - 503FA86A2753F04B00BBB92A /* FLEXBundleShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6AA2753F04A00BBB92A /* FLEXBundleShortcuts.m */; }; - 503FA86B2753F04B00BBB92A /* FLEXClassShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6AB2753F04A00BBB92A /* FLEXClassShortcuts.h */; }; - 503FA86C2753F04B00BBB92A /* FLEXBlockShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6AC2753F04A00BBB92A /* FLEXBlockShortcuts.h */; }; - 503FA86D2753F04B00BBB92A /* FLEXNSStringShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6AD2753F04A00BBB92A /* FLEXNSStringShortcuts.m */; }; - 503FA86E2753F04B00BBB92A /* FLEXImageShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6AE2753F04A00BBB92A /* FLEXImageShortcuts.h */; }; - 503FA86F2753F04B00BBB92A /* FLEXLayerShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6AF2753F04A00BBB92A /* FLEXLayerShortcuts.m */; }; - 503FA8702753F04B00BBB92A /* FLEXUIAppShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B02753F04A00BBB92A /* FLEXUIAppShortcuts.m */; }; - 503FA8712753F04B00BBB92A /* FLEXShortcutsFactory+Defaults.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.m */; }; - 503FA8722753F04B00BBB92A /* FLEXShortcut.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B22753F04A00BBB92A /* FLEXShortcut.m */; }; - 503FA8732753F04B00BBB92A /* FLEXViewControllerShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B32753F04A00BBB92A /* FLEXViewControllerShortcuts.m */; }; - 503FA8742753F04B00BBB92A /* FLEXNSDataShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B42753F04A00BBB92A /* FLEXNSDataShortcuts.m */; }; - 503FA8752753F04B00BBB92A /* FLEXMutableListSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6B52753F04A00BBB92A /* FLEXMutableListSection.h */; }; - 503FA8762753F04B00BBB92A /* FLEXObjectInfoSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6B62753F04A00BBB92A /* FLEXObjectInfoSection.h */; }; - 503FA8772753F04B00BBB92A /* FLEXMetadataSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6B72753F04A00BBB92A /* FLEXMetadataSection.m */; }; - 503FA8782753F04B00BBB92A /* FLEXObjectExplorerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6B82753F04A00BBB92A /* FLEXObjectExplorerViewController.h */; }; - 503FA8792753F04B00BBB92A /* FLEXObjectExplorer.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6B92753F04A00BBB92A /* FLEXObjectExplorer.h */; }; - 503FA87A2753F04B00BBB92A /* FLEXObjectExplorerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6BA2753F04A00BBB92A /* FLEXObjectExplorerFactory.h */; }; - 503FA87B2753F04B00BBB92A /* FLEXObjectExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6BB2753F04A00BBB92A /* FLEXObjectExplorerViewController.m */; }; - 503FA87C2753F04B00BBB92A /* FLEXObjectExplorer.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6BC2753F04A00BBB92A /* FLEXObjectExplorer.m */; }; - 503FA87D2753F04B00BBB92A /* FLEXNetworkCurlLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6BE2753F04A00BBB92A /* FLEXNetworkCurlLogger.h */; }; - 503FA87E2753F04B00BBB92A /* FLEXNetworkTransaction.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6BF2753F04A00BBB92A /* FLEXNetworkTransaction.m */; }; - 503FA87F2753F04B00BBB92A /* FLEXNetworkSettingsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C02753F04A00BBB92A /* FLEXNetworkSettingsController.m */; }; - 503FA8802753F04B00BBB92A /* FLEXNetworkRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C12753F04A00BBB92A /* FLEXNetworkRecorder.m */; }; - 503FA8812753F04B00BBB92A /* FLEXHTTPTransactionDetailController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6C22753F04A00BBB92A /* FLEXHTTPTransactionDetailController.h */; }; - 503FA8822753F04B00BBB92A /* FLEXNetworkMITMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C32753F04A00BBB92A /* FLEXNetworkMITMViewController.m */; }; - 503FA8832753F04B00BBB92A /* FLEXMITMDataSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6C42753F04A00BBB92A /* FLEXMITMDataSource.h */; }; - 503FA8842753F04B00BBB92A /* FLEXNetworkTransactionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C52753F04A00BBB92A /* FLEXNetworkTransactionCell.m */; }; - 503FA8852753F04B00BBB92A /* FLEXNetworkTransaction.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6C62753F04A00BBB92A /* FLEXNetworkTransaction.h */; }; - 503FA8862753F04B00BBB92A /* FLEXNetworkCurlLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C72753F04A00BBB92A /* FLEXNetworkCurlLogger.m */; }; - 503FA8872753F04B00BBB92A /* FLEXNetworkMITMViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6C82753F04A00BBB92A /* FLEXNetworkMITMViewController.h */; }; - 503FA8882753F04B00BBB92A /* FLEXHTTPTransactionDetailController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6C92753F04A00BBB92A /* FLEXHTTPTransactionDetailController.m */; }; - 503FA8892753F04B00BBB92A /* FLEXNetworkRecorder.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6CA2753F04A00BBB92A /* FLEXNetworkRecorder.h */; }; - 503FA88A2753F04B00BBB92A /* FLEXNetworkSettingsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6CB2753F04A00BBB92A /* FLEXNetworkSettingsController.h */; }; - 503FA88B2753F04B00BBB92A /* FLEXMITMDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6CC2753F04A00BBB92A /* FLEXMITMDataSource.m */; }; - 503FA88C2753F04B00BBB92A /* FLEXNetworkObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6CE2753F04A00BBB92A /* FLEXNetworkObserver.h */; }; - 503FA88D2753F04B00BBB92A /* FLEXNetworkObserver.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6D02753F04A00BBB92A /* FLEXNetworkObserver.m */; }; - 503FA88E2753F04B00BBB92A /* FLEXNetworkTransactionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6D12753F04A00BBB92A /* FLEXNetworkTransactionCell.h */; }; - 503FA88F2753F04B00BBB92A /* OSCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6D42753F04A00BBB92A /* OSCache.m */; }; - 503FA8902753F04B00BBB92A /* OSCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6D52753F04A00BBB92A /* OSCache.h */; }; - 503FA8912753F04B00BBB92A /* FLEXExplorerToolbarItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6D72753F04A00BBB92A /* FLEXExplorerToolbarItem.h */; }; - 503FA8922753F04B00BBB92A /* FLEXExplorerToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6D82753F04A00BBB92A /* FLEXExplorerToolbar.h */; }; - 503FA8932753F04B00BBB92A /* FLEXExplorerToolbarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6D92753F04A00BBB92A /* FLEXExplorerToolbarItem.m */; }; - 503FA8942753F04B00BBB92A /* FLEXExplorerToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6DA2753F04A00BBB92A /* FLEXExplorerToolbar.m */; }; - 503FA8952753F04B00BBB92A /* FLEX-Categories.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6DB2753F04A00BBB92A /* FLEX-Categories.h */; }; - 503FA8962753F04B00BBB92A /* FLEX-Core.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6DC2753F04A00BBB92A /* FLEX-Core.h */; }; - 503FA8972753F04B00BBB92A /* FLEX-ObjectExploring.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6DD2753F04A00BBB92A /* FLEX-ObjectExploring.h */; }; - 503FA8982753F04B00BBB92A /* FLEXManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6DF2753F04A00BBB92A /* FLEXManager.h */; }; - 503FA8992753F04B00BBB92A /* FLEXManager+Extensibility.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6E02753F04A00BBB92A /* FLEXManager+Extensibility.m */; }; - 503FA89A2753F04B00BBB92A /* FLEXManager+Networking.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6E12753F04A00BBB92A /* FLEXManager+Networking.h */; }; - 503FA89B2753F04C00BBB92A /* FLEXManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6E22753F04A00BBB92A /* FLEXManager.m */; }; - 503FA89C2753F04C00BBB92A /* FLEXManager+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6E42753F04A00BBB92A /* FLEXManager+Private.h */; }; - 503FA89D2753F04C00BBB92A /* FLEXManager+Networking.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6E52753F04A00BBB92A /* FLEXManager+Networking.m */; }; - 503FA89E2753F04C00BBB92A /* FLEXManager+Extensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6E62753F04A00BBB92A /* FLEXManager+Extensibility.h */; }; - 503FA89F2753F04C00BBB92A /* FLEXDefaultEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6E82753F04A00BBB92A /* FLEXDefaultEditorViewController.m */; }; - 503FA8A02753F04C00BBB92A /* FLEXVariableEditorViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6E92753F04A00BBB92A /* FLEXVariableEditorViewController.h */; }; - 503FA8A12753F04C00BBB92A /* FLEXFieldEditorViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6EA2753F04A00BBB92A /* FLEXFieldEditorViewController.h */; }; - 503FA8A22753F04C00BBB92A /* FLEXFieldEditorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6EB2753F04A00BBB92A /* FLEXFieldEditorView.h */; }; - 503FA8A32753F04C00BBB92A /* FLEXMethodCallingViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6EC2753F04A00BBB92A /* FLEXMethodCallingViewController.m */; }; - 503FA8A42753F04C00BBB92A /* FLEXArgumentInputViewFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6ED2753F04A00BBB92A /* FLEXArgumentInputViewFactory.h */; }; - 503FA8A52753F04C00BBB92A /* FLEXFieldEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6EE2753F04A00BBB92A /* FLEXFieldEditorViewController.m */; }; - 503FA8A62753F04C00BBB92A /* FLEXVariableEditorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6EF2753F04A00BBB92A /* FLEXVariableEditorViewController.m */; }; - 503FA8A72753F04C00BBB92A /* FLEXDefaultEditorViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6F02753F04A00BBB92A /* FLEXDefaultEditorViewController.h */; }; - 503FA8A82753F04C00BBB92A /* FLEXArgumentInputStringView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F22753F04A00BBB92A /* FLEXArgumentInputStringView.m */; }; - 503FA8A92753F04C00BBB92A /* FLEXArgumentInputColorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F32753F04A00BBB92A /* FLEXArgumentInputColorView.m */; }; - 503FA8AA2753F04C00BBB92A /* FLEXArgumentInputView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F42753F04A00BBB92A /* FLEXArgumentInputView.m */; }; - 503FA8AB2753F04C00BBB92A /* FLEXArgumentInputFontView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6F52753F04A00BBB92A /* FLEXArgumentInputFontView.h */; }; - 503FA8AC2753F04C00BBB92A /* FLEXArgumentInputTextView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6F62753F04A00BBB92A /* FLEXArgumentInputTextView.h */; }; - 503FA8AD2753F04C00BBB92A /* FLEXArgumentInputSwitchView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F72753F04A00BBB92A /* FLEXArgumentInputSwitchView.m */; }; - 503FA8AE2753F04C00BBB92A /* FLEXArgumentInputStructView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F82753F04A00BBB92A /* FLEXArgumentInputStructView.m */; }; - 503FA8AF2753F04C00BBB92A /* FLEXArgumentInputDateView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6F92753F04A00BBB92A /* FLEXArgumentInputDateView.m */; }; - 503FA8B02753F04C00BBB92A /* FLEXArgumentInputNumberView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6FA2753F04A00BBB92A /* FLEXArgumentInputNumberView.h */; }; - 503FA8B12753F04C00BBB92A /* FLEXArgumentInputFontsPickerView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6FB2753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.h */; }; - 503FA8B22753F04C00BBB92A /* FLEXArgumentInputNotSupportedView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6FC2753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.h */; }; - 503FA8B32753F04C00BBB92A /* FLEXArgumentInputObjectView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6FD2753F04A00BBB92A /* FLEXArgumentInputObjectView.m */; }; - 503FA8B42753F04C00BBB92A /* FLEXArgumentInputFontView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA6FE2753F04A00BBB92A /* FLEXArgumentInputFontView.m */; }; - 503FA8B52753F04C00BBB92A /* FLEXArgumentInputView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA6FF2753F04A00BBB92A /* FLEXArgumentInputView.h */; }; - 503FA8B62753F04C00BBB92A /* FLEXArgumentInputColorView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7002753F04A00BBB92A /* FLEXArgumentInputColorView.h */; }; - 503FA8B72753F04C00BBB92A /* FLEXArgumentInputStringView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7012753F04A00BBB92A /* FLEXArgumentInputStringView.h */; }; - 503FA8B82753F04C00BBB92A /* FLEXArgumentInputSwitchView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7022753F04A00BBB92A /* FLEXArgumentInputSwitchView.h */; }; - 503FA8B92753F04C00BBB92A /* FLEXArgumentInputTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7032753F04A00BBB92A /* FLEXArgumentInputTextView.m */; }; - 503FA8BA2753F04C00BBB92A /* FLEXArgumentInputFontsPickerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7042753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.m */; }; - 503FA8BB2753F04C00BBB92A /* FLEXArgumentInputNumberView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7052753F04A00BBB92A /* FLEXArgumentInputNumberView.m */; }; - 503FA8BC2753F04C00BBB92A /* FLEXArgumentInputDateView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7062753F04A00BBB92A /* FLEXArgumentInputDateView.h */; }; - 503FA8BD2753F04C00BBB92A /* FLEXArgumentInputStructView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7072753F04A00BBB92A /* FLEXArgumentInputStructView.h */; }; - 503FA8BE2753F04C00BBB92A /* FLEXArgumentInputObjectView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7082753F04A00BBB92A /* FLEXArgumentInputObjectView.h */; }; - 503FA8BF2753F04C00BBB92A /* FLEXArgumentInputNotSupportedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7092753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.m */; }; - 503FA8C02753F04C00BBB92A /* FLEXArgumentInputViewFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA70A2753F04A00BBB92A /* FLEXArgumentInputViewFactory.m */; }; - 503FA8C12753F04C00BBB92A /* FLEXMethodCallingViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA70B2753F04A00BBB92A /* FLEXMethodCallingViewController.h */; }; - 503FA8C22753F04C00BBB92A /* FLEXFieldEditorView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA70C2753F04A00BBB92A /* FLEXFieldEditorView.m */; }; - 503FA8C32753F04C00BBB92A /* FLEXRuntimeSafety.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA70E2753F04A00BBB92A /* FLEXRuntimeSafety.h */; }; - 503FA8C42753F04C00BBB92A /* FLEXExplorerToolbarItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA70F2753F04A00BBB92A /* FLEXExplorerToolbarItem.h */; }; - 503FA8C52753F04C00BBB92A /* FLEXManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7102753F04A00BBB92A /* FLEXManager.h */; }; - 503FA8C62753F04C00BBB92A /* FLEXBlockDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7112753F04A00BBB92A /* FLEXBlockDescription.h */; }; - 503FA8C72753F04C00BBB92A /* FLEXMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7122753F04A00BBB92A /* FLEXMacros.h */; }; - 503FA8C82753F04C00BBB92A /* FLEXProtocolBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7132753F04A00BBB92A /* FLEXProtocolBuilder.h */; }; - 503FA8C92753F04C00BBB92A /* FLEXColorPreviewSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7142753F04A00BBB92A /* FLEXColorPreviewSection.h */; }; - 503FA8CA2753F04C00BBB92A /* FLEXCollectionContentSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7152753F04A00BBB92A /* FLEXCollectionContentSection.h */; }; - 503FA8CB2753F04C00BBB92A /* FLEX-Runtime.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7162753F04A00BBB92A /* FLEX-Runtime.h */; }; - 503FA8CC2753F04C00BBB92A /* UIBarButtonItem+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7172753F04A00BBB92A /* UIBarButtonItem+FLEX.h */; }; - 503FA8CD2753F04C00BBB92A /* FLEXResources.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7182753F04A00BBB92A /* FLEXResources.h */; }; - 503FA8CE2753F04C00BBB92A /* FLEXTypeEncodingParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7192753F04A00BBB92A /* FLEXTypeEncodingParser.h */; }; - 503FA8CF2753F04C00BBB92A /* FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71A2753F04A00BBB92A /* FLEX.h */; }; - 503FA8D02753F04C00BBB92A /* FLEXRuntimeConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71B2753F04A00BBB92A /* FLEXRuntimeConstants.h */; }; - 503FA8D12753F04C00BBB92A /* FLEXClassBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71C2753F04A00BBB92A /* FLEXClassBuilder.h */; }; - 503FA8D22753F04C00BBB92A /* FLEXCodeFontCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71D2753F04A00BBB92A /* FLEXCodeFontCell.h */; }; - 503FA8D32753F04C00BBB92A /* FLEXTableViewSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71E2753F04A00BBB92A /* FLEXTableViewSection.h */; }; - 503FA8D42753F04C00BBB92A /* FLEXFilteringTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA71F2753F04A00BBB92A /* FLEXFilteringTableViewController.h */; }; - 503FA8D52753F04C00BBB92A /* CALayer+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7202753F04A00BBB92A /* CALayer+FLEX.h */; }; - 503FA8D62753F04C00BBB92A /* FLEXSubtitleTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7212753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */; }; - 503FA8D72753F04C00BBB92A /* FLEXObjectExplorerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7222753F04A00BBB92A /* FLEXObjectExplorerViewController.h */; }; - 503FA8D82753F04C00BBB92A /* FLEXManager+Networking.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7232753F04A00BBB92A /* FLEXManager+Networking.h */; }; - 503FA8D92753F04C00BBB92A /* FLEXMetadataSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7242753F04A00BBB92A /* FLEXMetadataSection.h */; }; - 503FA8DA2753F04C00BBB92A /* FLEX-Categories.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7252753F04A00BBB92A /* FLEX-Categories.h */; }; - 503FA8DB2753F04C00BBB92A /* UIFont+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7262753F04A00BBB92A /* UIFont+FLEX.h */; }; - 503FA8DC2753F04C00BBB92A /* FLEXTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7272753F04A00BBB92A /* FLEXTableView.h */; }; - 503FA8DD2753F04C00BBB92A /* FLEXMethodBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7282753F04A00BBB92A /* FLEXMethodBase.h */; }; - 503FA8DE2753F04C00BBB92A /* FLEXObjectExplorer.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7292753F04A00BBB92A /* FLEXObjectExplorer.h */; }; - 503FA8DF2753F04C00BBB92A /* FLEXShortcut.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72A2753F04A00BBB92A /* FLEXShortcut.h */; }; - 503FA8E02753F04C00BBB92A /* FLEXTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72B2753F04A00BBB92A /* FLEXTableViewCell.h */; }; - 503FA8E12753F04C00BBB92A /* FLEX-Core.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72C2753F04A00BBB92A /* FLEX-Core.h */; }; - 503FA8E22753F04C00BBB92A /* FLEXMultilineTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72D2753F04A00BBB92A /* FLEXMultilineTableViewCell.h */; }; - 503FA8E32753F04C00BBB92A /* FLEXProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72E2753F04A00BBB92A /* FLEXProtocol.h */; }; - 503FA8E42753F04C00BBB92A /* FLEXExplorerToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA72F2753F04A00BBB92A /* FLEXExplorerToolbar.h */; }; - 503FA8E52753F04C00BBB92A /* FLEXGlobalsEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7302753F04A00BBB92A /* FLEXGlobalsEntry.h */; }; - 503FA8E62753F04C00BBB92A /* NSObject+FLEX_Reflection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7312753F04A00BBB92A /* NSObject+FLEX_Reflection.h */; }; - 503FA8E72753F04C00BBB92A /* FLEX-ObjectExploring.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7322753F04A00BBB92A /* FLEX-ObjectExploring.h */; }; - 503FA8E82753F04C00BBB92A /* NSArray+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7332753F04A00BBB92A /* NSArray+FLEX.h */; }; - 503FA8E92753F04C00BBB92A /* FLEXRuntime+Compare.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7342753F04A00BBB92A /* FLEXRuntime+Compare.h */; }; - 503FA8EA2753F04C00BBB92A /* FLEXShortcutsSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7352753F04A00BBB92A /* FLEXShortcutsSection.h */; }; - 503FA8EB2753F04C00BBB92A /* FLEXPropertyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7362753F04A00BBB92A /* FLEXPropertyAttributes.h */; }; - 503FA8EC2753F04C00BBB92A /* UIGestureRecognizer+Blocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7372753F04A00BBB92A /* UIGestureRecognizer+Blocks.h */; }; - 503FA8ED2753F04C00BBB92A /* FLEXMirror.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7382753F04A00BBB92A /* FLEXMirror.h */; }; - 503FA8EE2753F04C00BBB92A /* FLEXObjectExplorerFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7392753F04A00BBB92A /* FLEXObjectExplorerFactory.h */; }; - 503FA8EF2753F04C00BBB92A /* FLEXKeyValueTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73A2753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */; }; - 503FA8F02753F04C00BBB92A /* FLEXNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73B2753F04A00BBB92A /* FLEXNavigationController.h */; }; - 503FA8F12753F04C00BBB92A /* NSTimer+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73C2753F04A00BBB92A /* NSTimer+FLEX.h */; }; - 503FA8F22753F04C00BBB92A /* FLEXDefaultsContentSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73D2753F04A00BBB92A /* FLEXDefaultsContentSection.h */; }; - 503FA8F32753F04C00BBB92A /* FLEXTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73E2753F04A00BBB92A /* FLEXTableViewController.h */; }; - 503FA8F42753F04C00BBB92A /* FLEXRuntime+UIKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA73F2753F04A00BBB92A /* FLEXRuntime+UIKitHelpers.h */; }; - 503FA8F52753F04C00BBB92A /* FLEXProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7402753F04A00BBB92A /* FLEXProperty.h */; }; - 503FA8F62753F04C00BBB92A /* FLEXMutableListSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7412753F04A00BBB92A /* FLEXMutableListSection.h */; }; - 503FA8F72753F04C00BBB92A /* UIPasteboard+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7422753F04A00BBB92A /* UIPasteboard+FLEX.h */; }; - 503FA8F82753F04C00BBB92A /* FLEXObjcInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7432753F04A00BBB92A /* FLEXObjcInternal.h */; }; - 503FA8F92753F04C00BBB92A /* FLEXManager+Extensibility.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7442753F04A00BBB92A /* FLEXManager+Extensibility.h */; }; - 503FA8FA2753F04C00BBB92A /* UIMenu+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7452753F04A00BBB92A /* UIMenu+FLEX.h */; }; - 503FA8FB2753F04C00BBB92A /* FLEXObjectInfoSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7462753F04A00BBB92A /* FLEXObjectInfoSection.h */; }; - 503FA8FC2753F04C00BBB92A /* UITextField+Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7472753F04A00BBB92A /* UITextField+Range.h */; }; - 503FA8FD2753F04C00BBB92A /* FLEXIvar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7482753F04A00BBB92A /* FLEXIvar.h */; }; - 503FA8FE2753F04C00BBB92A /* NSUserDefaults+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7492753F04A00BBB92A /* NSUserDefaults+FLEX.h */; }; - 503FA8FF2753F04C00BBB92A /* FLEXSingleRowSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA74A2753F04A00BBB92A /* FLEXSingleRowSection.h */; }; - 503FA9002753F04C00BBB92A /* FLEXAlert.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA74B2753F04A00BBB92A /* FLEXAlert.h */; }; - 503FA9012753F04C00BBB92A /* FLEXMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA74C2753F04A00BBB92A /* FLEXMethod.h */; }; - 503FA9022753F04C00BBB92A /* FLEXTabList.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA74F2753F04A00BBB92A /* FLEXTabList.h */; }; - 503FA9032753F04C00BBB92A /* FLEXTabsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7502753F04A00BBB92A /* FLEXTabsViewController.m */; }; - 503FA9042753F04C00BBB92A /* FLEXTabList.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7512753F04A00BBB92A /* FLEXTabList.m */; }; - 503FA9052753F04C00BBB92A /* FLEXTabsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7522753F04A00BBB92A /* FLEXTabsViewController.h */; }; - 503FA9062753F04C00BBB92A /* FLEXExplorerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7532753F04A00BBB92A /* FLEXExplorerViewController.m */; }; - 503FA9072753F04C00BBB92A /* FLEXWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7542753F04A00BBB92A /* FLEXWindow.m */; }; - 503FA9082753F04C00BBB92A /* FLEXViewControllersViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7552753F04A00BBB92A /* FLEXViewControllersViewController.h */; }; - 503FA9092753F04C00BBB92A /* FLEXWindowManagerController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7562753F04A00BBB92A /* FLEXWindowManagerController.m */; }; - 503FA90A2753F04C00BBB92A /* FLEXBookmarkManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7582753F04A00BBB92A /* FLEXBookmarkManager.h */; }; - 503FA90B2753F04C00BBB92A /* FLEXBookmarksViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7592753F04A00BBB92A /* FLEXBookmarksViewController.h */; }; - 503FA90C2753F04C00BBB92A /* FLEXBookmarkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA75A2753F04A00BBB92A /* FLEXBookmarkManager.m */; }; - 503FA90D2753F04C00BBB92A /* FLEXBookmarksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA75B2753F04A00BBB92A /* FLEXBookmarksViewController.m */; }; - 503FA90E2753F04C00BBB92A /* FLEXExplorerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA75C2753F04A00BBB92A /* FLEXExplorerViewController.h */; }; - 503FA90F2753F04C00BBB92A /* FLEXWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA75D2753F04A00BBB92A /* FLEXWindow.h */; }; - 503FA9102753F04C00BBB92A /* FLEXWindowManagerController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA75E2753F04A00BBB92A /* FLEXWindowManagerController.h */; }; - 503FA9112753F04C00BBB92A /* FLEXViewControllersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA75F2753F04A00BBB92A /* FLEXViewControllersViewController.m */; }; - 503FA9122753F04C00BBB92A /* RuntimeExplore.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7612753F04A00BBB92A /* RuntimeExplore.h */; }; - 503FA9132753F04C00BBB92A /* FLEXGlobalsEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7632753F04A00BBB92A /* FLEXGlobalsEntry.m */; }; - 503FA9142753F04C00BBB92A /* FLEXGlobalsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7642753F04A00BBB92A /* FLEXGlobalsViewController.h */; }; - 503FA9152753F04C00BBB92A /* FLEXGlobalsSection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7652753F04A00BBB92A /* FLEXGlobalsSection.m */; }; - 503FA9162753F04C00BBB92A /* FLEXGlobalsEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7662753F04A00BBB92A /* FLEXGlobalsEntry.h */; }; - 503FA9172753F04C00BBB92A /* FLEXGlobalsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7672753F04A00BBB92A /* FLEXGlobalsViewController.m */; }; - 503FA9182753F04C00BBB92A /* FLEXGlobalsSection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7682753F04A00BBB92A /* FLEXGlobalsSection.h */; }; - 503FA9192753F04C00BBB92A /* FLEXObjectListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7692753F04A00BBB92A /* FLEXObjectListViewController.h */; }; - 503FA91A2753F04C00BBB92A /* FLEXLiveObjectsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA76A2753F04A00BBB92A /* FLEXLiveObjectsController.m */; }; - 503FA91B2753F04C00BBB92A /* FLEXObjectRef.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA76B2753F04A00BBB92A /* FLEXObjectRef.m */; }; - 503FA91C2753F04C00BBB92A /* FLEXWebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA76C2753F04A00BBB92A /* FLEXWebViewController.m */; }; - 503FA91D2753F04C00BBB92A /* FLEXAddressExplorerCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA76D2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.h */; }; - 503FA91E2753F04C00BBB92A /* FLEXCookiesViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA76E2753F04A00BBB92A /* FLEXCookiesViewController.h */; }; - 503FA91F2753F04C00BBB92A /* FLEXLiveObjectsController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA76F2753F04A00BBB92A /* FLEXLiveObjectsController.h */; }; - 503FA9202753F04C00BBB92A /* FLEXObjectListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7702753F04A00BBB92A /* FLEXObjectListViewController.m */; }; - 503FA9212753F04C00BBB92A /* RuntimeExplore.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7712753F04A00BBB92A /* RuntimeExplore.m */; }; - 503FA9222753F04C00BBB92A /* FLEXKeychain.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7732753F04A00BBB92A /* FLEXKeychain.h */; }; - 503FA9232753F04C00BBB92A /* FLEXKeychainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7742753F04A00BBB92A /* FLEXKeychainViewController.m */; }; - 503FA9242753F04C00BBB92A /* FLEXKeychainQuery.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7752753F04A00BBB92A /* FLEXKeychainQuery.h */; }; - 503FA9252753F04C00BBB92A /* FLEXKeychain.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7772753F04A00BBB92A /* FLEXKeychain.m */; }; - 503FA9262753F04C00BBB92A /* FLEXKeychainViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7782753F04A00BBB92A /* FLEXKeychainViewController.h */; }; - 503FA9272753F04C00BBB92A /* FLEXKeychainQuery.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7792753F04A00BBB92A /* FLEXKeychainQuery.m */; }; - 503FA9282753F04C00BBB92A /* FLEXObjectRef.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA77A2753F04A00BBB92A /* FLEXObjectRef.h */; }; - 503FA9292753F04C00BBB92A /* FLEXFileBrowserSearchOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA77C2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.m */; }; - 503FA92A2753F04C00BBB92A /* FLEXFileBrowserController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA77D2753F04A00BBB92A /* FLEXFileBrowserController.m */; }; - 503FA92B2753F04C00BBB92A /* FLEXFileBrowserSearchOperation.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA77E2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.h */; }; - 503FA92C2753F04C00BBB92A /* FLEXFileBrowserController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA77F2753F04A00BBB92A /* FLEXFileBrowserController.h */; }; - 503FA92D2753F04C00BBB92A /* FLEXASLLogController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7812753F04A00BBB92A /* FLEXASLLogController.h */; }; - 503FA92E2753F04C00BBB92A /* FLEXLogController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7822753F04A00BBB92A /* FLEXLogController.h */; }; - 503FA92F2753F04C00BBB92A /* FLEXSystemLogCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7832753F04A00BBB92A /* FLEXSystemLogCell.m */; }; - 503FA9302753F04C00BBB92A /* FLEXOSLogController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7842753F04A00BBB92A /* FLEXOSLogController.h */; }; - 503FA9312753F04C00BBB92A /* FLEXSystemLogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7852753F04A00BBB92A /* FLEXSystemLogViewController.m */; }; - 503FA9322753F04C00BBB92A /* FLEXSystemLogMessage.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7862753F04A00BBB92A /* FLEXSystemLogMessage.m */; }; - 503FA9332753F04C00BBB92A /* FLEXASLLogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7872753F04A00BBB92A /* FLEXASLLogController.m */; }; - 503FA9342753F04C00BBB92A /* FLEXSystemLogCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7882753F04A00BBB92A /* FLEXSystemLogCell.h */; }; - 503FA9352753F04C00BBB92A /* FLEXSystemLogViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA78A2753F04A00BBB92A /* FLEXSystemLogViewController.h */; }; - 503FA9362753F04C00BBB92A /* FLEXOSLogController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA78B2753F04A00BBB92A /* FLEXOSLogController.m */; }; - 503FA9372753F04C00BBB92A /* ActivityStreamAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA78C2753F04A00BBB92A /* ActivityStreamAPI.h */; }; - 503FA9382753F04C00BBB92A /* FLEXSystemLogMessage.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA78D2753F04A00BBB92A /* FLEXSystemLogMessage.h */; }; - 503FA9392753F04C00BBB92A /* FLEXAddressExplorerCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA78E2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.m */; }; - 503FA93A2753F04C00BBB92A /* FLEXRealmDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7902753F04A00BBB92A /* FLEXRealmDefines.h */; }; - 503FA93B2753F04C00BBB92A /* FLEXTableLeftCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7912753F04A00BBB92A /* FLEXTableLeftCell.m */; }; - 503FA93C2753F04C00BBB92A /* FLEXRealmDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7922753F04A00BBB92A /* FLEXRealmDatabaseManager.h */; }; - 503FA93D2753F04C00BBB92A /* FLEXSQLResult.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7932753F04A00BBB92A /* FLEXSQLResult.m */; }; - 503FA93E2753F04C00BBB92A /* FLEXTableContentViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7952753F04A00BBB92A /* FLEXTableContentViewController.m */; }; - 503FA93F2753F04C00BBB92A /* FLEXDBQueryRowCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7962753F04A00BBB92A /* FLEXDBQueryRowCell.h */; }; - 503FA9402753F04C00BBB92A /* FLEXTableListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7972753F04A00BBB92A /* FLEXTableListViewController.m */; }; - 503FA9412753F04C00BBB92A /* FLEXTableColumnHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7982753F04A00BBB92A /* FLEXTableColumnHeader.m */; }; - 503FA9422753F04C00BBB92A /* FLEXMultiColumnTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7992753F04A00BBB92A /* FLEXMultiColumnTableView.m */; }; - 503FA9432753F04C00BBB92A /* FLEXSQLiteDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA79A2753F04A00BBB92A /* FLEXSQLiteDatabaseManager.h */; }; - 503FA9442753F04C00BBB92A /* FLEXTableLeftCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA79B2753F04A00BBB92A /* FLEXTableLeftCell.h */; }; - 503FA9452753F04C00BBB92A /* FLEXDatabaseManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA79C2753F04A00BBB92A /* FLEXDatabaseManager.h */; }; - 503FA9462753F04C00BBB92A /* FLEXSQLResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA79D2753F04A00BBB92A /* FLEXSQLResult.h */; }; - 503FA9472753F04C00BBB92A /* FLEXRealmDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA79E2753F04A00BBB92A /* FLEXRealmDatabaseManager.m */; }; - 503FA9482753F04D00BBB92A /* FLEXDBQueryRowCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA79F2753F04A00BBB92A /* FLEXDBQueryRowCell.m */; }; - 503FA9492753F04D00BBB92A /* FLEXTableContentViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A02753F04A00BBB92A /* FLEXTableContentViewController.h */; }; - 503FA94A2753F04D00BBB92A /* FLEXSQLiteDatabaseManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7A12753F04A00BBB92A /* FLEXSQLiteDatabaseManager.m */; }; - 503FA94B2753F04D00BBB92A /* FLEXMultiColumnTableView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A22753F04A00BBB92A /* FLEXMultiColumnTableView.h */; }; - 503FA94C2753F04D00BBB92A /* FLEXTableColumnHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A32753F04A00BBB92A /* FLEXTableColumnHeader.h */; }; - 503FA94D2753F04D00BBB92A /* FLEXTableListViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A42753F04A00BBB92A /* FLEXTableListViewController.h */; }; - 503FA94E2753F04D00BBB92A /* FLEXWebViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A52753F04A00BBB92A /* FLEXWebViewController.h */; }; - 503FA94F2753F04D00BBB92A /* FLEXCookiesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7A62753F04B00BBB92A /* FLEXCookiesViewController.m */; }; - 503FA9502753F04D00BBB92A /* FLEXRuntimeController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7A92753F04B00BBB92A /* FLEXRuntimeController.h */; }; - 503FA9512753F04D00BBB92A /* FLEXRuntimeClient.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7AA2753F04B00BBB92A /* FLEXRuntimeClient.m */; }; - 503FA9522753F04D00BBB92A /* FLEXRuntimeExporter.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7AB2753F04B00BBB92A /* FLEXRuntimeExporter.h */; }; - 503FA9532753F04D00BBB92A /* FLEXRuntimeClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7AC2753F04B00BBB92A /* FLEXRuntimeClient.h */; }; - 503FA9542753F04D00BBB92A /* FLEXRuntimeController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7AD2753F04B00BBB92A /* FLEXRuntimeController.m */; }; - 503FA9552753F04D00BBB92A /* FLEXRuntimeExporter.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7AE2753F04B00BBB92A /* FLEXRuntimeExporter.m */; }; - 503FA9562753F04D00BBB92A /* FLEXKBToolbarButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7AF2753F04B00BBB92A /* FLEXKBToolbarButton.h */; }; - 503FA9572753F04D00BBB92A /* FLEXRuntimeKeyPathTokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7B02753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.h */; }; - 503FA9582753F04D00BBB92A /* FLEXObjcRuntimeViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7B12753F04B00BBB92A /* FLEXObjcRuntimeViewController.h */; }; - 503FA9592753F04D00BBB92A /* FLEXKeyboardToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7B22753F04B00BBB92A /* FLEXKeyboardToolbar.h */; }; - 503FA95A2753F04D00BBB92A /* FLEXRuntimeKeyPath.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B32753F04B00BBB92A /* FLEXRuntimeKeyPath.m */; }; - 503FA95B2753F04D00BBB92A /* FLEXRuntimeBrowserToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B42753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.m */; }; - 503FA95C2753F04D00BBB92A /* FLEXKeyPathSearchController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7B52753F04B00BBB92A /* FLEXKeyPathSearchController.h */; }; - 503FA95D2753F04D00BBB92A /* FLEXSearchToken.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B62753F04B00BBB92A /* FLEXSearchToken.m */; }; - 503FA95E2753F04D00BBB92A /* FLEXKBToolbarButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B72753F04B00BBB92A /* FLEXKBToolbarButton.m */; }; - 503FA95F2753F04D00BBB92A /* FLEXKeyboardToolbar.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B82753F04B00BBB92A /* FLEXKeyboardToolbar.m */; }; - 503FA9602753F04D00BBB92A /* FLEXObjcRuntimeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7B92753F04B00BBB92A /* FLEXObjcRuntimeViewController.m */; }; - 503FA9612753F04D00BBB92A /* FLEXRuntimeKeyPathTokenizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7BA2753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.m */; }; - 503FA9622753F04D00BBB92A /* FLEXRuntimeBrowserToolbar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7BB2753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.h */; }; - 503FA9632753F04D00BBB92A /* FLEXRuntimeKeyPath.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7BC2753F04B00BBB92A /* FLEXRuntimeKeyPath.h */; }; - 503FA9642753F04D00BBB92A /* FLEXSearchToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7BD2753F04B00BBB92A /* FLEXSearchToken.h */; }; - 503FA9652753F04D00BBB92A /* FLEXKeyPathSearchController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7BE2753F04B00BBB92A /* FLEXKeyPathSearchController.m */; }; - 503FA9662753F04D00BBB92A /* FLEXImagePreviewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7C02753F04B00BBB92A /* FLEXImagePreviewViewController.m */; }; - 503FA9672753F04D00BBB92A /* FHSViewSnapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7C22753F04B00BBB92A /* FHSViewSnapshot.m */; }; - 503FA9682753F04D00BBB92A /* FHSView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7C32753F04B00BBB92A /* FHSView.h */; }; - 503FA9692753F04D00BBB92A /* FHSViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7C42753F04B00BBB92A /* FHSViewController.h */; }; - 503FA96A2753F04D00BBB92A /* FHSRangeSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7C52753F04B00BBB92A /* FHSRangeSlider.m */; }; - 503FA96B2753F04D00BBB92A /* FHSSnapshotView.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7C62753F04B00BBB92A /* FHSSnapshotView.h */; }; - 503FA96C2753F04D00BBB92A /* FHSView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7C72753F04B00BBB92A /* FHSView.m */; }; - 503FA96D2753F04D00BBB92A /* FHSViewSnapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7C82753F04B00BBB92A /* FHSViewSnapshot.h */; }; - 503FA96E2753F04D00BBB92A /* FHSViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7C92753F04B00BBB92A /* FHSViewController.m */; }; - 503FA96F2753F04D00BBB92A /* SceneKit+Snapshot.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7CB2753F04B00BBB92A /* SceneKit+Snapshot.m */; }; - 503FA9702753F04D00BBB92A /* FHSSnapshotNodes.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7CC2753F04B00BBB92A /* FHSSnapshotNodes.m */; }; - 503FA9712753F04D00BBB92A /* SceneKit+Snapshot.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7CD2753F04B00BBB92A /* SceneKit+Snapshot.h */; }; - 503FA9722753F04D00BBB92A /* FHSSnapshotNodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7CE2753F04B00BBB92A /* FHSSnapshotNodes.h */; }; - 503FA9732753F04D00BBB92A /* FHSSnapshotView.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7CF2753F04B00BBB92A /* FHSSnapshotView.m */; }; - 503FA9742753F04D00BBB92A /* FHSRangeSlider.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7D02753F04B00BBB92A /* FHSRangeSlider.h */; }; - 503FA9752753F04D00BBB92A /* FLEXHierarchyViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7D12753F04B00BBB92A /* FLEXHierarchyViewController.h */; }; - 503FA9762753F04D00BBB92A /* FLEXHierarchyTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7D32753F04B00BBB92A /* FLEXHierarchyTableViewCell.m */; }; - 503FA9772753F04D00BBB92A /* FLEXHierarchyTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7D42753F04B00BBB92A /* FLEXHierarchyTableViewController.h */; }; - 503FA9782753F04D00BBB92A /* FLEXHierarchyTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7D52753F04B00BBB92A /* FLEXHierarchyTableViewCell.h */; }; - 503FA9792753F04D00BBB92A /* FLEXHierarchyTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7D62753F04B00BBB92A /* FLEXHierarchyTableViewController.m */; }; - 503FA97A2753F04D00BBB92A /* FLEXImagePreviewViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7D72753F04B00BBB92A /* FLEXImagePreviewViewController.h */; }; - 503FA97B2753F04D00BBB92A /* FLEXHierarchyViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7D82753F04B00BBB92A /* FLEXHierarchyViewController.m */; }; - 503FA97C2753F04D00BBB92A /* FLEXUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7DA2753F04B00BBB92A /* FLEXUtility.m */; }; - 503FA97D2753F04D00BBB92A /* FLEXMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7DB2753F04B00BBB92A /* FLEXMacros.h */; }; - 503FA97E2753F04D00BBB92A /* FLEXHeapEnumerator.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7DC2753F04B00BBB92A /* FLEXHeapEnumerator.m */; }; - 503FA97F2753F04D00BBB92A /* FLEXResources.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7DD2753F04B00BBB92A /* FLEXResources.h */; }; - 503FA9802753F04D00BBB92A /* flex_fishhook.c in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7E02753F04B00BBB92A /* flex_fishhook.c */; }; - 503FA9812753F04D00BBB92A /* FLEXRuntimeUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7E12753F04B00BBB92A /* FLEXRuntimeUtility.m */; }; - 503FA9822753F04D00BBB92A /* FLEXRuntimeUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7E22753F04B00BBB92A /* FLEXRuntimeUtility.h */; }; - 503FA9832753F04D00BBB92A /* flex_fishhook.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7E32753F04B00BBB92A /* flex_fishhook.h */; }; - 503FA9842753F04D00BBB92A /* FLEXRuntimeSafety.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7E52753F04B00BBB92A /* FLEXRuntimeSafety.h */; }; - 503FA9852753F04D00BBB92A /* FLEXTypeEncodingParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7E62753F04B00BBB92A /* FLEXTypeEncodingParser.h */; }; - 503FA9862753F04D00BBB92A /* FLEXRuntimeConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7E72753F04B00BBB92A /* FLEXRuntimeConstants.h */; }; - 503FA9872753F04D00BBB92A /* FLEXRuntimeSafety.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7E82753F04B00BBB92A /* FLEXRuntimeSafety.m */; }; - 503FA9882753F04D00BBB92A /* FLEXRuntimeConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7E92753F04B00BBB92A /* FLEXRuntimeConstants.m */; }; - 503FA9892753F04D00BBB92A /* FLEXTypeEncodingParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7EA2753F04B00BBB92A /* FLEXTypeEncodingParser.m */; }; - 503FA98A2753F04D00BBB92A /* FLEXObjcInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7EB2753F04B00BBB92A /* FLEXObjcInternal.h */; }; - 503FA98B2753F04D00BBB92A /* FLEXObjcInternal.mm in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7EC2753F04B00BBB92A /* FLEXObjcInternal.mm */; }; - 503FA98C2753F04D00BBB92A /* FLEXMirror.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7EE2753F04B00BBB92A /* FLEXMirror.m */; }; - 503FA98D2753F04D00BBB92A /* FLEXPropertyAttributes.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7EF2753F04B00BBB92A /* FLEXPropertyAttributes.m */; }; - 503FA98E2753F04D00BBB92A /* FLEXBlockDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7F02753F04B00BBB92A /* FLEXBlockDescription.h */; }; - 503FA98F2753F04D00BBB92A /* FLEXProtocolBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7F12753F04B00BBB92A /* FLEXProtocolBuilder.h */; }; - 503FA9902753F04D00BBB92A /* FLEXProperty.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7F22753F04B00BBB92A /* FLEXProperty.m */; }; - 503FA9912753F04D00BBB92A /* FLEXClassBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7F32753F04B00BBB92A /* FLEXClassBuilder.h */; }; - 503FA9922753F04D00BBB92A /* FLEXMethodBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7F42753F04B00BBB92A /* FLEXMethodBase.h */; }; - 503FA9932753F04D00BBB92A /* FLEXMethod.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7F52753F04B00BBB92A /* FLEXMethod.m */; }; - 503FA9942753F04D00BBB92A /* FLEXIvar.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7F62753F04B00BBB92A /* FLEXIvar.m */; }; - 503FA9952753F04D00BBB92A /* FLEXProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7F72753F04B00BBB92A /* FLEXProtocol.h */; }; - 503FA9962753F04D00BBB92A /* FLEXProtocolBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7F82753F04B00BBB92A /* FLEXProtocolBuilder.m */; }; - 503FA9972753F04D00BBB92A /* FLEXBlockDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7F92753F04B00BBB92A /* FLEXBlockDescription.m */; }; - 503FA9982753F04D00BBB92A /* FLEXPropertyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7FA2753F04B00BBB92A /* FLEXPropertyAttributes.h */; }; - 503FA9992753F04D00BBB92A /* FLEXMirror.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7FB2753F04B00BBB92A /* FLEXMirror.h */; }; - 503FA99A2753F04D00BBB92A /* FLEXClassBuilder.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7FC2753F04B00BBB92A /* FLEXClassBuilder.m */; }; - 503FA99B2753F04D00BBB92A /* FLEXProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7FD2753F04B00BBB92A /* FLEXProperty.h */; }; - 503FA99C2753F04D00BBB92A /* FLEXProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA7FE2753F04B00BBB92A /* FLEXProtocol.m */; }; - 503FA99D2753F04D00BBB92A /* FLEXIvar.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA7FF2753F04B00BBB92A /* FLEXIvar.h */; }; - 503FA99E2753F04D00BBB92A /* FLEXMethod.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8002753F04B00BBB92A /* FLEXMethod.h */; }; - 503FA99F2753F04D00BBB92A /* FLEXMethodBase.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8012753F04B00BBB92A /* FLEXMethodBase.m */; }; - 503FA9A02753F04D00BBB92A /* FLEXAlert.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8022753F04B00BBB92A /* FLEXAlert.m */; }; - 503FA9A12753F04D00BBB92A /* FLEXColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8032753F04B00BBB92A /* FLEXColor.h */; }; - 503FA9A22753F04D00BBB92A /* FLEXHeapEnumerator.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8042753F04B00BBB92A /* FLEXHeapEnumerator.h */; }; - 503FA9A32753F04D00BBB92A /* FLEXUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8052753F04B00BBB92A /* FLEXUtility.h */; }; - 503FA9A42753F04D00BBB92A /* FLEXResources.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8062753F04B00BBB92A /* FLEXResources.m */; }; - 503FA9A52753F04D00BBB92A /* FLEXColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8072753F04B00BBB92A /* FLEXColor.m */; }; - 503FA9A62753F04D00BBB92A /* UIGestureRecognizer+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8092753F04B00BBB92A /* UIGestureRecognizer+Blocks.m */; }; - 503FA9A72753F04D00BBB92A /* FLEXRuntime+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA80A2753F04B00BBB92A /* FLEXRuntime+Compare.m */; }; - 503FA9A82753F04D00BBB92A /* NSArray+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA80B2753F04B00BBB92A /* NSArray+FLEX.m */; }; - 503FA9A92753F04D00BBB92A /* NSObject+FLEX_Reflection.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA80C2753F04B00BBB92A /* NSObject+FLEX_Reflection.m */; }; - 503FA9AA2753F04D00BBB92A /* UIBarButtonItem+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA80D2753F04B00BBB92A /* UIBarButtonItem+FLEX.h */; }; - 503FA9AB2753F04D00BBB92A /* FLEXRuntime+UIKitHelpers.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA80E2753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.m */; }; - 503FA9AC2753F04D00BBB92A /* NSTimer+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA80F2753F04B00BBB92A /* NSTimer+FLEX.m */; }; - 503FA9AD2753F04D00BBB92A /* UIMenu+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8102753F04B00BBB92A /* UIMenu+FLEX.m */; }; - 503FA9AE2753F04D00BBB92A /* CALayer+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8112753F04B00BBB92A /* CALayer+FLEX.h */; }; - 503FA9AF2753F04D00BBB92A /* UIPasteboard+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8122753F04B00BBB92A /* UIPasteboard+FLEX.m */; }; - 503FA9B02753F04D00BBB92A /* UIFont+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8132753F04B00BBB92A /* UIFont+FLEX.h */; }; - 503FA9B12753F04D00BBB92A /* NSUserDefaults+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8142753F04B00BBB92A /* NSUserDefaults+FLEX.m */; }; - 503FA9B22753F04D00BBB92A /* UITextField+Range.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8152753F04B00BBB92A /* UITextField+Range.m */; }; - 503FA9B32753F04D00BBB92A /* NSObject+FLEX_Reflection.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8162753F04B00BBB92A /* NSObject+FLEX_Reflection.h */; }; - 503FA9B42753F04D00BBB92A /* NSArray+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8172753F04B00BBB92A /* NSArray+FLEX.h */; }; - 503FA9B52753F04D00BBB92A /* FLEXRuntime+Compare.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8182753F04B00BBB92A /* FLEXRuntime+Compare.h */; }; - 503FA9B62753F04D00BBB92A /* UIGestureRecognizer+Blocks.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8192753F04B00BBB92A /* UIGestureRecognizer+Blocks.h */; }; - 503FA9B72753F04D00BBB92A /* UIView+FLEX_Layout.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA81B2753F04B00BBB92A /* UIView+FLEX_Layout.m */; }; - 503FA9B82753F04D00BBB92A /* NSString+ObjcRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA81C2753F04B00BBB92A /* NSString+ObjcRuntime.h */; }; - 503FA9B92753F04D00BBB92A /* NSMapTable+FLEX_Subscripting.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA81D2753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.h */; }; - 503FA9BA2753F04D00BBB92A /* NSString+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA81E2753F04B00BBB92A /* NSString+FLEX.h */; }; - 503FA9BB2753F04D00BBB92A /* Cocoa+FLEXShortcuts.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA81F2753F04B00BBB92A /* Cocoa+FLEXShortcuts.h */; }; - 503FA9BC2753F04D00BBB92A /* NSDictionary+ObjcRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8202753F04B00BBB92A /* NSDictionary+ObjcRuntime.h */; }; - 503FA9BD2753F04D00BBB92A /* UIView+FLEX_Layout.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8212753F04B00BBB92A /* UIView+FLEX_Layout.h */; }; - 503FA9BE2753F04D00BBB92A /* NSMapTable+FLEX_Subscripting.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8222753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.m */; }; - 503FA9BF2753F04D00BBB92A /* NSString+ObjcRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8232753F04B00BBB92A /* NSString+ObjcRuntime.m */; }; - 503FA9C02753F04D00BBB92A /* Cocoa+FLEXShortcuts.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8242753F04B00BBB92A /* Cocoa+FLEXShortcuts.m */; }; - 503FA9C12753F04D00BBB92A /* NSString+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8252753F04B00BBB92A /* NSString+FLEX.m */; }; - 503FA9C22753F04D00BBB92A /* NSDictionary+ObjcRuntime.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8262753F04B00BBB92A /* NSDictionary+ObjcRuntime.m */; }; - 503FA9C32753F04D00BBB92A /* NSTimer+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8272753F04B00BBB92A /* NSTimer+FLEX.h */; }; - 503FA9C42753F04D00BBB92A /* FLEXRuntime+UIKitHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8282753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.h */; }; - 503FA9C52753F04D00BBB92A /* UIBarButtonItem+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8292753F04B00BBB92A /* UIBarButtonItem+FLEX.m */; }; - 503FA9C62753F04D00BBB92A /* UIPasteboard+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA82A2753F04B00BBB92A /* UIPasteboard+FLEX.h */; }; - 503FA9C72753F04D00BBB92A /* UIMenu+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA82B2753F04B00BBB92A /* UIMenu+FLEX.h */; }; - 503FA9C82753F04D00BBB92A /* CALayer+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA82C2753F04B00BBB92A /* CALayer+FLEX.m */; }; - 503FA9C92753F04D00BBB92A /* UITextField+Range.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA82D2753F04B00BBB92A /* UITextField+Range.h */; }; - 503FA9CA2753F04D00BBB92A /* NSUserDefaults+FLEX.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA82E2753F04B00BBB92A /* NSUserDefaults+FLEX.h */; }; - 503FA9CB2753F04D00BBB92A /* UIFont+FLEX.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA82F2753F04B00BBB92A /* UIFont+FLEX.m */; }; - 503FA9CC2753F04D00BBB92A /* FLEXAlert.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8302753F04B00BBB92A /* FLEXAlert.h */; }; - 503FA9CD2753F04D00BBB92A /* FLEXKeyboardHelpViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8322753F04B00BBB92A /* FLEXKeyboardHelpViewController.h */; }; - 503FA9CE2753F04D00BBB92A /* FLEXKeyboardShortcutManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8332753F04B00BBB92A /* FLEXKeyboardShortcutManager.m */; }; - 503FA9CF2753F04D00BBB92A /* FLEXKeyboardHelpViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 503FA8342753F04B00BBB92A /* FLEXKeyboardHelpViewController.m */; }; - 503FA9D02753F04D00BBB92A /* FLEXKeyboardShortcutManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 503FA8352753F04B00BBB92A /* FLEXKeyboardShortcutManager.h */; }; - 504C1C5B288F32050056F5EC /* Preferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 504C1C5A288F32050056F5EC /* Preferences.framework */; }; 505C0EBC2801ECAB0028D1C9 /* BHDownloadInlineButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 505C0EBB2801ECAB0028D1C9 /* BHDownloadInlineButton.h */; }; 505C0EBE2801ED020028D1C9 /* BHDownloadInlineButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 505C0EBD2801ED020028D1C9 /* BHDownloadInlineButton.m */; }; 5061F3C02806133400F3D5D3 /* CustomTabBarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5061F3BF2806133400F3D5D3 /* CustomTabBarViewController.swift */; }; @@ -488,6 +51,9 @@ 50FAE05B288545DC00CDCEB2 /* CepheiUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 50FAE056288545DB00CDCEB2 /* CepheiUI.framework */; }; 50FAE060288545F600CDCEB2 /* SettingsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50FAE05E288545F600CDCEB2 /* SettingsViewController.h */; }; 50FAE061288545F600CDCEB2 /* SettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50FAE05F288545F600CDCEB2 /* SettingsViewController.m */; }; + 91086148293001530011609E /* FLEX in Frameworks */ = {isa = PBXBuildFile; productRef = 91086147293001530011609E /* FLEX */; }; + 9108614B293005750011609E /* JGProgressHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 9108614A293005750011609E /* JGProgressHUD */; }; + 916F1E1B2912F16D00865DD2 /* Preferences.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 916F1E1A2912F16D00865DD2 /* Preferences.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -512,31 +78,6 @@ 5020A8D524E759190080F292 /* TWHeaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TWHeaders.h; sourceTree = ""; }; 5020A8D624E759190080F292 /* BHTManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHTManager.h; sourceTree = ""; }; 5020A8D724E759190080F292 /* BHTManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BHTManager.m; sourceTree = ""; }; - 5020AA2924E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDIndeterminateIndicatorView.m; sourceTree = ""; }; - 5020AA2A24E759390080F292 /* JGProgressHUDErrorIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDErrorIndicatorView.m; sourceTree = ""; }; - 5020AA2B24E759390080F292 /* JGProgressHUDAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDAnimation.m; sourceTree = ""; }; - 5020AA2D24E759390080F292 /* JGProgressHUDSuccessIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDSuccessIndicatorView.h; sourceTree = ""; }; - 5020AA2E24E759390080F292 /* JGProgressHUDImageIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDImageIndicatorView.h; sourceTree = ""; }; - 5020AA2F24E759390080F292 /* JGProgressHUDIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDIndicatorView.h; sourceTree = ""; }; - 5020AA3024E759390080F292 /* JGProgressHUD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUD.h; sourceTree = ""; }; - 5020AA3124E759390080F292 /* JGProgressHUDShadow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDShadow.h; sourceTree = ""; }; - 5020AA3224E759390080F292 /* JGProgressHUDPieIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDPieIndicatorView.h; sourceTree = ""; }; - 5020AA3324E759390080F292 /* JGProgressHUDRingIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDRingIndicatorView.h; sourceTree = ""; }; - 5020AA3424E759390080F292 /* JGProgressHUDFadeAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDFadeAnimation.h; sourceTree = ""; }; - 5020AA3524E759390080F292 /* JGProgressHUD-Defines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JGProgressHUD-Defines.h"; sourceTree = ""; }; - 5020AA3624E759390080F292 /* JGProgressHUDAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDAnimation.h; sourceTree = ""; }; - 5020AA3724E759390080F292 /* JGProgressHUDErrorIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDErrorIndicatorView.h; sourceTree = ""; }; - 5020AA3824E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDIndeterminateIndicatorView.h; sourceTree = ""; }; - 5020AA3924E759390080F292 /* JGProgressHUDFadeZoomAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JGProgressHUDFadeZoomAnimation.h; sourceTree = ""; }; - 5020AA3A24E759390080F292 /* JGProgressHUDFadeZoomAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDFadeZoomAnimation.m; sourceTree = ""; }; - 5020AA3B24E759390080F292 /* JGProgressHUDImageIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDImageIndicatorView.m; sourceTree = ""; }; - 5020AA3C24E759390080F292 /* JGProgressHUDSuccessIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDSuccessIndicatorView.m; sourceTree = ""; }; - 5020AA3D24E759390080F292 /* JGProgressHUDIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDIndicatorView.m; sourceTree = ""; }; - 5020AA3E24E759390080F292 /* JGProgressHUD.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUD.m; sourceTree = ""; }; - 5020AA3F24E759390080F292 /* JGProgressHUDFadeAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDFadeAnimation.m; sourceTree = ""; }; - 5020AA4024E759390080F292 /* JGProgressHUDRingIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDRingIndicatorView.m; sourceTree = ""; }; - 5020AA4124E759390080F292 /* JGProgressHUDPieIndicatorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDPieIndicatorView.m; sourceTree = ""; }; - 5020AA4224E759390080F292 /* JGProgressHUDShadow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JGProgressHUDShadow.m; sourceTree = ""; }; 5020AA5E24E759590080F292 /* Colours.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Colours.h; sourceTree = ""; }; 5020AA6024E759590080F292 /* Colours.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Colours.m; sourceTree = ""; }; 5020AA6824E759700080F292 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; @@ -550,423 +91,6 @@ 5020AA7824E759960080F292 /* SafariServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SafariServices.framework; path = System/Library/Frameworks/SafariServices.framework; sourceTree = SDKROOT; }; 5020AA7A24E7599B0080F292 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; }; 5020AA7C24E759A20080F292 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; - 503FA66E2753F04A00BBB92A /* FLEX-Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Runtime.h"; sourceTree = ""; }; - 503FA6702753F04A00BBB92A /* FLEXTableViewSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewSection.h; sourceTree = ""; }; - 503FA6712753F04A00BBB92A /* FLEXSingleRowSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSingleRowSection.m; sourceTree = ""; }; - 503FA6722753F04A00BBB92A /* FLEXTableViewSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableViewSection.m; sourceTree = ""; }; - 503FA6742753F04A00BBB92A /* FLEXTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableViewController.m; sourceTree = ""; }; - 503FA6752753F04A00BBB92A /* FLEXNavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNavigationController.m; sourceTree = ""; }; - 503FA6762753F04A00BBB92A /* FLEXFilteringTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFilteringTableViewController.h; sourceTree = ""; }; - 503FA6772753F04A00BBB92A /* FLEXNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNavigationController.h; sourceTree = ""; }; - 503FA6782753F04A00BBB92A /* FLEXTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewController.h; sourceTree = ""; }; - 503FA6792753F04A00BBB92A /* FLEXFilteringTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFilteringTableViewController.m; sourceTree = ""; }; - 503FA67C2753F04A00BBB92A /* FLEXCodeFontCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCodeFontCell.h; sourceTree = ""; }; - 503FA67D2753F04A00BBB92A /* FLEXKeyValueTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyValueTableViewCell.m; sourceTree = ""; }; - 503FA67E2753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSubtitleTableViewCell.h; sourceTree = ""; }; - 503FA67F2753F04A00BBB92A /* FLEXTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewCell.h; sourceTree = ""; }; - 503FA6802753F04A00BBB92A /* FLEXMultilineTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultilineTableViewCell.h; sourceTree = ""; }; - 503FA6812753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyValueTableViewCell.h; sourceTree = ""; }; - 503FA6822753F04A00BBB92A /* FLEXCodeFontCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCodeFontCell.m; sourceTree = ""; }; - 503FA6832753F04A00BBB92A /* FLEXSubtitleTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSubtitleTableViewCell.m; sourceTree = ""; }; - 503FA6842753F04A00BBB92A /* FLEXMultilineTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultilineTableViewCell.m; sourceTree = ""; }; - 503FA6852753F04A00BBB92A /* FLEXTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableViewCell.m; sourceTree = ""; }; - 503FA6862753F04A00BBB92A /* FLEXTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableView.h; sourceTree = ""; }; - 503FA6882753F04A00BBB92A /* FLEXCarouselCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCarouselCell.h; sourceTree = ""; }; - 503FA6892753F04A00BBB92A /* FLEXScopeCarousel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXScopeCarousel.m; sourceTree = ""; }; - 503FA68A2753F04A00BBB92A /* FLEXScopeCarousel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXScopeCarousel.h; sourceTree = ""; }; - 503FA68B2753F04A00BBB92A /* FLEXCarouselCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCarouselCell.m; sourceTree = ""; }; - 503FA68C2753F04A00BBB92A /* FLEXTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableView.m; sourceTree = ""; }; - 503FA68D2753F04A00BBB92A /* FLEXSingleRowSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSingleRowSection.h; sourceTree = ""; }; - 503FA68E2753F04A00BBB92A /* FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEX.h; sourceTree = ""; }; - 503FA6902753F04A00BBB92A /* FLEXObjectExplorerFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectExplorerFactory.m; sourceTree = ""; }; - 503FA6922753F04A00BBB92A /* FLEXColorPreviewSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXColorPreviewSection.h; sourceTree = ""; }; - 503FA6932753F04A00BBB92A /* FLEXCollectionContentSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCollectionContentSection.h; sourceTree = ""; }; - 503FA6942753F04A00BBB92A /* FLEXDefaultsContentSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDefaultsContentSection.m; sourceTree = ""; }; - 503FA6952753F04A00BBB92A /* FLEXMutableListSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMutableListSection.m; sourceTree = ""; }; - 503FA6962753F04A00BBB92A /* FLEXMetadataSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMetadataSection.h; sourceTree = ""; }; - 503FA6972753F04A00BBB92A /* FLEXCollectionContentSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCollectionContentSection.m; sourceTree = ""; }; - 503FA6982753F04A00BBB92A /* FLEXColorPreviewSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXColorPreviewSection.m; sourceTree = ""; }; - 503FA6992753F04A00BBB92A /* FLEXDefaultsContentSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDefaultsContentSection.h; sourceTree = ""; }; - 503FA69B2753F04A00BBB92A /* FLEXBundleShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBundleShortcuts.h; sourceTree = ""; }; - 503FA69C2753F04A00BBB92A /* FLEXShortcutsSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXShortcutsSection.m; sourceTree = ""; }; - 503FA69D2753F04A00BBB92A /* FLEXViewShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXViewShortcuts.h; sourceTree = ""; }; - 503FA69E2753F04A00BBB92A /* FLEXNSStringShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNSStringShortcuts.h; sourceTree = ""; }; - 503FA69F2753F04A00BBB92A /* FLEXBlockShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXBlockShortcuts.m; sourceTree = ""; }; - 503FA6A02753F04A00BBB92A /* FLEXClassShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXClassShortcuts.m; sourceTree = ""; }; - 503FA6A12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXShortcutsFactory+Defaults.h"; sourceTree = ""; }; - 503FA6A22753F04A00BBB92A /* FLEXUIAppShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXUIAppShortcuts.h; sourceTree = ""; }; - 503FA6A32753F04A00BBB92A /* FLEXLayerShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLayerShortcuts.h; sourceTree = ""; }; - 503FA6A42753F04A00BBB92A /* FLEXImageShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXImageShortcuts.m; sourceTree = ""; }; - 503FA6A52753F04A00BBB92A /* FLEXNSDataShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNSDataShortcuts.h; sourceTree = ""; }; - 503FA6A62753F04A00BBB92A /* FLEXViewControllerShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXViewControllerShortcuts.h; sourceTree = ""; }; - 503FA6A72753F04A00BBB92A /* FLEXShortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXShortcut.h; sourceTree = ""; }; - 503FA6A82753F04A00BBB92A /* FLEXViewShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewShortcuts.m; sourceTree = ""; }; - 503FA6A92753F04A00BBB92A /* FLEXShortcutsSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXShortcutsSection.h; sourceTree = ""; }; - 503FA6AA2753F04A00BBB92A /* FLEXBundleShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXBundleShortcuts.m; sourceTree = ""; }; - 503FA6AB2753F04A00BBB92A /* FLEXClassShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXClassShortcuts.h; sourceTree = ""; }; - 503FA6AC2753F04A00BBB92A /* FLEXBlockShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBlockShortcuts.h; sourceTree = ""; }; - 503FA6AD2753F04A00BBB92A /* FLEXNSStringShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNSStringShortcuts.m; sourceTree = ""; }; - 503FA6AE2753F04A00BBB92A /* FLEXImageShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXImageShortcuts.h; sourceTree = ""; }; - 503FA6AF2753F04A00BBB92A /* FLEXLayerShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXLayerShortcuts.m; sourceTree = ""; }; - 503FA6B02753F04A00BBB92A /* FLEXUIAppShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXUIAppShortcuts.m; sourceTree = ""; }; - 503FA6B12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLEXShortcutsFactory+Defaults.m"; sourceTree = ""; }; - 503FA6B22753F04A00BBB92A /* FLEXShortcut.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXShortcut.m; sourceTree = ""; }; - 503FA6B32753F04A00BBB92A /* FLEXViewControllerShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewControllerShortcuts.m; sourceTree = ""; }; - 503FA6B42753F04A00BBB92A /* FLEXNSDataShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNSDataShortcuts.m; sourceTree = ""; }; - 503FA6B52753F04A00BBB92A /* FLEXMutableListSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMutableListSection.h; sourceTree = ""; }; - 503FA6B62753F04A00BBB92A /* FLEXObjectInfoSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectInfoSection.h; sourceTree = ""; }; - 503FA6B72753F04A00BBB92A /* FLEXMetadataSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMetadataSection.m; sourceTree = ""; }; - 503FA6B82753F04A00BBB92A /* FLEXObjectExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerViewController.h; sourceTree = ""; }; - 503FA6B92753F04A00BBB92A /* FLEXObjectExplorer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorer.h; sourceTree = ""; }; - 503FA6BA2753F04A00BBB92A /* FLEXObjectExplorerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerFactory.h; sourceTree = ""; }; - 503FA6BB2753F04A00BBB92A /* FLEXObjectExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectExplorerViewController.m; sourceTree = ""; }; - 503FA6BC2753F04A00BBB92A /* FLEXObjectExplorer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectExplorer.m; sourceTree = ""; }; - 503FA6BE2753F04A00BBB92A /* FLEXNetworkCurlLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkCurlLogger.h; sourceTree = ""; }; - 503FA6BF2753F04A00BBB92A /* FLEXNetworkTransaction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkTransaction.m; sourceTree = ""; }; - 503FA6C02753F04A00BBB92A /* FLEXNetworkSettingsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkSettingsController.m; sourceTree = ""; }; - 503FA6C12753F04A00BBB92A /* FLEXNetworkRecorder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkRecorder.m; sourceTree = ""; }; - 503FA6C22753F04A00BBB92A /* FLEXHTTPTransactionDetailController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHTTPTransactionDetailController.h; sourceTree = ""; }; - 503FA6C32753F04A00BBB92A /* FLEXNetworkMITMViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkMITMViewController.m; sourceTree = ""; }; - 503FA6C42753F04A00BBB92A /* FLEXMITMDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMITMDataSource.h; sourceTree = ""; }; - 503FA6C52753F04A00BBB92A /* FLEXNetworkTransactionCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkTransactionCell.m; sourceTree = ""; }; - 503FA6C62753F04A00BBB92A /* FLEXNetworkTransaction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkTransaction.h; sourceTree = ""; }; - 503FA6C72753F04A00BBB92A /* FLEXNetworkCurlLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkCurlLogger.m; sourceTree = ""; }; - 503FA6C82753F04A00BBB92A /* FLEXNetworkMITMViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkMITMViewController.h; sourceTree = ""; }; - 503FA6C92753F04A00BBB92A /* FLEXHTTPTransactionDetailController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHTTPTransactionDetailController.m; sourceTree = ""; }; - 503FA6CA2753F04A00BBB92A /* FLEXNetworkRecorder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkRecorder.h; sourceTree = ""; }; - 503FA6CB2753F04A00BBB92A /* FLEXNetworkSettingsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkSettingsController.h; sourceTree = ""; }; - 503FA6CC2753F04A00BBB92A /* FLEXMITMDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMITMDataSource.m; sourceTree = ""; }; - 503FA6CE2753F04A00BBB92A /* FLEXNetworkObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkObserver.h; sourceTree = ""; }; - 503FA6CF2753F04A00BBB92A /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 503FA6D02753F04A00BBB92A /* FLEXNetworkObserver.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXNetworkObserver.m; sourceTree = ""; }; - 503FA6D12753F04A00BBB92A /* FLEXNetworkTransactionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNetworkTransactionCell.h; sourceTree = ""; }; - 503FA6D32753F04A00BBB92A /* LICENSE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = ""; }; - 503FA6D42753F04A00BBB92A /* OSCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSCache.m; sourceTree = ""; }; - 503FA6D52753F04A00BBB92A /* OSCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSCache.h; sourceTree = ""; }; - 503FA6D72753F04A00BBB92A /* FLEXExplorerToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerToolbarItem.h; sourceTree = ""; }; - 503FA6D82753F04A00BBB92A /* FLEXExplorerToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerToolbar.h; sourceTree = ""; }; - 503FA6D92753F04A00BBB92A /* FLEXExplorerToolbarItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXExplorerToolbarItem.m; sourceTree = ""; }; - 503FA6DA2753F04A00BBB92A /* FLEXExplorerToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXExplorerToolbar.m; sourceTree = ""; }; - 503FA6DB2753F04A00BBB92A /* FLEX-Categories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Categories.h"; sourceTree = ""; }; - 503FA6DC2753F04A00BBB92A /* FLEX-Core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Core.h"; sourceTree = ""; }; - 503FA6DD2753F04A00BBB92A /* FLEX-ObjectExploring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-ObjectExploring.h"; sourceTree = ""; }; - 503FA6DF2753F04A00BBB92A /* FLEXManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXManager.h; sourceTree = ""; }; - 503FA6E02753F04A00BBB92A /* FLEXManager+Extensibility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLEXManager+Extensibility.m"; sourceTree = ""; }; - 503FA6E12753F04A00BBB92A /* FLEXManager+Networking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Networking.h"; sourceTree = ""; }; - 503FA6E22753F04A00BBB92A /* FLEXManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXManager.m; sourceTree = ""; }; - 503FA6E42753F04A00BBB92A /* FLEXManager+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Private.h"; sourceTree = ""; }; - 503FA6E52753F04A00BBB92A /* FLEXManager+Networking.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLEXManager+Networking.m"; sourceTree = ""; }; - 503FA6E62753F04A00BBB92A /* FLEXManager+Extensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Extensibility.h"; sourceTree = ""; }; - 503FA6E82753F04A00BBB92A /* FLEXDefaultEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDefaultEditorViewController.m; sourceTree = ""; }; - 503FA6E92753F04A00BBB92A /* FLEXVariableEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXVariableEditorViewController.h; sourceTree = ""; }; - 503FA6EA2753F04A00BBB92A /* FLEXFieldEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFieldEditorViewController.h; sourceTree = ""; }; - 503FA6EB2753F04A00BBB92A /* FLEXFieldEditorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFieldEditorView.h; sourceTree = ""; }; - 503FA6EC2753F04A00BBB92A /* FLEXMethodCallingViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMethodCallingViewController.m; sourceTree = ""; }; - 503FA6ED2753F04A00BBB92A /* FLEXArgumentInputViewFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputViewFactory.h; sourceTree = ""; }; - 503FA6EE2753F04A00BBB92A /* FLEXFieldEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFieldEditorViewController.m; sourceTree = ""; }; - 503FA6EF2753F04A00BBB92A /* FLEXVariableEditorViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXVariableEditorViewController.m; sourceTree = ""; }; - 503FA6F02753F04A00BBB92A /* FLEXDefaultEditorViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDefaultEditorViewController.h; sourceTree = ""; }; - 503FA6F22753F04A00BBB92A /* FLEXArgumentInputStringView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputStringView.m; sourceTree = ""; }; - 503FA6F32753F04A00BBB92A /* FLEXArgumentInputColorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputColorView.m; sourceTree = ""; }; - 503FA6F42753F04A00BBB92A /* FLEXArgumentInputView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputView.m; sourceTree = ""; }; - 503FA6F52753F04A00BBB92A /* FLEXArgumentInputFontView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputFontView.h; sourceTree = ""; }; - 503FA6F62753F04A00BBB92A /* FLEXArgumentInputTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputTextView.h; sourceTree = ""; }; - 503FA6F72753F04A00BBB92A /* FLEXArgumentInputSwitchView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputSwitchView.m; sourceTree = ""; }; - 503FA6F82753F04A00BBB92A /* FLEXArgumentInputStructView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputStructView.m; sourceTree = ""; }; - 503FA6F92753F04A00BBB92A /* FLEXArgumentInputDateView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputDateView.m; sourceTree = ""; }; - 503FA6FA2753F04A00BBB92A /* FLEXArgumentInputNumberView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputNumberView.h; sourceTree = ""; }; - 503FA6FB2753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputFontsPickerView.h; sourceTree = ""; }; - 503FA6FC2753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputNotSupportedView.h; sourceTree = ""; }; - 503FA6FD2753F04A00BBB92A /* FLEXArgumentInputObjectView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputObjectView.m; sourceTree = ""; }; - 503FA6FE2753F04A00BBB92A /* FLEXArgumentInputFontView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputFontView.m; sourceTree = ""; }; - 503FA6FF2753F04A00BBB92A /* FLEXArgumentInputView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputView.h; sourceTree = ""; }; - 503FA7002753F04A00BBB92A /* FLEXArgumentInputColorView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputColorView.h; sourceTree = ""; }; - 503FA7012753F04A00BBB92A /* FLEXArgumentInputStringView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputStringView.h; sourceTree = ""; }; - 503FA7022753F04A00BBB92A /* FLEXArgumentInputSwitchView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputSwitchView.h; sourceTree = ""; }; - 503FA7032753F04A00BBB92A /* FLEXArgumentInputTextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputTextView.m; sourceTree = ""; }; - 503FA7042753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputFontsPickerView.m; sourceTree = ""; }; - 503FA7052753F04A00BBB92A /* FLEXArgumentInputNumberView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputNumberView.m; sourceTree = ""; }; - 503FA7062753F04A00BBB92A /* FLEXArgumentInputDateView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputDateView.h; sourceTree = ""; }; - 503FA7072753F04A00BBB92A /* FLEXArgumentInputStructView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputStructView.h; sourceTree = ""; }; - 503FA7082753F04A00BBB92A /* FLEXArgumentInputObjectView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXArgumentInputObjectView.h; sourceTree = ""; }; - 503FA7092753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputNotSupportedView.m; sourceTree = ""; }; - 503FA70A2753F04A00BBB92A /* FLEXArgumentInputViewFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXArgumentInputViewFactory.m; sourceTree = ""; }; - 503FA70B2753F04A00BBB92A /* FLEXMethodCallingViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethodCallingViewController.h; sourceTree = ""; }; - 503FA70C2753F04A00BBB92A /* FLEXFieldEditorView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFieldEditorView.m; sourceTree = ""; }; - 503FA70E2753F04A00BBB92A /* FLEXRuntimeSafety.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeSafety.h; sourceTree = ""; }; - 503FA70F2753F04A00BBB92A /* FLEXExplorerToolbarItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerToolbarItem.h; sourceTree = ""; }; - 503FA7102753F04A00BBB92A /* FLEXManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXManager.h; sourceTree = ""; }; - 503FA7112753F04A00BBB92A /* FLEXBlockDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBlockDescription.h; sourceTree = ""; }; - 503FA7122753F04A00BBB92A /* FLEXMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMacros.h; sourceTree = ""; }; - 503FA7132753F04A00BBB92A /* FLEXProtocolBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProtocolBuilder.h; sourceTree = ""; }; - 503FA7142753F04A00BBB92A /* FLEXColorPreviewSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXColorPreviewSection.h; sourceTree = ""; }; - 503FA7152753F04A00BBB92A /* FLEXCollectionContentSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCollectionContentSection.h; sourceTree = ""; }; - 503FA7162753F04A00BBB92A /* FLEX-Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Runtime.h"; sourceTree = ""; }; - 503FA7172753F04A00BBB92A /* UIBarButtonItem+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+FLEX.h"; sourceTree = ""; }; - 503FA7182753F04A00BBB92A /* FLEXResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXResources.h; sourceTree = ""; }; - 503FA7192753F04A00BBB92A /* FLEXTypeEncodingParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTypeEncodingParser.h; sourceTree = ""; }; - 503FA71A2753F04A00BBB92A /* FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEX.h; sourceTree = ""; }; - 503FA71B2753F04A00BBB92A /* FLEXRuntimeConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeConstants.h; sourceTree = ""; }; - 503FA71C2753F04A00BBB92A /* FLEXClassBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXClassBuilder.h; sourceTree = ""; }; - 503FA71D2753F04A00BBB92A /* FLEXCodeFontCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCodeFontCell.h; sourceTree = ""; }; - 503FA71E2753F04A00BBB92A /* FLEXTableViewSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewSection.h; sourceTree = ""; }; - 503FA71F2753F04A00BBB92A /* FLEXFilteringTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFilteringTableViewController.h; sourceTree = ""; }; - 503FA7202753F04A00BBB92A /* CALayer+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+FLEX.h"; sourceTree = ""; }; - 503FA7212753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSubtitleTableViewCell.h; sourceTree = ""; }; - 503FA7222753F04A00BBB92A /* FLEXObjectExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerViewController.h; sourceTree = ""; }; - 503FA7232753F04A00BBB92A /* FLEXManager+Networking.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Networking.h"; sourceTree = ""; }; - 503FA7242753F04A00BBB92A /* FLEXMetadataSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMetadataSection.h; sourceTree = ""; }; - 503FA7252753F04A00BBB92A /* FLEX-Categories.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Categories.h"; sourceTree = ""; }; - 503FA7262753F04A00BBB92A /* UIFont+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+FLEX.h"; sourceTree = ""; }; - 503FA7272753F04A00BBB92A /* FLEXTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableView.h; sourceTree = ""; }; - 503FA7282753F04A00BBB92A /* FLEXMethodBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethodBase.h; sourceTree = ""; }; - 503FA7292753F04A00BBB92A /* FLEXObjectExplorer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorer.h; sourceTree = ""; }; - 503FA72A2753F04A00BBB92A /* FLEXShortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXShortcut.h; sourceTree = ""; }; - 503FA72B2753F04A00BBB92A /* FLEXTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewCell.h; sourceTree = ""; }; - 503FA72C2753F04A00BBB92A /* FLEX-Core.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-Core.h"; sourceTree = ""; }; - 503FA72D2753F04A00BBB92A /* FLEXMultilineTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultilineTableViewCell.h; sourceTree = ""; }; - 503FA72E2753F04A00BBB92A /* FLEXProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProtocol.h; sourceTree = ""; }; - 503FA72F2753F04A00BBB92A /* FLEXExplorerToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerToolbar.h; sourceTree = ""; }; - 503FA7302753F04A00BBB92A /* FLEXGlobalsEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsEntry.h; sourceTree = ""; }; - 503FA7312753F04A00BBB92A /* NSObject+FLEX_Reflection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+FLEX_Reflection.h"; sourceTree = ""; }; - 503FA7322753F04A00BBB92A /* FLEX-ObjectExploring.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEX-ObjectExploring.h"; sourceTree = ""; }; - 503FA7332753F04A00BBB92A /* NSArray+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+FLEX.h"; sourceTree = ""; }; - 503FA7342753F04A00BBB92A /* FLEXRuntime+Compare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXRuntime+Compare.h"; sourceTree = ""; }; - 503FA7352753F04A00BBB92A /* FLEXShortcutsSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXShortcutsSection.h; sourceTree = ""; }; - 503FA7362753F04A00BBB92A /* FLEXPropertyAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXPropertyAttributes.h; sourceTree = ""; }; - 503FA7372753F04A00BBB92A /* UIGestureRecognizer+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIGestureRecognizer+Blocks.h"; sourceTree = ""; }; - 503FA7382753F04A00BBB92A /* FLEXMirror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMirror.h; sourceTree = ""; }; - 503FA7392753F04A00BBB92A /* FLEXObjectExplorerFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectExplorerFactory.h; sourceTree = ""; }; - 503FA73A2753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyValueTableViewCell.h; sourceTree = ""; }; - 503FA73B2753F04A00BBB92A /* FLEXNavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXNavigationController.h; sourceTree = ""; }; - 503FA73C2753F04A00BBB92A /* NSTimer+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+FLEX.h"; sourceTree = ""; }; - 503FA73D2753F04A00BBB92A /* FLEXDefaultsContentSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDefaultsContentSection.h; sourceTree = ""; }; - 503FA73E2753F04A00BBB92A /* FLEXTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableViewController.h; sourceTree = ""; }; - 503FA73F2753F04A00BBB92A /* FLEXRuntime+UIKitHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXRuntime+UIKitHelpers.h"; sourceTree = ""; }; - 503FA7402753F04A00BBB92A /* FLEXProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProperty.h; sourceTree = ""; }; - 503FA7412753F04A00BBB92A /* FLEXMutableListSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMutableListSection.h; sourceTree = ""; }; - 503FA7422753F04A00BBB92A /* UIPasteboard+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIPasteboard+FLEX.h"; sourceTree = ""; }; - 503FA7432753F04A00BBB92A /* FLEXObjcInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjcInternal.h; sourceTree = ""; }; - 503FA7442753F04A00BBB92A /* FLEXManager+Extensibility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXManager+Extensibility.h"; sourceTree = ""; }; - 503FA7452753F04A00BBB92A /* UIMenu+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIMenu+FLEX.h"; sourceTree = ""; }; - 503FA7462753F04A00BBB92A /* FLEXObjectInfoSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectInfoSection.h; sourceTree = ""; }; - 503FA7472753F04A00BBB92A /* UITextField+Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+Range.h"; sourceTree = ""; }; - 503FA7482753F04A00BBB92A /* FLEXIvar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXIvar.h; sourceTree = ""; }; - 503FA7492753F04A00BBB92A /* NSUserDefaults+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+FLEX.h"; sourceTree = ""; }; - 503FA74A2753F04A00BBB92A /* FLEXSingleRowSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSingleRowSection.h; sourceTree = ""; }; - 503FA74B2753F04A00BBB92A /* FLEXAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXAlert.h; sourceTree = ""; }; - 503FA74C2753F04A00BBB92A /* FLEXMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethod.h; sourceTree = ""; }; - 503FA74F2753F04A00BBB92A /* FLEXTabList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTabList.h; sourceTree = ""; }; - 503FA7502753F04A00BBB92A /* FLEXTabsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTabsViewController.m; sourceTree = ""; }; - 503FA7512753F04A00BBB92A /* FLEXTabList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTabList.m; sourceTree = ""; }; - 503FA7522753F04A00BBB92A /* FLEXTabsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTabsViewController.h; sourceTree = ""; }; - 503FA7532753F04A00BBB92A /* FLEXExplorerViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXExplorerViewController.m; sourceTree = ""; }; - 503FA7542753F04A00BBB92A /* FLEXWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXWindow.m; sourceTree = ""; }; - 503FA7552753F04A00BBB92A /* FLEXViewControllersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXViewControllersViewController.h; sourceTree = ""; }; - 503FA7562753F04A00BBB92A /* FLEXWindowManagerController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXWindowManagerController.m; sourceTree = ""; }; - 503FA7582753F04A00BBB92A /* FLEXBookmarkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBookmarkManager.h; sourceTree = ""; }; - 503FA7592753F04A00BBB92A /* FLEXBookmarksViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBookmarksViewController.h; sourceTree = ""; }; - 503FA75A2753F04A00BBB92A /* FLEXBookmarkManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXBookmarkManager.m; sourceTree = ""; }; - 503FA75B2753F04A00BBB92A /* FLEXBookmarksViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXBookmarksViewController.m; sourceTree = ""; }; - 503FA75C2753F04A00BBB92A /* FLEXExplorerViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXExplorerViewController.h; sourceTree = ""; }; - 503FA75D2753F04A00BBB92A /* FLEXWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXWindow.h; sourceTree = ""; }; - 503FA75E2753F04A00BBB92A /* FLEXWindowManagerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXWindowManagerController.h; sourceTree = ""; }; - 503FA75F2753F04A00BBB92A /* FLEXViewControllersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXViewControllersViewController.m; sourceTree = ""; }; - 503FA7612753F04A00BBB92A /* RuntimeExplore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeExplore.h; sourceTree = ""; }; - 503FA7632753F04A00BBB92A /* FLEXGlobalsEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXGlobalsEntry.m; sourceTree = ""; }; - 503FA7642753F04A00BBB92A /* FLEXGlobalsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsViewController.h; sourceTree = ""; }; - 503FA7652753F04A00BBB92A /* FLEXGlobalsSection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXGlobalsSection.m; sourceTree = ""; }; - 503FA7662753F04A00BBB92A /* FLEXGlobalsEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsEntry.h; sourceTree = ""; }; - 503FA7672753F04A00BBB92A /* FLEXGlobalsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXGlobalsViewController.m; sourceTree = ""; }; - 503FA7682753F04A00BBB92A /* FLEXGlobalsSection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXGlobalsSection.h; sourceTree = ""; }; - 503FA7692753F04A00BBB92A /* FLEXObjectListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectListViewController.h; sourceTree = ""; }; - 503FA76A2753F04A00BBB92A /* FLEXLiveObjectsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXLiveObjectsController.m; sourceTree = ""; }; - 503FA76B2753F04A00BBB92A /* FLEXObjectRef.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectRef.m; sourceTree = ""; }; - 503FA76C2753F04A00BBB92A /* FLEXWebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXWebViewController.m; sourceTree = ""; }; - 503FA76D2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXAddressExplorerCoordinator.h; sourceTree = ""; }; - 503FA76E2753F04A00BBB92A /* FLEXCookiesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXCookiesViewController.h; sourceTree = ""; }; - 503FA76F2753F04A00BBB92A /* FLEXLiveObjectsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLiveObjectsController.h; sourceTree = ""; }; - 503FA7702753F04A00BBB92A /* FLEXObjectListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjectListViewController.m; sourceTree = ""; }; - 503FA7712753F04A00BBB92A /* RuntimeExplore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RuntimeExplore.m; sourceTree = ""; }; - 503FA7732753F04A00BBB92A /* FLEXKeychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeychain.h; sourceTree = ""; }; - 503FA7742753F04A00BBB92A /* FLEXKeychainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeychainViewController.m; sourceTree = ""; }; - 503FA7752753F04A00BBB92A /* FLEXKeychainQuery.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeychainQuery.h; sourceTree = ""; }; - 503FA7762753F04A00BBB92A /* SSKeychain_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = SSKeychain_LICENSE; sourceTree = ""; }; - 503FA7772753F04A00BBB92A /* FLEXKeychain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeychain.m; sourceTree = ""; }; - 503FA7782753F04A00BBB92A /* FLEXKeychainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeychainViewController.h; sourceTree = ""; }; - 503FA7792753F04A00BBB92A /* FLEXKeychainQuery.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeychainQuery.m; sourceTree = ""; }; - 503FA77A2753F04A00BBB92A /* FLEXObjectRef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjectRef.h; sourceTree = ""; }; - 503FA77C2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserSearchOperation.m; sourceTree = ""; }; - 503FA77D2753F04A00BBB92A /* FLEXFileBrowserController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXFileBrowserController.m; sourceTree = ""; }; - 503FA77E2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFileBrowserSearchOperation.h; sourceTree = ""; }; - 503FA77F2753F04A00BBB92A /* FLEXFileBrowserController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXFileBrowserController.h; sourceTree = ""; }; - 503FA7812753F04A00BBB92A /* FLEXASLLogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXASLLogController.h; sourceTree = ""; }; - 503FA7822753F04A00BBB92A /* FLEXLogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXLogController.h; sourceTree = ""; }; - 503FA7832753F04A00BBB92A /* FLEXSystemLogCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogCell.m; sourceTree = ""; }; - 503FA7842753F04A00BBB92A /* FLEXOSLogController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXOSLogController.h; sourceTree = ""; }; - 503FA7852753F04A00BBB92A /* FLEXSystemLogViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogViewController.m; sourceTree = ""; }; - 503FA7862753F04A00BBB92A /* FLEXSystemLogMessage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSystemLogMessage.m; sourceTree = ""; }; - 503FA7872753F04A00BBB92A /* FLEXASLLogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXASLLogController.m; sourceTree = ""; }; - 503FA7882753F04A00BBB92A /* FLEXSystemLogCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogCell.h; sourceTree = ""; }; - 503FA7892753F04A00BBB92A /* LLVM_LICENSE.TXT */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LLVM_LICENSE.TXT; sourceTree = ""; }; - 503FA78A2753F04A00BBB92A /* FLEXSystemLogViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogViewController.h; sourceTree = ""; }; - 503FA78B2753F04A00BBB92A /* FLEXOSLogController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXOSLogController.m; sourceTree = ""; }; - 503FA78C2753F04A00BBB92A /* ActivityStreamAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ActivityStreamAPI.h; sourceTree = ""; }; - 503FA78D2753F04A00BBB92A /* FLEXSystemLogMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSystemLogMessage.h; sourceTree = ""; }; - 503FA78E2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXAddressExplorerCoordinator.m; sourceTree = ""; }; - 503FA7902753F04A00BBB92A /* FLEXRealmDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDefines.h; sourceTree = ""; }; - 503FA7912753F04A00BBB92A /* FLEXTableLeftCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableLeftCell.m; sourceTree = ""; }; - 503FA7922753F04A00BBB92A /* FLEXRealmDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRealmDatabaseManager.h; sourceTree = ""; }; - 503FA7932753F04A00BBB92A /* FLEXSQLResult.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSQLResult.m; sourceTree = ""; }; - 503FA7942753F04A00BBB92A /* LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = LICENSE; sourceTree = ""; }; - 503FA7952753F04A00BBB92A /* FLEXTableContentViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableContentViewController.m; sourceTree = ""; }; - 503FA7962753F04A00BBB92A /* FLEXDBQueryRowCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDBQueryRowCell.h; sourceTree = ""; }; - 503FA7972753F04A00BBB92A /* FLEXTableListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableListViewController.m; sourceTree = ""; }; - 503FA7982753F04A00BBB92A /* FLEXTableColumnHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTableColumnHeader.m; sourceTree = ""; }; - 503FA7992753F04A00BBB92A /* FLEXMultiColumnTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMultiColumnTableView.m; sourceTree = ""; }; - 503FA79A2753F04A00BBB92A /* FLEXSQLiteDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSQLiteDatabaseManager.h; sourceTree = ""; }; - 503FA79B2753F04A00BBB92A /* FLEXTableLeftCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableLeftCell.h; sourceTree = ""; }; - 503FA79C2753F04A00BBB92A /* FLEXDatabaseManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXDatabaseManager.h; sourceTree = ""; }; - 503FA79D2753F04A00BBB92A /* FLEXSQLResult.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSQLResult.h; sourceTree = ""; }; - 503FA79E2753F04A00BBB92A /* FLEXRealmDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRealmDatabaseManager.m; sourceTree = ""; }; - 503FA79F2753F04A00BBB92A /* FLEXDBQueryRowCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXDBQueryRowCell.m; sourceTree = ""; }; - 503FA7A02753F04A00BBB92A /* FLEXTableContentViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableContentViewController.h; sourceTree = ""; }; - 503FA7A12753F04A00BBB92A /* FLEXSQLiteDatabaseManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSQLiteDatabaseManager.m; sourceTree = ""; }; - 503FA7A22753F04A00BBB92A /* FLEXMultiColumnTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMultiColumnTableView.h; sourceTree = ""; }; - 503FA7A32753F04A00BBB92A /* FLEXTableColumnHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableColumnHeader.h; sourceTree = ""; }; - 503FA7A42753F04A00BBB92A /* FLEXTableListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTableListViewController.h; sourceTree = ""; }; - 503FA7A52753F04A00BBB92A /* FLEXWebViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXWebViewController.h; sourceTree = ""; }; - 503FA7A62753F04B00BBB92A /* FLEXCookiesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXCookiesViewController.m; sourceTree = ""; }; - 503FA7A92753F04B00BBB92A /* FLEXRuntimeController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeController.h; sourceTree = ""; }; - 503FA7AA2753F04B00BBB92A /* FLEXRuntimeClient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeClient.m; sourceTree = ""; }; - 503FA7AB2753F04B00BBB92A /* FLEXRuntimeExporter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeExporter.h; sourceTree = ""; }; - 503FA7AC2753F04B00BBB92A /* FLEXRuntimeClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeClient.h; sourceTree = ""; }; - 503FA7AD2753F04B00BBB92A /* FLEXRuntimeController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeController.m; sourceTree = ""; }; - 503FA7AE2753F04B00BBB92A /* FLEXRuntimeExporter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeExporter.m; sourceTree = ""; }; - 503FA7AF2753F04B00BBB92A /* FLEXKBToolbarButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKBToolbarButton.h; sourceTree = ""; }; - 503FA7B02753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeKeyPathTokenizer.h; sourceTree = ""; }; - 503FA7B12753F04B00BBB92A /* FLEXObjcRuntimeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjcRuntimeViewController.h; sourceTree = ""; }; - 503FA7B22753F04B00BBB92A /* FLEXKeyboardToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardToolbar.h; sourceTree = ""; }; - 503FA7B32753F04B00BBB92A /* FLEXRuntimeKeyPath.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeKeyPath.m; sourceTree = ""; }; - 503FA7B42753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeBrowserToolbar.m; sourceTree = ""; }; - 503FA7B52753F04B00BBB92A /* FLEXKeyPathSearchController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyPathSearchController.h; sourceTree = ""; }; - 503FA7B62753F04B00BBB92A /* FLEXSearchToken.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXSearchToken.m; sourceTree = ""; }; - 503FA7B72753F04B00BBB92A /* FLEXKBToolbarButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKBToolbarButton.m; sourceTree = ""; }; - 503FA7B82753F04B00BBB92A /* FLEXKeyboardToolbar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardToolbar.m; sourceTree = ""; }; - 503FA7B92753F04B00BBB92A /* FLEXObjcRuntimeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXObjcRuntimeViewController.m; sourceTree = ""; }; - 503FA7BA2753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeKeyPathTokenizer.m; sourceTree = ""; }; - 503FA7BB2753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeBrowserToolbar.h; sourceTree = ""; }; - 503FA7BC2753F04B00BBB92A /* FLEXRuntimeKeyPath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeKeyPath.h; sourceTree = ""; }; - 503FA7BD2753F04B00BBB92A /* FLEXSearchToken.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXSearchToken.h; sourceTree = ""; }; - 503FA7BE2753F04B00BBB92A /* FLEXKeyPathSearchController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyPathSearchController.m; sourceTree = ""; }; - 503FA7C02753F04B00BBB92A /* FLEXImagePreviewViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXImagePreviewViewController.m; sourceTree = ""; }; - 503FA7C22753F04B00BBB92A /* FHSViewSnapshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSViewSnapshot.m; sourceTree = ""; }; - 503FA7C32753F04B00BBB92A /* FHSView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSView.h; sourceTree = ""; }; - 503FA7C42753F04B00BBB92A /* FHSViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSViewController.h; sourceTree = ""; }; - 503FA7C52753F04B00BBB92A /* FHSRangeSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSRangeSlider.m; sourceTree = ""; }; - 503FA7C62753F04B00BBB92A /* FHSSnapshotView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSSnapshotView.h; sourceTree = ""; }; - 503FA7C72753F04B00BBB92A /* FHSView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSView.m; sourceTree = ""; }; - 503FA7C82753F04B00BBB92A /* FHSViewSnapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSViewSnapshot.h; sourceTree = ""; }; - 503FA7C92753F04B00BBB92A /* FHSViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSViewController.m; sourceTree = ""; }; - 503FA7CB2753F04B00BBB92A /* SceneKit+Snapshot.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SceneKit+Snapshot.m"; sourceTree = ""; }; - 503FA7CC2753F04B00BBB92A /* FHSSnapshotNodes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSSnapshotNodes.m; sourceTree = ""; }; - 503FA7CD2753F04B00BBB92A /* SceneKit+Snapshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SceneKit+Snapshot.h"; sourceTree = ""; }; - 503FA7CE2753F04B00BBB92A /* FHSSnapshotNodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSSnapshotNodes.h; sourceTree = ""; }; - 503FA7CF2753F04B00BBB92A /* FHSSnapshotView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FHSSnapshotView.m; sourceTree = ""; }; - 503FA7D02753F04B00BBB92A /* FHSRangeSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FHSRangeSlider.h; sourceTree = ""; }; - 503FA7D12753F04B00BBB92A /* FLEXHierarchyViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHierarchyViewController.h; sourceTree = ""; }; - 503FA7D32753F04B00BBB92A /* FLEXHierarchyTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHierarchyTableViewCell.m; sourceTree = ""; }; - 503FA7D42753F04B00BBB92A /* FLEXHierarchyTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHierarchyTableViewController.h; sourceTree = ""; }; - 503FA7D52753F04B00BBB92A /* FLEXHierarchyTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHierarchyTableViewCell.h; sourceTree = ""; }; - 503FA7D62753F04B00BBB92A /* FLEXHierarchyTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHierarchyTableViewController.m; sourceTree = ""; }; - 503FA7D72753F04B00BBB92A /* FLEXImagePreviewViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXImagePreviewViewController.h; sourceTree = ""; }; - 503FA7D82753F04B00BBB92A /* FLEXHierarchyViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHierarchyViewController.m; sourceTree = ""; }; - 503FA7DA2753F04B00BBB92A /* FLEXUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXUtility.m; sourceTree = ""; }; - 503FA7DB2753F04B00BBB92A /* FLEXMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMacros.h; sourceTree = ""; }; - 503FA7DC2753F04B00BBB92A /* FLEXHeapEnumerator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXHeapEnumerator.m; sourceTree = ""; }; - 503FA7DD2753F04B00BBB92A /* FLEXResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXResources.h; sourceTree = ""; }; - 503FA7DE2753F04B00BBB92A /* APPLE_LICENSE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = ""; }; - 503FA7E02753F04B00BBB92A /* flex_fishhook.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flex_fishhook.c; sourceTree = ""; }; - 503FA7E12753F04B00BBB92A /* FLEXRuntimeUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeUtility.m; sourceTree = ""; }; - 503FA7E22753F04B00BBB92A /* FLEXRuntimeUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeUtility.h; sourceTree = ""; }; - 503FA7E32753F04B00BBB92A /* flex_fishhook.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = flex_fishhook.h; sourceTree = ""; }; - 503FA7E52753F04B00BBB92A /* FLEXRuntimeSafety.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeSafety.h; sourceTree = ""; }; - 503FA7E62753F04B00BBB92A /* FLEXTypeEncodingParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXTypeEncodingParser.h; sourceTree = ""; }; - 503FA7E72753F04B00BBB92A /* FLEXRuntimeConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXRuntimeConstants.h; sourceTree = ""; }; - 503FA7E82753F04B00BBB92A /* FLEXRuntimeSafety.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeSafety.m; sourceTree = ""; }; - 503FA7E92753F04B00BBB92A /* FLEXRuntimeConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXRuntimeConstants.m; sourceTree = ""; }; - 503FA7EA2753F04B00BBB92A /* FLEXTypeEncodingParser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXTypeEncodingParser.m; sourceTree = ""; }; - 503FA7EB2753F04B00BBB92A /* FLEXObjcInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXObjcInternal.h; sourceTree = ""; }; - 503FA7EC2753F04B00BBB92A /* FLEXObjcInternal.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FLEXObjcInternal.mm; sourceTree = ""; }; - 503FA7EE2753F04B00BBB92A /* FLEXMirror.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMirror.m; sourceTree = ""; }; - 503FA7EF2753F04B00BBB92A /* FLEXPropertyAttributes.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXPropertyAttributes.m; sourceTree = ""; }; - 503FA7F02753F04B00BBB92A /* FLEXBlockDescription.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXBlockDescription.h; sourceTree = ""; }; - 503FA7F12753F04B00BBB92A /* FLEXProtocolBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProtocolBuilder.h; sourceTree = ""; }; - 503FA7F22753F04B00BBB92A /* FLEXProperty.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXProperty.m; sourceTree = ""; }; - 503FA7F32753F04B00BBB92A /* FLEXClassBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXClassBuilder.h; sourceTree = ""; }; - 503FA7F42753F04B00BBB92A /* FLEXMethodBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethodBase.h; sourceTree = ""; }; - 503FA7F52753F04B00BBB92A /* FLEXMethod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMethod.m; sourceTree = ""; }; - 503FA7F62753F04B00BBB92A /* FLEXIvar.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXIvar.m; sourceTree = ""; }; - 503FA7F72753F04B00BBB92A /* FLEXProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProtocol.h; sourceTree = ""; }; - 503FA7F82753F04B00BBB92A /* FLEXProtocolBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXProtocolBuilder.m; sourceTree = ""; }; - 503FA7F92753F04B00BBB92A /* FLEXBlockDescription.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXBlockDescription.m; sourceTree = ""; }; - 503FA7FA2753F04B00BBB92A /* FLEXPropertyAttributes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXPropertyAttributes.h; sourceTree = ""; }; - 503FA7FB2753F04B00BBB92A /* FLEXMirror.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMirror.h; sourceTree = ""; }; - 503FA7FC2753F04B00BBB92A /* FLEXClassBuilder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXClassBuilder.m; sourceTree = ""; }; - 503FA7FD2753F04B00BBB92A /* FLEXProperty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXProperty.h; sourceTree = ""; }; - 503FA7FE2753F04B00BBB92A /* FLEXProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXProtocol.m; sourceTree = ""; }; - 503FA7FF2753F04B00BBB92A /* FLEXIvar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXIvar.h; sourceTree = ""; }; - 503FA8002753F04B00BBB92A /* FLEXMethod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXMethod.h; sourceTree = ""; }; - 503FA8012753F04B00BBB92A /* FLEXMethodBase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXMethodBase.m; sourceTree = ""; }; - 503FA8022753F04B00BBB92A /* FLEXAlert.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXAlert.m; sourceTree = ""; }; - 503FA8032753F04B00BBB92A /* FLEXColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXColor.h; sourceTree = ""; }; - 503FA8042753F04B00BBB92A /* FLEXHeapEnumerator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXHeapEnumerator.h; sourceTree = ""; }; - 503FA8052753F04B00BBB92A /* FLEXUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXUtility.h; sourceTree = ""; }; - 503FA8062753F04B00BBB92A /* FLEXResources.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXResources.m; sourceTree = ""; }; - 503FA8072753F04B00BBB92A /* FLEXColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXColor.m; sourceTree = ""; }; - 503FA8092753F04B00BBB92A /* UIGestureRecognizer+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIGestureRecognizer+Blocks.m"; sourceTree = ""; }; - 503FA80A2753F04B00BBB92A /* FLEXRuntime+Compare.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLEXRuntime+Compare.m"; sourceTree = ""; }; - 503FA80B2753F04B00BBB92A /* NSArray+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+FLEX.m"; sourceTree = ""; }; - 503FA80C2753F04B00BBB92A /* NSObject+FLEX_Reflection.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+FLEX_Reflection.m"; sourceTree = ""; }; - 503FA80D2753F04B00BBB92A /* UIBarButtonItem+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIBarButtonItem+FLEX.h"; sourceTree = ""; }; - 503FA80E2753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "FLEXRuntime+UIKitHelpers.m"; sourceTree = ""; }; - 503FA80F2753F04B00BBB92A /* NSTimer+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSTimer+FLEX.m"; sourceTree = ""; }; - 503FA8102753F04B00BBB92A /* UIMenu+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIMenu+FLEX.m"; sourceTree = ""; }; - 503FA8112753F04B00BBB92A /* CALayer+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+FLEX.h"; sourceTree = ""; }; - 503FA8122753F04B00BBB92A /* UIPasteboard+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIPasteboard+FLEX.m"; sourceTree = ""; }; - 503FA8132753F04B00BBB92A /* UIFont+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIFont+FLEX.h"; sourceTree = ""; }; - 503FA8142753F04B00BBB92A /* NSUserDefaults+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+FLEX.m"; sourceTree = ""; }; - 503FA8152753F04B00BBB92A /* UITextField+Range.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UITextField+Range.m"; sourceTree = ""; }; - 503FA8162753F04B00BBB92A /* NSObject+FLEX_Reflection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+FLEX_Reflection.h"; sourceTree = ""; }; - 503FA8172753F04B00BBB92A /* NSArray+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+FLEX.h"; sourceTree = ""; }; - 503FA8182753F04B00BBB92A /* FLEXRuntime+Compare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXRuntime+Compare.h"; sourceTree = ""; }; - 503FA8192753F04B00BBB92A /* UIGestureRecognizer+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIGestureRecognizer+Blocks.h"; sourceTree = ""; }; - 503FA81B2753F04B00BBB92A /* UIView+FLEX_Layout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+FLEX_Layout.m"; sourceTree = ""; }; - 503FA81C2753F04B00BBB92A /* NSString+ObjcRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+ObjcRuntime.h"; sourceTree = ""; }; - 503FA81D2753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSMapTable+FLEX_Subscripting.h"; sourceTree = ""; }; - 503FA81E2753F04B00BBB92A /* NSString+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+FLEX.h"; sourceTree = ""; }; - 503FA81F2753F04B00BBB92A /* Cocoa+FLEXShortcuts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Cocoa+FLEXShortcuts.h"; sourceTree = ""; }; - 503FA8202753F04B00BBB92A /* NSDictionary+ObjcRuntime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+ObjcRuntime.h"; sourceTree = ""; }; - 503FA8212753F04B00BBB92A /* UIView+FLEX_Layout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+FLEX_Layout.h"; sourceTree = ""; }; - 503FA8222753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMapTable+FLEX_Subscripting.m"; sourceTree = ""; }; - 503FA8232753F04B00BBB92A /* NSString+ObjcRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+ObjcRuntime.m"; sourceTree = ""; }; - 503FA8242753F04B00BBB92A /* Cocoa+FLEXShortcuts.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Cocoa+FLEXShortcuts.m"; sourceTree = ""; }; - 503FA8252753F04B00BBB92A /* NSString+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+FLEX.m"; sourceTree = ""; }; - 503FA8262753F04B00BBB92A /* NSDictionary+ObjcRuntime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+ObjcRuntime.m"; sourceTree = ""; }; - 503FA8272753F04B00BBB92A /* NSTimer+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSTimer+FLEX.h"; sourceTree = ""; }; - 503FA8282753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "FLEXRuntime+UIKitHelpers.h"; sourceTree = ""; }; - 503FA8292753F04B00BBB92A /* UIBarButtonItem+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+FLEX.m"; sourceTree = ""; }; - 503FA82A2753F04B00BBB92A /* UIPasteboard+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIPasteboard+FLEX.h"; sourceTree = ""; }; - 503FA82B2753F04B00BBB92A /* UIMenu+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIMenu+FLEX.h"; sourceTree = ""; }; - 503FA82C2753F04B00BBB92A /* CALayer+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CALayer+FLEX.m"; sourceTree = ""; }; - 503FA82D2753F04B00BBB92A /* UITextField+Range.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UITextField+Range.h"; sourceTree = ""; }; - 503FA82E2753F04B00BBB92A /* NSUserDefaults+FLEX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSUserDefaults+FLEX.h"; sourceTree = ""; }; - 503FA82F2753F04B00BBB92A /* UIFont+FLEX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIFont+FLEX.m"; sourceTree = ""; }; - 503FA8302753F04B00BBB92A /* FLEXAlert.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXAlert.h; sourceTree = ""; }; - 503FA8322753F04B00BBB92A /* FLEXKeyboardHelpViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardHelpViewController.h; sourceTree = ""; }; - 503FA8332753F04B00BBB92A /* FLEXKeyboardShortcutManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardShortcutManager.m; sourceTree = ""; }; - 503FA8342753F04B00BBB92A /* FLEXKeyboardHelpViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLEXKeyboardHelpViewController.m; sourceTree = ""; }; - 503FA8352753F04B00BBB92A /* FLEXKeyboardShortcutManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLEXKeyboardShortcutManager.h; sourceTree = ""; }; 504C1C5A288F32050056F5EC /* Preferences.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Preferences.framework; path = ../../../../../opt/theos/sdks/iPhoneOS15.0.sdk/System/Library/PrivateFrameworks/Preferences.framework; sourceTree = ""; }; 505C0EBB2801ECAB0028D1C9 /* BHDownloadInlineButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BHDownloadInlineButton.h; sourceTree = ""; }; 505C0EBD2801ED020028D1C9 /* BHDownloadInlineButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BHDownloadInlineButton.m; sourceTree = ""; }; @@ -984,6 +108,7 @@ 50FAE056288545DB00CDCEB2 /* CepheiUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CepheiUI.framework; path = ../../../../../opt/theos/vendor/lib/CepheiUI.framework; sourceTree = ""; }; 50FAE05E288545F600CDCEB2 /* SettingsViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingsViewController.h; sourceTree = ""; }; 50FAE05F288545F600CDCEB2 /* SettingsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingsViewController.m; sourceTree = ""; }; + 916F1E1A2912F16D00865DD2 /* Preferences.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Preferences.framework; path = ../../../../../opt/theos/sdks/iPhoneOS16.0.sdk/System/Library/PrivateFrameworks/Preferences.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -994,13 +119,15 @@ 50E7ABEF24F5A8F700A8619D /* WebKit.framework in Frameworks */, 5020AA6F24E759790080F292 /* CoreGraphics.framework in Frameworks */, 5020AA7D24E759A20080F292 /* QuartzCore.framework in Frameworks */, + 91086148293001530011609E /* FLEX in Frameworks */, 5020AA7324E759860080F292 /* Photos.framework in Frameworks */, - 504C1C5B288F32050056F5EC /* Preferences.framework in Frameworks */, + 916F1E1B2912F16D00865DD2 /* Preferences.framework in Frameworks */, 50FAE05B288545DC00CDCEB2 /* CepheiUI.framework in Frameworks */, 50D73502252CBFC6007838C7 /* SceneKit.framework in Frameworks */, 50D73500252CBFC1007838C7 /* libz.tbd in Frameworks */, 5020AA6924E759700080F292 /* Accelerate.framework in Frameworks */, 50FAE057288545DB00CDCEB2 /* CepheiPrefs.framework in Frameworks */, + 9108614B293005750011609E /* JGProgressHUD in Frameworks */, 5020AA7124E7597F0080F292 /* ImageIO.framework in Frameworks */, 5020AA7524E7598D0080F292 /* CoreServices.framework in Frameworks */, 5020A87824E758E00080F292 /* UIKit.framework in Frameworks */, @@ -1054,6 +181,7 @@ isa = PBXGroup; children = ( 504C1C5A288F32050056F5EC /* Preferences.framework */, + 916F1E1A2912F16D00865DD2 /* Preferences.framework */, 50FAE055288545DB00CDCEB2 /* Cephei.framework */, 50FAE054288545DB00CDCEB2 /* CepheiPrefs.framework */, 50FAE056288545DB00CDCEB2 /* CepheiUI.framework */, @@ -1098,9 +226,7 @@ 50FAE05F288545F600CDCEB2 /* SettingsViewController.m */, 50EE4D49286F7F56007DE117 /* ThemeColor */, 5061F3BE2806132400F3D5D3 /* CustomTabBar */, - 503FA66D2753F04A00BBB92A /* Classes */, 500DA69526FF92F500C020B2 /* SAMKeychain */, - 5020AA2824E759390080F292 /* JGProgressHUD */, 5020A87E24E758E00080F292 /* Package */, 5020A88124E758E00080F292 /* Supporting Files */, 505C0ED028038B810028D1C9 /* BHTwitter-Bridging-Header.h */, @@ -1157,782 +283,6 @@ path = DynamicLibraries; sourceTree = ""; }; - 5020AA2824E759390080F292 /* JGProgressHUD */ = { - isa = PBXGroup; - children = ( - 5020AA2924E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.m */, - 5020AA2A24E759390080F292 /* JGProgressHUDErrorIndicatorView.m */, - 5020AA2B24E759390080F292 /* JGProgressHUDAnimation.m */, - 5020AA2C24E759390080F292 /* include */, - 5020AA3A24E759390080F292 /* JGProgressHUDFadeZoomAnimation.m */, - 5020AA3B24E759390080F292 /* JGProgressHUDImageIndicatorView.m */, - 5020AA3C24E759390080F292 /* JGProgressHUDSuccessIndicatorView.m */, - 5020AA3D24E759390080F292 /* JGProgressHUDIndicatorView.m */, - 5020AA3E24E759390080F292 /* JGProgressHUD.m */, - 5020AA3F24E759390080F292 /* JGProgressHUDFadeAnimation.m */, - 5020AA4024E759390080F292 /* JGProgressHUDRingIndicatorView.m */, - 5020AA4124E759390080F292 /* JGProgressHUDPieIndicatorView.m */, - 5020AA4224E759390080F292 /* JGProgressHUDShadow.m */, - ); - path = JGProgressHUD; - sourceTree = ""; - }; - 5020AA2C24E759390080F292 /* include */ = { - isa = PBXGroup; - children = ( - 5020AA2D24E759390080F292 /* JGProgressHUDSuccessIndicatorView.h */, - 5020AA2E24E759390080F292 /* JGProgressHUDImageIndicatorView.h */, - 5020AA2F24E759390080F292 /* JGProgressHUDIndicatorView.h */, - 5020AA3024E759390080F292 /* JGProgressHUD.h */, - 5020AA3124E759390080F292 /* JGProgressHUDShadow.h */, - 5020AA3224E759390080F292 /* JGProgressHUDPieIndicatorView.h */, - 5020AA3324E759390080F292 /* JGProgressHUDRingIndicatorView.h */, - 5020AA3424E759390080F292 /* JGProgressHUDFadeAnimation.h */, - 5020AA3524E759390080F292 /* JGProgressHUD-Defines.h */, - 5020AA3624E759390080F292 /* JGProgressHUDAnimation.h */, - 5020AA3724E759390080F292 /* JGProgressHUDErrorIndicatorView.h */, - 5020AA3824E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.h */, - 5020AA3924E759390080F292 /* JGProgressHUDFadeZoomAnimation.h */, - ); - path = include; - sourceTree = ""; - }; - 503FA66D2753F04A00BBB92A /* Classes */ = { - isa = PBXGroup; - children = ( - 503FA66E2753F04A00BBB92A /* FLEX-Runtime.h */, - 503FA66F2753F04A00BBB92A /* Core */, - 503FA68E2753F04A00BBB92A /* FLEX.h */, - 503FA68F2753F04A00BBB92A /* ObjectExplorers */, - 503FA6BD2753F04A00BBB92A /* Network */, - 503FA6D62753F04A00BBB92A /* Toolbar */, - 503FA6DB2753F04A00BBB92A /* FLEX-Categories.h */, - 503FA6DC2753F04A00BBB92A /* FLEX-Core.h */, - 503FA6DD2753F04A00BBB92A /* FLEX-ObjectExploring.h */, - 503FA6DE2753F04A00BBB92A /* Manager */, - 503FA6E72753F04A00BBB92A /* Editing */, - 503FA70D2753F04A00BBB92A /* Headers */, - 503FA74D2753F04A00BBB92A /* ExplorerInterface */, - 503FA7602753F04A00BBB92A /* GlobalStateExplorers */, - 503FA7BF2753F04B00BBB92A /* ViewHierarchy */, - 503FA7D92753F04B00BBB92A /* Utility */, - ); - path = Classes; - sourceTree = ""; - }; - 503FA66F2753F04A00BBB92A /* Core */ = { - isa = PBXGroup; - children = ( - 503FA6702753F04A00BBB92A /* FLEXTableViewSection.h */, - 503FA6712753F04A00BBB92A /* FLEXSingleRowSection.m */, - 503FA6722753F04A00BBB92A /* FLEXTableViewSection.m */, - 503FA6732753F04A00BBB92A /* Controllers */, - 503FA67A2753F04A00BBB92A /* Views */, - 503FA68D2753F04A00BBB92A /* FLEXSingleRowSection.h */, - ); - path = Core; - sourceTree = ""; - }; - 503FA6732753F04A00BBB92A /* Controllers */ = { - isa = PBXGroup; - children = ( - 503FA6742753F04A00BBB92A /* FLEXTableViewController.m */, - 503FA6752753F04A00BBB92A /* FLEXNavigationController.m */, - 503FA6762753F04A00BBB92A /* FLEXFilteringTableViewController.h */, - 503FA6772753F04A00BBB92A /* FLEXNavigationController.h */, - 503FA6782753F04A00BBB92A /* FLEXTableViewController.h */, - 503FA6792753F04A00BBB92A /* FLEXFilteringTableViewController.m */, - ); - path = Controllers; - sourceTree = ""; - }; - 503FA67A2753F04A00BBB92A /* Views */ = { - isa = PBXGroup; - children = ( - 503FA67B2753F04A00BBB92A /* Cells */, - 503FA6862753F04A00BBB92A /* FLEXTableView.h */, - 503FA6872753F04A00BBB92A /* Carousel */, - 503FA68C2753F04A00BBB92A /* FLEXTableView.m */, - ); - path = Views; - sourceTree = ""; - }; - 503FA67B2753F04A00BBB92A /* Cells */ = { - isa = PBXGroup; - children = ( - 503FA67C2753F04A00BBB92A /* FLEXCodeFontCell.h */, - 503FA67D2753F04A00BBB92A /* FLEXKeyValueTableViewCell.m */, - 503FA67E2753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */, - 503FA67F2753F04A00BBB92A /* FLEXTableViewCell.h */, - 503FA6802753F04A00BBB92A /* FLEXMultilineTableViewCell.h */, - 503FA6812753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */, - 503FA6822753F04A00BBB92A /* FLEXCodeFontCell.m */, - 503FA6832753F04A00BBB92A /* FLEXSubtitleTableViewCell.m */, - 503FA6842753F04A00BBB92A /* FLEXMultilineTableViewCell.m */, - 503FA6852753F04A00BBB92A /* FLEXTableViewCell.m */, - ); - path = Cells; - sourceTree = ""; - }; - 503FA6872753F04A00BBB92A /* Carousel */ = { - isa = PBXGroup; - children = ( - 503FA6882753F04A00BBB92A /* FLEXCarouselCell.h */, - 503FA6892753F04A00BBB92A /* FLEXScopeCarousel.m */, - 503FA68A2753F04A00BBB92A /* FLEXScopeCarousel.h */, - 503FA68B2753F04A00BBB92A /* FLEXCarouselCell.m */, - ); - path = Carousel; - sourceTree = ""; - }; - 503FA68F2753F04A00BBB92A /* ObjectExplorers */ = { - isa = PBXGroup; - children = ( - 503FA6902753F04A00BBB92A /* FLEXObjectExplorerFactory.m */, - 503FA6912753F04A00BBB92A /* Sections */, - 503FA6B82753F04A00BBB92A /* FLEXObjectExplorerViewController.h */, - 503FA6B92753F04A00BBB92A /* FLEXObjectExplorer.h */, - 503FA6BA2753F04A00BBB92A /* FLEXObjectExplorerFactory.h */, - 503FA6BB2753F04A00BBB92A /* FLEXObjectExplorerViewController.m */, - 503FA6BC2753F04A00BBB92A /* FLEXObjectExplorer.m */, - ); - path = ObjectExplorers; - sourceTree = ""; - }; - 503FA6912753F04A00BBB92A /* Sections */ = { - isa = PBXGroup; - children = ( - 503FA6922753F04A00BBB92A /* FLEXColorPreviewSection.h */, - 503FA6932753F04A00BBB92A /* FLEXCollectionContentSection.h */, - 503FA6942753F04A00BBB92A /* FLEXDefaultsContentSection.m */, - 503FA6952753F04A00BBB92A /* FLEXMutableListSection.m */, - 503FA6962753F04A00BBB92A /* FLEXMetadataSection.h */, - 503FA6972753F04A00BBB92A /* FLEXCollectionContentSection.m */, - 503FA6982753F04A00BBB92A /* FLEXColorPreviewSection.m */, - 503FA6992753F04A00BBB92A /* FLEXDefaultsContentSection.h */, - 503FA69A2753F04A00BBB92A /* Shortcuts */, - 503FA6B52753F04A00BBB92A /* FLEXMutableListSection.h */, - 503FA6B62753F04A00BBB92A /* FLEXObjectInfoSection.h */, - 503FA6B72753F04A00BBB92A /* FLEXMetadataSection.m */, - ); - path = Sections; - sourceTree = ""; - }; - 503FA69A2753F04A00BBB92A /* Shortcuts */ = { - isa = PBXGroup; - children = ( - 503FA69B2753F04A00BBB92A /* FLEXBundleShortcuts.h */, - 503FA69C2753F04A00BBB92A /* FLEXShortcutsSection.m */, - 503FA69D2753F04A00BBB92A /* FLEXViewShortcuts.h */, - 503FA69E2753F04A00BBB92A /* FLEXNSStringShortcuts.h */, - 503FA69F2753F04A00BBB92A /* FLEXBlockShortcuts.m */, - 503FA6A02753F04A00BBB92A /* FLEXClassShortcuts.m */, - 503FA6A12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.h */, - 503FA6A22753F04A00BBB92A /* FLEXUIAppShortcuts.h */, - 503FA6A32753F04A00BBB92A /* FLEXLayerShortcuts.h */, - 503FA6A42753F04A00BBB92A /* FLEXImageShortcuts.m */, - 503FA6A52753F04A00BBB92A /* FLEXNSDataShortcuts.h */, - 503FA6A62753F04A00BBB92A /* FLEXViewControllerShortcuts.h */, - 503FA6A72753F04A00BBB92A /* FLEXShortcut.h */, - 503FA6A82753F04A00BBB92A /* FLEXViewShortcuts.m */, - 503FA6A92753F04A00BBB92A /* FLEXShortcutsSection.h */, - 503FA6AA2753F04A00BBB92A /* FLEXBundleShortcuts.m */, - 503FA6AB2753F04A00BBB92A /* FLEXClassShortcuts.h */, - 503FA6AC2753F04A00BBB92A /* FLEXBlockShortcuts.h */, - 503FA6AD2753F04A00BBB92A /* FLEXNSStringShortcuts.m */, - 503FA6AE2753F04A00BBB92A /* FLEXImageShortcuts.h */, - 503FA6AF2753F04A00BBB92A /* FLEXLayerShortcuts.m */, - 503FA6B02753F04A00BBB92A /* FLEXUIAppShortcuts.m */, - 503FA6B12753F04A00BBB92A /* FLEXShortcutsFactory+Defaults.m */, - 503FA6B22753F04A00BBB92A /* FLEXShortcut.m */, - 503FA6B32753F04A00BBB92A /* FLEXViewControllerShortcuts.m */, - 503FA6B42753F04A00BBB92A /* FLEXNSDataShortcuts.m */, - ); - path = Shortcuts; - sourceTree = ""; - }; - 503FA6BD2753F04A00BBB92A /* Network */ = { - isa = PBXGroup; - children = ( - 503FA6BE2753F04A00BBB92A /* FLEXNetworkCurlLogger.h */, - 503FA6BF2753F04A00BBB92A /* FLEXNetworkTransaction.m */, - 503FA6C02753F04A00BBB92A /* FLEXNetworkSettingsController.m */, - 503FA6C12753F04A00BBB92A /* FLEXNetworkRecorder.m */, - 503FA6C22753F04A00BBB92A /* FLEXHTTPTransactionDetailController.h */, - 503FA6C32753F04A00BBB92A /* FLEXNetworkMITMViewController.m */, - 503FA6C42753F04A00BBB92A /* FLEXMITMDataSource.h */, - 503FA6C52753F04A00BBB92A /* FLEXNetworkTransactionCell.m */, - 503FA6C62753F04A00BBB92A /* FLEXNetworkTransaction.h */, - 503FA6C72753F04A00BBB92A /* FLEXNetworkCurlLogger.m */, - 503FA6C82753F04A00BBB92A /* FLEXNetworkMITMViewController.h */, - 503FA6C92753F04A00BBB92A /* FLEXHTTPTransactionDetailController.m */, - 503FA6CA2753F04A00BBB92A /* FLEXNetworkRecorder.h */, - 503FA6CB2753F04A00BBB92A /* FLEXNetworkSettingsController.h */, - 503FA6CC2753F04A00BBB92A /* FLEXMITMDataSource.m */, - 503FA6CD2753F04A00BBB92A /* PonyDebugger */, - 503FA6D12753F04A00BBB92A /* FLEXNetworkTransactionCell.h */, - 503FA6D22753F04A00BBB92A /* OSCache */, - ); - path = Network; - sourceTree = ""; - }; - 503FA6CD2753F04A00BBB92A /* PonyDebugger */ = { - isa = PBXGroup; - children = ( - 503FA6CE2753F04A00BBB92A /* FLEXNetworkObserver.h */, - 503FA6CF2753F04A00BBB92A /* LICENSE */, - 503FA6D02753F04A00BBB92A /* FLEXNetworkObserver.m */, - ); - path = PonyDebugger; - sourceTree = ""; - }; - 503FA6D22753F04A00BBB92A /* OSCache */ = { - isa = PBXGroup; - children = ( - 503FA6D32753F04A00BBB92A /* LICENSE.md */, - 503FA6D42753F04A00BBB92A /* OSCache.m */, - 503FA6D52753F04A00BBB92A /* OSCache.h */, - ); - path = OSCache; - sourceTree = ""; - }; - 503FA6D62753F04A00BBB92A /* Toolbar */ = { - isa = PBXGroup; - children = ( - 503FA6D72753F04A00BBB92A /* FLEXExplorerToolbarItem.h */, - 503FA6D82753F04A00BBB92A /* FLEXExplorerToolbar.h */, - 503FA6D92753F04A00BBB92A /* FLEXExplorerToolbarItem.m */, - 503FA6DA2753F04A00BBB92A /* FLEXExplorerToolbar.m */, - ); - path = Toolbar; - sourceTree = ""; - }; - 503FA6DE2753F04A00BBB92A /* Manager */ = { - isa = PBXGroup; - children = ( - 503FA6DF2753F04A00BBB92A /* FLEXManager.h */, - 503FA6E02753F04A00BBB92A /* FLEXManager+Extensibility.m */, - 503FA6E12753F04A00BBB92A /* FLEXManager+Networking.h */, - 503FA6E22753F04A00BBB92A /* FLEXManager.m */, - 503FA6E32753F04A00BBB92A /* Private */, - 503FA6E52753F04A00BBB92A /* FLEXManager+Networking.m */, - 503FA6E62753F04A00BBB92A /* FLEXManager+Extensibility.h */, - ); - path = Manager; - sourceTree = ""; - }; - 503FA6E32753F04A00BBB92A /* Private */ = { - isa = PBXGroup; - children = ( - 503FA6E42753F04A00BBB92A /* FLEXManager+Private.h */, - ); - path = Private; - sourceTree = ""; - }; - 503FA6E72753F04A00BBB92A /* Editing */ = { - isa = PBXGroup; - children = ( - 503FA6E82753F04A00BBB92A /* FLEXDefaultEditorViewController.m */, - 503FA6E92753F04A00BBB92A /* FLEXVariableEditorViewController.h */, - 503FA6EA2753F04A00BBB92A /* FLEXFieldEditorViewController.h */, - 503FA6EB2753F04A00BBB92A /* FLEXFieldEditorView.h */, - 503FA6EC2753F04A00BBB92A /* FLEXMethodCallingViewController.m */, - 503FA6ED2753F04A00BBB92A /* FLEXArgumentInputViewFactory.h */, - 503FA6EE2753F04A00BBB92A /* FLEXFieldEditorViewController.m */, - 503FA6EF2753F04A00BBB92A /* FLEXVariableEditorViewController.m */, - 503FA6F02753F04A00BBB92A /* FLEXDefaultEditorViewController.h */, - 503FA6F12753F04A00BBB92A /* ArgumentInputViews */, - 503FA70A2753F04A00BBB92A /* FLEXArgumentInputViewFactory.m */, - 503FA70B2753F04A00BBB92A /* FLEXMethodCallingViewController.h */, - 503FA70C2753F04A00BBB92A /* FLEXFieldEditorView.m */, - ); - path = Editing; - sourceTree = ""; - }; - 503FA6F12753F04A00BBB92A /* ArgumentInputViews */ = { - isa = PBXGroup; - children = ( - 503FA6F22753F04A00BBB92A /* FLEXArgumentInputStringView.m */, - 503FA6F32753F04A00BBB92A /* FLEXArgumentInputColorView.m */, - 503FA6F42753F04A00BBB92A /* FLEXArgumentInputView.m */, - 503FA6F52753F04A00BBB92A /* FLEXArgumentInputFontView.h */, - 503FA6F62753F04A00BBB92A /* FLEXArgumentInputTextView.h */, - 503FA6F72753F04A00BBB92A /* FLEXArgumentInputSwitchView.m */, - 503FA6F82753F04A00BBB92A /* FLEXArgumentInputStructView.m */, - 503FA6F92753F04A00BBB92A /* FLEXArgumentInputDateView.m */, - 503FA6FA2753F04A00BBB92A /* FLEXArgumentInputNumberView.h */, - 503FA6FB2753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.h */, - 503FA6FC2753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.h */, - 503FA6FD2753F04A00BBB92A /* FLEXArgumentInputObjectView.m */, - 503FA6FE2753F04A00BBB92A /* FLEXArgumentInputFontView.m */, - 503FA6FF2753F04A00BBB92A /* FLEXArgumentInputView.h */, - 503FA7002753F04A00BBB92A /* FLEXArgumentInputColorView.h */, - 503FA7012753F04A00BBB92A /* FLEXArgumentInputStringView.h */, - 503FA7022753F04A00BBB92A /* FLEXArgumentInputSwitchView.h */, - 503FA7032753F04A00BBB92A /* FLEXArgumentInputTextView.m */, - 503FA7042753F04A00BBB92A /* FLEXArgumentInputFontsPickerView.m */, - 503FA7052753F04A00BBB92A /* FLEXArgumentInputNumberView.m */, - 503FA7062753F04A00BBB92A /* FLEXArgumentInputDateView.h */, - 503FA7072753F04A00BBB92A /* FLEXArgumentInputStructView.h */, - 503FA7082753F04A00BBB92A /* FLEXArgumentInputObjectView.h */, - 503FA7092753F04A00BBB92A /* FLEXArgumentInputNotSupportedView.m */, - ); - path = ArgumentInputViews; - sourceTree = ""; - }; - 503FA70D2753F04A00BBB92A /* Headers */ = { - isa = PBXGroup; - children = ( - 503FA70E2753F04A00BBB92A /* FLEXRuntimeSafety.h */, - 503FA70F2753F04A00BBB92A /* FLEXExplorerToolbarItem.h */, - 503FA7102753F04A00BBB92A /* FLEXManager.h */, - 503FA7112753F04A00BBB92A /* FLEXBlockDescription.h */, - 503FA7122753F04A00BBB92A /* FLEXMacros.h */, - 503FA7132753F04A00BBB92A /* FLEXProtocolBuilder.h */, - 503FA7142753F04A00BBB92A /* FLEXColorPreviewSection.h */, - 503FA7152753F04A00BBB92A /* FLEXCollectionContentSection.h */, - 503FA7162753F04A00BBB92A /* FLEX-Runtime.h */, - 503FA7172753F04A00BBB92A /* UIBarButtonItem+FLEX.h */, - 503FA7182753F04A00BBB92A /* FLEXResources.h */, - 503FA7192753F04A00BBB92A /* FLEXTypeEncodingParser.h */, - 503FA71A2753F04A00BBB92A /* FLEX.h */, - 503FA71B2753F04A00BBB92A /* FLEXRuntimeConstants.h */, - 503FA71C2753F04A00BBB92A /* FLEXClassBuilder.h */, - 503FA71D2753F04A00BBB92A /* FLEXCodeFontCell.h */, - 503FA71E2753F04A00BBB92A /* FLEXTableViewSection.h */, - 503FA71F2753F04A00BBB92A /* FLEXFilteringTableViewController.h */, - 503FA7202753F04A00BBB92A /* CALayer+FLEX.h */, - 503FA7212753F04A00BBB92A /* FLEXSubtitleTableViewCell.h */, - 503FA7222753F04A00BBB92A /* FLEXObjectExplorerViewController.h */, - 503FA7232753F04A00BBB92A /* FLEXManager+Networking.h */, - 503FA7242753F04A00BBB92A /* FLEXMetadataSection.h */, - 503FA7252753F04A00BBB92A /* FLEX-Categories.h */, - 503FA7262753F04A00BBB92A /* UIFont+FLEX.h */, - 503FA7272753F04A00BBB92A /* FLEXTableView.h */, - 503FA7282753F04A00BBB92A /* FLEXMethodBase.h */, - 503FA7292753F04A00BBB92A /* FLEXObjectExplorer.h */, - 503FA72A2753F04A00BBB92A /* FLEXShortcut.h */, - 503FA72B2753F04A00BBB92A /* FLEXTableViewCell.h */, - 503FA72C2753F04A00BBB92A /* FLEX-Core.h */, - 503FA72D2753F04A00BBB92A /* FLEXMultilineTableViewCell.h */, - 503FA72E2753F04A00BBB92A /* FLEXProtocol.h */, - 503FA72F2753F04A00BBB92A /* FLEXExplorerToolbar.h */, - 503FA7302753F04A00BBB92A /* FLEXGlobalsEntry.h */, - 503FA7312753F04A00BBB92A /* NSObject+FLEX_Reflection.h */, - 503FA7322753F04A00BBB92A /* FLEX-ObjectExploring.h */, - 503FA7332753F04A00BBB92A /* NSArray+FLEX.h */, - 503FA7342753F04A00BBB92A /* FLEXRuntime+Compare.h */, - 503FA7352753F04A00BBB92A /* FLEXShortcutsSection.h */, - 503FA7362753F04A00BBB92A /* FLEXPropertyAttributes.h */, - 503FA7372753F04A00BBB92A /* UIGestureRecognizer+Blocks.h */, - 503FA7382753F04A00BBB92A /* FLEXMirror.h */, - 503FA7392753F04A00BBB92A /* FLEXObjectExplorerFactory.h */, - 503FA73A2753F04A00BBB92A /* FLEXKeyValueTableViewCell.h */, - 503FA73B2753F04A00BBB92A /* FLEXNavigationController.h */, - 503FA73C2753F04A00BBB92A /* NSTimer+FLEX.h */, - 503FA73D2753F04A00BBB92A /* FLEXDefaultsContentSection.h */, - 503FA73E2753F04A00BBB92A /* FLEXTableViewController.h */, - 503FA73F2753F04A00BBB92A /* FLEXRuntime+UIKitHelpers.h */, - 503FA7402753F04A00BBB92A /* FLEXProperty.h */, - 503FA7412753F04A00BBB92A /* FLEXMutableListSection.h */, - 503FA7422753F04A00BBB92A /* UIPasteboard+FLEX.h */, - 503FA7432753F04A00BBB92A /* FLEXObjcInternal.h */, - 503FA7442753F04A00BBB92A /* FLEXManager+Extensibility.h */, - 503FA7452753F04A00BBB92A /* UIMenu+FLEX.h */, - 503FA7462753F04A00BBB92A /* FLEXObjectInfoSection.h */, - 503FA7472753F04A00BBB92A /* UITextField+Range.h */, - 503FA7482753F04A00BBB92A /* FLEXIvar.h */, - 503FA7492753F04A00BBB92A /* NSUserDefaults+FLEX.h */, - 503FA74A2753F04A00BBB92A /* FLEXSingleRowSection.h */, - 503FA74B2753F04A00BBB92A /* FLEXAlert.h */, - 503FA74C2753F04A00BBB92A /* FLEXMethod.h */, - ); - path = Headers; - sourceTree = ""; - }; - 503FA74D2753F04A00BBB92A /* ExplorerInterface */ = { - isa = PBXGroup; - children = ( - 503FA74E2753F04A00BBB92A /* Tabs */, - 503FA7532753F04A00BBB92A /* FLEXExplorerViewController.m */, - 503FA7542753F04A00BBB92A /* FLEXWindow.m */, - 503FA7552753F04A00BBB92A /* FLEXViewControllersViewController.h */, - 503FA7562753F04A00BBB92A /* FLEXWindowManagerController.m */, - 503FA7572753F04A00BBB92A /* Bookmarks */, - 503FA75C2753F04A00BBB92A /* FLEXExplorerViewController.h */, - 503FA75D2753F04A00BBB92A /* FLEXWindow.h */, - 503FA75E2753F04A00BBB92A /* FLEXWindowManagerController.h */, - 503FA75F2753F04A00BBB92A /* FLEXViewControllersViewController.m */, - ); - path = ExplorerInterface; - sourceTree = ""; - }; - 503FA74E2753F04A00BBB92A /* Tabs */ = { - isa = PBXGroup; - children = ( - 503FA74F2753F04A00BBB92A /* FLEXTabList.h */, - 503FA7502753F04A00BBB92A /* FLEXTabsViewController.m */, - 503FA7512753F04A00BBB92A /* FLEXTabList.m */, - 503FA7522753F04A00BBB92A /* FLEXTabsViewController.h */, - ); - path = Tabs; - sourceTree = ""; - }; - 503FA7572753F04A00BBB92A /* Bookmarks */ = { - isa = PBXGroup; - children = ( - 503FA7582753F04A00BBB92A /* FLEXBookmarkManager.h */, - 503FA7592753F04A00BBB92A /* FLEXBookmarksViewController.h */, - 503FA75A2753F04A00BBB92A /* FLEXBookmarkManager.m */, - 503FA75B2753F04A00BBB92A /* FLEXBookmarksViewController.m */, - ); - path = Bookmarks; - sourceTree = ""; - }; - 503FA7602753F04A00BBB92A /* GlobalStateExplorers */ = { - isa = PBXGroup; - children = ( - 503FA7612753F04A00BBB92A /* RuntimeExplore.h */, - 503FA7622753F04A00BBB92A /* Globals */, - 503FA7692753F04A00BBB92A /* FLEXObjectListViewController.h */, - 503FA76A2753F04A00BBB92A /* FLEXLiveObjectsController.m */, - 503FA76B2753F04A00BBB92A /* FLEXObjectRef.m */, - 503FA76C2753F04A00BBB92A /* FLEXWebViewController.m */, - 503FA76D2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.h */, - 503FA76E2753F04A00BBB92A /* FLEXCookiesViewController.h */, - 503FA76F2753F04A00BBB92A /* FLEXLiveObjectsController.h */, - 503FA7702753F04A00BBB92A /* FLEXObjectListViewController.m */, - 503FA7712753F04A00BBB92A /* RuntimeExplore.m */, - 503FA7722753F04A00BBB92A /* Keychain */, - 503FA77A2753F04A00BBB92A /* FLEXObjectRef.h */, - 503FA77B2753F04A00BBB92A /* FileBrowser */, - 503FA7802753F04A00BBB92A /* SystemLog */, - 503FA78E2753F04A00BBB92A /* FLEXAddressExplorerCoordinator.m */, - 503FA78F2753F04A00BBB92A /* DatabaseBrowser */, - 503FA7A52753F04A00BBB92A /* FLEXWebViewController.h */, - 503FA7A62753F04B00BBB92A /* FLEXCookiesViewController.m */, - 503FA7A72753F04B00BBB92A /* RuntimeBrowser */, - ); - path = GlobalStateExplorers; - sourceTree = ""; - }; - 503FA7622753F04A00BBB92A /* Globals */ = { - isa = PBXGroup; - children = ( - 503FA7632753F04A00BBB92A /* FLEXGlobalsEntry.m */, - 503FA7642753F04A00BBB92A /* FLEXGlobalsViewController.h */, - 503FA7652753F04A00BBB92A /* FLEXGlobalsSection.m */, - 503FA7662753F04A00BBB92A /* FLEXGlobalsEntry.h */, - 503FA7672753F04A00BBB92A /* FLEXGlobalsViewController.m */, - 503FA7682753F04A00BBB92A /* FLEXGlobalsSection.h */, - ); - path = Globals; - sourceTree = ""; - }; - 503FA7722753F04A00BBB92A /* Keychain */ = { - isa = PBXGroup; - children = ( - 503FA7732753F04A00BBB92A /* FLEXKeychain.h */, - 503FA7742753F04A00BBB92A /* FLEXKeychainViewController.m */, - 503FA7752753F04A00BBB92A /* FLEXKeychainQuery.h */, - 503FA7762753F04A00BBB92A /* SSKeychain_LICENSE */, - 503FA7772753F04A00BBB92A /* FLEXKeychain.m */, - 503FA7782753F04A00BBB92A /* FLEXKeychainViewController.h */, - 503FA7792753F04A00BBB92A /* FLEXKeychainQuery.m */, - ); - path = Keychain; - sourceTree = ""; - }; - 503FA77B2753F04A00BBB92A /* FileBrowser */ = { - isa = PBXGroup; - children = ( - 503FA77C2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.m */, - 503FA77D2753F04A00BBB92A /* FLEXFileBrowserController.m */, - 503FA77E2753F04A00BBB92A /* FLEXFileBrowserSearchOperation.h */, - 503FA77F2753F04A00BBB92A /* FLEXFileBrowserController.h */, - ); - path = FileBrowser; - sourceTree = ""; - }; - 503FA7802753F04A00BBB92A /* SystemLog */ = { - isa = PBXGroup; - children = ( - 503FA7812753F04A00BBB92A /* FLEXASLLogController.h */, - 503FA7822753F04A00BBB92A /* FLEXLogController.h */, - 503FA7832753F04A00BBB92A /* FLEXSystemLogCell.m */, - 503FA7842753F04A00BBB92A /* FLEXOSLogController.h */, - 503FA7852753F04A00BBB92A /* FLEXSystemLogViewController.m */, - 503FA7862753F04A00BBB92A /* FLEXSystemLogMessage.m */, - 503FA7872753F04A00BBB92A /* FLEXASLLogController.m */, - 503FA7882753F04A00BBB92A /* FLEXSystemLogCell.h */, - 503FA7892753F04A00BBB92A /* LLVM_LICENSE.TXT */, - 503FA78A2753F04A00BBB92A /* FLEXSystemLogViewController.h */, - 503FA78B2753F04A00BBB92A /* FLEXOSLogController.m */, - 503FA78C2753F04A00BBB92A /* ActivityStreamAPI.h */, - 503FA78D2753F04A00BBB92A /* FLEXSystemLogMessage.h */, - ); - path = SystemLog; - sourceTree = ""; - }; - 503FA78F2753F04A00BBB92A /* DatabaseBrowser */ = { - isa = PBXGroup; - children = ( - 503FA7902753F04A00BBB92A /* FLEXRealmDefines.h */, - 503FA7912753F04A00BBB92A /* FLEXTableLeftCell.m */, - 503FA7922753F04A00BBB92A /* FLEXRealmDatabaseManager.h */, - 503FA7932753F04A00BBB92A /* FLEXSQLResult.m */, - 503FA7942753F04A00BBB92A /* LICENSE */, - 503FA7952753F04A00BBB92A /* FLEXTableContentViewController.m */, - 503FA7962753F04A00BBB92A /* FLEXDBQueryRowCell.h */, - 503FA7972753F04A00BBB92A /* FLEXTableListViewController.m */, - 503FA7982753F04A00BBB92A /* FLEXTableColumnHeader.m */, - 503FA7992753F04A00BBB92A /* FLEXMultiColumnTableView.m */, - 503FA79A2753F04A00BBB92A /* FLEXSQLiteDatabaseManager.h */, - 503FA79B2753F04A00BBB92A /* FLEXTableLeftCell.h */, - 503FA79C2753F04A00BBB92A /* FLEXDatabaseManager.h */, - 503FA79D2753F04A00BBB92A /* FLEXSQLResult.h */, - 503FA79E2753F04A00BBB92A /* FLEXRealmDatabaseManager.m */, - 503FA79F2753F04A00BBB92A /* FLEXDBQueryRowCell.m */, - 503FA7A02753F04A00BBB92A /* FLEXTableContentViewController.h */, - 503FA7A12753F04A00BBB92A /* FLEXSQLiteDatabaseManager.m */, - 503FA7A22753F04A00BBB92A /* FLEXMultiColumnTableView.h */, - 503FA7A32753F04A00BBB92A /* FLEXTableColumnHeader.h */, - 503FA7A42753F04A00BBB92A /* FLEXTableListViewController.h */, - ); - path = DatabaseBrowser; - sourceTree = ""; - }; - 503FA7A72753F04B00BBB92A /* RuntimeBrowser */ = { - isa = PBXGroup; - children = ( - 503FA7A82753F04B00BBB92A /* DataSources */, - 503FA7AF2753F04B00BBB92A /* FLEXKBToolbarButton.h */, - 503FA7B02753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.h */, - 503FA7B12753F04B00BBB92A /* FLEXObjcRuntimeViewController.h */, - 503FA7B22753F04B00BBB92A /* FLEXKeyboardToolbar.h */, - 503FA7B32753F04B00BBB92A /* FLEXRuntimeKeyPath.m */, - 503FA7B42753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.m */, - 503FA7B52753F04B00BBB92A /* FLEXKeyPathSearchController.h */, - 503FA7B62753F04B00BBB92A /* FLEXSearchToken.m */, - 503FA7B72753F04B00BBB92A /* FLEXKBToolbarButton.m */, - 503FA7B82753F04B00BBB92A /* FLEXKeyboardToolbar.m */, - 503FA7B92753F04B00BBB92A /* FLEXObjcRuntimeViewController.m */, - 503FA7BA2753F04B00BBB92A /* FLEXRuntimeKeyPathTokenizer.m */, - 503FA7BB2753F04B00BBB92A /* FLEXRuntimeBrowserToolbar.h */, - 503FA7BC2753F04B00BBB92A /* FLEXRuntimeKeyPath.h */, - 503FA7BD2753F04B00BBB92A /* FLEXSearchToken.h */, - 503FA7BE2753F04B00BBB92A /* FLEXKeyPathSearchController.m */, - ); - path = RuntimeBrowser; - sourceTree = ""; - }; - 503FA7A82753F04B00BBB92A /* DataSources */ = { - isa = PBXGroup; - children = ( - 503FA7A92753F04B00BBB92A /* FLEXRuntimeController.h */, - 503FA7AA2753F04B00BBB92A /* FLEXRuntimeClient.m */, - 503FA7AB2753F04B00BBB92A /* FLEXRuntimeExporter.h */, - 503FA7AC2753F04B00BBB92A /* FLEXRuntimeClient.h */, - 503FA7AD2753F04B00BBB92A /* FLEXRuntimeController.m */, - 503FA7AE2753F04B00BBB92A /* FLEXRuntimeExporter.m */, - ); - path = DataSources; - sourceTree = ""; - }; - 503FA7BF2753F04B00BBB92A /* ViewHierarchy */ = { - isa = PBXGroup; - children = ( - 503FA7C02753F04B00BBB92A /* FLEXImagePreviewViewController.m */, - 503FA7C12753F04B00BBB92A /* SnapshotExplorer */, - 503FA7D12753F04B00BBB92A /* FLEXHierarchyViewController.h */, - 503FA7D22753F04B00BBB92A /* TreeExplorer */, - 503FA7D72753F04B00BBB92A /* FLEXImagePreviewViewController.h */, - 503FA7D82753F04B00BBB92A /* FLEXHierarchyViewController.m */, - ); - path = ViewHierarchy; - sourceTree = ""; - }; - 503FA7C12753F04B00BBB92A /* SnapshotExplorer */ = { - isa = PBXGroup; - children = ( - 503FA7C22753F04B00BBB92A /* FHSViewSnapshot.m */, - 503FA7C32753F04B00BBB92A /* FHSView.h */, - 503FA7C42753F04B00BBB92A /* FHSViewController.h */, - 503FA7C52753F04B00BBB92A /* FHSRangeSlider.m */, - 503FA7C62753F04B00BBB92A /* FHSSnapshotView.h */, - 503FA7C72753F04B00BBB92A /* FHSView.m */, - 503FA7C82753F04B00BBB92A /* FHSViewSnapshot.h */, - 503FA7C92753F04B00BBB92A /* FHSViewController.m */, - 503FA7CA2753F04B00BBB92A /* Scene */, - 503FA7CF2753F04B00BBB92A /* FHSSnapshotView.m */, - 503FA7D02753F04B00BBB92A /* FHSRangeSlider.h */, - ); - path = SnapshotExplorer; - sourceTree = ""; - }; - 503FA7CA2753F04B00BBB92A /* Scene */ = { - isa = PBXGroup; - children = ( - 503FA7CB2753F04B00BBB92A /* SceneKit+Snapshot.m */, - 503FA7CC2753F04B00BBB92A /* FHSSnapshotNodes.m */, - 503FA7CD2753F04B00BBB92A /* SceneKit+Snapshot.h */, - 503FA7CE2753F04B00BBB92A /* FHSSnapshotNodes.h */, - ); - path = Scene; - sourceTree = ""; - }; - 503FA7D22753F04B00BBB92A /* TreeExplorer */ = { - isa = PBXGroup; - children = ( - 503FA7D32753F04B00BBB92A /* FLEXHierarchyTableViewCell.m */, - 503FA7D42753F04B00BBB92A /* FLEXHierarchyTableViewController.h */, - 503FA7D52753F04B00BBB92A /* FLEXHierarchyTableViewCell.h */, - 503FA7D62753F04B00BBB92A /* FLEXHierarchyTableViewController.m */, - ); - path = TreeExplorer; - sourceTree = ""; - }; - 503FA7D92753F04B00BBB92A /* Utility */ = { - isa = PBXGroup; - children = ( - 503FA7DA2753F04B00BBB92A /* FLEXUtility.m */, - 503FA7DB2753F04B00BBB92A /* FLEXMacros.h */, - 503FA7DC2753F04B00BBB92A /* FLEXHeapEnumerator.m */, - 503FA7DD2753F04B00BBB92A /* FLEXResources.h */, - 503FA7DE2753F04B00BBB92A /* APPLE_LICENSE */, - 503FA7DF2753F04B00BBB92A /* Runtime */, - 503FA8022753F04B00BBB92A /* FLEXAlert.m */, - 503FA8032753F04B00BBB92A /* FLEXColor.h */, - 503FA8042753F04B00BBB92A /* FLEXHeapEnumerator.h */, - 503FA8052753F04B00BBB92A /* FLEXUtility.h */, - 503FA8062753F04B00BBB92A /* FLEXResources.m */, - 503FA8072753F04B00BBB92A /* FLEXColor.m */, - 503FA8082753F04B00BBB92A /* Categories */, - 503FA8302753F04B00BBB92A /* FLEXAlert.h */, - 503FA8312753F04B00BBB92A /* Keyboard */, - ); - path = Utility; - sourceTree = ""; - }; - 503FA7DF2753F04B00BBB92A /* Runtime */ = { - isa = PBXGroup; - children = ( - 503FA7E02753F04B00BBB92A /* flex_fishhook.c */, - 503FA7E12753F04B00BBB92A /* FLEXRuntimeUtility.m */, - 503FA7E22753F04B00BBB92A /* FLEXRuntimeUtility.h */, - 503FA7E32753F04B00BBB92A /* flex_fishhook.h */, - 503FA7E42753F04B00BBB92A /* Objc */, - ); - path = Runtime; - sourceTree = ""; - }; - 503FA7E42753F04B00BBB92A /* Objc */ = { - isa = PBXGroup; - children = ( - 503FA7E52753F04B00BBB92A /* FLEXRuntimeSafety.h */, - 503FA7E62753F04B00BBB92A /* FLEXTypeEncodingParser.h */, - 503FA7E72753F04B00BBB92A /* FLEXRuntimeConstants.h */, - 503FA7E82753F04B00BBB92A /* FLEXRuntimeSafety.m */, - 503FA7E92753F04B00BBB92A /* FLEXRuntimeConstants.m */, - 503FA7EA2753F04B00BBB92A /* FLEXTypeEncodingParser.m */, - 503FA7EB2753F04B00BBB92A /* FLEXObjcInternal.h */, - 503FA7EC2753F04B00BBB92A /* FLEXObjcInternal.mm */, - 503FA7ED2753F04B00BBB92A /* Reflection */, - ); - path = Objc; - sourceTree = ""; - }; - 503FA7ED2753F04B00BBB92A /* Reflection */ = { - isa = PBXGroup; - children = ( - 503FA7EE2753F04B00BBB92A /* FLEXMirror.m */, - 503FA7EF2753F04B00BBB92A /* FLEXPropertyAttributes.m */, - 503FA7F02753F04B00BBB92A /* FLEXBlockDescription.h */, - 503FA7F12753F04B00BBB92A /* FLEXProtocolBuilder.h */, - 503FA7F22753F04B00BBB92A /* FLEXProperty.m */, - 503FA7F32753F04B00BBB92A /* FLEXClassBuilder.h */, - 503FA7F42753F04B00BBB92A /* FLEXMethodBase.h */, - 503FA7F52753F04B00BBB92A /* FLEXMethod.m */, - 503FA7F62753F04B00BBB92A /* FLEXIvar.m */, - 503FA7F72753F04B00BBB92A /* FLEXProtocol.h */, - 503FA7F82753F04B00BBB92A /* FLEXProtocolBuilder.m */, - 503FA7F92753F04B00BBB92A /* FLEXBlockDescription.m */, - 503FA7FA2753F04B00BBB92A /* FLEXPropertyAttributes.h */, - 503FA7FB2753F04B00BBB92A /* FLEXMirror.h */, - 503FA7FC2753F04B00BBB92A /* FLEXClassBuilder.m */, - 503FA7FD2753F04B00BBB92A /* FLEXProperty.h */, - 503FA7FE2753F04B00BBB92A /* FLEXProtocol.m */, - 503FA7FF2753F04B00BBB92A /* FLEXIvar.h */, - 503FA8002753F04B00BBB92A /* FLEXMethod.h */, - 503FA8012753F04B00BBB92A /* FLEXMethodBase.m */, - ); - path = Reflection; - sourceTree = ""; - }; - 503FA8082753F04B00BBB92A /* Categories */ = { - isa = PBXGroup; - children = ( - 503FA8092753F04B00BBB92A /* UIGestureRecognizer+Blocks.m */, - 503FA80A2753F04B00BBB92A /* FLEXRuntime+Compare.m */, - 503FA80B2753F04B00BBB92A /* NSArray+FLEX.m */, - 503FA80C2753F04B00BBB92A /* NSObject+FLEX_Reflection.m */, - 503FA80D2753F04B00BBB92A /* UIBarButtonItem+FLEX.h */, - 503FA80E2753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.m */, - 503FA80F2753F04B00BBB92A /* NSTimer+FLEX.m */, - 503FA8102753F04B00BBB92A /* UIMenu+FLEX.m */, - 503FA8112753F04B00BBB92A /* CALayer+FLEX.h */, - 503FA8122753F04B00BBB92A /* UIPasteboard+FLEX.m */, - 503FA8132753F04B00BBB92A /* UIFont+FLEX.h */, - 503FA8142753F04B00BBB92A /* NSUserDefaults+FLEX.m */, - 503FA8152753F04B00BBB92A /* UITextField+Range.m */, - 503FA8162753F04B00BBB92A /* NSObject+FLEX_Reflection.h */, - 503FA8172753F04B00BBB92A /* NSArray+FLEX.h */, - 503FA8182753F04B00BBB92A /* FLEXRuntime+Compare.h */, - 503FA8192753F04B00BBB92A /* UIGestureRecognizer+Blocks.h */, - 503FA81A2753F04B00BBB92A /* Private */, - 503FA8272753F04B00BBB92A /* NSTimer+FLEX.h */, - 503FA8282753F04B00BBB92A /* FLEXRuntime+UIKitHelpers.h */, - 503FA8292753F04B00BBB92A /* UIBarButtonItem+FLEX.m */, - 503FA82A2753F04B00BBB92A /* UIPasteboard+FLEX.h */, - 503FA82B2753F04B00BBB92A /* UIMenu+FLEX.h */, - 503FA82C2753F04B00BBB92A /* CALayer+FLEX.m */, - 503FA82D2753F04B00BBB92A /* UITextField+Range.h */, - 503FA82E2753F04B00BBB92A /* NSUserDefaults+FLEX.h */, - 503FA82F2753F04B00BBB92A /* UIFont+FLEX.m */, - ); - path = Categories; - sourceTree = ""; - }; - 503FA81A2753F04B00BBB92A /* Private */ = { - isa = PBXGroup; - children = ( - 503FA81B2753F04B00BBB92A /* UIView+FLEX_Layout.m */, - 503FA81C2753F04B00BBB92A /* NSString+ObjcRuntime.h */, - 503FA81D2753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.h */, - 503FA81E2753F04B00BBB92A /* NSString+FLEX.h */, - 503FA81F2753F04B00BBB92A /* Cocoa+FLEXShortcuts.h */, - 503FA8202753F04B00BBB92A /* NSDictionary+ObjcRuntime.h */, - 503FA8212753F04B00BBB92A /* UIView+FLEX_Layout.h */, - 503FA8222753F04B00BBB92A /* NSMapTable+FLEX_Subscripting.m */, - 503FA8232753F04B00BBB92A /* NSString+ObjcRuntime.m */, - 503FA8242753F04B00BBB92A /* Cocoa+FLEXShortcuts.m */, - 503FA8252753F04B00BBB92A /* NSString+FLEX.m */, - 503FA8262753F04B00BBB92A /* NSDictionary+ObjcRuntime.m */, - ); - path = Private; - sourceTree = ""; - }; - 503FA8312753F04B00BBB92A /* Keyboard */ = { - isa = PBXGroup; - children = ( - 503FA8322753F04B00BBB92A /* FLEXKeyboardHelpViewController.h */, - 503FA8332753F04B00BBB92A /* FLEXKeyboardShortcutManager.m */, - 503FA8342753F04B00BBB92A /* FLEXKeyboardHelpViewController.m */, - 503FA8352753F04B00BBB92A /* FLEXKeyboardShortcutManager.h */, - ); - path = Keyboard; - sourceTree = ""; - }; 5061F3BE2806132400F3D5D3 /* CustomTabBar */ = { isa = PBXGroup; children = ( @@ -1956,273 +306,17 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 503FA8C52753F04C00BBB92A /* FLEXManager.h in Headers */, - 503FA9BB2753F04D00BBB92A /* Cocoa+FLEXShortcuts.h in Headers */, - 503FA9082753F04C00BBB92A /* FLEXViewControllersViewController.h in Headers */, - 503FA9B32753F04D00BBB92A /* NSObject+FLEX_Reflection.h in Headers */, - 503FA8782753F04B00BBB92A /* FLEXObjectExplorerViewController.h in Headers */, - 503FA8952753F04B00BBB92A /* FLEX-Categories.h in Headers */, - 503FA8E72753F04C00BBB92A /* FLEX-ObjectExploring.h in Headers */, - 503FA8A72753F04C00BBB92A /* FLEXDefaultEditorViewController.h in Headers */, - 503FA9342753F04C00BBB92A /* FLEXSystemLogCell.h in Headers */, - 503FA9382753F04C00BBB92A /* FLEXSystemLogMessage.h in Headers */, - 503FA9A32753F04D00BBB92A /* FLEXUtility.h in Headers */, - 503FA8D02753F04C00BBB92A /* FLEXRuntimeConstants.h in Headers */, - 503FA8752753F04B00BBB92A /* FLEXMutableListSection.h in Headers */, - 503FA9502753F04D00BBB92A /* FLEXRuntimeController.h in Headers */, - 5020AA4624E759390080F292 /* JGProgressHUDSuccessIndicatorView.h in Headers */, - 503FA90E2753F04C00BBB92A /* FLEXExplorerViewController.h in Headers */, - 503FA88A2753F04B00BBB92A /* FLEXNetworkSettingsController.h in Headers */, - 503FA85E2753F04B00BBB92A /* FLEXNSStringShortcuts.h in Headers */, - 503FA83C2753F04B00BBB92A /* FLEXFilteringTableViewController.h in Headers */, 50FAE060288545F600CDCEB2 /* SettingsViewController.h in Headers */, - 503FA94D2753F04D00BBB92A /* FLEXTableListViewController.h in Headers */, - 5020AA4D24E759390080F292 /* JGProgressHUDFadeAnimation.h in Headers */, - 503FA8EF2753F04C00BBB92A /* FLEXKeyValueTableViewCell.h in Headers */, - 503FA9122753F04C00BBB92A /* RuntimeExplore.h in Headers */, - 503FA8632753F04B00BBB92A /* FLEXLayerShortcuts.h in Headers */, - 503FA8DD2753F04C00BBB92A /* FLEXMethodBase.h in Headers */, - 503FA9052753F04C00BBB92A /* FLEXTabsViewController.h in Headers */, - 503FA8E52753F04C00BBB92A /* FLEXGlobalsEntry.h in Headers */, - 503FA85B2753F04B00BBB92A /* FLEXBundleShortcuts.h in Headers */, - 503FA9442753F04C00BBB92A /* FLEXTableLeftCell.h in Headers */, - 503FA8CC2753F04C00BBB92A /* UIBarButtonItem+FLEX.h in Headers */, - 503FA9002753F04C00BBB92A /* FLEXAlert.h in Headers */, - 503FA8B02753F04C00BBB92A /* FLEXArgumentInputNumberView.h in Headers */, - 503FA8D22753F04C00BBB92A /* FLEXCodeFontCell.h in Headers */, - 503FA8E02753F04C00BBB92A /* FLEXTableViewCell.h in Headers */, - 503FA87D2753F04B00BBB92A /* FLEXNetworkCurlLogger.h in Headers */, - 503FA8622753F04B00BBB92A /* FLEXUIAppShortcuts.h in Headers */, - 5020AA5024E759390080F292 /* JGProgressHUDErrorIndicatorView.h in Headers */, - 503FA99B2753F04D00BBB92A /* FLEXProperty.h in Headers */, - 503FA8962753F04B00BBB92A /* FLEX-Core.h in Headers */, - 5020AA5124E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.h in Headers */, - 503FA9842753F04D00BBB92A /* FLEXRuntimeSafety.h in Headers */, - 503FA85A2753F04B00BBB92A /* FLEXDefaultsContentSection.h in Headers */, - 503FA8542753F04B00BBB92A /* FLEXCollectionContentSection.h in Headers */, - 503FA8852753F04B00BBB92A /* FLEXNetworkTransaction.h in Headers */, - 503FA8F12753F04C00BBB92A /* NSTimer+FLEX.h in Headers */, - 503FA8EB2753F04C00BBB92A /* FLEXPropertyAttributes.h in Headers */, - 503FA8E92753F04C00BBB92A /* FLEXRuntime+Compare.h in Headers */, - 503FA8F62753F04C00BBB92A /* FLEXMutableListSection.h in Headers */, - 503FA8902753F04B00BBB92A /* OSCache.h in Headers */, - 503FA8A12753F04C00BBB92A /* FLEXFieldEditorViewController.h in Headers */, - 503FA92C2753F04C00BBB92A /* FLEXFileBrowserController.h in Headers */, - 503FA9102753F04C00BBB92A /* FLEXWindowManagerController.h in Headers */, - 503FA8F42753F04C00BBB92A /* FLEXRuntime+UIKitHelpers.h in Headers */, 505C0EBC2801ECAB0028D1C9 /* BHDownloadInlineButton.h in Headers */, - 503FA8652753F04B00BBB92A /* FLEXNSDataShortcuts.h in Headers */, - 5020AA4C24E759390080F292 /* JGProgressHUDRingIndicatorView.h in Headers */, - 503FA9012753F04C00BBB92A /* FLEXMethod.h in Headers */, - 503FA9782753F04D00BBB92A /* FLEXHierarchyTableViewCell.h in Headers */, - 503FA8C62753F04C00BBB92A /* FLEXBlockDescription.h in Headers */, - 503FA8EE2753F04C00BBB92A /* FLEXObjectExplorerFactory.h in Headers */, - 503FA8DB2753F04C00BBB92A /* UIFont+FLEX.h in Headers */, - 503FA9242753F04C00BBB92A /* FLEXKeychainQuery.h in Headers */, - 503FA8422753F04B00BBB92A /* FLEXSubtitleTableViewCell.h in Headers */, - 503FA9AE2753F04D00BBB92A /* CALayer+FLEX.h in Headers */, - 503FA8D12753F04C00BBB92A /* FLEXClassBuilder.h in Headers */, - 503FA9562753F04D00BBB92A /* FLEXKBToolbarButton.h in Headers */, - 503FA94E2753F04D00BBB92A /* FLEXWebViewController.h in Headers */, - 503FA8B72753F04C00BBB92A /* FLEXArgumentInputStringView.h in Headers */, - 503FA8762753F04B00BBB92A /* FLEXObjectInfoSection.h in Headers */, - 503FA86E2753F04B00BBB92A /* FLEXImageShortcuts.h in Headers */, - 503FA83D2753F04B00BBB92A /* FLEXNavigationController.h in Headers */, - 503FA8792753F04B00BBB92A /* FLEXObjectExplorer.h in Headers */, - 503FA92B2753F04C00BBB92A /* FLEXFileBrowserSearchOperation.h in Headers */, - 503FA8B82753F04C00BBB92A /* FLEXArgumentInputSwitchView.h in Headers */, - 503FA8922753F04B00BBB92A /* FLEXExplorerToolbar.h in Headers */, - 503FA9CD2753F04D00BBB92A /* FLEXKeyboardHelpViewController.h in Headers */, - 503FA93F2753F04C00BBB92A /* FLEXDBQueryRowCell.h in Headers */, - 503FA8E22753F04C00BBB92A /* FLEXMultilineTableViewCell.h in Headers */, - 503FA9992753F04D00BBB92A /* FLEXMirror.h in Headers */, - 503FA8432753F04B00BBB92A /* FLEXTableViewCell.h in Headers */, - 503FA9532753F04D00BBB92A /* FLEXRuntimeClient.h in Headers */, - 503FA9182753F04C00BBB92A /* FLEXGlobalsSection.h in Headers */, - 503FA9AA2753F04D00BBB92A /* UIBarButtonItem+FLEX.h in Headers */, - 503FA9452753F04C00BBB92A /* FLEXDatabaseManager.h in Headers */, - 503FA8502753F04B00BBB92A /* FLEXSingleRowSection.h in Headers */, - 503FA9522753F04D00BBB92A /* FLEXRuntimeExporter.h in Headers */, - 503FA8B22753F04C00BBB92A /* FLEXArgumentInputNotSupportedView.h in Headers */, - 503FA99D2753F04D00BBB92A /* FLEXIvar.h in Headers */, - 5020AA4924E759390080F292 /* JGProgressHUD.h in Headers */, - 503FA8E62753F04C00BBB92A /* NSObject+FLEX_Reflection.h in Headers */, - 503FA90A2753F04C00BBB92A /* FLEXBookmarkManager.h in Headers */, - 5020AA4824E759390080F292 /* JGProgressHUDIndicatorView.h in Headers */, - 503FA8FC2753F04C00BBB92A /* UITextField+Range.h in Headers */, - 503FA9B82753F04D00BBB92A /* NSString+ObjcRuntime.h in Headers */, - 503FA8CB2753F04C00BBB92A /* FLEX-Runtime.h in Headers */, - 503FA9862753F04D00BBB92A /* FLEXRuntimeConstants.h in Headers */, - 503FA8442753F04B00BBB92A /* FLEXMultilineTableViewCell.h in Headers */, - 503FA90F2753F04C00BBB92A /* FLEXWindow.h in Headers */, - 503FA88C2753F04B00BBB92A /* FLEXNetworkObserver.h in Headers */, - 503FA9C92753F04D00BBB92A /* UITextField+Range.h in Headers */, - 503FA8C12753F04C00BBB92A /* FLEXMethodCallingViewController.h in Headers */, - 503FA96D2753F04D00BBB92A /* FHSViewSnapshot.h in Headers */, - 503FA9582753F04D00BBB92A /* FLEXObjcRuntimeViewController.h in Headers */, 500DA6A826FF9D5100C020B2 /* AuthViewController.h in Headers */, - 503FA8402753F04B00BBB92A /* FLEXCodeFontCell.h in Headers */, - 503FA8F02753F04C00BBB92A /* FLEXNavigationController.h in Headers */, - 503FA8B12753F04C00BBB92A /* FLEXArgumentInputFontsPickerView.h in Headers */, - 503FA9302753F04C00BBB92A /* FLEXOSLogController.h in Headers */, - 503FA8A02753F04C00BBB92A /* FLEXVariableEditorViewController.h in Headers */, - 503FA92E2753F04C00BBB92A /* FLEXLogController.h in Headers */, - 503FA8692753F04B00BBB92A /* FLEXShortcutsSection.h in Headers */, - 503FA8FA2753F04C00BBB92A /* UIMenu+FLEX.h in Headers */, - 503FA8C92753F04C00BBB92A /* FLEXColorPreviewSection.h in Headers */, - 503FA8ED2753F04C00BBB92A /* FLEXMirror.h in Headers */, - 503FA9712753F04D00BBB92A /* SceneKit+Snapshot.h in Headers */, - 503FA8892753F04B00BBB92A /* FLEXNetworkRecorder.h in Headers */, - 503FA90B2753F04C00BBB92A /* FLEXBookmarksViewController.h in Headers */, - 503FA84B2753F04B00BBB92A /* FLEXCarouselCell.h in Headers */, - 503FA8BE2753F04C00BBB92A /* FLEXArgumentInputObjectView.h in Headers */, - 503FA93A2753F04C00BBB92A /* FLEXRealmDefines.h in Headers */, - 503FA8E82753F04C00BBB92A /* NSArray+FLEX.h in Headers */, - 503FA8872753F04B00BBB92A /* FLEXNetworkMITMViewController.h in Headers */, - 503FA99E2753F04D00BBB92A /* FLEXMethod.h in Headers */, - 503FA9A22753F04D00BBB92A /* FLEXHeapEnumerator.h in Headers */, - 503FA8372753F04B00BBB92A /* FLEXTableViewSection.h in Headers */, - 503FA9C62753F04D00BBB92A /* UIPasteboard+FLEX.h in Headers */, - 503FA98F2753F04D00BBB92A /* FLEXProtocolBuilder.h in Headers */, - 503FA8512753F04B00BBB92A /* FLEX.h in Headers */, - 503FA96B2753F04D00BBB92A /* FHSSnapshotView.h in Headers */, - 503FA8BD2753F04C00BBB92A /* FLEXArgumentInputStructView.h in Headers */, - 503FA9BA2753F04D00BBB92A /* NSString+FLEX.h in Headers */, - 503FA8F72753F04C00BBB92A /* UIPasteboard+FLEX.h in Headers */, 5020A8D824E759190080F292 /* TWHeaders.h in Headers */, - 503FA8612753F04B00BBB92A /* FLEXShortcutsFactory+Defaults.h in Headers */, - 503FA8E32753F04C00BBB92A /* FLEXProtocol.h in Headers */, - 503FA8C72753F04C00BBB92A /* FLEXMacros.h in Headers */, - 503FA8DE2753F04C00BBB92A /* FLEXObjectExplorer.h in Headers */, - 503FA95C2753F04D00BBB92A /* FLEXKeyPathSearchController.h in Headers */, - 503FA91F2753F04C00BBB92A /* FLEXLiveObjectsController.h in Headers */, - 503FA98A2753F04D00BBB92A /* FLEXObjcInternal.h in Headers */, - 503FA89C2753F04C00BBB92A /* FLEXManager+Private.h in Headers */, - 503FA8E42753F04C00BBB92A /* FLEXExplorerToolbar.h in Headers */, - 503FA8FE2753F04C00BBB92A /* NSUserDefaults+FLEX.h in Headers */, - 503FA9B42753F04D00BBB92A /* NSArray+FLEX.h in Headers */, - 5020AA4B24E759390080F292 /* JGProgressHUDPieIndicatorView.h in Headers */, - 503FA8F82753F04C00BBB92A /* FLEXObjcInternal.h in Headers */, - 503FA9922753F04D00BBB92A /* FLEXMethodBase.h in Headers */, - 503FA8F52753F04C00BBB92A /* FLEXProperty.h in Headers */, - 503FA9752753F04D00BBB92A /* FLEXHierarchyViewController.h in Headers */, - 503FA8662753F04B00BBB92A /* FLEXViewControllerShortcuts.h in Headers */, - 503FA8D92753F04C00BBB92A /* FLEXMetadataSection.h in Headers */, - 503FA8F32753F04C00BBB92A /* FLEXTableViewController.h in Headers */, - 503FA8C32753F04C00BBB92A /* FLEXRuntimeSafety.h in Headers */, - 503FA8532753F04B00BBB92A /* FLEXColorPreviewSection.h in Headers */, - 503FA94B2753F04D00BBB92A /* FLEXMultiColumnTableView.h in Headers */, - 503FA8DA2753F04C00BBB92A /* FLEX-Categories.h in Headers */, - 503FA9832753F04D00BBB92A /* flex_fishhook.h in Headers */, - 503FA89E2753F04C00BBB92A /* FLEXManager+Extensibility.h in Headers */, - 503FA92D2753F04C00BBB92A /* FLEXASLLogController.h in Headers */, - 5020AA5224E759390080F292 /* JGProgressHUDFadeZoomAnimation.h in Headers */, - 503FA89A2753F04B00BBB92A /* FLEXManager+Networking.h in Headers */, - 503FA9C32753F04D00BBB92A /* NSTimer+FLEX.h in Headers */, - 503FA8AC2753F04C00BBB92A /* FLEXArgumentInputTextView.h in Headers */, - 5020AA4A24E759390080F292 /* JGProgressHUDShadow.h in Headers */, - 503FA84A2753F04B00BBB92A /* FLEXTableView.h in Headers */, - 503FA87A2753F04B00BBB92A /* FLEXObjectExplorerFactory.h in Headers */, 50F7929128A0EA22000A2269 /* BHTBundle.h in Headers */, 5020AA6424E759590080F292 /* Colours.h in Headers */, - 503FA9632753F04D00BBB92A /* FLEXRuntimeKeyPath.h in Headers */, - 503FA9592753F04D00BBB92A /* FLEXKeyboardToolbar.h in Headers */, - 503FA9692753F04D00BBB92A /* FHSViewController.h in Headers */, - 503FA8EA2753F04C00BBB92A /* FLEXShortcutsSection.h in Headers */, 50198012250E053900207745 /* BHDownload.h in Headers */, 500DA6A526FF9CFE00C020B2 /* SAMKeychain.h in Headers */, - 503FA9192753F04C00BBB92A /* FLEXObjectListViewController.h in Headers */, - 503FA9572753F04D00BBB92A /* FLEXRuntimeKeyPathTokenizer.h in Headers */, - 503FA8A22753F04C00BBB92A /* FLEXFieldEditorView.h in Headers */, - 503FA88E2753F04B00BBB92A /* FLEXNetworkTransactionCell.h in Headers */, - 503FA9C42753F04D00BBB92A /* FLEXRuntime+UIKitHelpers.h in Headers */, - 503FA8572753F04B00BBB92A /* FLEXMetadataSection.h in Headers */, - 503FA8FB2753F04C00BBB92A /* FLEXObjectInfoSection.h in Headers */, - 503FA8CF2753F04C00BBB92A /* FLEX.h in Headers */, - 503FA9162753F04C00BBB92A /* FLEXGlobalsEntry.h in Headers */, - 503FA9D02753F04D00BBB92A /* FLEXKeyboardShortcutManager.h in Headers */, - 503FA8672753F04B00BBB92A /* FLEXShortcut.h in Headers */, - 503FA8982753F04B00BBB92A /* FLEXManager.h in Headers */, - 503FA9262753F04C00BBB92A /* FLEXKeychainViewController.h in Headers */, - 503FA97A2753F04D00BBB92A /* FLEXImagePreviewViewController.h in Headers */, - 503FA9BD2753F04D00BBB92A /* UIView+FLEX_Layout.h in Headers */, - 503FA8A42753F04C00BBB92A /* FLEXArgumentInputViewFactory.h in Headers */, - 503FA9912753F04D00BBB92A /* FLEXClassBuilder.h in Headers */, 5020A8D924E759190080F292 /* BHTManager.h in Headers */, - 503FA8FD2753F04C00BBB92A /* FLEXIvar.h in Headers */, - 503FA8EC2753F04C00BBB92A /* UIGestureRecognizer+Blocks.h in Headers */, - 503FA9492753F04D00BBB92A /* FLEXTableContentViewController.h in Headers */, - 503FA9282753F04C00BBB92A /* FLEXObjectRef.h in Headers */, - 503FA9B02753F04D00BBB92A /* UIFont+FLEX.h in Headers */, - 503FA9222753F04C00BBB92A /* FLEXKeychain.h in Headers */, - 503FA9682753F04D00BBB92A /* FHSView.h in Headers */, - 503FA8452753F04B00BBB92A /* FLEXKeyValueTableViewCell.h in Headers */, - 503FA98E2753F04D00BBB92A /* FLEXBlockDescription.h in Headers */, - 503FA8D72753F04C00BBB92A /* FLEXObjectExplorerViewController.h in Headers */, - 503FA9B52753F04D00BBB92A /* FLEXRuntime+Compare.h in Headers */, - 503FA85D2753F04B00BBB92A /* FLEXViewShortcuts.h in Headers */, - 503FA8972753F04B00BBB92A /* FLEX-ObjectExploring.h in Headers */, - 503FA91E2753F04C00BBB92A /* FLEXCookiesViewController.h in Headers */, - 503FA9BC2753F04D00BBB92A /* NSDictionary+ObjcRuntime.h in Headers */, - 503FA9C72753F04D00BBB92A /* UIMenu+FLEX.h in Headers */, - 503FA9A12753F04D00BBB92A /* FLEXColor.h in Headers */, - 5020AA4E24E759390080F292 /* JGProgressHUD-Defines.h in Headers */, - 503FA8C82753F04C00BBB92A /* FLEXProtocolBuilder.h in Headers */, - 503FA8D32753F04C00BBB92A /* FLEXTableViewSection.h in Headers */, - 503FA8F22753F04C00BBB92A /* FLEXDefaultsContentSection.h in Headers */, - 503FA8D52753F04C00BBB92A /* CALayer+FLEX.h in Headers */, - 503FA8E12753F04C00BBB92A /* FLEX-Core.h in Headers */, - 503FA8912753F04B00BBB92A /* FLEXExplorerToolbarItem.h in Headers */, - 503FA9372753F04C00BBB92A /* ActivityStreamAPI.h in Headers */, - 503FA9742753F04D00BBB92A /* FHSRangeSlider.h in Headers */, - 503FA9952753F04D00BBB92A /* FLEXProtocol.h in Headers */, - 503FA8DF2753F04C00BBB92A /* FLEXShortcut.h in Headers */, - 503FA9CA2753F04D00BBB92A /* NSUserDefaults+FLEX.h in Headers */, - 503FA91D2753F04C00BBB92A /* FLEXAddressExplorerCoordinator.h in Headers */, - 503FA8832753F04B00BBB92A /* FLEXMITMDataSource.h in Headers */, - 503FA86B2753F04B00BBB92A /* FLEXClassShortcuts.h in Headers */, - 503FA9462753F04C00BBB92A /* FLEXSQLResult.h in Headers */, - 503FA8812753F04B00BBB92A /* FLEXHTTPTransactionDetailController.h in Headers */, - 503FA9022753F04C00BBB92A /* FLEXTabList.h in Headers */, - 503FA97D2753F04D00BBB92A /* FLEXMacros.h in Headers */, - 503FA8F92753F04C00BBB92A /* FLEXManager+Extensibility.h in Headers */, - 503FA8C42753F04C00BBB92A /* FLEXExplorerToolbarItem.h in Headers */, 500DA69C26FF930A00C020B2 /* SAMKeychainQuery.h in Headers */, - 503FA9982753F04D00BBB92A /* FLEXPropertyAttributes.h in Headers */, - 503FA94C2753F04D00BBB92A /* FLEXTableColumnHeader.h in Headers */, - 503FA8AB2753F04C00BBB92A /* FLEXArgumentInputFontView.h in Headers */, - 503FA9772753F04D00BBB92A /* FLEXHierarchyTableViewController.h in Headers */, - 503FA8D82753F04C00BBB92A /* FLEXManager+Networking.h in Headers */, - 503FA8DC2753F04C00BBB92A /* FLEXTableView.h in Headers */, - 503FA9622753F04D00BBB92A /* FLEXRuntimeBrowserToolbar.h in Headers */, - 503FA9642753F04D00BBB92A /* FLEXSearchToken.h in Headers */, - 503FA9852753F04D00BBB92A /* FLEXTypeEncodingParser.h in Headers */, - 503FA84D2753F04B00BBB92A /* FLEXScopeCarousel.h in Headers */, - 503FA8D62753F04C00BBB92A /* FLEXSubtitleTableViewCell.h in Headers */, - 503FA9822753F04D00BBB92A /* FLEXRuntimeUtility.h in Headers */, - 5020AA4724E759390080F292 /* JGProgressHUDImageIndicatorView.h in Headers */, - 503FA8B52753F04C00BBB92A /* FLEXArgumentInputView.h in Headers */, - 503FA93C2753F04C00BBB92A /* FLEXRealmDatabaseManager.h in Headers */, - 503FA8CE2753F04C00BBB92A /* FLEXTypeEncodingParser.h in Headers */, - 503FA9722753F04D00BBB92A /* FHSSnapshotNodes.h in Headers */, - 503FA8362753F04B00BBB92A /* FLEX-Runtime.h in Headers */, - 503FA8CD2753F04C00BBB92A /* FLEXResources.h in Headers */, - 503FA83E2753F04B00BBB92A /* FLEXTableViewController.h in Headers */, - 503FA8CA2753F04C00BBB92A /* FLEXCollectionContentSection.h in Headers */, - 5020AA4F24E759390080F292 /* JGProgressHUDAnimation.h in Headers */, - 503FA8D42753F04C00BBB92A /* FLEXFilteringTableViewController.h in Headers */, - 503FA9352753F04C00BBB92A /* FLEXSystemLogViewController.h in Headers */, - 503FA9142753F04C00BBB92A /* FLEXGlobalsViewController.h in Headers */, 500DA6A026FF95B100C020B2 /* keychain.h in Headers */, - 503FA9B62753F04D00BBB92A /* UIGestureRecognizer+Blocks.h in Headers */, - 503FA97F2753F04D00BBB92A /* FLEXResources.h in Headers */, - 503FA8B62753F04C00BBB92A /* FLEXArgumentInputColorView.h in Headers */, - 503FA9CC2753F04D00BBB92A /* FLEXAlert.h in Headers */, - 503FA86C2753F04B00BBB92A /* FLEXBlockShortcuts.h in Headers */, - 503FA8BC2753F04C00BBB92A /* FLEXArgumentInputDateView.h in Headers */, - 503FA9432753F04C00BBB92A /* FLEXSQLiteDatabaseManager.h in Headers */, - 503FA8FF2753F04C00BBB92A /* FLEXSingleRowSection.h in Headers */, - 503FA9B92753F04D00BBB92A /* NSMapTable+FLEX_Subscripting.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2238,13 +332,16 @@ 5020A87024E758E00080F292 /* Frameworks */, 5020A87124E758E00080F292 /* Headers */, 5020A87224E758E00080F292 /* ShellScript */, - 505C0ED32803B6020028D1C9 /* ShellScript */, ); buildRules = ( ); dependencies = ( ); name = BHTwitter; + packageProductDependencies = ( + 91086147293001530011609E /* FLEX */, + 9108614A293005750011609E /* JGProgressHUD */, + ); productName = BHTwitter; productReference = 5020A87424E758E00080F292 /* BHTwitter.dylib */; productType = "com.apple.product-type.library.dynamic"; @@ -2272,6 +369,10 @@ Base, ); mainGroup = 5020A86924E758E00080F292; + packageReferences = ( + 91086146293001530011609E /* XCRemoteSwiftPackageReference "FLEX" */, + 91086149293005750011609E /* XCRemoteSwiftPackageReference "JGProgressHUD" */, + ); productRefGroup = 5020A87524E758E00080F292 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -2316,23 +417,6 @@ shellPath = /bin/sh; shellScript = "/opt/MonkeyDev/bin/md --xcbp\n"; }; - 505C0ED32803B6020028D1C9 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "# /Users/bandarhelal/Desktop/resign/resign.sh\n\n\n\n\n\n"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -2340,199 +424,19 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5020AA5924E759390080F292 /* JGProgressHUDRingIndicatorView.m in Sources */, - 503FA9232753F04C00BBB92A /* FLEXKeychainViewController.m in Sources */, - 503FA9A52753F04D00BBB92A /* FLEXColor.m in Sources */, - 503FA8682753F04B00BBB92A /* FLEXViewShortcuts.m in Sources */, - 5020AA5824E759390080F292 /* JGProgressHUDFadeAnimation.m in Sources */, - 503FA9962753F04D00BBB92A /* FLEXProtocolBuilder.m in Sources */, - 503FA87E2753F04B00BBB92A /* FLEXNetworkTransaction.m in Sources */, - 503FA9CE2753F04D00BBB92A /* FLEXKeyboardShortcutManager.m in Sources */, - 503FA9892753F04D00BBB92A /* FLEXTypeEncodingParser.m in Sources */, - 503FA9652753F04D00BBB92A /* FLEXKeyPathSearchController.m in Sources */, - 503FA84F2753F04B00BBB92A /* FLEXTableView.m in Sources */, - 503FA9802753F04D00BBB92A /* flex_fishhook.c in Sources */, - 503FA8592753F04B00BBB92A /* FLEXColorPreviewSection.m in Sources */, - 503FA85C2753F04B00BBB92A /* FLEXShortcutsSection.m in Sources */, - 503FA9A72753F04D00BBB92A /* FLEXRuntime+Compare.m in Sources */, - 503FA9B72753F04D00BBB92A /* UIView+FLEX_Layout.m in Sources */, - 503FA89F2753F04C00BBB92A /* FLEXDefaultEditorViewController.m in Sources */, - 503FA9402753F04C00BBB92A /* FLEXTableListViewController.m in Sources */, 5020A8DA24E759190080F292 /* BHTManager.m in Sources */, - 503FA87C2753F04B00BBB92A /* FLEXObjectExplorer.m in Sources */, - 503FA8882753F04B00BBB92A /* FLEXHTTPTransactionDetailController.m in Sources */, - 503FA9702753F04D00BBB92A /* FHSSnapshotNodes.m in Sources */, - 503FA83F2753F04B00BBB92A /* FLEXFilteringTableViewController.m in Sources */, - 503FA8732753F04B00BBB92A /* FLEXViewControllerShortcuts.m in Sources */, - 503FA8A92753F04C00BBB92A /* FLEXArgumentInputColorView.m in Sources */, - 503FA9C52753F04D00BBB92A /* UIBarButtonItem+FLEX.m in Sources */, - 5020AA4424E759390080F292 /* JGProgressHUDErrorIndicatorView.m in Sources */, - 503FA8992753F04B00BBB92A /* FLEXManager+Extensibility.m in Sources */, - 503FA8742753F04B00BBB92A /* FLEXNSDataShortcuts.m in Sources */, - 503FA8492753F04B00BBB92A /* FLEXTableViewCell.m in Sources */, - 503FA9212753F04C00BBB92A /* RuntimeExplore.m in Sources */, - 503FA8A82753F04C00BBB92A /* FLEXArgumentInputStringView.m in Sources */, - 503FA9602753F04D00BBB92A /* FLEXObjcRuntimeViewController.m in Sources */, - 503FA8BF2753F04C00BBB92A /* FLEXArgumentInputNotSupportedView.m in Sources */, - 503FA8C22753F04C00BBB92A /* FLEXFieldEditorView.m in Sources */, 5020AA6624E759590080F292 /* Colours.m in Sources */, - 503FA8A52753F04C00BBB92A /* FLEXFieldEditorViewController.m in Sources */, - 503FA9CF2753F04D00BBB92A /* FLEXKeyboardHelpViewController.m in Sources */, - 503FA97E2753F04D00BBB92A /* FLEXHeapEnumerator.m in Sources */, - 503FA87F2753F04B00BBB92A /* FLEXNetworkSettingsController.m in Sources */, - 503FA96A2753F04D00BBB92A /* FHSRangeSlider.m in Sources */, - 503FA9942753F04D00BBB92A /* FLEXIvar.m in Sources */, - 503FA86D2753F04B00BBB92A /* FLEXNSStringShortcuts.m in Sources */, - 503FA9AF2753F04D00BBB92A /* UIPasteboard+FLEX.m in Sources */, - 503FA94A2753F04D00BBB92A /* FLEXSQLiteDatabaseManager.m in Sources */, - 5020AA5424E759390080F292 /* JGProgressHUDImageIndicatorView.m in Sources */, - 503FA8802753F04B00BBB92A /* FLEXNetworkRecorder.m in Sources */, - 503FA9A42753F04D00BBB92A /* FLEXResources.m in Sources */, - 503FA90D2753F04C00BBB92A /* FLEXBookmarksViewController.m in Sources */, - 503FA9132753F04C00BBB92A /* FLEXGlobalsEntry.m in Sources */, - 503FA88F2753F04B00BBB92A /* OSCache.m in Sources */, - 503FA91A2753F04C00BBB92A /* FLEXLiveObjectsController.m in Sources */, - 503FA8712753F04B00BBB92A /* FLEXShortcutsFactory+Defaults.m in Sources */, - 503FA8BA2753F04C00BBB92A /* FLEXArgumentInputFontsPickerView.m in Sources */, - 503FA9472753F04C00BBB92A /* FLEXRealmDatabaseManager.m in Sources */, - 503FA83B2753F04B00BBB92A /* FLEXNavigationController.m in Sources */, - 5020AA5A24E759390080F292 /* JGProgressHUDPieIndicatorView.m in Sources */, - 503FA9062753F04C00BBB92A /* FLEXExplorerViewController.m in Sources */, - 503FA8562753F04B00BBB92A /* FLEXMutableListSection.m in Sources */, - 503FA98B2753F04D00BBB92A /* FLEXObjcInternal.mm in Sources */, - 503FA8772753F04B00BBB92A /* FLEXMetadataSection.m in Sources */, - 503FA8932753F04B00BBB92A /* FLEXExplorerToolbarItem.m in Sources */, - 503FA95E2753F04D00BBB92A /* FLEXKBToolbarButton.m in Sources */, - 503FA8382753F04B00BBB92A /* FLEXSingleRowSection.m in Sources */, - 503FA9B12753F04D00BBB92A /* NSUserDefaults+FLEX.m in Sources */, - 503FA8392753F04B00BBB92A /* FLEXTableViewSection.m in Sources */, - 503FA92A2753F04C00BBB92A /* FLEXFileBrowserController.m in Sources */, - 503FA9A92753F04D00BBB92A /* NSObject+FLEX_Reflection.m in Sources */, - 503FA8B32753F04C00BBB92A /* FLEXArgumentInputObjectView.m in Sources */, - 503FA91C2753F04C00BBB92A /* FLEXWebViewController.m in Sources */, - 503FA8552753F04B00BBB92A /* FLEXDefaultsContentSection.m in Sources */, - 5020AA5724E759390080F292 /* JGProgressHUD.m in Sources */, - 503FA9AB2753F04D00BBB92A /* FLEXRuntime+UIKitHelpers.m in Sources */, - 503FA9C22753F04D00BBB92A /* NSDictionary+ObjcRuntime.m in Sources */, - 503FA89B2753F04C00BBB92A /* FLEXManager.m in Sources */, - 503FA8AA2753F04C00BBB92A /* FLEXArgumentInputView.m in Sources */, - 503FA9872753F04D00BBB92A /* FLEXRuntimeSafety.m in Sources */, - 503FA8B92753F04C00BBB92A /* FLEXArgumentInputTextView.m in Sources */, - 503FA9272753F04C00BBB92A /* FLEXKeychainQuery.m in Sources */, - 503FA9932753F04D00BBB92A /* FLEXMethod.m in Sources */, - 503FA9C12753F04D00BBB92A /* NSString+FLEX.m in Sources */, - 503FA9A02753F04D00BBB92A /* FLEXAlert.m in Sources */, - 503FA9412753F04C00BBB92A /* FLEXTableColumnHeader.m in Sources */, - 503FA9812753F04D00BBB92A /* FLEXRuntimeUtility.m in Sources */, - 503FA90C2753F04C00BBB92A /* FLEXBookmarkManager.m in Sources */, - 503FA8522753F04B00BBB92A /* FLEXObjectExplorerFactory.m in Sources */, - 503FA9BF2753F04D00BBB92A /* NSString+ObjcRuntime.m in Sources */, - 503FA9902753F04D00BBB92A /* FLEXProperty.m in Sources */, - 503FA8B42753F04C00BBB92A /* FLEXArgumentInputFontView.m in Sources */, - 503FA96F2753F04D00BBB92A /* SceneKit+Snapshot.m in Sources */, - 5020AA4324E759390080F292 /* JGProgressHUDIndeterminateIndicatorView.m in Sources */, - 503FA88B2753F04B00BBB92A /* FLEXMITMDataSource.m in Sources */, - 503FA8472753F04B00BBB92A /* FLEXSubtitleTableViewCell.m in Sources */, - 503FA9A82753F04D00BBB92A /* NSArray+FLEX.m in Sources */, - 5020AA5324E759390080F292 /* JGProgressHUDFadeZoomAnimation.m in Sources */, - 503FA84C2753F04B00BBB92A /* FLEXScopeCarousel.m in Sources */, - 503FA9C02753F04D00BBB92A /* Cocoa+FLEXShortcuts.m in Sources */, - 503FA8582753F04B00BBB92A /* FLEXCollectionContentSection.m in Sources */, - 503FA8842753F04B00BBB92A /* FLEXNetworkTransactionCell.m in Sources */, 505C0EBE2801ED020028D1C9 /* BHDownloadInlineButton.m in Sources */, - 503FA96E2753F04D00BBB92A /* FHSViewController.m in Sources */, - 503FA9B22753F04D00BBB92A /* UITextField+Range.m in Sources */, - 503FA9AC2753F04D00BBB92A /* NSTimer+FLEX.m in Sources */, 50FAE061288545F600CDCEB2 /* SettingsViewController.m in Sources */, - 503FA99A2753F04D00BBB92A /* FLEXClassBuilder.m in Sources */, - 503FA9422753F04C00BBB92A /* FLEXMultiColumnTableView.m in Sources */, - 503FA8702753F04B00BBB92A /* FLEXUIAppShortcuts.m in Sources */, 500DA69D26FF930A00C020B2 /* SAMKeychainQuery.m in Sources */, - 503FA93D2753F04C00BBB92A /* FLEXSQLResult.m in Sources */, - 5020AA5624E759390080F292 /* JGProgressHUDIndicatorView.m in Sources */, 50198013250E053900207745 /* BHDownload.m in Sources */, 500DA6A426FF9CFE00C020B2 /* SAMKeychain.m in Sources */, - 5020AA5524E759390080F292 /* JGProgressHUDSuccessIndicatorView.m in Sources */, - 503FA9312753F04C00BBB92A /* FLEXSystemLogViewController.m in Sources */, - 503FA9322753F04C00BBB92A /* FLEXSystemLogMessage.m in Sources */, - 503FA9542753F04D00BBB92A /* FLEXRuntimeController.m in Sources */, - 503FA9CB2753F04D00BBB92A /* UIFont+FLEX.m in Sources */, 5020A88524E758E00080F292 /* BHTwitter.mm in Sources */, - 503FA8482753F04B00BBB92A /* FLEXMultilineTableViewCell.m in Sources */, - 503FA95A2753F04D00BBB92A /* FLEXRuntimeKeyPath.m in Sources */, - 503FA8642753F04B00BBB92A /* FLEXImageShortcuts.m in Sources */, - 503FA9332753F04C00BBB92A /* FLEXASLLogController.m in Sources */, - 503FA8942753F04B00BBB92A /* FLEXExplorerToolbar.m in Sources */, - 503FA8A32753F04C00BBB92A /* FLEXMethodCallingViewController.m in Sources */, - 503FA8602753F04B00BBB92A /* FLEXClassShortcuts.m in Sources */, - 503FA8462753F04B00BBB92A /* FLEXCodeFontCell.m in Sources */, - 503FA9032753F04C00BBB92A /* FLEXTabsViewController.m in Sources */, - 503FA9552753F04D00BBB92A /* FLEXRuntimeExporter.m in Sources */, - 503FA9C82753F04D00BBB92A /* CALayer+FLEX.m in Sources */, - 503FA9BE2753F04D00BBB92A /* NSMapTable+FLEX_Subscripting.m in Sources */, - 503FA95F2753F04D00BBB92A /* FLEXKeyboardToolbar.m in Sources */, - 503FA87B2753F04B00BBB92A /* FLEXObjectExplorerViewController.m in Sources */, - 503FA9972753F04D00BBB92A /* FLEXBlockDescription.m in Sources */, - 503FA9612753F04D00BBB92A /* FLEXRuntimeKeyPathTokenizer.m in Sources */, - 503FA93E2753F04C00BBB92A /* FLEXTableContentViewController.m in Sources */, - 503FA9AD2753F04D00BBB92A /* UIMenu+FLEX.m in Sources */, - 503FA99C2753F04D00BBB92A /* FLEXProtocol.m in Sources */, - 503FA9732753F04D00BBB92A /* FHSSnapshotView.m in Sources */, - 503FA8AF2753F04C00BBB92A /* FLEXArgumentInputDateView.m in Sources */, - 503FA83A2753F04B00BBB92A /* FLEXTableViewController.m in Sources */, - 503FA9152753F04C00BBB92A /* FLEXGlobalsSection.m in Sources */, - 503FA9512753F04D00BBB92A /* FLEXRuntimeClient.m in Sources */, - 503FA9042753F04C00BBB92A /* FLEXTabList.m in Sources */, 500DA6A926FF9D5100C020B2 /* AuthViewController.m in Sources */, - 503FA86F2753F04B00BBB92A /* FLEXLayerShortcuts.m in Sources */, - 503FA85F2753F04B00BBB92A /* FLEXBlockShortcuts.m in Sources */, - 503FA9362753F04C00BBB92A /* FLEXOSLogController.m in Sources */, 5061F3C02806133400F3D5D3 /* CustomTabBarViewController.swift in Sources */, - 503FA97B2753F04D00BBB92A /* FLEXHierarchyViewController.m in Sources */, - 503FA98D2753F04D00BBB92A /* FLEXPropertyAttributes.m in Sources */, - 503FA99F2753F04D00BBB92A /* FLEXMethodBase.m in Sources */, - 503FA9792753F04D00BBB92A /* FLEXHierarchyTableViewController.m in Sources */, - 503FA86A2753F04B00BBB92A /* FLEXBundleShortcuts.m in Sources */, - 503FA9252753F04C00BBB92A /* FLEXKeychain.m in Sources */, - 503FA96C2753F04D00BBB92A /* FHSView.m in Sources */, - 503FA9392753F04C00BBB92A /* FLEXAddressExplorerCoordinator.m in Sources */, 50EE4D4B286F7F70007DE117 /* BHColorThemeViewController.swift in Sources */, - 503FA8412753F04B00BBB92A /* FLEXKeyValueTableViewCell.m in Sources */, - 503FA97C2753F04D00BBB92A /* FLEXUtility.m in Sources */, - 503FA8722753F04B00BBB92A /* FLEXShortcut.m in Sources */, - 503FA8AD2753F04C00BBB92A /* FLEXArgumentInputSwitchView.m in Sources */, - 503FA9662753F04D00BBB92A /* FLEXImagePreviewViewController.m in Sources */, - 503FA91B2753F04C00BBB92A /* FLEXObjectRef.m in Sources */, - 503FA8AE2753F04C00BBB92A /* FLEXArgumentInputStructView.m in Sources */, - 503FA8822753F04B00BBB92A /* FLEXNetworkMITMViewController.m in Sources */, - 503FA8862753F04B00BBB92A /* FLEXNetworkCurlLogger.m in Sources */, - 503FA89D2753F04C00BBB92A /* FLEXManager+Networking.m in Sources */, - 503FA9202753F04C00BBB92A /* FLEXObjectListViewController.m in Sources */, - 503FA9882753F04D00BBB92A /* FLEXRuntimeConstants.m in Sources */, - 503FA95D2753F04D00BBB92A /* FLEXSearchToken.m in Sources */, - 503FA8C02753F04C00BBB92A /* FLEXArgumentInputViewFactory.m in Sources */, - 503FA95B2753F04D00BBB92A /* FLEXRuntimeBrowserToolbar.m in Sources */, - 503FA9072753F04C00BBB92A /* FLEXWindow.m in Sources */, - 503FA9672753F04D00BBB92A /* FHSViewSnapshot.m in Sources */, - 503FA94F2753F04D00BBB92A /* FLEXCookiesViewController.m in Sources */, - 5020AA4524E759390080F292 /* JGProgressHUDAnimation.m in Sources */, - 503FA8A62753F04C00BBB92A /* FLEXVariableEditorViewController.m in Sources */, - 503FA9292753F04C00BBB92A /* FLEXFileBrowserSearchOperation.m in Sources */, - 503FA88D2753F04B00BBB92A /* FLEXNetworkObserver.m in Sources */, - 503FA9482753F04D00BBB92A /* FLEXDBQueryRowCell.m in Sources */, 50F7929028A0EA22000A2269 /* BHTBundle.m in Sources */, - 5020AA5B24E759390080F292 /* JGProgressHUDShadow.m in Sources */, - 503FA9172753F04C00BBB92A /* FLEXGlobalsViewController.m in Sources */, - 503FA9762753F04D00BBB92A /* FLEXHierarchyTableViewCell.m in Sources */, - 503FA92F2753F04C00BBB92A /* FLEXSystemLogCell.m in Sources */, - 503FA84E2753F04B00BBB92A /* FLEXCarouselCell.m in Sources */, - 503FA9A62753F04D00BBB92A /* UIGestureRecognizer+Blocks.m in Sources */, - 503FA9112753F04C00BBB92A /* FLEXViewControllersViewController.m in Sources */, - 503FA8BB2753F04C00BBB92A /* FLEXArgumentInputNumberView.m in Sources */, - 503FA93B2753F04C00BBB92A /* FLEXTableLeftCell.m in Sources */, - 503FA9092753F04C00BBB92A /* FLEXWindowManagerController.m in Sources */, 500DA6A126FF95B100C020B2 /* keychain.m in Sources */, - 503FA98C2753F04D00BBB92A /* FLEXMirror.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2657,15 +561,14 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 8JMV3RHX32; + DEVELOPMENT_TEAM = 5549UW99P6; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", /opt/theos/lib, /opt/theos/vendor/lib, - /opt/theos/sdks/iPhoneOS14.4.sdk/System/Library/PrivateFrameworks, - /opt/theos/sdks/iPhoneOS15.0.sdk/System/Library/PrivateFrameworks, + /opt/theos/sdks/iPhoneOS16.0.sdk/System/Library/PrivateFrameworks, ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BHTwitter/BHTwitter-Prefix.pch"; @@ -2720,15 +623,14 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = 8JMV3RHX32; + DEVELOPMENT_TEAM = 5549UW99P6; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", /opt/theos/lib, /opt/theos/vendor/lib, - /opt/theos/sdks/iPhoneOS14.4.sdk/System/Library/PrivateFrameworks, - /opt/theos/sdks/iPhoneOS15.0.sdk/System/Library/PrivateFrameworks, + /opt/theos/sdks/iPhoneOS16.0.sdk/System/Library/PrivateFrameworks, ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BHTwitter/BHTwitter-Prefix.pch"; @@ -2796,6 +698,38 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 91086146293001530011609E /* XCRemoteSwiftPackageReference "FLEX" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/FLEXTool/FLEX"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.0.0; + }; + }; + 91086149293005750011609E /* XCRemoteSwiftPackageReference "JGProgressHUD" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/JonasGessner/JGProgressHUD"; + requirement = { + branch = master; + kind = branch; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 91086147293001530011609E /* FLEX */ = { + isa = XCSwiftPackageProductDependency; + package = 91086146293001530011609E /* XCRemoteSwiftPackageReference "FLEX" */; + productName = FLEX; + }; + 9108614A293005750011609E /* JGProgressHUD */ = { + isa = XCSwiftPackageProductDependency; + package = 91086149293005750011609E /* XCRemoteSwiftPackageReference "JGProgressHUD" */; + productName = JGProgressHUD; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = 5020A86A24E758E00080F292 /* Project object */; } diff --git a/BHTwitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/BHTwitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata index f03a5458..919434a6 100644 --- a/BHTwitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/BHTwitter.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/BHTwitter.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/BHTwitter.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..6dd446c5 --- /dev/null +++ b/BHTwitter.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,23 @@ +{ + "pins" : [ + { + "identity" : "flex", + "kind" : "remoteSourceControl", + "location" : "https://github.com/FLEXTool/FLEX", + "state" : { + "revision" : "e0acf59d06d498041f65bbea1e5914b6e4b39733", + "version" : "5.22.10" + } + }, + { + "identity" : "jgprogresshud", + "kind" : "remoteSourceControl", + "location" : "https://github.com/JonasGessner/JGProgressHUD", + "state" : { + "branch" : "master", + "revision" : "103d67f308b8c0c18926061025549af98cdfd6fc" + } + } + ], + "version" : 2 +} diff --git a/BHTwitter/BHDownloadInlineButton.m b/BHTwitter/BHDownloadInlineButton.m index 5a3ef659..69f8ee38 100644 --- a/BHTwitter/BHDownloadInlineButton.m +++ b/BHTwitter/BHDownloadInlineButton.m @@ -50,21 +50,83 @@ - (void)DownloadHandler:(UIButton *)sender { NSMutableArray *actions = [[NSMutableArray alloc] init]; [actions addObject:title]; + NSMutableArray *innerActions = [[NSMutableArray alloc] init]; + [innerActions addObject:title]; + - for (TFSTwitterEntityMedia *i in self.delegate.viewModel.entities.media) { - for (TFSTwitterEntityMediaVideoVariant *k in i.videoInfo.variants) { - if ([k.contentType isEqualToString:@"video/mp4"]) { - TFNActionItem *download = [objc_getClass("TFNActionItem") actionItemWithTitle:[BHTManager getVideoQuality:k.url] imageName:@"arrow_down_circle_stroke" action:^{ - BHDownload *DownloadManager = [[BHDownload alloc] init]; - [DownloadManager downloadFileWithURL:[NSURL URLWithString:k.url]]; - [DownloadManager setDelegate:self]; - if (!([BHTManager DirectSave])) { + if ([self.delegate.delegate isKindOfClass:objc_getClass("T1SlideshowStatusView")]) { + T1SlideshowStatusView *selectedMedia = self.delegate.delegate; + + for (TFSTwitterEntityMediaVideoVariant *video in selectedMedia.media.videoInfo.variants) { + if ([video.contentType isEqualToString:@"video/mp4"]) { + + TFNActionItem *option = [objc_getClass("TFNActionItem") actionItemWithTitle:[BHTManager getVideoQuality:video.url] imageName:@"arrow_down_circle_stroke" action:^{ + BHDownload *dwManager = [[BHDownload alloc] init]; + [dwManager downloadFileWithURL:[NSURL URLWithString:video.url]]; + [dwManager setDelegate:self]; + + if (![BHTManager DirectSave]) { self.hud = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark]; self.hud.textLabel.text = [[BHTBundle sharedBundle] localizedStringForKey:@"PROGRESS_DOWNLOADING_STATUS_TITLE"]; [self.hud showInView:topMostController().view]; } }]; - [actions addObject:download]; + + [actions addObject:option]; + } + } + } else { + if (self.delegate.viewModel.representedMediaEntities.count > 1) { + [self.delegate.viewModel.representedMediaEntities enumerateObjectsUsingBlock:^(TFSTwitterEntityMedia * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + + if (obj.mediaType == 2 || obj.mediaType == 3) { + TFNActionItem *option = [objc_getClass("TFNActionItem") actionItemWithTitle:[NSString stringWithFormat:@"Video %lu", (unsigned long)idx+1] imageName:@"arrow_down_circle_stroke" action:^{ + + for (TFSTwitterEntityMediaVideoVariant *video in obj.videoInfo.variants) { + if ([video.contentType isEqualToString:@"video/mp4"]) { + TFNActionItem *innerOption = [objc_getClass("TFNActionItem") actionItemWithTitle:[BHTManager getVideoQuality:video.url] imageName:@"arrow_down_circle_stroke" action:^{ + + BHDownload *dwManager = [[BHDownload alloc] init]; + [dwManager downloadFileWithURL:[NSURL URLWithString:video.url]]; + [dwManager setDelegate:self]; + + if (![BHTManager DirectSave]) { + self.hud = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark]; + self.hud.textLabel.text = [[BHTBundle sharedBundle] localizedStringForKey:@"PROGRESS_DOWNLOADING_STATUS_TITLE"]; + [self.hud showInView:topMostController().view]; + } + + }]; + + [innerActions addObject:innerOption]; + } + } + + TFNMenuSheetViewController *innerAlert = [[objc_getClass("TFNMenuSheetViewController") alloc] initWithActionItems:[NSArray arrayWithArray:innerActions]]; + [innerAlert tfnPresentedCustomPresentFromViewController:topMostController() animated:YES completion:nil]; + }]; + + [actions addObject:option]; + } + }]; + } else { + for (TFSTwitterEntityMediaVideoVariant *video in self.delegate.viewModel.representedMediaEntities.firstObject.videoInfo.variants) { + if ([video.contentType isEqualToString:@"video/mp4"]) { + + TFNActionItem *option = [objc_getClass("TFNActionItem") actionItemWithTitle:[BHTManager getVideoQuality:video.url] imageName:@"arrow_down_circle_stroke" action:^{ + BHDownload *dwManager = [[BHDownload alloc] init]; + [dwManager downloadFileWithURL:[NSURL URLWithString:video.url]]; + [dwManager setDelegate:self]; + + if (![BHTManager DirectSave]) { + self.hud = [JGProgressHUD progressHUDWithStyle:JGProgressHUDStyleDark]; + self.hud.textLabel.text = [[BHTBundle sharedBundle] localizedStringForKey:@"PROGRESS_DOWNLOADING_STATUS_TITLE"]; + [self.hud showInView:topMostController().view]; + } + }]; + + [actions addObject:option]; + } } } } diff --git a/BHTwitter/BHTManager.m b/BHTwitter/BHTManager.m index 960ddb97..a430a06e 100644 --- a/BHTwitter/BHTManager.m +++ b/BHTwitter/BHTManager.m @@ -83,12 +83,7 @@ + (NSString *)getVideoQuality:(NSString *)url { return [NSString stringWithFormat:@"%@x%@", q.firstObject, q.lastObject]; } + (BOOL)isVideoCell:(id )model { - TFSTwitterEntityMedia *i = model.entities.media.firstObject; - if (i.videoInfo == nil) { - return false; - } else { - return true; - } + return model.isMediaEntityVideo || model.isGIF; } + (void)save:(NSURL *)url { [[PHPhotoLibrary sharedPhotoLibrary] performChangesAndWait:^{ diff --git a/BHTwitter/BHTwitter-Bridging-Header.h b/BHTwitter/BHTwitter-Bridging-Header.h index 14ac1b95..6be3d279 100644 --- a/BHTwitter/BHTwitter-Bridging-Header.h +++ b/BHTwitter/BHTwitter-Bridging-Header.h @@ -3,3 +3,4 @@ // #import "TWHeaders.h" +#import "BHTBundle.h" diff --git a/BHTwitter/BHTwitter.xm b/BHTwitter/BHTwitter.xm index 9d72fb9f..5ad49802 100644 --- a/BHTwitter/BHTwitter.xm +++ b/BHTwitter/BHTwitter.xm @@ -758,7 +758,7 @@ %hook T1TweetComposeViewController - (void)_t1_didTapSendButton:(UIButton *)tweetButton { if ([BHTManager TweetConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -771,7 +771,7 @@ } - (void)_t1_handleTweet { if ([BHTManager TweetConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -800,7 +800,7 @@ %hook TUIFollowControl - (void)_followUser:(id)arg1 event:(id)arg2 { if ([BHTManager FollowConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -817,7 +817,7 @@ %hook TTAStatusInlineFavoriteButton - (void)didTap { if ([BHTManager LikeConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -833,7 +833,7 @@ %hook T1StatusInlineFavoriteButton - (void)didTap { if ([BHTManager LikeConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -849,7 +849,7 @@ %hook T1ImmersiveExploreCardView - (void)handleDoubleTap:(id)arg1 { if ([BHTManager LikeConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; @@ -865,7 +865,7 @@ %hook T1TweetDetailsViewController - (void)_t1_toggleFavoriteOnCurrentStatus { if ([BHTManager LikeConfirm]) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { + [%c(FLEXAlert) makeAlert:^(FLEXAlert *make) { make.message([[BHTBundle sharedBundle] localizedStringForKey:@"CONFIRM_ALERT_MESSAGE"]); make.button([[BHTBundle sharedBundle] localizedStringForKey:@"YES_BUTTON_TITLE"]).handler(^(NSArray *strings) { %orig; diff --git a/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.h b/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.h deleted file mode 100644 index f0488a17..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.h +++ /dev/null @@ -1,89 +0,0 @@ -// -// FLEXFilteringTableViewController.h -// FLEX -// -// Created by Tanner on 3/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" - -#pragma mark - FLEXTableViewFiltering -@protocol FLEXTableViewFiltering - -/// An array of visible, "filtered" sections. For example, -/// if you have 3 sections in \c allSections and the user searches -/// for something that matches rows in only one section, then -/// this property would only contain that on matching section. -@property (nonatomic, copy) NSArray *sections; -/// An array of all possible sections. Empty sections are to be removed -/// and the resulting array stored in the \c section property. Setting -/// this property should immediately set \c sections to \c nonemptySections -/// -/// Do not manually initialize this property, it will be -/// initialized for you using the result of \c makeSections. -@property (nonatomic, copy) NSArray *allSections; - -/// This computed property should filter \c allSections for assignment to \c sections -@property (nonatomic, readonly, copy) NSArray *nonemptySections; - -/// This should be able to re-initialize \c allSections -- (NSArray *)makeSections; - -@end - - -#pragma mark - FLEXFilteringTableViewController -/// A table view which implements \c UITableView* methods using arrays of -/// \c FLEXTableViewSection objects provied by a special delegate. -@interface FLEXFilteringTableViewController : FLEXTableViewController - -/// Stores the current search query. -@property (nonatomic, copy) NSString *filterText; - -/// This property is set to \c self by default. -/// -/// This property is used to power almost all of the table view's data source -/// and delegate methods automatically, including row and section filtering -/// when the user searches, 3D Touch context menus, row selection, etc. -/// -/// Setting this property will also set \c searchDelegate to that object. -@property (nonatomic, weak) id filterDelegate; - -/// Defaults to \c NO. If enabled, all filtering will be done by calling -/// \c onBackgroundQueue:thenOnMainQueue: with the UI updated on the main queue. -@property (nonatomic) BOOL filterInBackground; - -/// Defaults to \c NO. If enabled, one • will be supplied as an index title for each section. -@property (nonatomic) BOOL wantsSectionIndexTitles; - -/// Recalculates the non-empty sections and reloads the table view. -/// -/// Subclasses may override to perform additional reloading logic, -/// such as calling \c -reloadSections if needed. Be sure to call -/// \c super after any logic that would affect the appearance of -/// the table view, since the table view is reloaded last. -/// -/// Called at the end of this class's implementation of \c updateSearchResults: -- (void)reloadData; - -/// Invoke this method to call \c -reloadData on each section -/// in \c self.filterDelegate.allSections. -- (void)reloadSections; - -#pragma mark FLEXTableViewFiltering - -@property (nonatomic, copy) NSArray *sections; -@property (nonatomic, copy) NSArray *allSections; - -/// Subclasses can override to hide specific sections under certain conditions -/// if using \c self as the \c filterDelegate, as is the default. -/// -/// For example, the object explorer hides the description section when searching. -@property (nonatomic, readonly, copy) NSArray *nonemptySections; - -/// If using \c self as the \c filterDelegate, as is the default, -/// subclasses should override to provide the sections for the table view. -- (NSArray *)makeSections; - -@end diff --git a/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.m b/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.m deleted file mode 100644 index b9cd17e2..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXFilteringTableViewController.m +++ /dev/null @@ -1,209 +0,0 @@ -// -// FLEXFilteringTableViewController.m -// FLEX -// -// Created by Tanner on 3/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" -#import "FLEXTableViewSection.h" -#import "NSArray+FLEX.h" -#import "FLEXMacros.h" - -@interface FLEXFilteringTableViewController () - -@end - -@implementation FLEXFilteringTableViewController -@synthesize allSections = _allSections; - -#pragma mark - View controller lifecycle - -- (void)loadView { - [super loadView]; - - if (!self.filterDelegate) { - self.filterDelegate = self; - } else { - [self _registerCellsForReuse]; - } -} - -- (void)_registerCellsForReuse { - for (FLEXTableViewSection *section in self.filterDelegate.allSections) { - if (section.cellRegistrationMapping) { - [self.tableView registerCells:section.cellRegistrationMapping]; - } - } -} - - -#pragma mark - Public - -- (void)setFilterDelegate:(id)filterDelegate { - _filterDelegate = filterDelegate; - filterDelegate.allSections = [filterDelegate makeSections]; - - if (self.isViewLoaded) { - [self _registerCellsForReuse]; - } -} - -- (void)reloadData { - [self reloadData:self.nonemptySections]; -} - -- (void)reloadData:(NSArray *)nonemptySections { - // Recalculate displayed sections - self.filterDelegate.sections = nonemptySections; - - // Refresh table view - if (self.isViewLoaded) { - [self.tableView reloadData]; - } -} - -- (void)reloadSections { - for (FLEXTableViewSection *section in self.filterDelegate.allSections) { - [section reloadData]; - } -} - - -#pragma mark - Search - -- (void)updateSearchResults:(NSString *)newText { - NSArray *(^filter)(void) = ^NSArray *{ - self.filterText = newText; - - // Sections will adjust data based on this property - for (FLEXTableViewSection *section in self.filterDelegate.allSections) { - section.filterText = newText; - } - - return nil; - }; - - if (self.filterInBackground) { - [self onBackgroundQueue:filter thenOnMainQueue:^(NSArray *unused) { - if ([self.searchText isEqualToString:newText]) { - [self reloadData]; - } - }]; - } else { - filter(); - [self reloadData]; - } -} - - -#pragma mark Filtering - -- (NSArray *)nonemptySections { - return [self.filterDelegate.allSections flex_filtered:^BOOL(FLEXTableViewSection *section, NSUInteger idx) { - return section.numberOfRows > 0; - }]; -} - -- (NSArray *)makeSections { - return @[]; -} - -- (void)setAllSections:(NSArray *)allSections { - _allSections = allSections.copy; - // Only display nonempty sections - self.sections = self.nonemptySections; -} - -- (void)setSections:(NSArray *)sections { - // Allow sections to reload a portion of the table view at will - [sections enumerateObjectsUsingBlock:^(FLEXTableViewSection *s, NSUInteger idx, BOOL *stop) { - [s setTable:self.tableView section:idx]; - }]; - _sections = sections.copy; -} - - -#pragma mark - UITableViewDataSource - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return self.filterDelegate.sections.count; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.filterDelegate.sections[section].numberOfRows; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return self.filterDelegate.sections[section].title; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString *reuse = [self.filterDelegate.sections[indexPath.section] reuseIdentifierForRow:indexPath.row]; - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuse forIndexPath:indexPath]; - [self.filterDelegate.sections[indexPath.section] configureCell:cell forRow:indexPath.row]; - return cell; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return UITableViewAutomaticDimension; -} - -- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { - if (self.wantsSectionIndexTitles) { - return [NSArray flex_forEachUpTo:self.filterDelegate.sections.count map:^id(NSUInteger i) { - return @"⦁"; - }]; - } - - return nil; -} - - -#pragma mark - UITableViewDelegate - -- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath { - return [self.filterDelegate.sections[indexPath.section] canSelectRow:indexPath.row]; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXTableViewSection *section = self.filterDelegate.sections[indexPath.section]; - - void (^action)(UIViewController *) = [section didSelectRowAction:indexPath.row]; - UIViewController *details = [section viewControllerToPushForRow:indexPath.row]; - - if (action) { - action(self); - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - } else if (details) { - [self.navigationController pushViewController:details animated:YES]; - } else { - [NSException raise:NSInternalInconsistencyException - format:@"Row is selectable but has no action or view controller"]; - } -} - -- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - [self.filterDelegate.sections[indexPath.section] didPressInfoButtonAction:indexPath.row](self); -} - -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point __IOS_AVAILABLE(13.0) { - FLEXTableViewSection *section = self.filterDelegate.sections[indexPath.section]; - NSString *title = [section menuTitleForRow:indexPath.row]; - NSArray *menuItems = [section menuItemsForRow:indexPath.row sender:self]; - - if (menuItems.count) { - return [UIContextMenuConfiguration - configurationWithIdentifier:nil - previewProvider:nil - actionProvider:^UIMenu *(NSArray *suggestedActions) { - return [UIMenu menuWithTitle:title children:menuItems]; - } - ]; - } - - return nil; -} - -@end diff --git a/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.h b/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.h deleted file mode 100644 index f0533a8c..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXNavigationController.h -// FLEX -// -// Created by Tanner on 1/30/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXNavigationController : UINavigationController - -+ (instancetype)withRootViewController:(UIViewController *)rootVC; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.m b/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.m deleted file mode 100644 index 176e2b62..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXNavigationController.m +++ /dev/null @@ -1,196 +0,0 @@ -// -// FLEXNavigationController.m -// FLEX -// -// Created by Tanner on 1/30/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXNavigationController.h" -#import "FLEXExplorerViewController.h" -#import "FLEXTabList.h" - -@interface UINavigationController (Private) -- (void)_gestureRecognizedInteractiveHide:(UIGestureRecognizer *)sender; -@end -@interface UIPanGestureRecognizer (Private) -- (void)_setDelegate:(id)delegate; -@end - -@interface FLEXNavigationController () -@property (nonatomic, readonly) BOOL toolbarWasHidden; -@property (nonatomic) BOOL waitingToAddTab; -@property (nonatomic, readonly) BOOL canShowToolbar; -@property (nonatomic) BOOL didSetupPendingDismissButtons; -@property (nonatomic) UISwipeGestureRecognizer *navigationBarSwipeGesture; -@end - -@implementation FLEXNavigationController - -+ (instancetype)withRootViewController:(UIViewController *)rootVC { - return [[self alloc] initWithRootViewController:rootVC]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.waitingToAddTab = YES; - - // Add gesture to reveal toolbar if hidden - UITapGestureRecognizer *navbarTapGesture = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleNavigationBarTap:) - ]; - - // Don't cancel touches to work around bug on versions of iOS prior to 13 - navbarTapGesture.cancelsTouchesInView = NO; - [self.navigationBar addGestureRecognizer:navbarTapGesture]; - - // Add gesture to dismiss if not presented with a sheet style - if (@available(iOS 13, *)) { - switch (self.modalPresentationStyle) { - case UIModalPresentationAutomatic: - case UIModalPresentationPageSheet: - case UIModalPresentationFormSheet: - break; - - default: - [self addNavigationBarSwipeGesture]; - break; - } - } else { - [self addNavigationBarSwipeGesture]; - } -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - if (self.beingPresented && !self.didSetupPendingDismissButtons) { - for (UIViewController *vc in self.viewControllers) { - [self addNavigationBarItemsToViewController:vc.navigationItem]; - } - - self.didSetupPendingDismissButtons = YES; - } -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - if (self.waitingToAddTab) { - // Only add new tab if we're presented properly - if ([self.presentingViewController isKindOfClass:[FLEXExplorerViewController class]]) { - // New navigation controllers always add themselves as new tabs, - // tabs are closed by FLEXExplorerViewController - [FLEXTabList.sharedList addTab:self]; - self.waitingToAddTab = NO; - } - } -} - -- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { - [super pushViewController:viewController animated:animated]; - [self addNavigationBarItemsToViewController:viewController.navigationItem]; -} - -- (void)dismissAnimated { - // Tabs are only closed if the done button is pressed; this - // allows you to leave a tab open by dragging down to dismiss - if ([self.presentingViewController isKindOfClass:[FLEXExplorerViewController class]]) { - [FLEXTabList.sharedList closeTab:self]; - } - - [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; -} - -- (BOOL)canShowToolbar { - return self.topViewController.toolbarItems.count; -} - -- (void)addNavigationBarItemsToViewController:(UINavigationItem *)navigationItem { - if (!self.presentingViewController) { - return; - } - - // Check if a done item already exists - for (UIBarButtonItem *item in navigationItem.rightBarButtonItems) { - if (item.style == UIBarButtonItemStyleDone) { - return; - } - } - - // Give root view controllers a Done button if it does not already have one - UIBarButtonItem *done = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self - action:@selector(dismissAnimated) - ]; - - // Prepend the button if other buttons exist already - NSArray *existingItems = navigationItem.rightBarButtonItems; - if (existingItems.count) { - navigationItem.rightBarButtonItems = [@[done] arrayByAddingObjectsFromArray:existingItems]; - } else { - navigationItem.rightBarButtonItem = done; - } - - // Keeps us from calling this method again on - // the same view controllers in -viewWillAppear: - self.didSetupPendingDismissButtons = YES; -} - -- (void)addNavigationBarSwipeGesture { - UISwipeGestureRecognizer *swipe = [[UISwipeGestureRecognizer alloc] - initWithTarget:self action:@selector(handleNavigationBarSwipe:) - ]; - swipe.direction = UISwipeGestureRecognizerDirectionDown; - swipe.delegate = self; - self.navigationBarSwipeGesture = swipe; - [self.navigationBar addGestureRecognizer:swipe]; -} - -- (void)handleNavigationBarSwipe:(UISwipeGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateRecognized) { - [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; - } -} - -- (void)handleNavigationBarTap:(UIGestureRecognizer *)sender { - // Don't reveal the toolbar if we were just tapping a button - CGPoint location = [sender locationInView:self.navigationBar]; - UIView *hitView = [self.navigationBar hitTest:location withEvent:nil]; - if ([hitView isKindOfClass:[UIControl class]]) { - return; - } - - if (sender.state == UIGestureRecognizerStateRecognized) { - if (self.toolbarHidden && self.canShowToolbar) { - [self setToolbarHidden:NO animated:YES]; - } - } -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)g1 shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)g2 { - if (g1 == self.navigationBarSwipeGesture && g2 == self.barHideOnSwipeGestureRecognizer) { - return YES; - } - - return NO; -} - -- (void)_gestureRecognizedInteractiveHide:(UIPanGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateRecognized) { - BOOL show = self.canShowToolbar; - CGFloat yTranslation = [sender translationInView:self.view].y; - CGFloat yVelocity = [sender velocityInView:self.view].y; - if (yVelocity > 2000) { - [self setToolbarHidden:YES animated:YES]; - } else if (show && yTranslation > 20 && yVelocity > 250) { - [self setToolbarHidden:NO animated:YES]; - } else if (yTranslation < -20) { - [self setToolbarHidden:YES animated:YES]; - } - } -} - -@end diff --git a/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.h b/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.h deleted file mode 100644 index 762c815d..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.h +++ /dev/null @@ -1,153 +0,0 @@ -// -// FLEXTableViewController.h -// FLEX -// -// Created by Tanner on 7/5/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import "FLEXTableView.h" -@class FLEXScopeCarousel, FLEXWindow, FLEXTableViewSection; - -typedef CGFloat FLEXDebounceInterval; -/// No delay, all events delivered -extern CGFloat const kFLEXDebounceInstant; -/// Small delay which makes UI seem smoother by avoiding rapid events -extern CGFloat const kFLEXDebounceFast; -/// Slower than Fast, faster than ExpensiveIO -extern CGFloat const kFLEXDebounceForAsyncSearch; -/// The least frequent, at just over once per second; for I/O or other expensive operations -extern CGFloat const kFLEXDebounceForExpensiveIO; - -@protocol FLEXSearchResultsUpdating -/// A method to handle search query update events. -/// -/// \c searchBarDebounceInterval is used to reduce the frequency at which this -/// method is called. This method is also called when the search bar becomes -/// the first responder, and when the selected search bar scope index changes. -- (void)updateSearchResults:(NSString *)newText; -@end - -@interface FLEXTableViewController : UITableViewController < - UISearchResultsUpdating, UISearchControllerDelegate, UISearchBarDelegate -> - -/// A grouped table view. Inset on iOS 13. -/// -/// Simply calls into \c initWithStyle: -- (id)init; - -/// Subclasses may override to configure the controller before \c viewDidLoad: -- (id)initWithStyle:(UITableViewStyle)style; - -@property (nonatomic) FLEXTableView *tableView; - -/// If your subclass conforms to \c FLEXSearchResultsUpdating -/// then this property is assigned to \c self automatically. -/// -/// Setting \c filterDelegate will also set this property to that object. -@property (nonatomic, weak) id searchDelegate; - -/// Defaults to NO. -/// -/// Setting this to YES will initialize the carousel and the view. -@property (nonatomic) BOOL showsCarousel; -/// A horizontally scrolling list with functionality similar to -/// that of a search bar's scope bar. You'd want to use this when -/// you have potentially more than 4 scope options. -@property (nonatomic) FLEXScopeCarousel *carousel; - -/// Defaults to NO. -/// -/// Setting this to YES will initialize searchController and the view. -@property (nonatomic) BOOL showsSearchBar; -/// Defaults to NO. -/// -/// Setting this to YES will make the search bar appear whenever the view appears. -/// Otherwise, iOS will only show the search bar when you scroll up. -@property (nonatomic) BOOL showSearchBarInitially; -/// Defaults to NO. -/// -/// Setting this to YES will make the search bar activate whenever the view appears. -@property (nonatomic) BOOL activatesSearchBarAutomatically; - -/// nil unless showsSearchBar is set to YES. -/// -/// self is used as the default search results updater and delegate. -/// The search bar will not dim the background or hide the navigation bar by default. -/// On iOS 11 and up, the search bar will appear in the navigation bar below the title. -@property (nonatomic) UISearchController *searchController; -/// Used to initialize the search controller. Defaults to nil. -@property (nonatomic) UIViewController *searchResultsController; -/// Defaults to "Fast" -/// -/// Determines how often search bar results will be "debounced." -/// Empty query events are always sent instantly. Query events will -/// be sent when the user has not changed the query for this interval. -@property (nonatomic) FLEXDebounceInterval searchBarDebounceInterval; -/// Whether the search bar stays at the top of the view while scrolling. -/// -/// Calls into self.navigationItem.hidesSearchBarWhenScrolling. -/// Do not change self.navigationItem.hidesSearchBarWhenScrolling directly, -/// or it will not be respsected. Use this instead. -/// Defaults to NO. -@property (nonatomic) BOOL pinSearchBar; -/// By default, we will show the search bar's cancel button when -/// search becomes active and hide it when search is dismissed. -/// -/// Do not set the showsCancelButton property on the searchController's -/// searchBar manually. Set this property after turning on showsSearchBar. -/// -/// Does nothing pre-iOS 13, safe to call on any version. -@property (nonatomic) BOOL automaticallyShowsSearchBarCancelButton; - -/// If using the scope bar, self.searchController.searchBar.selectedScopeButtonIndex. -/// Otherwise, this is the selected index of the carousel, or NSNotFound if using neither. -@property (nonatomic) NSInteger selectedScope; -/// self.searchController.searchBar.text -@property (nonatomic, readonly, copy) NSString *searchText; - -/// A totally optional delegate to forward search results updater calls to. -/// If a delegate is set, updateSearchResults: is not called on this view controller. -@property (nonatomic, weak) id searchResultsUpdater; - -/// self.view.window as a \c FLEXWindow -@property (nonatomic, readonly) FLEXWindow *window; - -/// Convenient for doing some async processor-intensive searching -/// in the background before updating the UI back on the main queue. -- (void)onBackgroundQueue:(NSArray *(^)(void))backgroundBlock thenOnMainQueue:(void(^)(NSArray *))mainBlock; - -/// Adds up to 3 additional items to the toolbar in right-to-left order. -/// -/// That is, the first item in the given array will be the rightmost item behind -/// any existing toolbar items. By default, buttons for bookmarks and tabs are shown. -/// -/// If you wish to have more control over how the buttons are arranged or which -/// buttons are displayed, you can access the properties for the pre-existing -/// toolbar items directly and manually set \c self.toolbarItems by overriding -/// the \c setupToolbarItems method below. -- (void)addToolbarItems:(NSArray *)items; - -/// Subclasses may override. You should not need to call this method directly. -- (void)setupToolbarItems; - -@property (nonatomic, readonly) UIBarButtonItem *shareToolbarItem; -@property (nonatomic, readonly) UIBarButtonItem *bookmarksToolbarItem; -@property (nonatomic, readonly) UIBarButtonItem *openTabsToolbarItem; - -/// Whether or not to display the "share" icon in the middle of the toolbar. NO by default. -/// -/// Turning this on after you have added custom toolbar items will -/// push off the leftmost toolbar item and shift the others leftward. -@property (nonatomic) BOOL showsShareToolbarItem; -/// Called when the share button is pressed. -/// Default implementation does nothign. Subclasses may override. -- (void)shareButtonPressed:(UIBarButtonItem *)sender; - -/// Subclasses may call this to opt-out of all toolbar related behavior. -/// This is necessary if you want to disable the gesture which reveals the toolbar. -- (void)disableToolbar; - -@end diff --git a/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.m b/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.m deleted file mode 100644 index 896a8a1d..00000000 --- a/BHTwitter/Classes/Core/Controllers/FLEXTableViewController.m +++ /dev/null @@ -1,618 +0,0 @@ -// -// FLEXTableViewController.m -// FLEX -// -// Created by Tanner on 7/5/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" -#import "FLEXExplorerViewController.h" -#import "FLEXBookmarksViewController.h" -#import "FLEXTabsViewController.h" -#import "FLEXScopeCarousel.h" -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "FLEXResources.h" -#import "UIBarButtonItem+FLEX.h" -#import - -@interface Block : NSObject -- (void)invoke; -@end - -CGFloat const kFLEXDebounceInstant = 0.f; -CGFloat const kFLEXDebounceFast = 0.05; -CGFloat const kFLEXDebounceForAsyncSearch = 0.15; -CGFloat const kFLEXDebounceForExpensiveIO = 0.5; - -@interface FLEXTableViewController () -@property (nonatomic) NSTimer *debounceTimer; -@property (nonatomic) BOOL didInitiallyRevealSearchBar; -@property (nonatomic) UITableViewStyle style; - -@property (nonatomic) BOOL hasAppeared; -@property (nonatomic, readonly) UIView *tableHeaderViewContainer; - -@property (nonatomic, readonly) BOOL manuallyDeactivateSearchOnDisappear; - -@property (nonatomic) UIBarButtonItem *middleToolbarItem; -@property (nonatomic) UIBarButtonItem *middleLeftToolbarItem; -@property (nonatomic) UIBarButtonItem *leftmostToolbarItem; -@end - -@implementation FLEXTableViewController -@dynamic tableView; -@synthesize showsShareToolbarItem = _showsShareToolbarItem; -@synthesize tableHeaderViewContainer = _tableHeaderViewContainer; -@synthesize automaticallyShowsSearchBarCancelButton = _automaticallyShowsSearchBarCancelButton; - -#pragma mark - Initialization - -- (id)init { - if (@available(iOS 13.0, *)) { - self = [self initWithStyle:UITableViewStyleInsetGrouped]; - } else { - self = [self initWithStyle:UITableViewStyleGrouped]; - } - - return self; -} - -- (id)initWithStyle:(UITableViewStyle)style { - self = [super initWithStyle:style]; - - if (self) { - _searchBarDebounceInterval = kFLEXDebounceFast; - _showSearchBarInitially = YES; - _style = style; - _manuallyDeactivateSearchOnDisappear = ({ - NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 11; - }); - - // We will be our own search delegate if we implement this method - if ([self respondsToSelector:@selector(updateSearchResults:)]) { - self.searchDelegate = (id)self; - } - } - - return self; -} - - -#pragma mark - Public - -- (FLEXWindow *)window { - return (id)self.view.window; -} - -- (void)setShowsSearchBar:(BOOL)showsSearchBar { - if (_showsSearchBar == showsSearchBar) return; - _showsSearchBar = showsSearchBar; - - if (showsSearchBar) { - UIViewController *results = self.searchResultsController; - self.searchController = [[UISearchController alloc] initWithSearchResultsController:results]; - self.searchController.searchBar.placeholder = @"Filter"; - self.searchController.searchResultsUpdater = (id)self; - self.searchController.delegate = (id)self; - self.searchController.dimsBackgroundDuringPresentation = NO; - self.searchController.hidesNavigationBarDuringPresentation = NO; - /// Not necessary in iOS 13; remove this when iOS 13 is the minimum deployment target - self.searchController.searchBar.delegate = self; - - self.automaticallyShowsSearchBarCancelButton = YES; - - if (@available(iOS 13, *)) { - self.searchController.automaticallyShowsScopeBar = NO; - } - - [self addSearchController:self.searchController]; - } else { - // Search already shown and just set to NO, so remove it - [self removeSearchController:self.searchController]; - } -} - -- (void)setShowsCarousel:(BOOL)showsCarousel { - if (_showsCarousel == showsCarousel) return; - _showsCarousel = showsCarousel; - - if (showsCarousel) { - _carousel = ({ weakify(self) - - FLEXScopeCarousel *carousel = [FLEXScopeCarousel new]; - carousel.selectedIndexChangedAction = ^(NSInteger idx) { strongify(self); - [self.searchDelegate updateSearchResults:self.searchText]; - }; - - // UITableView won't update the header size unless you reset the header view - [carousel registerBlockForDynamicTypeChanges:^(FLEXScopeCarousel *_) { strongify(self); - [self layoutTableHeaderIfNeeded]; - }]; - - carousel; - }); - [self addCarousel:_carousel]; - } else { - // Carousel already shown and just set to NO, so remove it - [self removeCarousel:_carousel]; - } -} - -- (NSInteger)selectedScope { - if (self.searchController.searchBar.showsScopeBar) { - return self.searchController.searchBar.selectedScopeButtonIndex; - } else if (self.showsCarousel) { - return self.carousel.selectedIndex; - } else { - return 0; - } -} - -- (void)setSelectedScope:(NSInteger)selectedScope { - if (self.searchController.searchBar.showsScopeBar) { - self.searchController.searchBar.selectedScopeButtonIndex = selectedScope; - } else if (self.showsCarousel) { - self.carousel.selectedIndex = selectedScope; - } - - [self.searchDelegate updateSearchResults:self.searchText]; -} - -- (NSString *)searchText { - return self.searchController.searchBar.text; -} - -- (BOOL)automaticallyShowsSearchBarCancelButton { - if (@available(iOS 13, *)) { - return self.searchController.automaticallyShowsCancelButton; - } - - return _automaticallyShowsSearchBarCancelButton; -} - -- (void)setAutomaticallyShowsSearchBarCancelButton:(BOOL)value { - if (@available(iOS 13, *)) { - self.searchController.automaticallyShowsCancelButton = value; - } - - _automaticallyShowsSearchBarCancelButton = value; -} - -- (void)onBackgroundQueue:(NSArray *(^)(void))backgroundBlock thenOnMainQueue:(void(^)(NSArray *))mainBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSArray *items = backgroundBlock(); - dispatch_async(dispatch_get_main_queue(), ^{ - mainBlock(items); - }); - }); -} - -- (void)setsShowsShareToolbarItem:(BOOL)showsShareToolbarItem { - _showsShareToolbarItem = showsShareToolbarItem; - if (self.isViewLoaded) { - [self setupToolbarItems]; - } -} - -- (void)disableToolbar { - self.navigationController.toolbarHidden = YES; - self.navigationController.hidesBarsOnSwipe = NO; - self.toolbarItems = nil; -} - - -#pragma mark - View Controller Lifecycle - -- (void)loadView { - self.view = [FLEXTableView style:self.style]; - self.tableView.dataSource = self; - self.tableView.delegate = self; - - _shareToolbarItem = FLEXBarButtonItemSystem(Action, self, @selector(shareButtonPressed:)); - _bookmarksToolbarItem = [UIBarButtonItem - flex_itemWithImage:FLEXResources.bookmarksIcon target:self action:@selector(showBookmarks) - ]; - _openTabsToolbarItem = [UIBarButtonItem - flex_itemWithImage:FLEXResources.openTabsIcon target:self action:@selector(showTabSwitcher) - ]; - - self.leftmostToolbarItem = UIBarButtonItem.flex_fixedSpace; - self.middleLeftToolbarItem = UIBarButtonItem.flex_fixedSpace; - self.middleToolbarItem = UIBarButtonItem.flex_fixedSpace; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag; - - // Toolbar - self.navigationController.toolbarHidden = self.toolbarItems.count > 0; - self.navigationController.hidesBarsOnSwipe = YES; - - // On iOS 13, the root view controller shows it's search bar no matter what. - // Turning this off avoids some weird flash the navigation bar does when we - // toggle navigationItem.hidesSearchBarWhenScrolling on and off. The flash - // will still happen on subsequent view controllers, but we can at least - // avoid it for the root view controller - if (@available(iOS 13, *)) { - if (self.navigationController.viewControllers.firstObject == self) { - _showSearchBarInitially = NO; - } - } -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - if (@available(iOS 11.0, *)) { - // When going back, make the search bar reappear instead of hiding - if ((self.pinSearchBar || self.showSearchBarInitially) && !self.didInitiallyRevealSearchBar) { - self.navigationItem.hidesSearchBarWhenScrolling = NO; - } - } - - // Make the keyboard seem to appear faster - if (self.activatesSearchBarAutomatically) { - [self makeKeyboardAppearNow]; - } - - [self setupToolbarItems]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // Allow scrolling to collapse the search bar, only if we don't want it pinned - if (@available(iOS 11.0, *)) { - if (self.showSearchBarInitially && !self.pinSearchBar && !self.didInitiallyRevealSearchBar) { - // All this mumbo jumbo is necessary to work around a bug in iOS 13 up to 13.2 - // wherein quickly toggling navigationItem.hidesSearchBarWhenScrolling to make - // the search bar appear initially results in a bugged search bar that - // becomes transparent and floats over the screen as you scroll - [UIView animateWithDuration:0.2 animations:^{ - self.navigationItem.hidesSearchBarWhenScrolling = YES; - [self.navigationController.view setNeedsLayout]; - [self.navigationController.view layoutIfNeeded]; - }]; - } - } - - if (self.activatesSearchBarAutomatically) { - // Keyboard has appeared, now we call this as we soon present our search bar - [self removeDummyTextField]; - - // Activate the search bar - dispatch_async(dispatch_get_main_queue(), ^{ - // This doesn't work unless it's wrapped in this dispatch_async call - [self.searchController.searchBar becomeFirstResponder]; - }); - } - - // We only want to reveal the search bar when the view controller first appears. - self.didInitiallyRevealSearchBar = YES; -} - -- (void)viewWillDisappear:(BOOL)animated { - [super viewWillDisappear:animated]; - - if (self.manuallyDeactivateSearchOnDisappear && self.searchController.isActive) { - self.searchController.active = NO; - } -} - -- (void)didMoveToParentViewController:(UIViewController *)parent { - [super didMoveToParentViewController:parent]; - // Reset this since we are re-appearing under a new - // parent view controller and need to show it again - self.didInitiallyRevealSearchBar = NO; -} - - -#pragma mark - Toolbar, Public - -- (void)setupToolbarItems { - if (!self.isViewLoaded) { - return; - } - - self.toolbarItems = @[ - self.leftmostToolbarItem, - UIBarButtonItem.flex_flexibleSpace, - self.middleLeftToolbarItem, - UIBarButtonItem.flex_flexibleSpace, - self.middleToolbarItem, - UIBarButtonItem.flex_flexibleSpace, - self.bookmarksToolbarItem, - UIBarButtonItem.flex_flexibleSpace, - self.openTabsToolbarItem, - ]; - - for (UIBarButtonItem *item in self.toolbarItems) { - [item _setWidth:60]; - // This does not work for anything but fixed spaces for some reason - // item.width = 60; - } - - // Disable tabs entirely when not presented by FLEXExplorerViewController - UIViewController *presenter = self.navigationController.presentingViewController; - if (![presenter isKindOfClass:[FLEXExplorerViewController class]]) { - self.openTabsToolbarItem.enabled = NO; - } -} - -- (void)addToolbarItems:(NSArray *)items { - if (self.showsShareToolbarItem) { - // Share button is in the middle, skip middle button - if (items.count > 0) { - self.middleLeftToolbarItem = items[0]; - } - if (items.count > 1) { - self.leftmostToolbarItem = items[1]; - } - } else { - // Add buttons right-to-left - if (items.count > 0) { - self.middleToolbarItem = items[0]; - } - if (items.count > 1) { - self.middleLeftToolbarItem = items[1]; - } - if (items.count > 2) { - self.leftmostToolbarItem = items[2]; - } - } - - [self setupToolbarItems]; -} - -- (void)setShowsShareToolbarItem:(BOOL)showShare { - if (_showsShareToolbarItem != showShare) { - _showsShareToolbarItem = showShare; - - if (showShare) { - // Push out leftmost item - self.leftmostToolbarItem = self.middleLeftToolbarItem; - self.middleLeftToolbarItem = self.middleToolbarItem; - - // Use share for middle - self.middleToolbarItem = self.shareToolbarItem; - } else { - // Remove share, shift custom items rightward - self.middleToolbarItem = self.middleLeftToolbarItem; - self.middleLeftToolbarItem = self.leftmostToolbarItem; - self.leftmostToolbarItem = UIBarButtonItem.flex_fixedSpace; - } - } - - [self setupToolbarItems]; -} - -- (void)shareButtonPressed:(UIBarButtonItem *)sender { - -} - - -#pragma mark - Private - -- (void)debounce:(void(^)(void))block { - [self.debounceTimer invalidate]; - - self.debounceTimer = [NSTimer - scheduledTimerWithTimeInterval:self.searchBarDebounceInterval - target:block - selector:@selector(invoke) - userInfo:nil - repeats:NO - ]; -} - -- (void)layoutTableHeaderIfNeeded { - if (self.showsCarousel) { - self.carousel.frame = FLEXRectSetHeight( - self.carousel.frame, self.carousel.intrinsicContentSize.height - ); - } - - self.tableView.tableHeaderView = self.tableView.tableHeaderView; -} - -- (void)addCarousel:(FLEXScopeCarousel *)carousel { - if (@available(iOS 11.0, *)) { - self.tableView.tableHeaderView = carousel; - } else { - carousel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; - - CGRect frame = self.tableHeaderViewContainer.frame; - CGRect subviewFrame = carousel.frame; - subviewFrame.origin.y = 0; - - // Put the carousel below the search bar if it's already there - if (self.showsSearchBar) { - carousel.frame = subviewFrame = FLEXRectSetY( - subviewFrame, self.searchController.searchBar.frame.size.height - ); - frame.size.height += carousel.intrinsicContentSize.height; - } else { - frame.size.height = carousel.intrinsicContentSize.height; - } - - self.tableHeaderViewContainer.frame = frame; - [self.tableHeaderViewContainer addSubview:carousel]; - } - - [self layoutTableHeaderIfNeeded]; -} - -- (void)removeCarousel:(FLEXScopeCarousel *)carousel { - [carousel removeFromSuperview]; - - if (@available(iOS 11.0, *)) { - self.tableView.tableHeaderView = nil; - } else { - if (self.showsSearchBar) { - [self removeSearchController:self.searchController]; - [self addSearchController:self.searchController]; - } else { - self.tableView.tableHeaderView = nil; - _tableHeaderViewContainer = nil; - } - } -} - -- (void)addSearchController:(UISearchController *)controller { - if (@available(iOS 11.0, *)) { - self.navigationItem.searchController = controller; - } else { - controller.searchBar.autoresizingMask |= UIViewAutoresizingFlexibleBottomMargin; - [self.tableHeaderViewContainer addSubview:controller.searchBar]; - CGRect subviewFrame = controller.searchBar.frame; - CGRect frame = self.tableHeaderViewContainer.frame; - frame.size.width = MAX(frame.size.width, subviewFrame.size.width); - frame.size.height = subviewFrame.size.height; - - // Move the carousel down if it's already there - if (self.showsCarousel) { - self.carousel.frame = FLEXRectSetY( - self.carousel.frame, subviewFrame.size.height - ); - frame.size.height += self.carousel.frame.size.height; - } - - self.tableHeaderViewContainer.frame = frame; - [self layoutTableHeaderIfNeeded]; - } -} - -- (void)removeSearchController:(UISearchController *)controller { - if (@available(iOS 11.0, *)) { - self.navigationItem.searchController = nil; - } else { - [controller.searchBar removeFromSuperview]; - - if (self.showsCarousel) { -// self.carousel.frame = FLEXRectRemake(CGPointZero, self.carousel.frame.size); - [self removeCarousel:self.carousel]; - [self addCarousel:self.carousel]; - } else { - self.tableView.tableHeaderView = nil; - _tableHeaderViewContainer = nil; - } - } -} - -- (UIView *)tableHeaderViewContainer { - if (!_tableHeaderViewContainer) { - _tableHeaderViewContainer = [UIView new]; - self.tableView.tableHeaderView = self.tableHeaderViewContainer; - } - - return _tableHeaderViewContainer; -} - -- (void)showBookmarks { - UINavigationController *nav = [[UINavigationController alloc] - initWithRootViewController:[FLEXBookmarksViewController new] - ]; - [self presentViewController:nav animated:YES completion:nil]; -} - -- (void)showTabSwitcher { - UINavigationController *nav = [[UINavigationController alloc] - initWithRootViewController:[FLEXTabsViewController new] - ]; - [self presentViewController:nav animated:YES completion:nil]; -} - - -#pragma mark - Search Bar - -#pragma mark Faster keyboard - -static UITextField *kDummyTextField = nil; - -/// Make the keyboard appear instantly. We use this to make the -/// keyboard appear faster when the search bar is set to appear initially. -/// You must call \c -removeDummyTextField before your search bar is to appear. -- (void)makeKeyboardAppearNow { - if (!kDummyTextField) { - kDummyTextField = [UITextField new]; - kDummyTextField.autocorrectionType = UITextAutocorrectionTypeNo; - } - - kDummyTextField.inputAccessoryView = self.searchController.searchBar.inputAccessoryView; - [UIApplication.sharedApplication.keyWindow addSubview:kDummyTextField]; - [kDummyTextField becomeFirstResponder]; -} - -- (void)removeDummyTextField { - if (kDummyTextField.superview) { - [kDummyTextField removeFromSuperview]; - } -} - -#pragma mark UISearchResultsUpdating - -- (void)updateSearchResultsForSearchController:(UISearchController *)searchController { - [self.debounceTimer invalidate]; - NSString *text = searchController.searchBar.text; - - void (^updateSearchResults)(void) = ^{ - if (self.searchResultsUpdater) { - [self.searchResultsUpdater updateSearchResults:text]; - } else { - [self.searchDelegate updateSearchResults:text]; - } - }; - - // Only debounce if we want to, and if we have a non-empty string - // Empty string events are sent instantly - if (text.length && self.searchBarDebounceInterval > kFLEXDebounceInstant) { - [self debounce:updateSearchResults]; - } else { - updateSearchResults(); - } -} - - -#pragma mark UISearchControllerDelegate - -- (void)willPresentSearchController:(UISearchController *)searchController { - // Manually show cancel button for < iOS 13 - if (!@available(iOS 13, *) && self.automaticallyShowsSearchBarCancelButton) { - [searchController.searchBar setShowsCancelButton:YES animated:YES]; - } -} - -- (void)willDismissSearchController:(UISearchController *)searchController { - // Manually hide cancel button for < iOS 13 - if (!@available(iOS 13, *) && self.automaticallyShowsSearchBarCancelButton) { - [searchController.searchBar setShowsCancelButton:NO animated:YES]; - } -} - - -#pragma mark UISearchBarDelegate - -/// Not necessary in iOS 13; remove this when iOS 13 is the deployment target -- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope { - [self updateSearchResultsForSearchController:self.searchController]; -} - - -#pragma mark Table View - -/// Not having a title in the first section looks weird with a rounded-corner table view style -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - if (@available(iOS 13, *)) { - if (self.style == UITableViewStyleInsetGrouped) { - return @" "; - } - } - - return nil; // For plain/gropued style -} - -@end diff --git a/BHTwitter/Classes/Core/FLEXSingleRowSection.h b/BHTwitter/Classes/Core/FLEXSingleRowSection.h deleted file mode 100644 index 6b04a0e4..00000000 --- a/BHTwitter/Classes/Core/FLEXSingleRowSection.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// FLEXSingleRowSection.h -// FLEX -// -// Created by Tanner Bennett on 9/25/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" - -/// A section providing a specific single row. -/// -/// You may optionally provide a view controller to push when the row -/// is selected, or an action to perform when it is selected. -/// Which one is used first is up to the table view data source. -@interface FLEXSingleRowSection : FLEXTableViewSection - -/// @param reuseIdentifier if nil, kFLEXDefaultCell is used. -+ (instancetype)title:(NSString *)sectionTitle - reuse:(NSString *)reuseIdentifier - cell:(void(^)(__kindof UITableViewCell *cell))cellConfiguration; - -@property (nonatomic) UIViewController *pushOnSelection; -@property (nonatomic) void (^selectionAction)(UIViewController *host); -/// Called to determine whether the single row should display itself or not. -@property (nonatomic) BOOL (^filterMatcher)(NSString *filterText); - -@end diff --git a/BHTwitter/Classes/Core/FLEXSingleRowSection.m b/BHTwitter/Classes/Core/FLEXSingleRowSection.m deleted file mode 100644 index 79409412..00000000 --- a/BHTwitter/Classes/Core/FLEXSingleRowSection.m +++ /dev/null @@ -1,87 +0,0 @@ -// -// FLEXSingleRowSection.m -// FLEX -// -// Created by Tanner Bennett on 9/25/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSingleRowSection.h" -#import "FLEXTableView.h" - -@interface FLEXSingleRowSection () -@property (nonatomic, readonly) NSString *reuseIdentifier; -@property (nonatomic, readonly) void (^cellConfiguration)(__kindof UITableViewCell *cell); - -@property (nonatomic) NSString *lastTitle; -@property (nonatomic) NSString *lastSubitle; -@end - -@implementation FLEXSingleRowSection - -#pragma mark - Public - -+ (instancetype)title:(NSString *)title - reuse:(NSString *)reuse - cell:(void (^)(__kindof UITableViewCell *))config { - return [[self alloc] initWithTitle:title reuse:reuse cell:config]; -} - -- (id)initWithTitle:(NSString *)sectionTitle - reuse:(NSString *)reuseIdentifier - cell:(void (^)(__kindof UITableViewCell *))cellConfiguration { - self = [super init]; - if (self) { - _title = sectionTitle; - _reuseIdentifier = reuseIdentifier ?: kFLEXDefaultCell; - _cellConfiguration = cellConfiguration; - } - - return self; -} - -#pragma mark - Overrides - -- (NSInteger)numberOfRows { - if (self.filterMatcher && self.filterText.length) { - return self.filterMatcher(self.filterText) ? 1 : 0; - } - - return 1; -} - -- (BOOL)canSelectRow:(NSInteger)row { - return self.pushOnSelection || self.selectionAction; -} - -- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row { - return self.selectionAction; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return self.pushOnSelection; -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - return self.reuseIdentifier; -} - -- (void)configureCell:(__kindof UITableViewCell *)cell forRow:(NSInteger)row { - cell.textLabel.text = nil; - cell.detailTextLabel.text = nil; - cell.accessoryType = UITableViewCellAccessoryNone; - - self.cellConfiguration(cell); - self.lastTitle = cell.textLabel.text; - self.lastSubitle = cell.detailTextLabel.text; -} - -- (NSString *)titleForRow:(NSInteger)row { - return self.lastTitle; -} - -- (NSString *)subtitleForRow:(NSInteger)row { - return self.lastSubitle; -} - -@end diff --git a/BHTwitter/Classes/Core/FLEXTableViewSection.h b/BHTwitter/Classes/Core/FLEXTableViewSection.h deleted file mode 100644 index f43e7d7a..00000000 --- a/BHTwitter/Classes/Core/FLEXTableViewSection.h +++ /dev/null @@ -1,146 +0,0 @@ -// -// FLEXTableViewSection.h -// FLEX -// -// Created by Tanner on 1/29/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import "NSArray+FLEX.h" -@class FLEXTableView; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark FLEXTableViewSection - -/// An abstract base class for table view sections. -/// -/// Many properties or methods here return nil or some logical equivalent by default. -/// Even so, most of the methods with defaults are intended to be overriden by subclasses. -/// Some methods are not implemented at all and MUST be implemented by a subclass. -@interface FLEXTableViewSection : NSObject { - @protected - /// Unused by default, use if you want - NSString *_title; - - @private - __weak UITableView *_tableView; - NSInteger _sectionIndex; -} - -#pragma mark - Data - -/// A title to be displayed for the custom section. -/// Subclasses may override or use the \c _title ivar. -@property (nonatomic, readonly, nullable, copy) NSString *title; -/// The number of rows in this section. Subclasses must override. -/// This should not change until \c filterText is changed or \c reloadData is called. -@property (nonatomic, readonly) NSInteger numberOfRows; -/// A map of reuse identifiers to \c UITableViewCell (sub)class objects. -/// Subclasses \e may override this as necessary, but are not required to. -/// See \c FLEXTableView.h for more information. -/// @return nil by default. -@property (nonatomic, readonly, nullable) NSDictionary *cellRegistrationMapping; - -/// The section should filter itself based on the contents of this property -/// as it is set. If it is set to nil or an empty string, it should not filter. -/// Subclasses should override or observe this property and react to changes. -/// -/// It is common practice to use two arrays for the underlying model: -/// One to hold all rows, and one to hold unfiltered rows. When \c setFilterText: -/// is called, call \c super to store the new value, and re-filter your model accordingly. -@property (nonatomic, nullable) NSString *filterText; - -/// Provides an avenue for the section to refresh data or change the number of rows. -/// -/// This is called before reloading the table view itself. If your section pulls data -/// from an external data source, this is a good place to refresh that data entirely. -/// If your section does not, then it might be simpler for you to just override -/// \c setFilterText: to call \c super and call \c reloadData. -- (void)reloadData; - -/// Like \c reloadData, but optionally reloads the table view section -/// associated with this section object, if any. Do not override. -/// Do not call outside of the main thread. -- (void)reloadData:(BOOL)updateTable; - -/// Provide a table view and section index to allow the section to efficiently reload -/// its own section of the table when something changes it. The table reference is -/// held weakly, and subclasses cannot access it or the index. Call this method again -/// if the section numbers have changed since you last called it. -- (void)setTable:(UITableView *)tableView section:(NSInteger)index; - -#pragma mark - Row Selection - -/// Whether the given row should be selectable, such as if tapping the cell -/// should take the user to a new screen or trigger an action. -/// Subclasses \e may override this as necessary, but are not required to. -/// @return \c NO by default -- (BOOL)canSelectRow:(NSInteger)row; - -/// An action "future" to be triggered when the row is selected, if the row -/// supports being selected as indicated by \c canSelectRow:. Subclasses -/// must implement this in accordance with how they implement \c canSelectRow: -/// if they do not implement \c viewControllerToPushForRow: -/// @return This returns \c nil if no view controller is provided by -/// \c viewControllerToPushForRow: — otherwise it pushes that view controller -/// onto \c host.navigationController -- (nullable void(^)(__kindof UIViewController *host))didSelectRowAction:(NSInteger)row; - -/// A view controller to display when the row is selected, if the row -/// supports being selected as indicated by \c canSelectRow:. Subclasses -/// must implement this in accordance with how they implement \c canSelectRow: -/// if they do not implement \c didSelectRowAction: -/// @return \c nil by default -- (nullable UIViewController *)viewControllerToPushForRow:(NSInteger)row; - -/// Called when the accessory view's detail button is pressed. -/// @return \c nil by default. -- (nullable void(^)(__kindof UIViewController *host))didPressInfoButtonAction:(NSInteger)row; - -#pragma mark - Context Menus - -/// By default, this is the title of the row. -/// @return The title of the context menu, if any. -- (nullable NSString *)menuTitleForRow:(NSInteger)row API_AVAILABLE(ios(13.0)); -/// Protected, not intended for public use. \c menuTitleForRow: -/// already includes the value returned from this method. -/// -/// By default, this returns \c @"". Subclasses may override to -/// provide a detailed description of the target of the context menu. -- (NSString *)menuSubtitleForRow:(NSInteger)row API_AVAILABLE(ios(13.0)); -/// The context menu items, if any. Subclasses may override. -/// By default, only inludes items for \c copyMenuItemsForRow:. -- (nullable NSArray *)menuItemsForRow:(NSInteger)row sender:(UIViewController *)sender API_AVAILABLE(ios(13.0)); -/// Subclasses may override to return a list of copiable items. -/// -/// Every two elements in the list compose a key-value pair, where the key -/// should be a description of what will be copied, and the values should be -/// the strings to copy. Return an empty string as a value to show a disabled action. -- (nullable NSArray *)copyMenuItemsForRow:(NSInteger)row API_AVAILABLE(ios(13.0)); - -#pragma mark - Cell Configuration - -/// Provide a reuse identifier for the given row. Subclasses should override. -/// -/// Custom reuse identifiers should be specified in \c cellRegistrationMapping. -/// You may return any of the identifiers in \c FLEXTableView.h -/// without including them in the \c cellRegistrationMapping. -/// @return \c kFLEXDefaultCell by default. -- (NSString *)reuseIdentifierForRow:(NSInteger)row; -/// Configure a cell for the given row. Subclasses must override. -- (void)configureCell:(__kindof UITableViewCell *)cell forRow:(NSInteger)row; - -#pragma mark - External Convenience - -/// For use by whatever view controller uses your section. Not required. -/// @return An optional title. -- (nullable NSString *)titleForRow:(NSInteger)row; -/// For use by whatever view controller uses your section. Not required. -/// @return An optional subtitle. -- (nullable NSString *)subtitleForRow:(NSInteger)row; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Core/FLEXTableViewSection.m b/BHTwitter/Classes/Core/FLEXTableViewSection.m deleted file mode 100644 index 3fcd96b6..00000000 --- a/BHTwitter/Classes/Core/FLEXTableViewSection.m +++ /dev/null @@ -1,137 +0,0 @@ -// -// FLEXTableViewSection.m -// FLEX -// -// Created by Tanner on 1/29/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "UIMenu+FLEX.h" - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wincomplete-implementation" - -@implementation FLEXTableViewSection - -- (NSInteger)numberOfRows { - return 0; -} - -- (void)reloadData { } - -- (void)reloadData:(BOOL)updateTable { - [self reloadData]; - if (updateTable) { - NSIndexSet *index = [NSIndexSet indexSetWithIndex:_sectionIndex]; - [_tableView reloadSections:index withRowAnimation:UITableViewRowAnimationNone]; - } -} - -- (void)setTable:(UITableView *)tableView section:(NSInteger)index { - _tableView = tableView; - _sectionIndex = index; -} - -- (NSDictionary *)cellRegistrationMapping { - return nil; -} - -- (BOOL)canSelectRow:(NSInteger)row { return NO; } - -- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row { - UIViewController *toPush = [self viewControllerToPushForRow:row]; - if (toPush) { - return ^(UIViewController *host) { - [host.navigationController pushViewController:toPush animated:YES]; - }; - } - - return nil; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return nil; -} - -- (void (^)(__kindof UIViewController *))didPressInfoButtonAction:(NSInteger)row { - return nil; -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - return kFLEXDefaultCell; -} - -- (NSString *)menuTitleForRow:(NSInteger)row { - NSString *title = [self titleForRow:row]; - NSString *subtitle = [self menuSubtitleForRow:row]; - - if (subtitle.length) { - return [NSString stringWithFormat:@"%@\n\n%@", title, subtitle]; - } - - return title; -} - -- (NSString *)menuSubtitleForRow:(NSInteger)row { - return @""; -} - -- (NSArray *)menuItemsForRow:(NSInteger)row sender:(UIViewController *)sender API_AVAILABLE(ios(13)) { - NSArray *copyItems = [self copyMenuItemsForRow:row]; - NSAssert(copyItems.count % 2 == 0, @"copyMenuItemsForRow: should return an even list"); - - if (copyItems.count) { - NSInteger numberOfActions = copyItems.count / 2; - BOOL collapseMenu = numberOfActions > 4; - UIImage *copyIcon = [UIImage systemImageNamed:@"doc.on.doc"]; - - NSMutableArray *actions = [NSMutableArray new]; - - for (NSInteger i = 0; i < copyItems.count; i += 2) { - NSString *key = copyItems[i], *value = copyItems[i+1]; - NSString *title = collapseMenu ? key : [@"Copy " stringByAppendingString:key]; - - UIAction *copy = [UIAction - actionWithTitle:title - image:copyIcon - identifier:nil - handler:^(__kindof UIAction *action) { - UIPasteboard.generalPasteboard.string = value; - } - ]; - if (!value.length) { - copy.attributes = UIMenuElementAttributesDisabled; - } - - [actions addObject:copy]; - } - - UIMenu *copyMenu = [UIMenu - flex_inlineMenuWithTitle:@"Copy…" - image:copyIcon - children:actions - ]; - - if (collapseMenu) { - return @[[copyMenu flex_collapsed]]; - } else { - return @[copyMenu]; - } - } - - return @[]; -} - -- (NSArray *)copyMenuItemsForRow:(NSInteger)row { - return nil; -} - -- (NSString *)titleForRow:(NSInteger)row { return nil; } -- (NSString *)subtitleForRow:(NSInteger)row { return nil; } - -@end - -#pragma clang diagnostic pop diff --git a/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.h b/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.h deleted file mode 100644 index d8afbd02..00000000 --- a/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// FLEXCarouselCell.h -// FLEX -// -// Created by Tanner Bennett on 7/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXCarouselCell : UICollectionViewCell - -@property (nonatomic, copy) NSString *title; - -@end diff --git a/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.m b/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.m deleted file mode 100644 index aabfbecb..00000000 --- a/BHTwitter/Classes/Core/Views/Carousel/FLEXCarouselCell.m +++ /dev/null @@ -1,93 +0,0 @@ -// -// FLEXCarouselCell.m -// FLEX -// -// Created by Tanner Bennett on 7/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCarouselCell.h" -#import "FLEXColor.h" -#import "UIView+FLEX_Layout.h" - -@interface FLEXCarouselCell () -@property (nonatomic, readonly) UILabel *titleLabel; -@property (nonatomic, readonly) UIView *selectionIndicatorStripe; -@property (nonatomic) BOOL constraintsInstalled; -@end - -@implementation FLEXCarouselCell - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - _titleLabel = [UILabel new]; - _selectionIndicatorStripe = [UIView new]; - - self.titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleBody]; - self.selectionIndicatorStripe.backgroundColor = self.tintColor; - if (@available(iOS 10, *)) { - self.titleLabel.adjustsFontForContentSizeCategory = YES; - } - - [self.contentView addSubview:self.titleLabel]; - [self.contentView addSubview:self.selectionIndicatorStripe]; - - [self installConstraints]; - - [self updateAppearance]; - } - - return self; -} - -- (void)updateAppearance { - self.selectionIndicatorStripe.hidden = !self.selected; - - if (self.selected) { - self.titleLabel.textColor = self.tintColor; - } else { - self.titleLabel.textColor = FLEXColor.deemphasizedTextColor; - } -} - -#pragma mark Public - -- (NSString *)title { - return self.titleLabel.text; -} - -- (void)setTitle:(NSString *)title { - self.titleLabel.text = title; - [self.titleLabel sizeToFit]; - [self setNeedsLayout]; -} - -#pragma mark Overrides - -- (void)prepareForReuse { - [super prepareForReuse]; - [self updateAppearance]; -} - -- (void)installConstraints { - CGFloat stripeHeight = 2; - - self.titleLabel.translatesAutoresizingMaskIntoConstraints = NO; - self.selectionIndicatorStripe.translatesAutoresizingMaskIntoConstraints = NO; - - UIView *superview = self.contentView; - [self.titleLabel flex_pinEdgesToSuperviewWithInsets:UIEdgeInsetsMake(10, 15, 8 + stripeHeight, 15)]; - - [self.selectionIndicatorStripe.leadingAnchor constraintEqualToAnchor:superview.leadingAnchor].active = YES; - [self.selectionIndicatorStripe.bottomAnchor constraintEqualToAnchor:superview.bottomAnchor].active = YES; - [self.selectionIndicatorStripe.trailingAnchor constraintEqualToAnchor:superview.trailingAnchor].active = YES; - [self.selectionIndicatorStripe.heightAnchor constraintEqualToConstant:stripeHeight].active = YES; -} - -- (void)setSelected:(BOOL)selected { - super.selected = selected; - [self updateAppearance]; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.h b/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.h deleted file mode 100644 index fb03676f..00000000 --- a/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// FLEXScopeCarousel.h -// FLEX -// -// Created by Tanner Bennett on 7/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -/// Only use on iOS 10 and up. Requires iOS 10 APIs for calculating row sizes. -@interface FLEXScopeCarousel : UIControl - -@property (nonatomic, copy) NSArray *items; -@property (nonatomic) NSInteger selectedIndex; -@property (nonatomic) void(^selectedIndexChangedAction)(NSInteger idx); - -- (void)registerBlockForDynamicTypeChanges:(void(^)(FLEXScopeCarousel *))handler; - -@end diff --git a/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.m b/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.m deleted file mode 100644 index daf967dd..00000000 --- a/BHTwitter/Classes/Core/Views/Carousel/FLEXScopeCarousel.m +++ /dev/null @@ -1,204 +0,0 @@ -// -// FLEXScopeCarousel.m -// FLEX -// -// Created by Tanner Bennett on 7/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXScopeCarousel.h" -#import "FLEXCarouselCell.h" -#import "FLEXColor.h" -#import "FLEXMacros.h" -#import "UIView+FLEX_Layout.h" - -const CGFloat kCarouselItemSpacing = 0; -NSString * const kCarouselCellReuseIdentifier = @"kCarouselCellReuseIdentifier"; - -@interface FLEXScopeCarousel () -@property (nonatomic, readonly) UICollectionView *collectionView; -@property (nonatomic, readonly) FLEXCarouselCell *sizingCell; - -@property (nonatomic, readonly) id dynamicTypeObserver; -@property (nonatomic, readonly) NSMutableArray *dynamicTypeHandlers; - -@property (nonatomic) BOOL constraintsInstalled; -@end - -@implementation FLEXScopeCarousel - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.backgroundColor = FLEXColor.primaryBackgroundColor; - self.autoresizingMask = UIViewAutoresizingFlexibleWidth; - self.translatesAutoresizingMaskIntoConstraints = YES; - _dynamicTypeHandlers = [NSMutableArray new]; - - CGSize itemSize = CGSizeZero; - if (@available(iOS 10.0, *)) { - itemSize = UICollectionViewFlowLayoutAutomaticSize; - } - - // Collection view layout - UICollectionViewFlowLayout *layout = ({ - UICollectionViewFlowLayout *layout = [UICollectionViewFlowLayout new]; - layout.scrollDirection = UICollectionViewScrollDirectionHorizontal; - layout.sectionInset = UIEdgeInsetsZero; - layout.minimumLineSpacing = kCarouselItemSpacing; - layout.itemSize = itemSize; - layout.estimatedItemSize = itemSize; - layout; - }); - - // Collection view - _collectionView = ({ - UICollectionView *cv = [[UICollectionView alloc] - initWithFrame:CGRectZero - collectionViewLayout:layout - ]; - cv.showsHorizontalScrollIndicator = NO; - cv.backgroundColor = UIColor.clearColor; - cv.delegate = self; - cv.dataSource = self; - [cv registerClass:[FLEXCarouselCell class] forCellWithReuseIdentifier:kCarouselCellReuseIdentifier]; - - [self addSubview:cv]; - cv; - }); - - - // Sizing cell - _sizingCell = [FLEXCarouselCell new]; - self.sizingCell.title = @"NSObject"; - - // Dynamic type - weakify(self); - _dynamicTypeObserver = [NSNotificationCenter.defaultCenter - addObserverForName:UIContentSizeCategoryDidChangeNotification - object:nil queue:nil usingBlock:^(NSNotification *note) { strongify(self) - [self.collectionView setNeedsLayout]; - [self setNeedsUpdateConstraints]; - - // Notify observers - for (void (^block)(FLEXScopeCarousel *) in self.dynamicTypeHandlers) { - block(self); - } - } - ]; - } - - return self; -} - -- (void)dealloc { - [NSNotificationCenter.defaultCenter removeObserver:self.dynamicTypeObserver]; -} - -#pragma mark - Overrides - -- (void)drawRect:(CGRect)rect { - [super drawRect:rect]; - - CGFloat width = 1.f / UIScreen.mainScreen.scale; - - // Draw hairline - CGContextRef context = UIGraphicsGetCurrentContext(); - CGContextSetStrokeColorWithColor(context, FLEXColor.hairlineColor.CGColor); - CGContextSetLineWidth(context, width); - CGContextMoveToPoint(context, 0, rect.size.height - width); - CGContextAddLineToPoint(context, rect.size.width, rect.size.height - width); - CGContextStrokePath(context); -} - -+ (BOOL)requiresConstraintBasedLayout { - return YES; -} - -- (void)updateConstraints { - if (!self.constraintsInstalled) { - self.collectionView.translatesAutoresizingMaskIntoConstraints = NO; - [self.collectionView flex_pinEdgesToSuperview]; - - self.constraintsInstalled = YES; - } - - [super updateConstraints]; -} - -- (CGSize)intrinsicContentSize { - return CGSizeMake( - UIViewNoIntrinsicMetric, - [self.sizingCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height - ); -} - -#pragma mark - Public - -- (void)setItems:(NSArray *)items { - NSParameterAssert(items.count); - - _items = items.copy; - - // Refresh list, select first item initially - [self.collectionView reloadData]; - self.selectedIndex = 0; -} - -- (void)setSelectedIndex:(NSInteger)idx { - NSParameterAssert(idx < self.items.count); - - _selectedIndex = idx; - NSIndexPath *path = [NSIndexPath indexPathForItem:idx inSection:0]; - [self.collectionView selectItemAtIndexPath:path - animated:YES - scrollPosition:UICollectionViewScrollPositionCenteredHorizontally]; - [self collectionView:self.collectionView didSelectItemAtIndexPath:path]; -} - -- (void)registerBlockForDynamicTypeChanges:(void (^)(FLEXScopeCarousel *))handler { - [self.dynamicTypeHandlers addObject:handler]; -} - -#pragma mark - UICollectionView - -- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { -// if (@available(iOS 10.0, *)) { -// return UICollectionViewFlowLayoutAutomaticSize; -// } - - self.sizingCell.title = self.items[indexPath.item]; - return [self.sizingCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; -} - -- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { - return self.items.count; -} - -- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView - cellForItemAtIndexPath:(NSIndexPath *)indexPath { - FLEXCarouselCell *cell = (id)[collectionView dequeueReusableCellWithReuseIdentifier:kCarouselCellReuseIdentifier - forIndexPath:indexPath]; - cell.title = self.items[indexPath.row]; - return cell; -} - -- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { - _selectedIndex = indexPath.item; // In case self.selectedIndex didn't trigger this call - - if (self.selectedIndexChangedAction) { - self.selectedIndexChangedAction(indexPath.row); - } - - // TODO: dynamically choose a scroll position. Very wide items should - // get "Left" while smaller items should not scroll at all, unless - // they are only partially on the screen, in which case they - // should get "HorizontallyCentered" to bring them onto the screen. - // For now, everything goes to the left, as this has a similar effect. - [collectionView scrollToItemAtIndexPath:indexPath - atScrollPosition:UICollectionViewScrollPositionLeft - animated:YES]; - [self sendActionsForControlEvents:UIControlEventValueChanged]; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.h b/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.h deleted file mode 100644 index c4afbf7d..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXCodeFontCell.h -// FLEX -// -// Created by Tanner on 12/27/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMultilineTableViewCell.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXCodeFontCell : FLEXMultilineDetailTableViewCell - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.m b/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.m deleted file mode 100644 index aff17306..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXCodeFontCell.m +++ /dev/null @@ -1,34 +0,0 @@ -// -// FLEXCodeFontCell.m -// FLEX -// -// Created by Tanner on 12/27/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCodeFontCell.h" -#import "UIFont+FLEX.h" - -@implementation FLEXCodeFontCell - -- (void)postInit { - [super postInit]; - - self.titleLabel.font = UIFont.flex_codeFont; - self.subtitleLabel.font = UIFont.flex_codeFont; - - self.titleLabel.adjustsFontSizeToFitWidth = YES; - self.titleLabel.minimumScaleFactor = 0.9; - self.subtitleLabel.adjustsFontSizeToFitWidth = YES; - self.subtitleLabel.minimumScaleFactor = 0.75; - - // Disable mutli-line pre iOS 11 - if (@available(iOS 11, *)) { - self.subtitleLabel.numberOfLines = 5; - } else { - self.titleLabel.numberOfLines = 1; - self.subtitleLabel.numberOfLines = 1; - } -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.h b/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.h deleted file mode 100644 index 7e3074ca..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXKeyValueTableViewCell.h -// FLEX -// -// Created by Tanner Bennett on 1/23/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewCell.h" - -@interface FLEXKeyValueTableViewCell : FLEXTableViewCell - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.m b/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.m deleted file mode 100644 index 28ca5022..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.m +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXKeyValueTableViewCell.m -// FLEX -// -// Created by Tanner Bennett on 1/23/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXKeyValueTableViewCell.h" - -@implementation FLEXKeyValueTableViewCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - return [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.h b/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.h deleted file mode 100644 index 914cf238..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// FLEXMultilineTableViewCell.h -// FLEX -// -// Created by Ryan Olson on 2/13/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewCell.h" - -/// A cell with both labels set to be multi-line capable. -@interface FLEXMultilineTableViewCell : FLEXTableViewCell - -+ (CGFloat)preferredHeightWithAttributedText:(NSAttributedString *)attributedText - maxWidth:(CGFloat)contentViewWidth - style:(UITableViewStyle)style - showsAccessory:(BOOL)showsAccessory; - -@end - -/// A \c FLEXMultilineTableViewCell initialized with \c UITableViewCellStyleSubtitle -@interface FLEXMultilineDetailTableViewCell : FLEXMultilineTableViewCell - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.m b/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.m deleted file mode 100644 index 58f008c5..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXMultilineTableViewCell.m +++ /dev/null @@ -1,67 +0,0 @@ -// -// FLEXMultilineTableViewCell.m -// FLEX -// -// Created by Ryan Olson on 2/13/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMultilineTableViewCell.h" -#import "UIView+FLEX_Layout.h" -#import "FLEXUtility.h" - -@interface FLEXMultilineTableViewCell () -@property (nonatomic, readonly) UILabel *_titleLabel; -@property (nonatomic, readonly) UILabel *_subtitleLabel; -@property (nonatomic) BOOL constraintsUpdated; -@end - -@implementation FLEXMultilineTableViewCell - -- (void)postInit { - [super postInit]; - - self.titleLabel.numberOfLines = 0; - self.subtitleLabel.numberOfLines = 0; -} - -+ (UIEdgeInsets)labelInsets { - return UIEdgeInsetsMake(10.0, 16.0, 10.0, 8.0); -} - -+ (CGFloat)preferredHeightWithAttributedText:(NSAttributedString *)attributedText - maxWidth:(CGFloat)contentViewWidth - style:(UITableViewStyle)style - showsAccessory:(BOOL)showsAccessory { - CGFloat labelWidth = contentViewWidth; - - // Content view inset due to accessory view observed on iOS 8.1 iPhone 6. - if (showsAccessory) { - labelWidth -= 34.0; - } - - UIEdgeInsets labelInsets = [self labelInsets]; - labelWidth -= (labelInsets.left + labelInsets.right); - - CGSize constrainSize = CGSizeMake(labelWidth, CGFLOAT_MAX); - CGRect boundingBox = [attributedText - boundingRectWithSize:constrainSize - options:NSStringDrawingUsesLineFragmentOrigin - context:nil - ]; - CGFloat preferredLabelHeight = FLEXFloor(boundingBox.size.height); - CGFloat preferredCellHeight = preferredLabelHeight + labelInsets.top + labelInsets.bottom + 1.0; - - return preferredCellHeight; -} - -@end - - -@implementation FLEXMultilineDetailTableViewCell - -- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - return [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.h b/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.h deleted file mode 100644 index 26858ab8..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXSubtitleTableViewCell.h -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewCell.h" - -/// A cell initialized with \c UITableViewCellStyleSubtitle -@interface FLEXSubtitleTableViewCell : FLEXTableViewCell - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.m b/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.m deleted file mode 100644 index b1bb3ad4..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.m +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXSubtitleTableViewCell.m -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSubtitleTableViewCell.h" - -@implementation FLEXSubtitleTableViewCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - return [super initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.h b/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.h deleted file mode 100644 index 6d065988..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// FLEXTableViewCell.h -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXTableViewCell : UITableViewCell - -/// Use this instead of .textLabel -@property (nonatomic, readonly) UILabel *titleLabel; -/// Use this instead of .detailTextLabel -@property (nonatomic, readonly) UILabel *subtitleLabel; - -/// Subclasses can override this instead of initializers to -/// perform additional initialization without lots of boilerplate. -/// Remember to call super! -- (void)postInit; - -@end diff --git a/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.m b/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.m deleted file mode 100644 index ceb4752e..00000000 --- a/BHTwitter/Classes/Core/Views/Cells/FLEXTableViewCell.m +++ /dev/null @@ -1,57 +0,0 @@ -// -// FLEXTableViewCell.m -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewCell.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" -#import "FLEXTableView.h" - -@interface UITableView (Internal) -// Exists at least since iOS 5 -- (BOOL)_canPerformAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender; -- (void)_performAction:(SEL)action forCell:(UITableViewCell *)cell sender:(id)sender; -@end - -@interface UITableViewCell (Internal) -// Exists at least since iOS 5 -@property (nonatomic, readonly) FLEXTableView *_tableView; -@end - -@implementation FLEXTableViewCell - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - [self postInit]; - } - - return self; -} - -- (void)postInit { - UIFont *cellFont = UIFont.flex_defaultTableCellFont; - self.titleLabel.font = cellFont; - self.subtitleLabel.font = cellFont; - self.subtitleLabel.textColor = FLEXColor.deemphasizedTextColor; - - self.titleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - self.subtitleLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - - self.titleLabel.numberOfLines = 1; - self.subtitleLabel.numberOfLines = 1; -} - -- (UILabel *)titleLabel { - return self.textLabel; -} - -- (UILabel *)subtitleLabel { - return self.detailTextLabel; -} - -@end diff --git a/BHTwitter/Classes/Core/Views/FLEXTableView.h b/BHTwitter/Classes/Core/Views/FLEXTableView.h deleted file mode 100644 index 9479b520..00000000 --- a/BHTwitter/Classes/Core/Views/FLEXTableView.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// FLEXTableView.h -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark Reuse identifiers - -typedef NSString * FLEXTableViewCellReuseIdentifier; - -/// A regular \c FLEXTableViewCell initialized with \c UITableViewCellStyleDefault -extern FLEXTableViewCellReuseIdentifier const kFLEXDefaultCell; -/// A \c FLEXSubtitleTableViewCell initialized with \c UITableViewCellStyleSubtitle -extern FLEXTableViewCellReuseIdentifier const kFLEXDetailCell; -/// A \c FLEXMultilineTableViewCell initialized with \c UITableViewCellStyleDefault -extern FLEXTableViewCellReuseIdentifier const kFLEXMultilineCell; -/// A \c FLEXMultilineTableViewCell initialized with \c UITableViewCellStyleSubtitle -extern FLEXTableViewCellReuseIdentifier const kFLEXMultilineDetailCell; -/// A \c FLEXTableViewCell initialized with \c UITableViewCellStyleValue1 -extern FLEXTableViewCellReuseIdentifier const kFLEXKeyValueCell; -/// A \c FLEXSubtitleTableViewCell which uses monospaced fonts for both labels -extern FLEXTableViewCellReuseIdentifier const kFLEXCodeFontCell; - -#pragma mark - FLEXTableView -@interface FLEXTableView : UITableView - -+ (instancetype)flexDefaultTableView; -+ (instancetype)groupedTableView; -+ (instancetype)plainTableView; -+ (instancetype)style:(UITableViewStyle)style; - -/// You do not need to register classes for any of the default reuse identifiers above -/// (annotated as \c FLEXTableViewCellReuseIdentifier types) unless you wish to provide -/// a custom cell for any of those reuse identifiers. By default, \c FLEXTableViewCell, -/// \c FLEXSubtitleTableViewCell, and \c FLEXMultilineTableViewCell are used, respectively. -/// -/// @param registrationMapping A map of reuse identifiers to \c UITableViewCell (sub)class objects. -- (void)registerCells:(NSDictionary *)registrationMapping; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Core/Views/FLEXTableView.m b/BHTwitter/Classes/Core/Views/FLEXTableView.m deleted file mode 100644 index 09973de8..00000000 --- a/BHTwitter/Classes/Core/Views/FLEXTableView.m +++ /dev/null @@ -1,83 +0,0 @@ -// -// FLEXTableView.m -// FLEX -// -// Created by Tanner on 4/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "FLEXSubtitleTableViewCell.h" -#import "FLEXMultilineTableViewCell.h" -#import "FLEXKeyValueTableViewCell.h" -#import "FLEXCodeFontCell.h" - -FLEXTableViewCellReuseIdentifier const kFLEXDefaultCell = @"kFLEXDefaultCell"; -FLEXTableViewCellReuseIdentifier const kFLEXDetailCell = @"kFLEXDetailCell"; -FLEXTableViewCellReuseIdentifier const kFLEXMultilineCell = @"kFLEXMultilineCell"; -FLEXTableViewCellReuseIdentifier const kFLEXMultilineDetailCell = @"kFLEXMultilineDetailCell"; -FLEXTableViewCellReuseIdentifier const kFLEXKeyValueCell = @"kFLEXKeyValueCell"; -FLEXTableViewCellReuseIdentifier const kFLEXCodeFontCell = @"kFLEXCodeFontCell"; - -#pragma mark Private - -@interface UITableView (Private) -- (CGFloat)_heightForHeaderInSection:(NSInteger)section; -- (NSString *)_titleForHeaderInSection:(NSInteger)section; -@end - -@implementation FLEXTableView - -+ (instancetype)flexDefaultTableView { - if (@available(iOS 13.0, *)) { - return [[self alloc] initWithFrame:CGRectZero style:UITableViewStyleInsetGrouped]; - } else { - return [[self alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; - } -} - -#pragma mark - Initialization - -+ (id)groupedTableView { - if (@available(iOS 13.0, *)) { - return [[self alloc] initWithFrame:CGRectZero style:UITableViewStyleInsetGrouped]; - } else { - return [[self alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped]; - } -} - -+ (id)plainTableView { - return [[self alloc] initWithFrame:CGRectZero style:UITableViewStylePlain]; -} - -+ (id)style:(UITableViewStyle)style { - return [[self alloc] initWithFrame:CGRectZero style:style]; -} - -- (id)initWithFrame:(CGRect)frame style:(UITableViewStyle)style { - self = [super initWithFrame:frame style:style]; - if (self) { - [self registerCells:@{ - kFLEXDefaultCell : [FLEXTableViewCell class], - kFLEXDetailCell : [FLEXSubtitleTableViewCell class], - kFLEXMultilineCell : [FLEXMultilineTableViewCell class], - kFLEXMultilineDetailCell : [FLEXMultilineDetailTableViewCell class], - kFLEXKeyValueCell : [FLEXKeyValueTableViewCell class], - kFLEXCodeFontCell : [FLEXCodeFontCell class], - }]; - } - - return self; -} - - -#pragma mark - Public - -- (void)registerCells:(NSDictionary *)registrationMapping { - [registrationMapping enumerateKeysAndObjectsUsingBlock:^(NSString *identifier, Class cellClass, BOOL *stop) { - [self registerClass:cellClass forCellReuseIdentifier:identifier]; - }]; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h deleted file mode 100644 index 961caa12..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputColorView.h -// Flipboard -// -// Created by Ryan Olson on 6/30/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputColorView : FLEXArgumentInputView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m deleted file mode 100644 index 7f101302..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputColorView.m +++ /dev/null @@ -1,311 +0,0 @@ -// -// FLEXArgumentInputColorView.m -// Flipboard -// -// Created by Ryan Olson on 6/30/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputColorView.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" - -@protocol FLEXColorComponentInputViewDelegate; - -@interface FLEXColorComponentInputView : UIView - -@property (nonatomic) UISlider *slider; -@property (nonatomic) UILabel *valueLabel; - -@property (nonatomic, weak) id delegate; - -@end - -@protocol FLEXColorComponentInputViewDelegate - -- (void)colorComponentInputViewValueDidChange:(FLEXColorComponentInputView *)colorComponentInputView; - -@end - - -@implementation FLEXColorComponentInputView - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.slider = [UISlider new]; - [self.slider addTarget:self action:@selector(sliderChanged:) forControlEvents:UIControlEventValueChanged]; - [self addSubview:self.slider]; - - self.valueLabel = [UILabel new]; - self.valueLabel.backgroundColor = self.backgroundColor; - self.valueLabel.font = [UIFont systemFontOfSize:14.0]; - self.valueLabel.textAlignment = NSTextAlignmentRight; - [self addSubview:self.valueLabel]; - - [self updateValueLabel]; - } - return self; -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - self.slider.backgroundColor = backgroundColor; - self.valueLabel.backgroundColor = backgroundColor; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - const CGFloat kValueLabelWidth = 50.0; - - [self.slider sizeToFit]; - CGFloat sliderWidth = self.bounds.size.width - kValueLabelWidth; - self.slider.frame = CGRectMake(0, 0, sliderWidth, self.slider.frame.size.height); - - [self.valueLabel sizeToFit]; - CGFloat valueLabelOriginX = CGRectGetMaxX(self.slider.frame); - CGFloat valueLabelOriginY = FLEXFloor((self.slider.frame.size.height - self.valueLabel.frame.size.height) / 2.0); - self.valueLabel.frame = CGRectMake(valueLabelOriginX, valueLabelOriginY, kValueLabelWidth, self.valueLabel.frame.size.height); -} - -- (void)sliderChanged:(id)sender { - [self.delegate colorComponentInputViewValueDidChange:self]; - [self updateValueLabel]; -} - -- (void)updateValueLabel { - self.valueLabel.text = [NSString stringWithFormat:@"%.3f", self.slider.value]; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat height = [self.slider sizeThatFits:size].height; - return CGSizeMake(size.width, height); -} - -@end - -@interface FLEXColorPreviewBox : UIView - -@property (nonatomic) UIColor *color; - -@property (nonatomic) UIView *colorOverlayView; - -@end - -@implementation FLEXColorPreviewBox - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.layer.borderWidth = 1.0; - self.layer.borderColor = UIColor.blackColor.CGColor; - self.backgroundColor = [UIColor colorWithPatternImage:[[self class] backgroundPatternImage]]; - - self.colorOverlayView = [[UIView alloc] initWithFrame:self.bounds]; - self.colorOverlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.colorOverlayView.backgroundColor = UIColor.clearColor; - [self addSubview:self.colorOverlayView]; - } - return self; -} - -- (void)setColor:(UIColor *)color { - self.colorOverlayView.backgroundColor = color; -} - -- (UIColor *)color { - return self.colorOverlayView.backgroundColor; -} - -+ (UIImage *)backgroundPatternImage { - const CGFloat kSquareDimension = 5.0; - CGSize squareSize = CGSizeMake(kSquareDimension, kSquareDimension); - CGSize imageSize = CGSizeMake(2.0 * kSquareDimension, 2.0 * kSquareDimension); - - UIGraphicsBeginImageContextWithOptions(imageSize, YES, UIScreen.mainScreen.scale); - - [UIColor.whiteColor setFill]; - UIRectFill(CGRectMake(0, 0, imageSize.width, imageSize.height)); - - [UIColor.grayColor setFill]; - UIRectFill(CGRectMake(squareSize.width, 0, squareSize.width, squareSize.height)); - UIRectFill(CGRectMake(0, squareSize.height, squareSize.width, squareSize.height)); - - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - return image; -} - -@end - -@interface FLEXArgumentInputColorView () - -@property (nonatomic) FLEXColorPreviewBox *colorPreviewBox; -@property (nonatomic) UILabel *hexLabel; -@property (nonatomic) FLEXColorComponentInputView *alphaInput; -@property (nonatomic) FLEXColorComponentInputView *redInput; -@property (nonatomic) FLEXColorComponentInputView *greenInput; -@property (nonatomic) FLEXColorComponentInputView *blueInput; - -@end - -@implementation FLEXArgumentInputColorView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.colorPreviewBox = [FLEXColorPreviewBox new]; - [self addSubview:self.colorPreviewBox]; - - self.hexLabel = [UILabel new]; - self.hexLabel.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9]; - self.hexLabel.textAlignment = NSTextAlignmentCenter; - self.hexLabel.font = [UIFont systemFontOfSize:12.0]; - [self addSubview:self.hexLabel]; - - self.alphaInput = [FLEXColorComponentInputView new]; - self.alphaInput.slider.minimumTrackTintColor = UIColor.blackColor; - self.alphaInput.delegate = self; - [self addSubview:self.alphaInput]; - - self.redInput = [FLEXColorComponentInputView new]; - self.redInput.slider.minimumTrackTintColor = UIColor.redColor; - self.redInput.delegate = self; - [self addSubview:self.redInput]; - - self.greenInput = [FLEXColorComponentInputView new]; - self.greenInput.slider.minimumTrackTintColor = UIColor.greenColor; - self.greenInput.delegate = self; - [self addSubview:self.greenInput]; - - self.blueInput = [FLEXColorComponentInputView new]; - self.blueInput.slider.minimumTrackTintColor = UIColor.blueColor; - self.blueInput.delegate = self; - [self addSubview:self.blueInput]; - } - return self; -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - self.alphaInput.backgroundColor = backgroundColor; - self.redInput.backgroundColor = backgroundColor; - self.greenInput.backgroundColor = backgroundColor; - self.blueInput.backgroundColor = backgroundColor; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat runningOriginY = 0; - CGSize constrainSize = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX); - - self.colorPreviewBox.frame = CGRectMake(0, runningOriginY, self.bounds.size.width, [[self class] colorPreviewBoxHeight]); - runningOriginY = CGRectGetMaxY(self.colorPreviewBox.frame) + [[self class] inputViewVerticalPadding]; - - [self.hexLabel sizeToFit]; - const CGFloat kLabelVerticalOutsetAmount = 0.0; - const CGFloat kLabelHorizontalOutsetAmount = 2.0; - UIEdgeInsets labelOutset = UIEdgeInsetsMake(-kLabelVerticalOutsetAmount, -kLabelHorizontalOutsetAmount, -kLabelVerticalOutsetAmount, -kLabelHorizontalOutsetAmount); - self.hexLabel.frame = UIEdgeInsetsInsetRect(self.hexLabel.frame, labelOutset); - CGFloat hexLabelOriginX = self.colorPreviewBox.layer.borderWidth; - CGFloat hexLabelOriginY = CGRectGetMaxY(self.colorPreviewBox.frame) - self.colorPreviewBox.layer.borderWidth - self.hexLabel.frame.size.height; - self.hexLabel.frame = CGRectMake(hexLabelOriginX, hexLabelOriginY, self.hexLabel.frame.size.width, self.hexLabel.frame.size.height); - - NSArray *colorComponentInputViews = @[self.alphaInput, self.redInput, self.greenInput, self.blueInput]; - for (FLEXColorComponentInputView *inputView in colorComponentInputViews) { - CGSize fitSize = [inputView sizeThatFits:constrainSize]; - inputView.frame = CGRectMake(0, runningOriginY, fitSize.width, fitSize.height); - runningOriginY = CGRectGetMaxY(inputView.frame) + [[self class] inputViewVerticalPadding]; - } -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue isKindOfClass:[UIColor class]]) { - [self updateWithColor:inputValue]; - } else if ([inputValue isKindOfClass:[NSValue class]]) { - const char *type = [inputValue objCType]; - if (strcmp(type, @encode(CGColorRef)) == 0) { - CGColorRef colorRef; - [inputValue getValue:&colorRef]; - UIColor *color = [[UIColor alloc] initWithCGColor:colorRef]; - [self updateWithColor:color]; - } - } else { - [self updateWithColor:UIColor.clearColor]; - } -} - -- (id)inputValue { - return [UIColor colorWithRed:self.redInput.slider.value green:self.greenInput.slider.value blue:self.blueInput.slider.value alpha:self.alphaInput.slider.value]; -} - -- (void)colorComponentInputViewValueDidChange:(FLEXColorComponentInputView *)colorComponentInputView { - [self updateColorPreview]; -} - -- (void)updateWithColor:(UIColor *)color { - CGFloat red, green, blue, white, alpha; - if ([color getRed:&red green:&green blue:&blue alpha:&alpha]) { - self.alphaInput.slider.value = alpha; - [self.alphaInput updateValueLabel]; - self.redInput.slider.value = red; - [self.redInput updateValueLabel]; - self.greenInput.slider.value = green; - [self.greenInput updateValueLabel]; - self.blueInput.slider.value = blue; - [self.blueInput updateValueLabel]; - } else if ([color getWhite:&white alpha:&alpha]) { - self.alphaInput.slider.value = alpha; - [self.alphaInput updateValueLabel]; - self.redInput.slider.value = white; - [self.redInput updateValueLabel]; - self.greenInput.slider.value = white; - [self.greenInput updateValueLabel]; - self.blueInput.slider.value = white; - [self.blueInput updateValueLabel]; - } - [self updateColorPreview]; -} - -- (void)updateColorPreview { - self.colorPreviewBox.color = self.inputValue; - unsigned char redByte = self.redInput.slider.value * 255; - unsigned char greenByte = self.greenInput.slider.value * 255; - unsigned char blueByte = self.blueInput.slider.value * 255; - self.hexLabel.text = [NSString stringWithFormat:@"#%02X%02X%02X", redByte, greenByte, blueByte]; - [self setNeedsLayout]; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat height = 0; - height += [[self class] colorPreviewBoxHeight]; - height += [[self class] inputViewVerticalPadding]; - height += [self.alphaInput sizeThatFits:size].height; - height += [[self class] inputViewVerticalPadding]; - height += [self.redInput sizeThatFits:size].height; - height += [[self class] inputViewVerticalPadding]; - height += [self.greenInput sizeThatFits:size].height; - height += [[self class] inputViewVerticalPadding]; - height += [self.blueInput sizeThatFits:size].height; - return CGSizeMake(size.width, height); -} - -+ (CGFloat)inputViewVerticalPadding { - return 10.0; -} - -+ (CGFloat)colorPreviewBoxHeight { - return 40.0; -} - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - - // We don't care if currentValue is a color or not; we will default to +clearColor - return (strcmp(type, @encode(CGColorRef)) == 0) || (strcmp(type, FLEXEncodeClass(UIColor)) == 0); -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h deleted file mode 100644 index bbfdb66c..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputDataView.h -// Flipboard -// -// Created by Daniel Rodriguez Troitino on 2/14/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputDateView : FLEXArgumentInputView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m deleted file mode 100644 index b1442108..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputDateView.m +++ /dev/null @@ -1,58 +0,0 @@ -// -// FLEXArgumentInputDataView.m -// Flipboard -// -// Created by Daniel Rodriguez Troitino on 2/14/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputDateView.h" -#import "FLEXRuntimeUtility.h" - -@interface FLEXArgumentInputDateView () - -@property (nonatomic) UIDatePicker *datePicker; - -@end - -@implementation FLEXArgumentInputDateView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.datePicker = [UIDatePicker new]; - self.datePicker.datePickerMode = UIDatePickerModeDateAndTime; - // Using UTC, because that's what the NSDate description prints - self.datePicker.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; - self.datePicker.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; - [self addSubview:self.datePicker]; - } - return self; -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue isKindOfClass:[NSDate class]]) { - self.datePicker.date = inputValue; - } -} - -- (id)inputValue { - return self.datePicker.date; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - self.datePicker.frame = self.bounds; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat height = [self.datePicker sizeThatFits:size].height; - return CGSizeMake(size.width, height); -} - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - return strcmp(type, FLEXEncodeClass(NSDate)) == 0; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h deleted file mode 100644 index 7183f286..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputFontView.h -// Flipboard -// -// Created by Ryan Olson on 6/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputFontView : FLEXArgumentInputView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m deleted file mode 100644 index d8b24325..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontView.m +++ /dev/null @@ -1,109 +0,0 @@ -// -// FLEXArgumentInputFontView.m -// Flipboard -// -// Created by Ryan Olson on 6/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputFontView.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXArgumentInputFontsPickerView.h" - -@interface FLEXArgumentInputFontView () - -@property (nonatomic) FLEXArgumentInputView *fontNameInput; -@property (nonatomic) FLEXArgumentInputView *pointSizeInput; - -@end - -@implementation FLEXArgumentInputFontView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.fontNameInput = [[FLEXArgumentInputFontsPickerView alloc] initWithArgumentTypeEncoding:FLEXEncodeClass(NSString)]; - self.fontNameInput.targetSize = FLEXArgumentInputViewSizeSmall; - self.fontNameInput.title = @"Font Name:"; - [self addSubview:self.fontNameInput]; - - self.pointSizeInput = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:@encode(CGFloat)]; - self.pointSizeInput.targetSize = FLEXArgumentInputViewSizeSmall; - self.pointSizeInput.title = @"Point Size:"; - [self addSubview:self.pointSizeInput]; - } - return self; -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - self.fontNameInput.backgroundColor = backgroundColor; - self.pointSizeInput.backgroundColor = backgroundColor; -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue isKindOfClass:[UIFont class]]) { - UIFont *font = (UIFont *)inputValue; - self.fontNameInput.inputValue = font.fontName; - self.pointSizeInput.inputValue = @(font.pointSize); - } -} - -- (id)inputValue { - CGFloat pointSize = 0; - if ([self.pointSizeInput.inputValue isKindOfClass:[NSValue class]]) { - NSValue *pointSizeValue = (NSValue *)self.pointSizeInput.inputValue; - if (strcmp([pointSizeValue objCType], @encode(CGFloat)) == 0) { - [pointSizeValue getValue:&pointSize]; - } - } - return [UIFont fontWithName:self.fontNameInput.inputValue size:pointSize]; -} - -- (BOOL)inputViewIsFirstResponder { - return [self.fontNameInput inputViewIsFirstResponder] || [self.pointSizeInput inputViewIsFirstResponder]; -} - - -#pragma mark - Layout and Sizing - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat runningOriginY = self.topInputFieldVerticalLayoutGuide; - - CGSize fontNameFitSize = [self.fontNameInput sizeThatFits:self.bounds.size]; - self.fontNameInput.frame = CGRectMake(0, runningOriginY, fontNameFitSize.width, fontNameFitSize.height); - runningOriginY = CGRectGetMaxY(self.fontNameInput.frame) + [[self class] verticalPaddingBetweenFields]; - - CGSize pointSizeFitSize = [self.pointSizeInput sizeThatFits:self.bounds.size]; - self.pointSizeInput.frame = CGRectMake(0, runningOriginY, pointSizeFitSize.width, pointSizeFitSize.height); -} - -+ (CGFloat)verticalPaddingBetweenFields { - return 10.0; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize fitSize = [super sizeThatFits:size]; - - CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); - - CGFloat height = fitSize.height; - height += [self.fontNameInput sizeThatFits:constrainSize].height; - height += [[self class] verticalPaddingBetweenFields]; - height += [self.pointSizeInput sizeThatFits:constrainSize].height; - - return CGSizeMake(fitSize.width, height); -} - - -#pragma mark - - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - return strcmp(type, FLEXEncodeClass(UIFont)) == 0; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h deleted file mode 100644 index a8bcb68c..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// FLEXArgumentInputFontsPickerView.h -// FLEX -// -// Created by 啟倫 陳 on 2014/7/27. -// Copyright (c) 2014年 f. All rights reserved. -// - -#import "FLEXArgumentInputTextView.h" - -@interface FLEXArgumentInputFontsPickerView : FLEXArgumentInputTextView -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m deleted file mode 100644 index f280be0f..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputFontsPickerView.m +++ /dev/null @@ -1,96 +0,0 @@ -// -// FLEXArgumentInputFontsPickerView.m -// FLEX -// -// Created by 啟倫 陳 on 2014/7/27. -// Copyright (c) 2014年 f. All rights reserved. -// - -#import "FLEXArgumentInputFontsPickerView.h" -#import "FLEXRuntimeUtility.h" - -@interface FLEXArgumentInputFontsPickerView () - -@property (nonatomic) NSMutableArray *availableFonts; - -@end - - -@implementation FLEXArgumentInputFontsPickerView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.targetSize = FLEXArgumentInputViewSizeSmall; - [self createAvailableFonts]; - self.inputTextView.inputView = [self createFontsPicker]; - } - return self; -} - -- (void)setInputValue:(id)inputValue { - self.inputTextView.text = inputValue; - if ([self.availableFonts indexOfObject:inputValue] == NSNotFound) { - [self.availableFonts insertObject:inputValue atIndex:0]; - } - [(UIPickerView *)self.inputTextView.inputView selectRow:[self.availableFonts indexOfObject:inputValue] inComponent:0 animated:NO]; -} - -- (id)inputValue { - return self.inputTextView.text.length > 0 ? [self.inputTextView.text copy] : nil; -} - -#pragma mark - private - -- (UIPickerView*)createFontsPicker { - UIPickerView *fontsPicker = [UIPickerView new]; - fontsPicker.dataSource = self; - fontsPicker.delegate = self; - fontsPicker.showsSelectionIndicator = YES; - return fontsPicker; -} - -- (void)createAvailableFonts { - NSMutableArray *unsortedFontsArray = [NSMutableArray new]; - for (NSString *eachFontFamily in UIFont.familyNames) { - for (NSString *eachFontName in [UIFont fontNamesForFamilyName:eachFontFamily]) { - [unsortedFontsArray addObject:eachFontName]; - } - } - self.availableFonts = [NSMutableArray arrayWithArray:[unsortedFontsArray sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]]; -} - -#pragma mark - UIPickerViewDataSource - -- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { - return 1; -} - -- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { - return self.availableFonts.count; -} - -#pragma mark - UIPickerViewDelegate - -- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view { - UILabel *fontLabel; - if (!view) { - fontLabel = [UILabel new]; - fontLabel.backgroundColor = UIColor.clearColor; - fontLabel.textAlignment = NSTextAlignmentCenter; - } else { - fontLabel = (UILabel*)view; - } - UIFont *font = [UIFont fontWithName:self.availableFonts[row] size:15.0]; - NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; - NSAttributedString *attributesString = [[NSAttributedString alloc] initWithString:self.availableFonts[row] attributes:attributesDictionary]; - fontLabel.attributedText = attributesString; - [fontLabel sizeToFit]; - return fontLabel; -} - -- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { - self.inputTextView.text = self.availableFonts[row]; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h deleted file mode 100644 index 9d2b39cc..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputNotSupportedView.h -// Flipboard -// -// Created by Ryan Olson on 6/18/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputTextView.h" - -@interface FLEXArgumentInputNotSupportedView : FLEXArgumentInputTextView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m deleted file mode 100644 index a7fd1524..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNotSupportedView.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEXArgumentInputNotSupportedView.m -// Flipboard -// -// Created by Ryan Olson on 6/18/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputNotSupportedView.h" -#import "FLEXColor.h" - -@implementation FLEXArgumentInputNotSupportedView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.inputTextView.userInteractionEnabled = NO; - self.inputTextView.backgroundColor = [FLEXColor secondaryGroupedBackgroundColorWithAlpha:0.5]; - self.inputPlaceholderText = @"nil (type not supported)"; - self.targetSize = FLEXArgumentInputViewSizeSmall; - } - return self; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h deleted file mode 100644 index 5d088979..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputNumberView.h -// Flipboard -// -// Created by Ryan Olson on 6/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputTextView.h" - -@interface FLEXArgumentInputNumberView : FLEXArgumentInputTextView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m deleted file mode 100644 index 6f6a48a4..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputNumberView.m +++ /dev/null @@ -1,62 +0,0 @@ -// -// FLEXArgumentInputNumberView.m -// Flipboard -// -// Created by Ryan Olson on 6/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputNumberView.h" -#import "FLEXRuntimeUtility.h" - -@implementation FLEXArgumentInputNumberView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation; - self.targetSize = FLEXArgumentInputViewSizeSmall; - } - - return self; -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue respondsToSelector:@selector(stringValue)]) { - self.inputTextView.text = [inputValue stringValue]; - } -} - -- (id)inputValue { - return [FLEXRuntimeUtility valueForNumberWithObjCType:self.typeEncoding.UTF8String fromInputString:self.inputTextView.text]; -} - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - - static NSArray *supportedTypes = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - supportedTypes = @[ - @FLEXEncodeClass(NSNumber), - @FLEXEncodeClass(NSDecimalNumber), - @(@encode(char)), - @(@encode(int)), - @(@encode(short)), - @(@encode(long)), - @(@encode(long long)), - @(@encode(unsigned char)), - @(@encode(unsigned int)), - @(@encode(unsigned short)), - @(@encode(unsigned long)), - @(@encode(unsigned long long)), - @(@encode(float)), - @(@encode(double)), - @(@encode(long double)) - ]; - }); - - return type && [supportedTypes containsObject:@(type)]; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.h deleted file mode 100644 index df2f7e6e..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputObjectView.h -// Flipboard -// -// Created by Ryan Olson on 6/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputTextView.h" - -@interface FLEXArgumentInputObjectView : FLEXArgumentInputTextView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.m deleted file mode 100644 index 0eddf866..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputObjectView.m +++ /dev/null @@ -1,232 +0,0 @@ -// -// FLEXArgumentInputJSONObjectView.m -// Flipboard -// -// Created by Ryan Olson on 6/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputObjectView.h" -#import "FLEXRuntimeUtility.h" - -static const CGFloat kSegmentInputMargin = 10; - -typedef NS_ENUM(NSUInteger, FLEXArgInputObjectType) { - FLEXArgInputObjectTypeJSON, - FLEXArgInputObjectTypeAddress -}; - -@interface FLEXArgumentInputObjectView () - -@property (nonatomic) UISegmentedControl *objectTypeSegmentControl; -@property (nonatomic) FLEXArgInputObjectType inputType; - -@end - -@implementation FLEXArgumentInputObjectView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - // Start with the numbers and punctuation keyboard since quotes, curly braces, or - // square brackets are likely to be the first characters type for the JSON. - self.inputTextView.keyboardType = UIKeyboardTypeNumbersAndPunctuation; - self.targetSize = FLEXArgumentInputViewSizeLarge; - - self.objectTypeSegmentControl = [[UISegmentedControl alloc] initWithItems:@[@"Value", @"Address"]]; - [self.objectTypeSegmentControl addTarget:self action:@selector(didChangeType) forControlEvents:UIControlEventValueChanged]; - self.objectTypeSegmentControl.selectedSegmentIndex = 0; - [self addSubview:self.objectTypeSegmentControl]; - - self.inputType = [[self class] preferredDefaultTypeForObjCType:typeEncoding withCurrentValue:nil]; - self.objectTypeSegmentControl.selectedSegmentIndex = self.inputType; - } - - return self; -} - -- (void)didChangeType { - self.inputType = self.objectTypeSegmentControl.selectedSegmentIndex; - - if (super.inputValue) { - // Trigger an update to the text field to show - // the address of the stored object we were given, - // or to show a JSON representation of the object - [self populateTextAreaFromValue:super.inputValue]; - } else { - // Clear the text field - [self populateTextAreaFromValue:nil]; - } -} - -- (void)setInputType:(FLEXArgInputObjectType)inputType { - if (_inputType == inputType) return; - - _inputType = inputType; - - // Resize input view - switch (inputType) { - case FLEXArgInputObjectTypeJSON: - self.targetSize = FLEXArgumentInputViewSizeLarge; - break; - case FLEXArgInputObjectTypeAddress: - self.targetSize = FLEXArgumentInputViewSizeSmall; - break; - } - - // Change placeholder - switch (inputType) { - case FLEXArgInputObjectTypeJSON: - self.inputPlaceholderText = - @"You can put any valid JSON here, such as a string, number, array, or dictionary:" - "\n\"This is a string\"" - "\n1234" - "\n{ \"name\": \"Bob\", \"age\": 47 }" - "\n[" - "\n 1, 2, 3" - "\n]"; - break; - case FLEXArgInputObjectTypeAddress: - self.inputPlaceholderText = @"0x0000deadb33f"; - break; - } - - [self setNeedsLayout]; - [self.superview setNeedsLayout]; -} - -- (void)setInputValue:(id)inputValue { - super.inputValue = inputValue; - [self populateTextAreaFromValue:inputValue]; -} - -- (id)inputValue { - switch (self.inputType) { - case FLEXArgInputObjectTypeJSON: - return [FLEXRuntimeUtility objectValueFromEditableJSONString:self.inputTextView.text]; - case FLEXArgInputObjectTypeAddress: { - NSScanner *scanner = [NSScanner scannerWithString:self.inputTextView.text]; - - unsigned long long objectPointerValue; - if ([scanner scanHexLongLong:&objectPointerValue]) { - return (__bridge id)(void *)objectPointerValue; - } - - return nil; - } - } -} - -- (void)populateTextAreaFromValue:(id)value { - if (!value) { - self.inputTextView.text = nil; - } else { - if (self.inputType == FLEXArgInputObjectTypeJSON) { - self.inputTextView.text = [FLEXRuntimeUtility editableJSONStringForObject:value]; - } else if (self.inputType == FLEXArgInputObjectTypeAddress) { - self.inputTextView.text = [NSString stringWithFormat:@"%p", value]; - } - } - - // Delegate methods are not called for programmatic changes - [self textViewDidChange:self.inputTextView]; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize fitSize = [super sizeThatFits:size]; - fitSize.height += [self.objectTypeSegmentControl sizeThatFits:size].height + kSegmentInputMargin; - - return fitSize; -} - -- (void)layoutSubviews { - CGFloat segmentHeight = [self.objectTypeSegmentControl sizeThatFits:self.frame.size].height; - self.objectTypeSegmentControl.frame = CGRectMake( - 0.0, - // Our segmented control is taking the position - // of the text view, as far as super is concerned, - // and we override this property to be different - super.topInputFieldVerticalLayoutGuide, - self.frame.size.width, - segmentHeight - ); - - [super layoutSubviews]; -} - -- (CGFloat)topInputFieldVerticalLayoutGuide { - // Our text view is offset from the segmented control - CGFloat segmentHeight = [self.objectTypeSegmentControl sizeThatFits:self.frame.size].height; - return segmentHeight + super.topInputFieldVerticalLayoutGuide + kSegmentInputMargin; -} - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - // Must be object type - return type[0] == FLEXTypeEncodingObjcObject || type[0] == FLEXTypeEncodingObjcClass; -} - -+ (FLEXArgInputObjectType)preferredDefaultTypeForObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type[0] == FLEXTypeEncodingObjcObject || type[0] == FLEXTypeEncodingObjcClass); - - if (value) { - // If there's a current value, it must be serializable to JSON - // to display the JSON editor. Otherwise display the address field. - if ([FLEXRuntimeUtility editableJSONStringForObject:value]) { - return FLEXArgInputObjectTypeJSON; - } else { - return FLEXArgInputObjectTypeAddress; - } - } else { - // Otherwise, see if we have more type information than just 'id'. - // If we do, make sure the encoding is something serializable to JSON. - // Properties and ivars keep more detailed type encoding information than method arguments. - if (strcmp(type, @encode(id)) != 0) { - BOOL isJSONSerializableType = NO; - - // Parse class name out of the string, - // which is in the form `@"ClassName"` - Class cls = NSClassFromString(({ - NSString *className = nil; - NSScanner *scan = [NSScanner scannerWithString:@(type)]; - NSCharacterSet *allowed = [NSCharacterSet - characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$" - ]; - - // Skip over the @" then scan the name - if ([scan scanString:@"@\"" intoString:nil]) { - [scan scanCharactersFromSet:allowed intoString:&className]; - } - - className; - })); - - // Note: we can't use @encode(NSString) here because that drops - // the class information and just goes to @encode(id). - NSArray *jsonTypes = @[ - [NSString class], - [NSNumber class], - [NSArray class], - [NSDictionary class], - ]; - - // Look for matching types - for (Class jsonClass in jsonTypes) { - if ([cls isSubclassOfClass:jsonClass]) { - isJSONSerializableType = YES; - break; - } - } - - if (isJSONSerializableType) { - return FLEXArgInputObjectTypeJSON; - } else { - return FLEXArgInputObjectTypeAddress; - } - } else { - return FLEXArgInputObjectTypeAddress; - } - } -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h deleted file mode 100644 index e17a26bb..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputStringView.h -// Flipboard -// -// Created by Ryan Olson on 6/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputTextView.h" - -@interface FLEXArgumentInputStringView : FLEXArgumentInputTextView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m deleted file mode 100644 index 5329bee0..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStringView.m +++ /dev/null @@ -1,129 +0,0 @@ -// -// FLEXArgumentInputStringView.m -// Flipboard -// -// Created by Ryan Olson on 6/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputStringView.h" -#import "FLEXRuntimeUtility.h" - -@implementation FLEXArgumentInputStringView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - FLEXTypeEncoding type = typeEncoding[0]; - if (type == FLEXTypeEncodingConst) { - // A crash here would mean an invalid type encoding string - type = typeEncoding[1]; - } - - // Selectors don't need a multi-line text box - if (type == FLEXTypeEncodingSelector) { - self.targetSize = FLEXArgumentInputViewSizeSmall; - } else { - self.targetSize = FLEXArgumentInputViewSizeLarge; - } - } - return self; -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue isKindOfClass:[NSString class]]) { - self.inputTextView.text = inputValue; - } else if ([inputValue isKindOfClass:[NSValue class]]) { - NSValue *value = (id)inputValue; - NSParameterAssert(strlen(value.objCType) == 1); - - // C-String or SEL from NSValue - FLEXTypeEncoding type = value.objCType[0]; - if (type == FLEXTypeEncodingConst) { - // A crash here would mean an invalid type encoding string - type = value.objCType[1]; - } - - if (type == FLEXTypeEncodingCString) { - self.inputTextView.text = @((const char *)value.pointerValue); - } else if (type == FLEXTypeEncodingSelector) { - self.inputTextView.text = NSStringFromSelector((SEL)value.pointerValue); - } - } -} - -- (id)inputValue { - NSString *text = self.inputTextView.text; - // Interpret empty string as nil. We loose the ability to set empty string as a string value, - // but we accept that tradeoff in exchange for not having to type quotes for every string. - if (!text.length) { - return nil; - } - - // Case: C-strings and SELs - if (self.typeEncoding.length <= 2) { - FLEXTypeEncoding type = [self.typeEncoding characterAtIndex:0]; - if (type == FLEXTypeEncodingConst) { - // A crash here would mean an invalid type encoding string - type = [self.typeEncoding characterAtIndex:1]; - } - - if (type == FLEXTypeEncodingCString || type == FLEXTypeEncodingSelector) { - const char *encoding = self.typeEncoding.UTF8String; - SEL selector = NSSelectorFromString(text); - return [NSValue valueWithBytes:&selector objCType:encoding]; - } - } - - // Case: NSStrings - return self.inputTextView.text.copy; -} - -// TODO: Support using object address for strings, as in the object arg view. - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - unsigned long len = strlen(type); - - BOOL isConst = type[0] == FLEXTypeEncodingConst; - NSInteger i = isConst ? 1 : 0; - - BOOL typeIsString = strcmp(type, FLEXEncodeClass(NSString)) == 0; - BOOL typeIsCString = len <= 2 && type[i] == FLEXTypeEncodingCString; - BOOL typeIsSEL = len <= 2 && type[i] == FLEXTypeEncodingSelector; - BOOL valueIsString = [value isKindOfClass:[NSString class]]; - - BOOL typeIsPrimitiveString = typeIsSEL || typeIsCString; - BOOL typeIsSupported = typeIsString || typeIsCString || typeIsSEL; - - BOOL valueIsNSValueWithCorrectType = NO; - if ([value isKindOfClass:[NSValue class]]) { - NSValue *v = (id)value; - len = strlen(v.objCType); - if (len == 1) { - FLEXTypeEncoding type = v.objCType[i]; - if (type == FLEXTypeEncodingCString && typeIsCString) { - valueIsNSValueWithCorrectType = YES; - } else if (type == FLEXTypeEncodingSelector && typeIsSEL) { - valueIsNSValueWithCorrectType = YES; - } - } - } - - if (!value && typeIsSupported) { - return YES; - } - - if (typeIsString && valueIsString) { - return YES; - } - - // Primitive strings can be input as NSStrings or NSValues - if (typeIsPrimitiveString && (valueIsString || valueIsNSValueWithCorrectType)) { - return YES; - } - - return NO; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h deleted file mode 100644 index 82270ae7..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputStructView.h -// Flipboard -// -// Created by Ryan Olson on 6/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputStructView : FLEXArgumentInputView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m deleted file mode 100644 index 2479d6a4..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputStructView.m +++ /dev/null @@ -1,220 +0,0 @@ -// -// FLEXArgumentInputStructView.m -// Flipboard -// -// Created by Ryan Olson on 6/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputStructView.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXTypeEncodingParser.h" - -@interface FLEXArgumentInputStructView () - -@property (nonatomic) NSArray *argumentInputViews; - -@end - -@implementation FLEXArgumentInputStructView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - NSMutableArray *inputViews = [NSMutableArray new]; - NSArray *customTitles = [[self class] customFieldTitlesForTypeEncoding:typeEncoding]; - [FLEXRuntimeUtility enumerateTypesInStructEncoding:typeEncoding usingBlock:^(NSString *structName, - const char *fieldTypeEncoding, - NSString *prettyTypeEncoding, - NSUInteger fieldIndex, - NSUInteger fieldOffset) { - - FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:fieldTypeEncoding]; - inputView.targetSize = FLEXArgumentInputViewSizeSmall; - - if (fieldIndex < customTitles.count) { - inputView.title = customTitles[fieldIndex]; - } else { - inputView.title = [NSString stringWithFormat:@"%@ field %lu (%@)", - structName, (unsigned long)fieldIndex, prettyTypeEncoding - ]; - } - - [inputViews addObject:inputView]; - [self addSubview:inputView]; - }]; - self.argumentInputViews = inputViews; - } - return self; -} - - -#pragma mark - Superclass Overrides - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - for (FLEXArgumentInputView *inputView in self.argumentInputViews) { - inputView.backgroundColor = backgroundColor; - } -} - -- (void)setInputValue:(id)inputValue { - if ([inputValue isKindOfClass:[NSValue class]]) { - const char *structTypeEncoding = [inputValue objCType]; - if (strcmp(self.typeEncoding.UTF8String, structTypeEncoding) == 0) { - NSUInteger valueSize = 0; - - if (FLEXGetSizeAndAlignment(structTypeEncoding, &valueSize, NULL)) { - void *unboxedValue = malloc(valueSize); - [inputValue getValue:unboxedValue]; - [FLEXRuntimeUtility enumerateTypesInStructEncoding:structTypeEncoding usingBlock:^(NSString *structName, - const char *fieldTypeEncoding, - NSString *prettyTypeEncoding, - NSUInteger fieldIndex, - NSUInteger fieldOffset) { - - void *fieldPointer = unboxedValue + fieldOffset; - FLEXArgumentInputView *inputView = self.argumentInputViews[fieldIndex]; - - if (fieldTypeEncoding[0] == FLEXTypeEncodingObjcObject || fieldTypeEncoding[0] == FLEXTypeEncodingObjcClass) { - inputView.inputValue = (__bridge id)fieldPointer; - } else { - NSValue *boxedField = [FLEXRuntimeUtility valueForPrimitivePointer:fieldPointer objCType:fieldTypeEncoding]; - inputView.inputValue = boxedField; - } - }]; - free(unboxedValue); - } - } - } -} - -- (id)inputValue { - NSValue *boxedStruct = nil; - const char *structTypeEncoding = self.typeEncoding.UTF8String; - NSUInteger structSize = 0; - - if (FLEXGetSizeAndAlignment(structTypeEncoding, &structSize, NULL)) { - void *unboxedStruct = malloc(structSize); - [FLEXRuntimeUtility enumerateTypesInStructEncoding:structTypeEncoding usingBlock:^(NSString *structName, - const char *fieldTypeEncoding, - NSString *prettyTypeEncoding, - NSUInteger fieldIndex, - NSUInteger fieldOffset) { - - void *fieldPointer = unboxedStruct + fieldOffset; - FLEXArgumentInputView *inputView = self.argumentInputViews[fieldIndex]; - - if (fieldTypeEncoding[0] == FLEXTypeEncodingObjcObject || fieldTypeEncoding[0] == FLEXTypeEncodingObjcClass) { - // Object fields - memcpy(fieldPointer, (__bridge void *)inputView.inputValue, sizeof(id)); - } else { - // Boxed primitive/struct fields - id inputValue = inputView.inputValue; - if ([inputValue isKindOfClass:[NSValue class]] && strcmp([inputValue objCType], fieldTypeEncoding) == 0) { - [inputValue getValue:fieldPointer]; - } - } - }]; - - boxedStruct = [NSValue value:unboxedStruct withObjCType:structTypeEncoding]; - free(unboxedStruct); - } - - return boxedStruct; -} - -- (BOOL)inputViewIsFirstResponder { - BOOL isFirstResponder = NO; - for (FLEXArgumentInputView *inputView in self.argumentInputViews) { - if ([inputView inputViewIsFirstResponder]) { - isFirstResponder = YES; - break; - } - } - return isFirstResponder; -} - - -#pragma mark - Layout and Sizing - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat runningOriginY = self.topInputFieldVerticalLayoutGuide; - - for (FLEXArgumentInputView *inputView in self.argumentInputViews) { - CGSize inputFitSize = [inputView sizeThatFits:self.bounds.size]; - inputView.frame = CGRectMake(0, runningOriginY, inputFitSize.width, inputFitSize.height); - runningOriginY = CGRectGetMaxY(inputView.frame) + [[self class] verticalPaddingBetweenFields]; - } -} - -+ (CGFloat)verticalPaddingBetweenFields { - return 10.0; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize fitSize = [super sizeThatFits:size]; - - CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); - CGFloat height = fitSize.height; - - for (FLEXArgumentInputView *inputView in self.argumentInputViews) { - height += [inputView sizeThatFits:constrainSize].height; - height += [[self class] verticalPaddingBetweenFields]; - } - - return CGSizeMake(fitSize.width, height); -} - - -#pragma mark - Class Helpers - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - if (type[0] == FLEXTypeEncodingStructBegin) { - return FLEXGetSizeAndAlignment(type, nil, nil); - } - - return NO; -} - -+ (NSArray *)customFieldTitlesForTypeEncoding:(const char *)typeEncoding { - NSArray *customTitles = nil; - if (strcmp(typeEncoding, @encode(CGRect)) == 0) { - customTitles = @[@"CGPoint origin", @"CGSize size"]; - } else if (strcmp(typeEncoding, @encode(CGPoint)) == 0) { - customTitles = @[@"CGFloat x", @"CGFloat y"]; - } else if (strcmp(typeEncoding, @encode(CGSize)) == 0) { - customTitles = @[@"CGFloat width", @"CGFloat height"]; - } else if (strcmp(typeEncoding, @encode(CGVector)) == 0) { - customTitles = @[@"CGFloat dx", @"CGFloat dy"]; - } else if (strcmp(typeEncoding, @encode(UIEdgeInsets)) == 0) { - customTitles = @[@"CGFloat top", @"CGFloat left", @"CGFloat bottom", @"CGFloat right"]; - } else if (strcmp(typeEncoding, @encode(UIOffset)) == 0) { - customTitles = @[@"CGFloat horizontal", @"CGFloat vertical"]; - } else if (strcmp(typeEncoding, @encode(NSRange)) == 0) { - customTitles = @[@"NSUInteger location", @"NSUInteger length"]; - } else if (strcmp(typeEncoding, @encode(CATransform3D)) == 0) { - customTitles = @[@"CGFloat m11", @"CGFloat m12", @"CGFloat m13", @"CGFloat m14", - @"CGFloat m21", @"CGFloat m22", @"CGFloat m23", @"CGFloat m24", - @"CGFloat m31", @"CGFloat m32", @"CGFloat m33", @"CGFloat m34", - @"CGFloat m41", @"CGFloat m42", @"CGFloat m43", @"CGFloat m44"]; - } else if (strcmp(typeEncoding, @encode(CGAffineTransform)) == 0) { - customTitles = @[@"CGFloat a", @"CGFloat b", - @"CGFloat c", @"CGFloat d", - @"CGFloat tx", @"CGFloat ty"]; - } else { - if (@available(iOS 11.0, *)) { - if (strcmp(typeEncoding, @encode(NSDirectionalEdgeInsets)) == 0) { - customTitles = @[@"CGFloat top", @"CGFloat leading", - @"CGFloat bottom", @"CGFloat trailing"]; - } - } - } - return customTitles; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h deleted file mode 100644 index 26d2f313..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXArgumentInputSwitchView.h -// Flipboard -// -// Created by Ryan Olson on 6/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputSwitchView : FLEXArgumentInputView - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m deleted file mode 100644 index 93808238..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputSwitchView.m +++ /dev/null @@ -1,81 +0,0 @@ -// -// FLEXArgumentInputSwitchView.m -// Flipboard -// -// Created by Ryan Olson on 6/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputSwitchView.h" - -@interface FLEXArgumentInputSwitchView () - -@property (nonatomic) UISwitch *inputSwitch; - -@end - -@implementation FLEXArgumentInputSwitchView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.inputSwitch = [UISwitch new]; - [self.inputSwitch addTarget:self action:@selector(switchValueDidChange:) forControlEvents:UIControlEventValueChanged]; - [self.inputSwitch sizeToFit]; - [self addSubview:self.inputSwitch]; - } - return self; -} - - -#pragma mark Input/Output - -- (void)setInputValue:(id)inputValue { - BOOL on = NO; - if ([inputValue isKindOfClass:[NSNumber class]]) { - NSNumber *number = (NSNumber *)inputValue; - on = [number boolValue]; - } else if ([inputValue isKindOfClass:[NSValue class]]) { - NSValue *value = (NSValue *)inputValue; - if (strcmp([value objCType], @encode(BOOL)) == 0) { - [value getValue:&on]; - } - } - self.inputSwitch.on = on; -} - -- (id)inputValue { - BOOL isOn = [self.inputSwitch isOn]; - NSValue *boxedBool = [NSValue value:&isOn withObjCType:@encode(BOOL)]; - return boxedBool; -} - -- (void)switchValueDidChange:(id)sender { - [self.delegate argumentInputViewValueDidChange:self]; -} - - -#pragma mark - Layout and Sizing - -- (void)layoutSubviews { - [super layoutSubviews]; - - self.inputSwitch.frame = CGRectMake(0, self.topInputFieldVerticalLayoutGuide, self.inputSwitch.frame.size.width, self.inputSwitch.frame.size.height); -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize fitSize = [super sizeThatFits:size]; - fitSize.height += self.inputSwitch.frame.size.height; - return fitSize; -} - - -#pragma mark - Class Helpers - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - NSParameterAssert(type); - // Only BOOLs. Current value is irrelevant. - return strcmp(type, @encode(BOOL)) == 0; -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h deleted file mode 100644 index 5bb8ec8a..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXArgumentInputTextView.h -// FLEXInjected -// -// Created by Ryan Olson on 6/15/14. -// -// - -#import "FLEXArgumentInputView.h" - -@interface FLEXArgumentInputTextView : FLEXArgumentInputView - -// For subclass eyes only - -@property (nonatomic, readonly) UITextView *inputTextView; -@property (nonatomic) NSString *inputPlaceholderText; - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m deleted file mode 100644 index 4ea2b057..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputTextView.m +++ /dev/null @@ -1,155 +0,0 @@ -// -// FLEXArgumentInputTextView.m -// FLEXInjected -// -// Created by Ryan Olson on 6/15/14. -// -// - -#import "FLEXColor.h" -#import "FLEXArgumentInputTextView.h" -#import "FLEXUtility.h" - -@interface FLEXArgumentInputTextView () - -@property (nonatomic) UITextView *inputTextView; -@property (nonatomic) UILabel *placeholderLabel; -@property (nonatomic, readonly) NSUInteger numberOfInputLines; - -@end - -@implementation FLEXArgumentInputTextView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithArgumentTypeEncoding:typeEncoding]; - if (self) { - self.inputTextView = [UITextView new]; - self.inputTextView.font = [[self class] inputFont]; - self.inputTextView.backgroundColor = FLEXColor.secondaryGroupedBackgroundColor; - self.inputTextView.layer.cornerRadius = 10.f; - self.inputTextView.contentInset = UIEdgeInsetsMake(0, 5, 0, 0); - self.inputTextView.autocapitalizationType = UITextAutocapitalizationTypeNone; - self.inputTextView.autocorrectionType = UITextAutocorrectionTypeNo; - self.inputTextView.delegate = self; - self.inputTextView.inputAccessoryView = [self createToolBar]; - if (@available(iOS 11, *)) { - self.inputTextView.smartQuotesType = UITextSmartQuotesTypeNo; - [self.inputTextView.layer setValue:@YES forKey:@"continuousCorners"]; - } else { - self.inputTextView.layer.borderWidth = 1.f; - self.inputTextView.layer.borderColor = FLEXColor.borderColor.CGColor; - } - - self.placeholderLabel = [UILabel new]; - self.placeholderLabel.font = self.inputTextView.font; - self.placeholderLabel.textColor = FLEXColor.deemphasizedTextColor; - self.placeholderLabel.numberOfLines = 0; - - [self addSubview:self.inputTextView]; - [self.inputTextView addSubview:self.placeholderLabel]; - - } - return self; -} - -#pragma mark - Private - -- (UIToolbar *)createToolBar { - UIToolbar *toolBar = [UIToolbar new]; - [toolBar sizeToFit]; - UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace - target:nil action:nil - ]; - UIBarButtonItem *pasteItem = [[UIBarButtonItem alloc] - initWithTitle:@"Paste" style:UIBarButtonItemStyleDone - target:self.inputTextView action:@selector(paste:) - ]; - UIBarButtonItem *doneItem = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemDone - target:self.inputTextView action:@selector(resignFirstResponder) - ]; - toolBar.items = @[spaceItem, pasteItem, doneItem]; - return toolBar; -} - -- (void)setInputPlaceholderText:(NSString *)placeholder { - self.placeholderLabel.text = placeholder; - if (placeholder.length) { - if (!self.inputTextView.text.length) { - self.placeholderLabel.hidden = NO; - } else { - self.placeholderLabel.hidden = YES; - } - } else { - self.placeholderLabel.hidden = YES; - } - - [self setNeedsLayout]; -} - -- (NSString *)inputPlaceholderText { - return self.placeholderLabel.text; -} - - -#pragma mark - Superclass Overrides - -- (BOOL)inputViewIsFirstResponder { - return self.inputTextView.isFirstResponder; -} - - -#pragma mark - Layout and Sizing - -- (void)layoutSubviews { - [super layoutSubviews]; - - self.inputTextView.frame = CGRectMake(0, self.topInputFieldVerticalLayoutGuide, self.bounds.size.width, [self inputTextViewHeight]); - // Placeholder label is positioned by insetting then origin - // by the content inset then the text container inset - CGSize s = self.inputTextView.frame.size; - self.placeholderLabel.frame = CGRectMake(0, 0, s.width, s.height); - self.placeholderLabel.frame = UIEdgeInsetsInsetRect( - UIEdgeInsetsInsetRect(self.placeholderLabel.frame, self.inputTextView.contentInset), - self.inputTextView.textContainerInset - ); -} - -- (NSUInteger)numberOfInputLines { - switch (self.targetSize) { - case FLEXArgumentInputViewSizeDefault: - return 2; - case FLEXArgumentInputViewSizeSmall: - return 1; - case FLEXArgumentInputViewSizeLarge: - return 8; - } -} - -- (CGFloat)inputTextViewHeight { - return ceil([[self class] inputFont].lineHeight * self.numberOfInputLines) + 16.0; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGSize fitSize = [super sizeThatFits:size]; - fitSize.height += [self inputTextViewHeight]; - return fitSize; -} - - -#pragma mark - Class Helpers - -+ (UIFont *)inputFont { - return [UIFont systemFontOfSize:14.0]; -} - - -#pragma mark - UITextViewDelegate - -- (void)textViewDidChange:(UITextView *)textView { - [self.delegate argumentInputViewValueDidChange:self]; - self.placeholderLabel.hidden = !(self.inputPlaceholderText.length && !textView.text.length); -} - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h deleted file mode 100644 index 171139e5..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// FLEXArgumentInputView.h -// Flipboard -// -// Created by Ryan Olson on 5/30/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -typedef NS_ENUM(NSUInteger, FLEXArgumentInputViewSize) { - /// 2 lines, medium-sized - FLEXArgumentInputViewSizeDefault = 0, - /// One line - FLEXArgumentInputViewSizeSmall, - /// Several lines - FLEXArgumentInputViewSizeLarge -}; - -@protocol FLEXArgumentInputViewDelegate; - -@interface FLEXArgumentInputView : UIView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding; - -/// The name of the field. Optional (can be nil). -@property (nonatomic, copy) NSString *title; - -/// To populate the filed with an initial value, set this property. -/// To reteive the value input by the user, access the property. -/// Primitive types and structs should/will be boxed in NSValue containers. -/// Concrete subclasses should override both the setter and getter for this property. -/// Subclasses can call super.inputValue to access a backing store for the value. -@property (nonatomic) id inputValue; - -/// Setting this value to large will make some argument input views increase the size of their input field(s). -/// Useful to increase the use of space if there is only one input view on screen (i.e. for property and ivar editing). -@property (nonatomic) FLEXArgumentInputViewSize targetSize; - -/// Users of the input view can get delegate callbacks for incremental changes in user input. -@property (nonatomic, weak) id delegate; - -// Subclasses can override - -/// If the input view has one or more text views, returns YES when one of them is focused. -@property (nonatomic, readonly) BOOL inputViewIsFirstResponder; - -/// For subclasses to indicate that they can handle editing a field the give type and value. -/// Used by FLEXArgumentInputViewFactory to create appropriate input views. -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value; - -// For subclass eyes only - -@property (nonatomic, readonly) UILabel *titleLabel; -@property (nonatomic, readonly) NSString *typeEncoding; -@property (nonatomic, readonly) CGFloat topInputFieldVerticalLayoutGuide; - -@end - -@protocol FLEXArgumentInputViewDelegate - -- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView; - -@end diff --git a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.m b/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.m deleted file mode 100644 index f991e52a..00000000 --- a/BHTwitter/Classes/Editing/ArgumentInputViews/FLEXArgumentInputView.m +++ /dev/null @@ -1,114 +0,0 @@ -// -// FLEXArgumentInputView.m -// Flipboard -// -// Created by Ryan Olson on 5/30/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXArgumentInputView.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" - -@interface FLEXArgumentInputView () - -@property (nonatomic) UILabel *titleLabel; -@property (nonatomic) NSString *typeEncoding; - -@end - -@implementation FLEXArgumentInputView - -- (instancetype)initWithArgumentTypeEncoding:(const char *)typeEncoding { - self = [super initWithFrame:CGRectZero]; - if (self) { - self.typeEncoding = typeEncoding != NULL ? @(typeEncoding) : nil; - } - return self; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - if (self.showsTitle) { - CGSize constrainSize = CGSizeMake(self.bounds.size.width, CGFLOAT_MAX); - CGSize labelSize = [self.titleLabel sizeThatFits:constrainSize]; - self.titleLabel.frame = CGRectMake(0, 0, labelSize.width, labelSize.height); - } -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - self.titleLabel.backgroundColor = backgroundColor; -} - -- (void)setTitle:(NSString *)title { - if (![_title isEqual:title]) { - _title = title; - self.titleLabel.text = title; - [self setNeedsLayout]; - } -} - -- (UILabel *)titleLabel { - if (!_titleLabel) { - _titleLabel = [UILabel new]; - _titleLabel.font = [[self class] titleFont]; - _titleLabel.textColor = FLEXColor.primaryTextColor; - _titleLabel.numberOfLines = 0; - [self addSubview:_titleLabel]; - } - return _titleLabel; -} - -- (BOOL)showsTitle { - return self.title.length > 0; -} - -- (CGFloat)topInputFieldVerticalLayoutGuide { - CGFloat verticalLayoutGuide = 0; - if (self.showsTitle) { - CGFloat titleHeight = [self.titleLabel sizeThatFits:self.bounds.size].height; - verticalLayoutGuide = titleHeight + [[self class] titleBottomPadding]; - } - return verticalLayoutGuide; -} - - -#pragma mark - Subclasses Can Override - -- (BOOL)inputViewIsFirstResponder { - return NO; -} - -+ (BOOL)supportsObjCType:(const char *)type withCurrentValue:(id)value { - return NO; -} - - -#pragma mark - Class Helpers - -+ (UIFont *)titleFont { - return [UIFont systemFontOfSize:12.0]; -} - -+ (CGFloat)titleBottomPadding { - return 4.0; -} - - -#pragma mark - Sizing - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat height = 0; - - if (self.title.length > 0) { - CGSize constrainSize = CGSizeMake(size.width, CGFLOAT_MAX); - height += ceil([self.titleLabel sizeThatFits:constrainSize].height); - height += [[self class] titleBottomPadding]; - } - - return CGSizeMake(size.width, height); -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.h b/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.h deleted file mode 100644 index f72e9073..00000000 --- a/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.h +++ /dev/null @@ -1,24 +0,0 @@ -// -// FLEXArgumentInputViewFactory.h -// FLEXInjected -// -// Created by Ryan Olson on 6/15/14. -// -// - -#import -#import "FLEXArgumentInputSwitchView.h" - -@interface FLEXArgumentInputViewFactory : NSObject - -/// Forwards to argumentInputViewForTypeEncoding:currentValue: with a nil currentValue. -+ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding; - -/// The main factory method for making argument input view subclasses that are the best fit for the type. -+ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue; - -/// A way to check if we should try editing a filed given its type encoding and value. -/// Useful when deciding whether to edit or explore a property, ivar, or NSUserDefaults value. -+ (BOOL)canEditFieldWithTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue; - -@end diff --git a/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.m b/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.m deleted file mode 100644 index fde1c8f3..00000000 --- a/BHTwitter/Classes/Editing/FLEXArgumentInputViewFactory.m +++ /dev/null @@ -1,70 +0,0 @@ -// -// FLEXArgumentInputViewFactory.m -// FLEXInjected -// -// Created by Ryan Olson on 6/15/14. -// -// - -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXArgumentInputView.h" -#import "FLEXArgumentInputObjectView.h" -#import "FLEXArgumentInputNumberView.h" -#import "FLEXArgumentInputSwitchView.h" -#import "FLEXArgumentInputStructView.h" -#import "FLEXArgumentInputNotSupportedView.h" -#import "FLEXArgumentInputStringView.h" -#import "FLEXArgumentInputFontView.h" -#import "FLEXArgumentInputColorView.h" -#import "FLEXArgumentInputDateView.h" -#import "FLEXRuntimeUtility.h" - -@implementation FLEXArgumentInputViewFactory - -+ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding { - return [self argumentInputViewForTypeEncoding:typeEncoding currentValue:nil]; -} - -+ (FLEXArgumentInputView *)argumentInputViewForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue { - Class subclass = [self argumentInputViewSubclassForTypeEncoding:typeEncoding currentValue:currentValue]; - if (!subclass) { - // Fall back to a FLEXArgumentInputNotSupportedView if we can't find a subclass that fits the type encoding. - // The unsupported view shows "nil" and does not allow user input. - subclass = [FLEXArgumentInputNotSupportedView class]; - } - // Remove the field name if there is any (e.g. \"width\"d -> d) - const NSUInteger fieldNameOffset = [FLEXRuntimeUtility fieldNameOffsetForTypeEncoding:typeEncoding]; - return [[subclass alloc] initWithArgumentTypeEncoding:typeEncoding + fieldNameOffset]; -} - -+ (Class)argumentInputViewSubclassForTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue { - // Remove the field name if there is any (e.g. \"width\"d -> d) - const NSUInteger fieldNameOffset = [FLEXRuntimeUtility fieldNameOffsetForTypeEncoding:typeEncoding]; - Class argumentInputViewSubclass = nil; - NSArray *inputViewClasses = @[[FLEXArgumentInputColorView class], - [FLEXArgumentInputFontView class], - [FLEXArgumentInputStringView class], - [FLEXArgumentInputStructView class], - [FLEXArgumentInputSwitchView class], - [FLEXArgumentInputDateView class], - [FLEXArgumentInputNumberView class], - [FLEXArgumentInputObjectView class]]; - - // Note that order is important here since multiple subclasses may support the same type. - // An example is the number subclass and the bool subclass for the type @encode(BOOL). - // Both work, but we'd prefer to use the bool subclass. - for (Class inputViewClass in inputViewClasses) { - if ([inputViewClass supportsObjCType:typeEncoding + fieldNameOffset withCurrentValue:currentValue]) { - argumentInputViewSubclass = inputViewClass; - break; - } - } - - return argumentInputViewSubclass; -} - -+ (BOOL)canEditFieldWithTypeEncoding:(const char *)typeEncoding currentValue:(id)currentValue { - return [self argumentInputViewSubclassForTypeEncoding:typeEncoding currentValue:currentValue] != nil; -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.h b/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.h deleted file mode 100644 index 5d6ae4cf..00000000 --- a/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// FLEXDefaultEditorViewController.h -// Flipboard -// -// Created by Ryan Olson on 5/23/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFieldEditorViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXDefaultEditorViewController : FLEXVariableEditorViewController - -+ (instancetype)target:(NSUserDefaults *)defaults key:(NSString *)key commitHandler:(void(^_Nullable)(void))onCommit; - -+ (BOOL)canEditDefaultWithValue:(nullable id)currentValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.m b/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.m deleted file mode 100644 index f368b7f2..00000000 --- a/BHTwitter/Classes/Editing/FLEXDefaultEditorViewController.m +++ /dev/null @@ -1,80 +0,0 @@ -// -// FLEXDefaultEditorViewController.m -// Flipboard -// -// Created by Ryan Olson on 5/23/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXDefaultEditorViewController.h" -#import "FLEXFieldEditorView.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXArgumentInputView.h" -#import "FLEXArgumentInputViewFactory.h" - -@interface FLEXDefaultEditorViewController () - -@property (nonatomic, readonly) NSUserDefaults *defaults; -@property (nonatomic, readonly) NSString *key; - -@end - -@implementation FLEXDefaultEditorViewController - -+ (instancetype)target:(NSUserDefaults *)defaults key:(NSString *)key commitHandler:(void(^_Nullable)(void))onCommit { - FLEXDefaultEditorViewController *editor = [self target:defaults data:key commitHandler:onCommit]; - editor.title = @"Edit Default"; - return editor; -} - -- (NSUserDefaults *)defaults { - return [_target isKindOfClass:[NSUserDefaults class]] ? _target : nil; -} - -- (NSString *)key { - return _data; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.fieldEditorView.fieldDescription = self.key; - - id currentValue = [self.defaults objectForKey:self.key]; - FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory - argumentInputViewForTypeEncoding:FLEXEncodeObject(currentValue) - currentValue:currentValue - ]; - inputView.backgroundColor = self.view.backgroundColor; - inputView.inputValue = currentValue; - self.fieldEditorView.argumentInputViews = @[inputView]; -} - -- (void)actionButtonPressed:(id)sender { - id value = self.firstInputView.inputValue; - if (value) { - [self.defaults setObject:value forKey:self.key]; - } else { - [self.defaults removeObjectForKey:self.key]; - } - [self.defaults synchronize]; - - // Dismiss keyboard and handle committed changes - [super actionButtonPressed:sender]; - - // Go back after setting, but not for switches. - if (sender) { - [self.navigationController popViewControllerAnimated:YES]; - } else { - self.firstInputView.inputValue = [self.defaults objectForKey:self.key]; - } -} - -+ (BOOL)canEditDefaultWithValue:(id)currentValue { - return [FLEXArgumentInputViewFactory - canEditFieldWithTypeEncoding:FLEXEncodeObject(currentValue) - currentValue:currentValue - ]; -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXFieldEditorView.h b/BHTwitter/Classes/Editing/FLEXFieldEditorView.h deleted file mode 100644 index 19c0e63b..00000000 --- a/BHTwitter/Classes/Editing/FLEXFieldEditorView.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// FLEXFieldEditorView.h -// Flipboard -// -// Created by Ryan Olson on 5/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@class FLEXArgumentInputView; - -@interface FLEXFieldEditorView : UIView - -@property (nonatomic, copy) NSString *targetDescription; -@property (nonatomic, copy) NSString *fieldDescription; - -@property (nonatomic, copy) NSArray *argumentInputViews; - -@end diff --git a/BHTwitter/Classes/Editing/FLEXFieldEditorView.m b/BHTwitter/Classes/Editing/FLEXFieldEditorView.m deleted file mode 100644 index b6fde89a..00000000 --- a/BHTwitter/Classes/Editing/FLEXFieldEditorView.m +++ /dev/null @@ -1,171 +0,0 @@ -// -// FLEXFieldEditorView.m -// Flipboard -// -// Created by Ryan Olson on 5/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFieldEditorView.h" -#import "FLEXArgumentInputView.h" -#import "FLEXUtility.h" - -@interface FLEXFieldEditorView () - -@property (nonatomic) UILabel *targetDescriptionLabel; -@property (nonatomic) UIView *targetDescriptionDivider; -@property (nonatomic) UILabel *fieldDescriptionLabel; -@property (nonatomic) UIView *fieldDescriptionDivider; - -@end - -@implementation FLEXFieldEditorView - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.targetDescriptionLabel = [UILabel new]; - self.targetDescriptionLabel.numberOfLines = 0; - self.targetDescriptionLabel.font = [[self class] labelFont]; - [self addSubview:self.targetDescriptionLabel]; - - self.targetDescriptionDivider = [[self class] dividerView]; - [self addSubview:self.targetDescriptionDivider]; - - self.fieldDescriptionLabel = [UILabel new]; - self.fieldDescriptionLabel.numberOfLines = 0; - self.fieldDescriptionLabel.font = [[self class] labelFont]; - [self addSubview:self.fieldDescriptionLabel]; - - self.fieldDescriptionDivider = [[self class] dividerView]; - [self addSubview:self.fieldDescriptionDivider]; - } - return self; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat horizontalPadding = [[self class] horizontalPadding]; - CGFloat verticalPadding = [[self class] verticalPadding]; - CGFloat dividerLineHeight = [[self class] dividerLineHeight]; - - CGFloat originY = verticalPadding; - CGFloat originX = horizontalPadding; - CGFloat contentWidth = self.bounds.size.width - 2.0 * horizontalPadding; - CGSize constrainSize = CGSizeMake(contentWidth, CGFLOAT_MAX); - - CGSize instanceDescriptionSize = [self.targetDescriptionLabel sizeThatFits:constrainSize]; - self.targetDescriptionLabel.frame = CGRectMake(originX, originY, instanceDescriptionSize.width, instanceDescriptionSize.height); - originY = CGRectGetMaxY(self.targetDescriptionLabel.frame) + verticalPadding; - - self.targetDescriptionDivider.frame = CGRectMake(originX, originY, contentWidth, dividerLineHeight); - originY = CGRectGetMaxY(self.targetDescriptionDivider.frame) + verticalPadding; - - CGSize fieldDescriptionSize = [self.fieldDescriptionLabel sizeThatFits:constrainSize]; - self.fieldDescriptionLabel.frame = CGRectMake(originX, originY, fieldDescriptionSize.width, fieldDescriptionSize.height); - originY = CGRectGetMaxY(self.fieldDescriptionLabel.frame) + verticalPadding; - - self.fieldDescriptionDivider.frame = CGRectMake(originX, originY, contentWidth, dividerLineHeight); - originY = CGRectGetMaxY(self.fieldDescriptionDivider.frame) + verticalPadding; - - for (UIView *argumentInputView in self.argumentInputViews) { - CGSize inputViewSize = [argumentInputView sizeThatFits:constrainSize]; - argumentInputView.frame = CGRectMake(originX, originY, inputViewSize.width, inputViewSize.height); - originY = CGRectGetMaxY(argumentInputView.frame) + verticalPadding; - } -} - -- (void)setBackgroundColor:(UIColor *)backgroundColor { - [super setBackgroundColor:backgroundColor]; - self.targetDescriptionLabel.backgroundColor = backgroundColor; - self.fieldDescriptionLabel.backgroundColor = backgroundColor; -} - -- (void)setTargetDescription:(NSString *)targetDescription { - if (![_targetDescription isEqual:targetDescription]) { - _targetDescription = targetDescription; - self.targetDescriptionLabel.text = targetDescription; - [self setNeedsLayout]; - } -} - -- (void)setFieldDescription:(NSString *)fieldDescription { - if (![_fieldDescription isEqual:fieldDescription]) { - _fieldDescription = fieldDescription; - self.fieldDescriptionLabel.text = fieldDescription; - [self setNeedsLayout]; - } -} - -- (void)setArgumentInputViews:(NSArray *)argumentInputViews { - if (![_argumentInputViews isEqual:argumentInputViews]) { - - for (FLEXArgumentInputView *inputView in _argumentInputViews) { - [inputView removeFromSuperview]; - } - - _argumentInputViews = argumentInputViews; - - for (FLEXArgumentInputView *newInputView in argumentInputViews) { - [self addSubview:newInputView]; - } - - [self setNeedsLayout]; - } -} - -+ (UIView *)dividerView { - UIView *dividerView = [UIView new]; - dividerView.backgroundColor = [self dividerColor]; - return dividerView; -} - -+ (UIColor *)dividerColor { - return UIColor.lightGrayColor; -} - -+ (CGFloat)horizontalPadding { - return 10.0; -} - -+ (CGFloat)verticalPadding { - return 20.0; -} - -+ (UIFont *)labelFont { - return [UIFont systemFontOfSize:14.0]; -} - -+ (CGFloat)dividerLineHeight { - return 1.0; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat horizontalPadding = [[self class] horizontalPadding]; - CGFloat verticalPadding = [[self class] verticalPadding]; - CGFloat dividerLineHeight = [[self class] dividerLineHeight]; - - CGFloat height = 0; - CGFloat availableWidth = size.width - 2.0 * horizontalPadding; - CGSize constrainSize = CGSizeMake(availableWidth, CGFLOAT_MAX); - - height += verticalPadding; - height += ceil([self.targetDescriptionLabel sizeThatFits:constrainSize].height); - height += verticalPadding; - height += dividerLineHeight; - height += verticalPadding; - height += ceil([self.fieldDescriptionLabel sizeThatFits:constrainSize].height); - height += verticalPadding; - height += dividerLineHeight; - height += verticalPadding; - - for (FLEXArgumentInputView *inputView in self.argumentInputViews) { - height += [inputView sizeThatFits:constrainSize].height; - height += verticalPadding; - } - - return CGSizeMake(size.width, height); -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.h b/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.h deleted file mode 100644 index c0250af7..00000000 --- a/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXFieldEditorViewController.h -// FLEX -// -// Created by Tanner on 11/22/18. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXVariableEditorViewController.h" -#import "FLEXProperty.h" -#import "FLEXIvar.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXFieldEditorViewController : FLEXVariableEditorViewController - -/// @return nil if the property is readonly or if the type is unsupported -+ (nullable instancetype)target:(id)target property:(FLEXProperty *)property commitHandler:(void(^_Nullable)(void))onCommit; -/// @return nil if the ivar type is unsupported -+ (nullable instancetype)target:(id)target ivar:(FLEXIvar *)ivar commitHandler:(void(^_Nullable)(void))onCommit; - -/// Subclasses can change the button title via the \c title property -@property (nonatomic, readonly) UIBarButtonItem *getterButton; - -- (void)getterButtonPressed:(id)sender; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.m b/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.m deleted file mode 100644 index ed5e6294..00000000 --- a/BHTwitter/Classes/Editing/FLEXFieldEditorViewController.m +++ /dev/null @@ -1,149 +0,0 @@ -// -// FLEXFieldEditorViewController.m -// FLEX -// -// Created by Tanner on 11/22/18. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFieldEditorViewController.h" -#import "FLEXFieldEditorView.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" -#import "UIBarButtonItem+FLEX.h" - -@interface FLEXFieldEditorViewController () - -@property (nonatomic) FLEXProperty *property; -@property (nonatomic) FLEXIvar *ivar; - -@property (nonatomic, readonly) id currentValue; -@property (nonatomic, readonly) const FLEXTypeEncoding *typeEncoding; -@property (nonatomic, readonly) NSString *fieldDescription; - -@end - -@implementation FLEXFieldEditorViewController - -#pragma mark - Initialization - -+ (instancetype)target:(id)target property:(nonnull FLEXProperty *)property commitHandler:(void(^_Nullable)(void))onCommit { - FLEXFieldEditorViewController *editor = [self target:target data:property commitHandler:onCommit]; - editor.title = [@"Property: " stringByAppendingString:property.name]; - editor.property = property; - return editor; -} - -+ (instancetype)target:(id)target ivar:(nonnull FLEXIvar *)ivar commitHandler:(void(^_Nullable)(void))onCommit { - FLEXFieldEditorViewController *editor = [self target:target data:ivar commitHandler:onCommit]; - editor.title = [@"Ivar: " stringByAppendingString:ivar.name]; - editor.ivar = ivar; - return editor; -} - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.view.backgroundColor = FLEXColor.groupedBackgroundColor; - - // Create getter button - _getterButton = [[UIBarButtonItem alloc] - initWithTitle:@"Get" - style:UIBarButtonItemStyleDone - target:self - action:@selector(getterButtonPressed:) - ]; - self.toolbarItems = @[ - UIBarButtonItem.flex_flexibleSpace, self.getterButton, self.actionButton - ]; - - // Configure input view - self.fieldEditorView.fieldDescription = self.fieldDescription; - FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:self.typeEncoding]; - inputView.inputValue = self.currentValue; - inputView.delegate = self; - self.fieldEditorView.argumentInputViews = @[inputView]; - - // Don't show a "set" button for switches; we mutate when the switch is flipped - if ([inputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { - self.actionButton.enabled = NO; - self.actionButton.title = @"Flip the switch to call the setter"; - // Put getter button before setter button - self.toolbarItems = @[ - UIBarButtonItem.flex_flexibleSpace, self.actionButton, self.getterButton - ]; - } -} - -- (void)actionButtonPressed:(id)sender { - if (self.property) { - id userInputObject = self.firstInputView.inputValue; - NSArray *arguments = userInputObject ? @[userInputObject] : nil; - SEL setterSelector = self.property.likelySetter; - NSError *error = nil; - [FLEXRuntimeUtility performSelector:setterSelector onObject:self.target withArguments:arguments error:&error]; - if (error) { - [FLEXAlert showAlert:@"Property Setter Failed" message:error.localizedDescription from:self]; - sender = nil; // Don't pop back - } - } else { - // TODO: check mutability and use mutableCopy if necessary; - // this currently could and would assign NSArray to NSMutableArray - [self.ivar setValue:self.firstInputView.inputValue onObject:self.target]; - } - - // Dismiss keyboard and handle committed changes - [super actionButtonPressed:sender]; - - // Go back after setting, but not for switches. - if (sender) { - [self.navigationController popViewControllerAnimated:YES]; - } else { - self.firstInputView.inputValue = self.currentValue; - } -} - -- (void)getterButtonPressed:(id)sender { - [self.fieldEditorView endEditing:YES]; - - [self exploreObjectOrPopViewController:self.currentValue]; -} - -- (void)argumentInputViewValueDidChange:(FLEXArgumentInputView *)argumentInputView { - if ([argumentInputView isKindOfClass:[FLEXArgumentInputSwitchView class]]) { - [self actionButtonPressed:nil]; - } -} - -#pragma mark - Private - -- (id)currentValue { - if (self.property) { - return [self.property getValue:self.target]; - } else { - return [self.ivar getValue:self.target]; - } -} - -- (const FLEXTypeEncoding *)typeEncoding { - if (self.property) { - return self.property.attributes.typeEncoding.UTF8String; - } else { - return self.ivar.typeEncoding.UTF8String; - } -} - -- (NSString *)fieldDescription { - if (self.property) { - return self.property.fullDescription; - } else { - return self.ivar.description; - } -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.h b/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.h deleted file mode 100644 index 6dc77a5d..00000000 --- a/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// FLEXMethodCallingViewController.h -// Flipboard -// -// Created by Ryan Olson on 5/23/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXVariableEditorViewController.h" -#import "FLEXMethod.h" - -@interface FLEXMethodCallingViewController : FLEXVariableEditorViewController - -+ (instancetype)target:(id)target method:(FLEXMethod *)method; - -@end diff --git a/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.m b/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.m deleted file mode 100644 index 9e25e6e8..00000000 --- a/BHTwitter/Classes/Editing/FLEXMethodCallingViewController.m +++ /dev/null @@ -1,110 +0,0 @@ -// -// FLEXMethodCallingViewController.m -// Flipboard -// -// Created by Ryan Olson on 5/23/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMethodCallingViewController.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXFieldEditorView.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXArgumentInputView.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXUtility.h" - -@interface FLEXMethodCallingViewController () -@property (nonatomic, readonly) FLEXMethod *method; -@end - -@implementation FLEXMethodCallingViewController - -+ (instancetype)target:(id)target method:(FLEXMethod *)method { - return [[self alloc] initWithTarget:target method:method]; -} - -- (id)initWithTarget:(id)target method:(FLEXMethod *)method { - NSParameterAssert(method.isInstanceMethod == !object_isClass(target)); - - self = [super initWithTarget:target data:method commitHandler:nil]; - if (self) { - self.title = method.isInstanceMethod ? @"Method: " : @"Class Method: "; - self.title = [self.title stringByAppendingString:method.selectorString]; - } - - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.actionButton.title = @"Call"; - - // Configure field editor view - self.fieldEditorView.argumentInputViews = [self argumentInputViews]; - self.fieldEditorView.fieldDescription = [NSString stringWithFormat: - @"Signature:\n%@\n\nReturn Type:\n%s", - self.method.description, (char *)self.method.returnType - ]; -} - -- (NSArray *)argumentInputViews { - Method method = self.method.objc_method; - NSArray *methodComponents = [FLEXRuntimeUtility prettyArgumentComponentsForMethod:method]; - NSMutableArray *argumentInputViews = [NSMutableArray new]; - unsigned int argumentIndex = kFLEXNumberOfImplicitArgs; - - for (NSString *methodComponent in methodComponents) { - char *argumentTypeEncoding = method_copyArgumentType(method, argumentIndex); - FLEXArgumentInputView *inputView = [FLEXArgumentInputViewFactory argumentInputViewForTypeEncoding:argumentTypeEncoding]; - free(argumentTypeEncoding); - - inputView.backgroundColor = self.view.backgroundColor; - inputView.title = methodComponent; - [argumentInputViews addObject:inputView]; - argumentIndex++; - } - - return argumentInputViews; -} - -- (void)actionButtonPressed:(id)sender { - // Gather arguments - NSMutableArray *arguments = [NSMutableArray new]; - for (FLEXArgumentInputView *inputView in self.fieldEditorView.argumentInputViews) { - // Use NSNull as a nil placeholder; it will be interpreted as nil - [arguments addObject:inputView.inputValue ?: NSNull.null]; - } - - // Call method - NSError *error = nil; - id returnValue = [FLEXRuntimeUtility - performSelector:self.method.selector - onObject:self.target - withArguments:arguments - error:&error - ]; - - // Dismiss keyboard and handle committed changes - [super actionButtonPressed:sender]; - - // Display return value or error - if (error) { - [FLEXAlert showAlert:@"Method Call Failed" message:error.localizedDescription from:self]; - } else if (returnValue) { - // For non-nil (or void) return types, push an explorer view controller to display the returned object - returnValue = [FLEXRuntimeUtility potentiallyUnwrapBoxedPointer:returnValue type:self.method.returnType]; - FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:returnValue]; - [self.navigationController pushViewController:explorer animated:YES]; - } else { - [self exploreObjectOrPopViewController:returnValue]; - } -} - -- (FLEXMethod *)method { - return _data; -} - -@end diff --git a/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.h b/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.h deleted file mode 100644 index 8225d6ca..00000000 --- a/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// FLEXVariableEditorViewController.h -// Flipboard -// -// Created by Ryan Olson on 5/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@class FLEXFieldEditorView; -@class FLEXArgumentInputView; - -NS_ASSUME_NONNULL_BEGIN - -/// An abstract screen for editing or configuring one or more variables. -/// "Target" is the target of the edit operation, and "data" is the data -/// you want to mutate or pass to the target when the action is performed. -/// The action may be something like calling a method, setting an ivar, etc. -@interface FLEXVariableEditorViewController : UIViewController { - @protected - id _target; - _Nullable id _data; - void (^_Nullable _commitHandler)(void); -} - -/// @param target The target of the operation -/// @param data The data associated with the operation -/// @param onCommit An action to perform when the data changes -+ (instancetype)target:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)(void))onCommit; -/// @param target The target of the operation -/// @param data The data associated with the operation -/// @param onCommit An action to perform when the data changes -- (id)initWithTarget:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)(void))onCommit; - -@property (nonatomic, readonly) id target; - -/// Convenience accessor since many subclasses only use one input view -@property (nonatomic, readonly, nullable) FLEXArgumentInputView *firstInputView; - -@property (nonatomic, readonly) FLEXFieldEditorView *fieldEditorView; -/// Subclasses can change the button title via the button's \c title property -@property (nonatomic, readonly) UIBarButtonItem *actionButton; - -/// Subclasses should override to provide "set" functionality. -/// The commit handler--if present--is called here. -- (void)actionButtonPressed:(nullable id)sender; - -/// Pushes an explorer view controller for the given object -/// or pops the current view controller. -- (void)exploreObjectOrPopViewController:(nullable id)objectOrNil; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.m b/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.m deleted file mode 100644 index 9085aab7..00000000 --- a/BHTwitter/Classes/Editing/FLEXVariableEditorViewController.m +++ /dev/null @@ -1,141 +0,0 @@ -// -// FLEXVariableEditorViewController.m -// Flipboard -// -// Created by Ryan Olson on 5/16/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXVariableEditorViewController.h" -#import "FLEXFieldEditorView.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXUtility.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXArgumentInputView.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXObjectExplorerViewController.h" -#import "UIBarButtonItem+FLEX.h" - -@interface FLEXVariableEditorViewController () -@property (nonatomic) UIScrollView *scrollView; -@end - -@implementation FLEXVariableEditorViewController - -#pragma mark - Initialization - -+ (instancetype)target:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)(void))onCommit { - return [[self alloc] initWithTarget:target data:data commitHandler:onCommit]; -} - -- (id)initWithTarget:(id)target data:(nullable id)data commitHandler:(void(^_Nullable)(void))onCommit { - self = [super init]; - if (self) { - _target = target; - _data = data; - _commitHandler = onCommit; - [NSNotificationCenter.defaultCenter - addObserver:self selector:@selector(keyboardDidShow:) - name:UIKeyboardDidShowNotification object:nil - ]; - [NSNotificationCenter.defaultCenter - addObserver:self selector:@selector(keyboardWillHide:) - name:UIKeyboardWillHideNotification object:nil - ]; - } - - return self; -} - -- (void)dealloc { - [NSNotificationCenter.defaultCenter removeObserver:self]; -} - -#pragma mark - UIViewController methods - -- (void)keyboardDidShow:(NSNotification *)notification { - CGRect keyboardRectInWindow = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; - CGSize keyboardSize = [self.view convertRect:keyboardRectInWindow fromView:nil].size; - UIEdgeInsets scrollInsets = self.scrollView.contentInset; - scrollInsets.bottom = keyboardSize.height; - self.scrollView.contentInset = scrollInsets; - self.scrollView.scrollIndicatorInsets = scrollInsets; - - // Find the active input view and scroll to make sure it's visible. - for (FLEXArgumentInputView *argumentInputView in self.fieldEditorView.argumentInputViews) { - if (argumentInputView.inputViewIsFirstResponder) { - CGRect scrollToVisibleRect = [self.scrollView convertRect:argumentInputView.bounds fromView:argumentInputView]; - [self.scrollView scrollRectToVisible:scrollToVisibleRect animated:YES]; - break; - } - } -} - -- (void)keyboardWillHide:(NSNotification *)notification { - UIEdgeInsets scrollInsets = self.scrollView.contentInset; - scrollInsets.bottom = 0.0; - self.scrollView.contentInset = scrollInsets; - self.scrollView.scrollIndicatorInsets = scrollInsets; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.view.backgroundColor = FLEXColor.scrollViewBackgroundColor; - - self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; - self.scrollView.backgroundColor = self.view.backgroundColor; - self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - self.scrollView.delegate = self; - [self.view addSubview:self.scrollView]; - - _fieldEditorView = [FLEXFieldEditorView new]; - self.fieldEditorView.targetDescription = [NSString stringWithFormat:@"%@ %p", [self.target class], self.target]; - [self.scrollView addSubview:self.fieldEditorView]; - - _actionButton = [[UIBarButtonItem alloc] - initWithTitle:@"Set" - style:UIBarButtonItemStyleDone - target:self - action:@selector(actionButtonPressed:) - ]; - - self.navigationController.toolbarHidden = NO; - self.toolbarItems = @[UIBarButtonItem.flex_flexibleSpace, self.actionButton]; -} - -- (void)viewWillLayoutSubviews { - CGSize constrainSize = CGSizeMake(self.scrollView.bounds.size.width, CGFLOAT_MAX); - CGSize fieldEditorSize = [self.fieldEditorView sizeThatFits:constrainSize]; - self.fieldEditorView.frame = CGRectMake(0, 0, fieldEditorSize.width, fieldEditorSize.height); - self.scrollView.contentSize = fieldEditorSize; -} - -#pragma mark - Public - -- (FLEXArgumentInputView *)firstInputView { - return [self.fieldEditorView argumentInputViews].firstObject; -} - -- (void)actionButtonPressed:(id)sender { - // Subclasses can override - [self.fieldEditorView endEditing:YES]; - if (_commitHandler) { - _commitHandler(); - } -} - -- (void)exploreObjectOrPopViewController:(id)objectOrNil { - if (objectOrNil) { - // For non-nil (or void) return types, push an explorer view controller to display the object - FLEXObjectExplorerViewController *explorerViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:objectOrNil]; - [self.navigationController pushViewController:explorerViewController animated:YES]; - } else { - // If we didn't get a returned object but the method call succeeded, - // pop this view controller off the stack to indicate that the call went through. - [self.navigationController popViewControllerAnimated:YES]; - } -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h b/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h deleted file mode 100644 index 5e4c84a6..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXBookmarkManager.h -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXBookmarkManager : NSObject - -@property (nonatomic, readonly, class) NSMutableArray *bookmarks; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.m b/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.m deleted file mode 100644 index fc9606d4..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarkManager.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEXBookmarkManager.m -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXBookmarkManager.h" - -static NSMutableArray *kFLEXBookmarkManagerBookmarks = nil; - -@implementation FLEXBookmarkManager - -+ (void)initialize { - if (self == [FLEXBookmarkManager class]) { - kFLEXBookmarkManagerBookmarks = [NSMutableArray new]; - } -} - -+ (NSMutableArray *)bookmarks { - return kFLEXBookmarkManagerBookmarks; -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h b/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h deleted file mode 100644 index 514184ff..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXBookmarksViewController.h -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXBookmarksViewController : FLEXTableViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.m b/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.m deleted file mode 100644 index f14140a3..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Bookmarks/FLEXBookmarksViewController.m +++ /dev/null @@ -1,235 +0,0 @@ -// -// FLEXBookmarksViewController.m -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXBookmarksViewController.h" -#import "FLEXExplorerViewController.h" -#import "FLEXNavigationController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXBookmarkManager.h" -#import "UIBarButtonItem+FLEX.h" -#import "FLEXColor.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXTableView.h" - -@interface FLEXBookmarksViewController () -@property (nonatomic, copy) NSArray *bookmarks; -@property (nonatomic, readonly) FLEXExplorerViewController *corePresenter; -@end - -@implementation FLEXBookmarksViewController - -#pragma mark - Initialization - -- (id)init { - return [self initWithStyle:UITableViewStylePlain]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.navigationController.hidesBarsOnSwipe = NO; - self.tableView.allowsMultipleSelectionDuringEditing = YES; - - [self reloadData]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self setupDefaultBarItems]; -} - - -#pragma mark - Private - -- (void)reloadData { - // We assume the bookmarks aren't going to change out from under us, since - // presenting any other tool via keyboard shortcuts should dismiss us first - self.bookmarks = FLEXBookmarkManager.bookmarks; - self.title = [NSString stringWithFormat:@"Bookmarks (%@)", @(self.bookmarks.count)]; -} - -- (void)setupDefaultBarItems { - self.navigationItem.rightBarButtonItem = FLEXBarButtonItemSystem(Done, self, @selector(dismissAnimated)); - self.toolbarItems = @[ - UIBarButtonItem.flex_flexibleSpace, - FLEXBarButtonItemSystem(Edit, self, @selector(toggleEditing)), - ]; - - // Disable editing if no bookmarks available - self.toolbarItems.lastObject.enabled = self.bookmarks.count > 0; -} - -- (void)setupEditingBarItems { - self.navigationItem.rightBarButtonItem = nil; - self.toolbarItems = @[ - [UIBarButtonItem flex_itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)], - UIBarButtonItem.flex_flexibleSpace, - // We use a non-system done item because we change its title dynamically - [UIBarButtonItem flex_doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)] - ]; - - self.toolbarItems.firstObject.tintColor = FLEXColor.destructiveColor; -} - -- (FLEXExplorerViewController *)corePresenter { - // We must be presented by a FLEXExplorerViewController, or presented - // by another view controller that was presented by FLEXExplorerViewController - FLEXExplorerViewController *presenter = (id)self.presentingViewController; - presenter = (id)presenter.presentingViewController ?: presenter; - presenter = (id)presenter.presentingViewController ?: presenter; - NSAssert( - [presenter isKindOfClass:[FLEXExplorerViewController class]], - @"The bookmarks view controller expects to be presented by the explorer controller" - ); - return presenter; -} - -#pragma mark Button Actions - -- (void)dismissAnimated { - [self dismissAnimated:nil]; -} - -- (void)dismissAnimated:(id)selectedObject { - if (selectedObject) { - UIViewController *explorer = [FLEXObjectExplorerFactory - explorerViewControllerForObject:selectedObject - ]; - if ([self.presentingViewController isKindOfClass:[FLEXNavigationController class]]) { - // I am presented on an existing navigation stack, so - // dismiss myself and push the bookmark there - UINavigationController *presenter = (id)self.presentingViewController; - [presenter dismissViewControllerAnimated:YES completion:^{ - [presenter pushViewController:explorer animated:YES]; - }]; - } else { - // Dismiss myself and present explorer - UIViewController *presenter = self.corePresenter; - [presenter dismissViewControllerAnimated:YES completion:^{ - [presenter presentViewController:[FLEXNavigationController - withRootViewController:explorer - ] animated:YES completion:nil]; - }]; - } - } else { - // Just dismiss myself - [self dismissViewControllerAnimated:YES completion:nil]; - } -} - -- (void)toggleEditing { - NSArray *selected = self.tableView.indexPathsForSelectedRows; - self.editing = !self.editing; - - if (self.isEditing) { - [self setupEditingBarItems]; - } else { - [self setupDefaultBarItems]; - - // Get index set of bookmarks to close - NSMutableIndexSet *indexes = [NSMutableIndexSet new]; - for (NSIndexPath *ip in selected) { - [indexes addIndex:ip.row]; - } - - if (selected.count) { - // Close bookmarks and update data source - [FLEXBookmarkManager.bookmarks removeObjectsAtIndexes:indexes]; - [self reloadData]; - - // Remove deleted rows - [self.tableView deleteRowsAtIndexPaths:selected withRowAnimation:UITableViewRowAnimationAutomatic]; - } - } -} - -- (void)closeAllButtonPressed:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - NSInteger count = self.bookmarks.count; - NSString *title = FLEXPluralFormatString(count, @"Remove %@ bookmarks", @"Remove %@ bookmark"); - make.button(title).destructiveStyle().handler(^(NSArray *strings) { - [self closeAll]; - [self toggleEditing]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - -- (void)closeAll { - NSInteger rowCount = self.bookmarks.count; - - // Close bookmarks and update data source - [FLEXBookmarkManager.bookmarks removeAllObjects]; - [self reloadData]; - - // Delete rows from table view - NSArray *allRows = [NSArray flex_forEachUpTo:rowCount map:^id(NSUInteger row) { - return [NSIndexPath indexPathForRow:row inSection:0]; - }]; - [self.tableView deleteRowsAtIndexPaths:allRows withRowAnimation:UITableViewRowAnimationAutomatic]; -} - - -#pragma mark - Table View Data Source - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.bookmarks.count; -} - -- (UITableViewCell *)tableView:(FLEXTableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXDetailCell forIndexPath:indexPath]; - - id object = self.bookmarks[indexPath.row]; - cell.textLabel.text = [FLEXRuntimeUtility safeDescriptionForObject:object]; - cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ — %p", [object class], object]; - - return cell; -} - - -#pragma mark - Table View Delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (self.editing) { - // Case: editing with multi-select - self.toolbarItems.lastObject.title = @"Remove Selected"; - self.toolbarItems.lastObject.tintColor = FLEXColor.destructiveColor; - } else { - // Case: selected a bookmark - [self dismissAnimated:self.bookmarks[indexPath.row]]; - } -} - -- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { - NSParameterAssert(self.editing); - - if (tableView.indexPathsForSelectedRows.count == 0) { - self.toolbarItems.lastObject.title = @"Done"; - self.toolbarItems.lastObject.tintColor = self.view.tintColor; - } -} - -- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (void)tableView:(UITableView *)table -commitEditingStyle:(UITableViewCellEditingStyle)edit -forRowAtIndexPath:(NSIndexPath *)indexPath { - NSParameterAssert(edit == UITableViewCellEditingStyleDelete); - - // Remove bookmark and update data source - [FLEXBookmarkManager.bookmarks removeObjectAtIndex:indexPath.row]; - [self reloadData]; - - // Delete row from table view - [table deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.h b/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.h deleted file mode 100644 index 6f92b34b..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.h +++ /dev/null @@ -1,61 +0,0 @@ -// -// FLEXExplorerViewController.h -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXExplorerToolbar.h" - -@class FLEXWindow; -@protocol FLEXExplorerViewControllerDelegate; - -/// A view controller that manages the FLEX toolbar. -@interface FLEXExplorerViewController : UIViewController - -@property (nonatomic, weak) id delegate; -@property (nonatomic, readonly) BOOL wantsWindowToBecomeKey; - -@property (nonatomic, readonly) FLEXExplorerToolbar *explorerToolbar; - -- (BOOL)shouldReceiveTouchAtWindowPoint:(CGPoint)pointInWindowCoordinates; - -/// @brief Used to present (or dismiss) a modal view controller ("tool"), -/// typically triggered by pressing a button in the toolbar. -/// -/// If a tool is already presented, this method simply dismisses it and calls the completion block. -/// If no tool is presented, @code future() @endcode is presented and the completion block is called. -- (void)toggleToolWithViewControllerProvider:(UINavigationController *(^)(void))future - completion:(void (^)(void))completion; - -/// @brief Used to present (or dismiss) a modal view controller ("tool"), -/// typically triggered by pressing a button in the toolbar. -/// -/// If a tool is already presented, this method dismisses it and presents the given tool. -/// The completion block is called once the tool has been presented. -- (void)presentTool:(UINavigationController *(^)(void))future - completion:(void (^)(void))completion; - -// Keyboard shortcut helpers - -- (void)toggleSelectTool; -- (void)toggleMoveTool; -- (void)toggleViewsTool; -- (void)toggleMenuTool; - -/// @return YES if the explorer used the key press to perform an action, NO otherwise -- (BOOL)handleDownArrowKeyPressed; -/// @return YES if the explorer used the key press to perform an action, NO otherwise -- (BOOL)handleUpArrowKeyPressed; -/// @return YES if the explorer used the key press to perform an action, NO otherwise -- (BOOL)handleRightArrowKeyPressed; -/// @return YES if the explorer used the key press to perform an action, NO otherwise -- (BOOL)handleLeftArrowKeyPressed; - -@end - -#pragma mark - -@protocol FLEXExplorerViewControllerDelegate -- (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerViewController; -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.m b/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.m deleted file mode 100644 index 57550da3..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXExplorerViewController.m +++ /dev/null @@ -1,1046 +0,0 @@ -// -// FLEXExplorerViewController.m -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXExplorerViewController.h" -#import "FLEXExplorerToolbarItem.h" -#import "FLEXUtility.h" -#import "FLEXWindow.h" -#import "FLEXTabList.h" -#import "FLEXNavigationController.h" -#import "FLEXHierarchyViewController.h" -#import "FLEXGlobalsViewController.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXNetworkMITMViewController.h" -#import "FLEXTabsViewController.h" -#import "FLEXWindowManagerController.h" -#import "FLEXViewControllersViewController.h" -#import "NSUserDefaults+FLEX.h" - -typedef NS_ENUM(NSUInteger, FLEXExplorerMode) { - FLEXExplorerModeDefault, - FLEXExplorerModeSelect, - FLEXExplorerModeMove -}; - -@interface FLEXExplorerViewController () - -/// Tracks the currently active tool/mode -@property (nonatomic) FLEXExplorerMode currentMode; - -/// Gesture recognizer for dragging a view in move mode -@property (nonatomic) UIPanGestureRecognizer *movePanGR; - -/// Gesture recognizer for showing additional details on the selected view -@property (nonatomic) UITapGestureRecognizer *detailsTapGR; - -/// Only valid while a move pan gesture is in progress. -@property (nonatomic) CGRect selectedViewFrameBeforeDragging; - -/// Only valid while a toolbar drag pan gesture is in progress. -@property (nonatomic) CGRect toolbarFrameBeforeDragging; - -/// Only valid while a selected view pan gesture is in progress. -@property (nonatomic) CGFloat selectedViewLastPanX; - -/// Borders of all the visible views in the hierarchy at the selection point. -/// The keys are NSValues with the corresponding view (nonretained). -@property (nonatomic) NSDictionary *outlineViewsForVisibleViews; - -/// The actual views at the selection point with the deepest view last. -@property (nonatomic) NSArray *viewsAtTapPoint; - -/// The view that we're currently highlighting with an overlay and displaying details for. -@property (nonatomic) UIView *selectedView; - -/// A colored transparent overlay to indicate that the view is selected. -@property (nonatomic) UIView *selectedViewOverlay; - -/// Used to actuate changes in view selection on iOS 10+ -@property (nonatomic, readonly) UISelectionFeedbackGenerator *selectionFBG API_AVAILABLE(ios(10.0)); - -/// self.view.window as a \c FLEXWindow -@property (nonatomic, readonly) FLEXWindow *window; - -/// All views that we're KVOing. Used to help us clean up properly. -@property (nonatomic) NSMutableSet *observedViews; - -/// Used to preserve the target app's UIMenuController items. -@property (nonatomic) NSArray *appMenuItems; - -@end - -@implementation FLEXExplorerViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - self.observedViews = [NSMutableSet new]; - } - return self; -} - -- (void)dealloc { - for (UIView *view in _observedViews) { - [self stopObservingView:view]; - } -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Toolbar - _explorerToolbar = [FLEXExplorerToolbar new]; - - // Start the toolbar off below any bars that may be at the top of the view. - CGFloat toolbarOriginY = NSUserDefaults.standardUserDefaults.flex_toolbarTopMargin; - - CGRect safeArea = [self viewSafeArea]; - CGSize toolbarSize = [self.explorerToolbar sizeThatFits:CGSizeMake( - CGRectGetWidth(self.view.bounds), CGRectGetHeight(safeArea) - )]; - [self updateToolbarPositionWithUnconstrainedFrame:CGRectMake( - CGRectGetMinX(safeArea), toolbarOriginY, toolbarSize.width, toolbarSize.height - )]; - self.explorerToolbar.autoresizingMask = UIViewAutoresizingFlexibleWidth | - UIViewAutoresizingFlexibleBottomMargin | - UIViewAutoresizingFlexibleTopMargin; - [self.view addSubview:self.explorerToolbar]; - [self setupToolbarActions]; - [self setupToolbarGestures]; - - // View selection - UITapGestureRecognizer *selectionTapGR = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleSelectionTap:) - ]; - [self.view addGestureRecognizer:selectionTapGR]; - - // View moving - self.movePanGR = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleMovePan:)]; - self.movePanGR.enabled = self.currentMode == FLEXExplorerModeMove; - [self.view addGestureRecognizer:self.movePanGR]; - - // Feedback - if (@available(iOS 10.0, *)) { - _selectionFBG = [UISelectionFeedbackGenerator new]; - } -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [self updateButtonStates]; -} - - -#pragma mark - Rotation - -- (UIViewController *)viewControllerForRotationAndOrientation { - UIViewController *viewController = FLEXUtility.appKeyWindow.rootViewController; - // Obfuscating selector _viewControllerForSupportedInterfaceOrientations - NSString *viewControllerSelectorString = [@[ - @"_vie", @"wContro", @"llerFor", @"Supported", @"Interface", @"Orientations" - ] componentsJoinedByString:@""]; - SEL viewControllerSelector = NSSelectorFromString(viewControllerSelectorString); - if ([viewController respondsToSelector:viewControllerSelector]) { - viewController = [viewController valueForKey:viewControllerSelectorString]; - } - - return viewController; -} - -- (UIInterfaceOrientationMask)supportedInterfaceOrientations { - // Commenting this out until I can figure out a better way to solve this -// if (self.window.isKeyWindow) { -// [self.window resignKeyWindow]; -// } - - UIViewController *viewControllerToAsk = [self viewControllerForRotationAndOrientation]; - UIInterfaceOrientationMask supportedOrientations = FLEXUtility.infoPlistSupportedInterfaceOrientationsMask; - if (viewControllerToAsk && ![viewControllerToAsk isKindOfClass:[self class]]) { - supportedOrientations = [viewControllerToAsk supportedInterfaceOrientations]; - } - - // The UIViewController docs state that this method must not return zero. - // If we weren't able to get a valid value for the supported interface - // orientations, default to all supported. - if (supportedOrientations == 0) { - supportedOrientations = UIInterfaceOrientationMaskAll; - } - - return supportedOrientations; -} - -- (BOOL)shouldAutorotate { - UIViewController *viewControllerToAsk = [self viewControllerForRotationAndOrientation]; - BOOL shouldAutorotate = YES; - if (viewControllerToAsk && viewControllerToAsk != self) { - shouldAutorotate = [viewControllerToAsk shouldAutorotate]; - } - return shouldAutorotate; -} - -- (void)viewWillTransitionToSize:(CGSize)size - withTransitionCoordinator:(id)coordinator { - [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - [coordinator animateAlongsideTransition:^(id context) { - for (UIView *outlineView in self.outlineViewsForVisibleViews.allValues) { - outlineView.hidden = YES; - } - self.selectedViewOverlay.hidden = YES; - } completion:^(id context) { - for (UIView *view in self.viewsAtTapPoint) { - NSValue *key = [NSValue valueWithNonretainedObject:view]; - UIView *outlineView = self.outlineViewsForVisibleViews[key]; - outlineView.frame = [self frameInLocalCoordinatesForView:view]; - if (self.currentMode == FLEXExplorerModeSelect) { - outlineView.hidden = NO; - } - } - - if (self.selectedView) { - self.selectedViewOverlay.frame = [self frameInLocalCoordinatesForView:self.selectedView]; - self.selectedViewOverlay.hidden = NO; - } - }]; -} - - -#pragma mark - Setter Overrides - -- (void)setSelectedView:(UIView *)selectedView { - if (![_selectedView isEqual:selectedView]) { - if (![self.viewsAtTapPoint containsObject:_selectedView]) { - [self stopObservingView:_selectedView]; - } - - _selectedView = selectedView; - - [self beginObservingView:selectedView]; - - // Update the toolbar and selected overlay - self.explorerToolbar.selectedViewDescription = [FLEXUtility - descriptionForView:selectedView includingFrame:YES - ]; - self.explorerToolbar.selectedViewOverlayColor = [FLEXUtility - consistentRandomColorForObject:selectedView - ]; - - if (selectedView) { - if (!self.selectedViewOverlay) { - self.selectedViewOverlay = [UIView new]; - [self.view addSubview:self.selectedViewOverlay]; - self.selectedViewOverlay.layer.borderWidth = 1.0; - } - UIColor *outlineColor = [FLEXUtility consistentRandomColorForObject:selectedView]; - self.selectedViewOverlay.backgroundColor = [outlineColor colorWithAlphaComponent:0.2]; - self.selectedViewOverlay.layer.borderColor = outlineColor.CGColor; - self.selectedViewOverlay.frame = [self.view convertRect:selectedView.bounds fromView:selectedView]; - - // Make sure the selected overlay is in front of all the other subviews - // except the toolbar, which should always stay on top. - [self.view bringSubviewToFront:self.selectedViewOverlay]; - [self.view bringSubviewToFront:self.explorerToolbar]; - } else { - [self.selectedViewOverlay removeFromSuperview]; - self.selectedViewOverlay = nil; - } - - // Some of the button states depend on whether we have a selected view. - [self updateButtonStates]; - } -} - -- (void)setViewsAtTapPoint:(NSArray *)viewsAtTapPoint { - if (![_viewsAtTapPoint isEqual:viewsAtTapPoint]) { - for (UIView *view in _viewsAtTapPoint) { - if (view != self.selectedView) { - [self stopObservingView:view]; - } - } - - _viewsAtTapPoint = viewsAtTapPoint; - - for (UIView *view in viewsAtTapPoint) { - [self beginObservingView:view]; - } - } -} - -- (void)setCurrentMode:(FLEXExplorerMode)currentMode { - if (_currentMode != currentMode) { - _currentMode = currentMode; - switch (currentMode) { - case FLEXExplorerModeDefault: - [self removeAndClearOutlineViews]; - self.viewsAtTapPoint = nil; - self.selectedView = nil; - break; - - case FLEXExplorerModeSelect: - // Make sure the outline views are unhidden in case we came from the move mode. - for (NSValue *key in self.outlineViewsForVisibleViews) { - UIView *outlineView = self.outlineViewsForVisibleViews[key]; - outlineView.hidden = NO; - } - break; - - case FLEXExplorerModeMove: - // Hide all the outline views to focus on the selected view, - // which is the only one that will move. - for (NSValue *key in self.outlineViewsForVisibleViews) { - UIView *outlineView = self.outlineViewsForVisibleViews[key]; - outlineView.hidden = YES; - } - break; - } - self.movePanGR.enabled = currentMode == FLEXExplorerModeMove; - [self updateButtonStates]; - } -} - - -#pragma mark - View Tracking - -- (void)beginObservingView:(UIView *)view { - // Bail if we're already observing this view or if there's nothing to observe. - if (!view || [self.observedViews containsObject:view]) { - return; - } - - for (NSString *keyPath in self.viewKeyPathsToTrack) { - [view addObserver:self forKeyPath:keyPath options:0 context:NULL]; - } - - [self.observedViews addObject:view]; -} - -- (void)stopObservingView:(UIView *)view { - if (!view) { - return; - } - - for (NSString *keyPath in self.viewKeyPathsToTrack) { - [view removeObserver:self forKeyPath:keyPath]; - } - - [self.observedViews removeObject:view]; -} - -- (NSArray *)viewKeyPathsToTrack { - static NSArray *trackedViewKeyPaths = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *frameKeyPath = NSStringFromSelector(@selector(frame)); - trackedViewKeyPaths = @[frameKeyPath]; - }); - return trackedViewKeyPaths; -} - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object - change:(NSDictionary *)change - context:(void *)context { - [self updateOverlayAndDescriptionForObjectIfNeeded:object]; -} - -- (void)updateOverlayAndDescriptionForObjectIfNeeded:(id)object { - NSUInteger indexOfView = [self.viewsAtTapPoint indexOfObject:object]; - if (indexOfView != NSNotFound) { - UIView *view = self.viewsAtTapPoint[indexOfView]; - NSValue *key = [NSValue valueWithNonretainedObject:view]; - UIView *outline = self.outlineViewsForVisibleViews[key]; - if (outline) { - outline.frame = [self frameInLocalCoordinatesForView:view]; - } - } - if (object == self.selectedView) { - // Update the selected view description since we show the frame value there. - self.explorerToolbar.selectedViewDescription = [FLEXUtility - descriptionForView:self.selectedView includingFrame:YES - ]; - CGRect selectedViewOutlineFrame = [self frameInLocalCoordinatesForView:self.selectedView]; - self.selectedViewOverlay.frame = selectedViewOutlineFrame; - } -} - -- (CGRect)frameInLocalCoordinatesForView:(UIView *)view { - // Convert to window coordinates since the view may be in a different window than our view - CGRect frameInWindow = [view convertRect:view.bounds toView:nil]; - // Convert from the window to our view's coordinate space - return [self.view convertRect:frameInWindow fromView:nil]; -} - - -#pragma mark - Toolbar Buttons - -- (void)setupToolbarActions { - FLEXExplorerToolbar *toolbar = self.explorerToolbar; - NSDictionary *actionsToItems = @{ - NSStringFromSelector(@selector(selectButtonTapped:)): toolbar.selectItem, - NSStringFromSelector(@selector(hierarchyButtonTapped:)): toolbar.hierarchyItem, - NSStringFromSelector(@selector(recentButtonTapped:)): toolbar.recentItem, - NSStringFromSelector(@selector(moveButtonTapped:)): toolbar.moveItem, - NSStringFromSelector(@selector(globalsButtonTapped:)): toolbar.globalsItem, - NSStringFromSelector(@selector(closeButtonTapped:)): toolbar.closeItem, - }; - - [actionsToItems enumerateKeysAndObjectsUsingBlock:^(NSString *sel, FLEXExplorerToolbarItem *item, BOOL *stop) { - [item addTarget:self action:NSSelectorFromString(sel) forControlEvents:UIControlEventTouchUpInside]; - }]; -} - -- (void)selectButtonTapped:(FLEXExplorerToolbarItem *)sender { - [self toggleSelectTool]; -} - -- (void)hierarchyButtonTapped:(FLEXExplorerToolbarItem *)sender { - [self toggleViewsTool]; -} - -- (UIWindow *)statusWindow { - NSString *statusBarString = [NSString stringWithFormat:@"%@arWindow", @"_statusB"]; - return [UIApplication.sharedApplication valueForKey:statusBarString]; -} - -- (void)recentButtonTapped:(FLEXExplorerToolbarItem *)sender { - NSAssert(FLEXTabList.sharedList.activeTab, @"Must have active tab"); - [self presentViewController:FLEXTabList.sharedList.activeTab animated:YES completion:nil]; -} - -- (void)moveButtonTapped:(FLEXExplorerToolbarItem *)sender { - [self toggleMoveTool]; -} - -- (void)globalsButtonTapped:(FLEXExplorerToolbarItem *)sender { - [self toggleMenuTool]; -} - -- (void)closeButtonTapped:(FLEXExplorerToolbarItem *)sender { - self.currentMode = FLEXExplorerModeDefault; - [self.delegate explorerViewControllerDidFinish:self]; -} - -- (void)updateButtonStates { - FLEXExplorerToolbar *toolbar = self.explorerToolbar; - - toolbar.selectItem.selected = self.currentMode == FLEXExplorerModeSelect; - - // Move only enabled when an object is selected. - BOOL hasSelectedObject = self.selectedView != nil; - toolbar.moveItem.enabled = hasSelectedObject; - toolbar.moveItem.selected = self.currentMode == FLEXExplorerModeMove; - - // Recent only enabled when we have a last active tab - toolbar.recentItem.enabled = FLEXTabList.sharedList.activeTab != nil; -} - - -#pragma mark - Toolbar Dragging - -- (void)setupToolbarGestures { - FLEXExplorerToolbar *toolbar = self.explorerToolbar; - - // Pan gesture for dragging. - [toolbar.dragHandle addGestureRecognizer:[[UIPanGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarPanGesture:) - ]]; - - // Tap gesture for hinting. - [toolbar.dragHandle addGestureRecognizer:[[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarHintTapGesture:) - ]]; - - // Tap gesture for showing additional details - self.detailsTapGR = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarDetailsTapGesture:) - ]; - [toolbar.selectedViewDescriptionContainer addGestureRecognizer:self.detailsTapGR]; - - // Swipe gestures for selecting deeper / higher views at a point - UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] - initWithTarget:self action:@selector(handleChangeViewAtPointGesture:) - ]; - [toolbar.selectedViewDescriptionContainer addGestureRecognizer:panGesture]; - - // Long press gesture to present tabs manager - [toolbar.globalsItem addGestureRecognizer:[[UILongPressGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarShowTabsGesture:) - ]]; - - // Long press gesture to present window manager - [toolbar.selectItem addGestureRecognizer:[[UILongPressGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarWindowManagerGesture:) - ]]; - - // Long press gesture to present view controllers at tap - [toolbar.hierarchyItem addGestureRecognizer:[[UILongPressGestureRecognizer alloc] - initWithTarget:self action:@selector(handleToolbarShowViewControllersGesture:) - ]]; -} - -- (void)handleToolbarPanGesture:(UIPanGestureRecognizer *)panGR { - switch (panGR.state) { - case UIGestureRecognizerStateBegan: - self.toolbarFrameBeforeDragging = self.explorerToolbar.frame; - [self updateToolbarPositionWithDragGesture:panGR]; - break; - - case UIGestureRecognizerStateChanged: - case UIGestureRecognizerStateEnded: - [self updateToolbarPositionWithDragGesture:panGR]; - break; - - default: - break; - } -} - -- (void)updateToolbarPositionWithDragGesture:(UIPanGestureRecognizer *)panGR { - CGPoint translation = [panGR translationInView:self.view]; - CGRect newToolbarFrame = self.toolbarFrameBeforeDragging; - newToolbarFrame.origin.y += translation.y; - - [self updateToolbarPositionWithUnconstrainedFrame:newToolbarFrame]; -} - -- (void)updateToolbarPositionWithUnconstrainedFrame:(CGRect)unconstrainedFrame { - CGRect safeArea = [self viewSafeArea]; - // We only constrain the Y-axis because we want the toolbar - // to handle the X-axis safeArea layout by itself - CGFloat minY = CGRectGetMinY(safeArea); - CGFloat maxY = CGRectGetMaxY(safeArea) - unconstrainedFrame.size.height; - if (unconstrainedFrame.origin.y < minY) { - unconstrainedFrame.origin.y = minY; - } else if (unconstrainedFrame.origin.y > maxY) { - unconstrainedFrame.origin.y = maxY; - } - - self.explorerToolbar.frame = unconstrainedFrame; - NSUserDefaults.standardUserDefaults.flex_toolbarTopMargin = unconstrainedFrame.origin.y; -} - -- (void)handleToolbarHintTapGesture:(UITapGestureRecognizer *)tapGR { - // Bounce the toolbar to indicate that it is draggable. - // TODO: make it bouncier. - if (tapGR.state == UIGestureRecognizerStateRecognized) { - CGRect originalToolbarFrame = self.explorerToolbar.frame; - const NSTimeInterval kHalfwayDuration = 0.2; - const CGFloat kVerticalOffset = 30.0; - [UIView animateWithDuration:kHalfwayDuration delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ - CGRect newToolbarFrame = self.explorerToolbar.frame; - newToolbarFrame.origin.y += kVerticalOffset; - self.explorerToolbar.frame = newToolbarFrame; - } completion:^(BOOL finished) { - [UIView animateWithDuration:kHalfwayDuration delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{ - self.explorerToolbar.frame = originalToolbarFrame; - } completion:nil]; - }]; - } -} - -- (void)handleToolbarDetailsTapGesture:(UITapGestureRecognizer *)tapGR { - if (tapGR.state == UIGestureRecognizerStateRecognized && self.selectedView) { - UIViewController *topStackVC = [FLEXObjectExplorerFactory explorerViewControllerForObject:self.selectedView]; - [self presentViewController: - [FLEXNavigationController withRootViewController:topStackVC] - animated:YES completion:nil]; - } -} - -- (void)handleToolbarShowTabsGesture:(UILongPressGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateBegan) { - // Back up the UIMenuController items since dismissViewController: will attempt to replace them - self.appMenuItems = UIMenuController.sharedMenuController.menuItems; - - // Don't use FLEXNavigationController because the tab viewer itself is not a tab - [super presentViewController:[[UINavigationController alloc] - initWithRootViewController:[FLEXTabsViewController new] - ] animated:YES completion:nil]; - } -} - -- (void)handleToolbarWindowManagerGesture:(UILongPressGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateBegan) { - // Back up the UIMenuController items since dismissViewController: will attempt to replace them - self.appMenuItems = UIMenuController.sharedMenuController.menuItems; - - [super presentViewController:[FLEXNavigationController - withRootViewController:[FLEXWindowManagerController new] - ] animated:YES completion:nil]; - } -} - -- (void)handleToolbarShowViewControllersGesture:(UILongPressGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateBegan && self.viewsAtTapPoint.count) { - // Back up the UIMenuController items since dismissViewController: will attempt to replace them - self.appMenuItems = UIMenuController.sharedMenuController.menuItems; - - UIViewController *list = [FLEXViewControllersViewController - controllersForViews:self.viewsAtTapPoint - ]; - [self presentViewController: - [FLEXNavigationController withRootViewController:list - ] animated:YES completion:nil]; - } -} - - -#pragma mark - View Selection - -- (void)handleSelectionTap:(UITapGestureRecognizer *)tapGR { - // Only if we're in selection mode - if (self.currentMode == FLEXExplorerModeSelect && tapGR.state == UIGestureRecognizerStateRecognized) { - // Note that [tapGR locationInView:nil] is broken in iOS 8, - // so we have to do a two step conversion to window coordinates. - // Thanks to @lascorbe for finding this: https://github.com/Flipboard/FLEX/pull/31 - CGPoint tapPointInView = [tapGR locationInView:self.view]; - CGPoint tapPointInWindow = [self.view convertPoint:tapPointInView toView:nil]; - [self updateOutlineViewsForSelectionPoint:tapPointInWindow]; - } -} - -- (void)handleChangeViewAtPointGesture:(UIPanGestureRecognizer *)sender { - NSInteger max = self.viewsAtTapPoint.count - 1; - NSInteger currentIdx = [self.viewsAtTapPoint indexOfObject:self.selectedView]; - CGFloat locationX = [sender locationInView:self.view].x; - - // Track the pan gesture: every N points we move along the X axis, - // actuate some haptic feedback and move up or down the hierarchy. - // We only store the "last" location when we've met the threshold. - // We only change the view and actuate feedback if the view selection - // changes; that is, as long as we don't go outside or under the array. - switch (sender.state) { - case UIGestureRecognizerStateBegan: { - self.selectedViewLastPanX = locationX; - break; - } - case UIGestureRecognizerStateChanged: { - static CGFloat kNextLevelThreshold = 20.f; - CGFloat lastX = self.selectedViewLastPanX; - NSInteger newSelection = currentIdx; - - // Left, go down the hierarchy - if (locationX < lastX && (lastX - locationX) >= kNextLevelThreshold) { - // Choose a new view index up to the max index - newSelection = MIN(max, currentIdx + 1); - self.selectedViewLastPanX = locationX; - } - // Right, go up the hierarchy - else if (lastX < locationX && (locationX - lastX) >= kNextLevelThreshold) { - // Choose a new view index down to the min index - newSelection = MAX(0, currentIdx - 1); - self.selectedViewLastPanX = locationX; - } - - if (currentIdx != newSelection) { - self.selectedView = self.viewsAtTapPoint[newSelection]; - [self actuateSelectionChangedFeedback]; - } - - break; - } - - default: break; - } -} - -- (void)actuateSelectionChangedFeedback { - if (@available(iOS 10.0, *)) { - [self.selectionFBG selectionChanged]; - } -} - -- (void)updateOutlineViewsForSelectionPoint:(CGPoint)selectionPointInWindow { - [self removeAndClearOutlineViews]; - - // Include hidden views in the "viewsAtTapPoint" array so we can show them in the hierarchy list. - self.viewsAtTapPoint = [self viewsAtPoint:selectionPointInWindow skipHiddenViews:NO]; - - // For outlined views and the selected view, only use visible views. - // Outlining hidden views adds clutter and makes the selection behavior confusing. - NSArray *visibleViewsAtTapPoint = [self viewsAtPoint:selectionPointInWindow skipHiddenViews:YES]; - NSMutableDictionary *newOutlineViewsForVisibleViews = [NSMutableDictionary new]; - for (UIView *view in visibleViewsAtTapPoint) { - UIView *outlineView = [self outlineViewForView:view]; - [self.view addSubview:outlineView]; - NSValue *key = [NSValue valueWithNonretainedObject:view]; - [newOutlineViewsForVisibleViews setObject:outlineView forKey:key]; - } - self.outlineViewsForVisibleViews = newOutlineViewsForVisibleViews; - self.selectedView = [self viewForSelectionAtPoint:selectionPointInWindow]; - - // Make sure the explorer toolbar doesn't end up behind the newly added outline views. - [self.view bringSubviewToFront:self.explorerToolbar]; - - [self updateButtonStates]; -} - -- (UIView *)outlineViewForView:(UIView *)view { - CGRect outlineFrame = [self frameInLocalCoordinatesForView:view]; - UIView *outlineView = [[UIView alloc] initWithFrame:outlineFrame]; - outlineView.backgroundColor = UIColor.clearColor; - outlineView.layer.borderColor = [FLEXUtility consistentRandomColorForObject:view].CGColor; - outlineView.layer.borderWidth = 1.0; - return outlineView; -} - -- (void)removeAndClearOutlineViews { - for (NSValue *key in self.outlineViewsForVisibleViews) { - UIView *outlineView = self.outlineViewsForVisibleViews[key]; - [outlineView removeFromSuperview]; - } - self.outlineViewsForVisibleViews = nil; -} - -- (NSArray *)viewsAtPoint:(CGPoint)tapPointInWindow skipHiddenViews:(BOOL)skipHidden { - NSMutableArray *views = [NSMutableArray new]; - for (UIWindow *window in FLEXUtility.allWindows) { - // Don't include the explorer's own window or subviews. - if (window != self.view.window && [window pointInside:tapPointInWindow withEvent:nil]) { - [views addObject:window]; - [views addObjectsFromArray:[self - recursiveSubviewsAtPoint:tapPointInWindow inView:window skipHiddenViews:skipHidden - ]]; - } - } - return views; -} - -- (UIView *)viewForSelectionAtPoint:(CGPoint)tapPointInWindow { - // Select in the window that would handle the touch, but don't just use the result of - // hitTest:withEvent: so we can still select views with interaction disabled. - // Default to the the application's key window if none of the windows want the touch. - UIWindow *windowForSelection = UIApplication.sharedApplication.keyWindow; - for (UIWindow *window in FLEXUtility.allWindows.reverseObjectEnumerator) { - // Ignore the explorer's own window. - if (window != self.view.window) { - if ([window hitTest:tapPointInWindow withEvent:nil]) { - windowForSelection = window; - break; - } - } - } - - // Select the deepest visible view at the tap point. This generally corresponds to what the user wants to select. - return [self recursiveSubviewsAtPoint:tapPointInWindow inView:windowForSelection skipHiddenViews:YES].lastObject; -} - -- (NSArray *)recursiveSubviewsAtPoint:(CGPoint)pointInView - inView:(UIView *)view - skipHiddenViews:(BOOL)skipHidden { - NSMutableArray *subviewsAtPoint = [NSMutableArray new]; - for (UIView *subview in view.subviews) { - BOOL isHidden = subview.hidden || subview.alpha < 0.01; - if (skipHidden && isHidden) { - continue; - } - - BOOL subviewContainsPoint = CGRectContainsPoint(subview.frame, pointInView); - if (subviewContainsPoint) { - [subviewsAtPoint addObject:subview]; - } - - // If this view doesn't clip to its bounds, we need to check its subviews even if it - // doesn't contain the selection point. They may be visible and contain the selection point. - if (subviewContainsPoint || !subview.clipsToBounds) { - CGPoint pointInSubview = [view convertPoint:pointInView toView:subview]; - [subviewsAtPoint addObjectsFromArray:[self - recursiveSubviewsAtPoint:pointInSubview inView:subview skipHiddenViews:skipHidden - ]]; - } - } - return subviewsAtPoint; -} - - -#pragma mark - Selected View Moving - -- (void)handleMovePan:(UIPanGestureRecognizer *)movePanGR { - switch (movePanGR.state) { - case UIGestureRecognizerStateBegan: - self.selectedViewFrameBeforeDragging = self.selectedView.frame; - [self updateSelectedViewPositionWithDragGesture:movePanGR]; - break; - - case UIGestureRecognizerStateChanged: - case UIGestureRecognizerStateEnded: - [self updateSelectedViewPositionWithDragGesture:movePanGR]; - break; - - default: - break; - } -} - -- (void)updateSelectedViewPositionWithDragGesture:(UIPanGestureRecognizer *)movePanGR { - CGPoint translation = [movePanGR translationInView:self.selectedView.superview]; - CGRect newSelectedViewFrame = self.selectedViewFrameBeforeDragging; - newSelectedViewFrame.origin.x = FLEXFloor(newSelectedViewFrame.origin.x + translation.x); - newSelectedViewFrame.origin.y = FLEXFloor(newSelectedViewFrame.origin.y + translation.y); - self.selectedView.frame = newSelectedViewFrame; -} - - -#pragma mark - Safe Area Handling - -- (CGRect)viewSafeArea { - CGRect safeArea = self.view.bounds; - if (@available(iOS 11.0, *)) { - safeArea = UIEdgeInsetsInsetRect(self.view.bounds, self.view.safeAreaInsets); - } - - return safeArea; -} - -- (void)viewSafeAreaInsetsDidChange { - if (@available(iOS 11.0, *)) { - [super viewSafeAreaInsetsDidChange]; - - CGRect safeArea = [self viewSafeArea]; - CGSize toolbarSize = [self.explorerToolbar sizeThatFits:CGSizeMake( - CGRectGetWidth(self.view.bounds), CGRectGetHeight(safeArea) - )]; - [self updateToolbarPositionWithUnconstrainedFrame:CGRectMake( - CGRectGetMinX(self.explorerToolbar.frame), - CGRectGetMinY(self.explorerToolbar.frame), - toolbarSize.width, - toolbarSize.height) - ]; - } -} - - -#pragma mark - Touch Handling - -- (BOOL)shouldReceiveTouchAtWindowPoint:(CGPoint)pointInWindowCoordinates { - BOOL shouldReceiveTouch = NO; - - CGPoint pointInLocalCoordinates = [self.view convertPoint:pointInWindowCoordinates fromView:nil]; - - // Always if it's on the toolbar - if (CGRectContainsPoint(self.explorerToolbar.frame, pointInLocalCoordinates)) { - shouldReceiveTouch = YES; - } - - // Always if we're in selection mode - if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeSelect) { - shouldReceiveTouch = YES; - } - - // Always in move mode too - if (!shouldReceiveTouch && self.currentMode == FLEXExplorerModeMove) { - shouldReceiveTouch = YES; - } - - // Always if we have a modal presented - if (!shouldReceiveTouch && self.presentedViewController) { - shouldReceiveTouch = YES; - } - - return shouldReceiveTouch; -} - - -#pragma mark - FLEXHierarchyDelegate - -- (void)viewHierarchyDidDismiss:(UIView *)selectedView { - // Note that we need to wait until the view controller is dismissed to calculate the frame - // of the outline view, otherwise the coordinate conversion doesn't give the correct result. - [self toggleViewsToolWithCompletion:^{ - // If the selected view is outside of the tap point array (selected from "Full Hierarchy"), - // then clear out the tap point array and remove all the outline views. - if (![self.viewsAtTapPoint containsObject:selectedView]) { - self.viewsAtTapPoint = nil; - [self removeAndClearOutlineViews]; - } - - // If we now have a selected view and we didn't have one previously, go to "select" mode. - if (self.currentMode == FLEXExplorerModeDefault && selectedView) { - self.currentMode = FLEXExplorerModeSelect; - } - - // The selected view setter will also update the selected view overlay appropriately. - self.selectedView = selectedView; - }]; -} - - -#pragma mark - Modal Presentation and Window Management - -- (void)presentViewController:(UIViewController *)toPresent - animated:(BOOL)animated - completion:(void (^)(void))completion { - // Make our window key to correctly handle input. - [self.view.window makeKeyWindow]; - - // Move the status bar on top of FLEX so we can get scroll to top behavior for taps. - if (!@available(iOS 13, *)) { - [self statusWindow].windowLevel = self.view.window.windowLevel + 1.0; - } - - // Back up and replace the UIMenuController items - // Edit: no longer replacing the items, but still backing them - // up in case we start replacing them again in the future - self.appMenuItems = UIMenuController.sharedMenuController.menuItems; - - // Show the view controller - [super presentViewController:toPresent animated:animated completion:completion]; -} - -- (void)dismissViewControllerAnimated:(BOOL)animated completion:(void (^)(void))completion { - UIWindow *appWindow = self.window.previousKeyWindow; - [appWindow makeKeyWindow]; - [appWindow.rootViewController setNeedsStatusBarAppearanceUpdate]; - - // Restore previous UIMenuController items - // Back up and replace the UIMenuController items - UIMenuController.sharedMenuController.menuItems = self.appMenuItems; - [UIMenuController.sharedMenuController update]; - self.appMenuItems = nil; - - // Restore the status bar window's normal window level. - // We want it above FLEX while a modal is presented for - // scroll to top, but below FLEX otherwise for exploration. - [self statusWindow].windowLevel = UIWindowLevelStatusBar; - - [self updateButtonStates]; - - [super dismissViewControllerAnimated:animated completion:completion]; -} - -- (BOOL)wantsWindowToBecomeKey { - return self.window.previousKeyWindow != nil; -} - -- (void)toggleToolWithViewControllerProvider:(UINavigationController *(^)(void))future - completion:(void (^)(void))completion { - if (self.presentedViewController) { - // We do NOT want to present the future; this is - // a convenience method for toggling the SAME TOOL - [self dismissViewControllerAnimated:YES completion:completion]; - } else if (future) { - [self presentViewController:future() animated:YES completion:completion]; - } -} - -- (void)presentTool:(UINavigationController *(^)(void))future - completion:(void (^)(void))completion { - if (self.presentedViewController) { - // If a tool is already presented, dismiss it first - [self dismissViewControllerAnimated:YES completion:^{ - [self presentViewController:future() animated:YES completion:completion]; - }]; - } else if (future) { - [self presentViewController:future() animated:YES completion:completion]; - } -} - -- (FLEXWindow *)window { - return (id)self.view.window; -} - - -#pragma mark - Keyboard Shortcut Helpers - -- (void)toggleSelectTool { - if (self.currentMode == FLEXExplorerModeSelect) { - self.currentMode = FLEXExplorerModeDefault; - } else { - self.currentMode = FLEXExplorerModeSelect; - } -} - -- (void)toggleMoveTool { - if (self.currentMode == FLEXExplorerModeMove) { - self.currentMode = FLEXExplorerModeSelect; - } else if (self.currentMode == FLEXExplorerModeSelect && self.selectedView) { - self.currentMode = FLEXExplorerModeMove; - } -} - -- (void)toggleViewsTool { - [self toggleViewsToolWithCompletion:nil]; -} - -- (void)toggleViewsToolWithCompletion:(void(^)(void))completion { - [self toggleToolWithViewControllerProvider:^UINavigationController *{ - if (self.selectedView) { - return [FLEXHierarchyViewController - delegate:self - viewsAtTap:self.viewsAtTapPoint - selectedView:self.selectedView - ]; - } else { - return [FLEXHierarchyViewController delegate:self]; - } - } completion:completion]; -} - -- (void)toggleMenuTool { - [self toggleToolWithViewControllerProvider:^UINavigationController *{ - return [FLEXNavigationController withRootViewController:[FLEXGlobalsViewController new]]; - } completion:nil]; -} - -- (BOOL)handleDownArrowKeyPressed { - if (self.currentMode == FLEXExplorerModeMove) { - CGRect frame = self.selectedView.frame; - frame.origin.y += 1.0 / UIScreen.mainScreen.scale; - self.selectedView.frame = frame; - } else if (self.currentMode == FLEXExplorerModeSelect && self.viewsAtTapPoint.count > 0) { - NSInteger selectedViewIndex = [self.viewsAtTapPoint indexOfObject:self.selectedView]; - if (selectedViewIndex > 0) { - self.selectedView = [self.viewsAtTapPoint objectAtIndex:selectedViewIndex - 1]; - } - } else { - return NO; - } - - return YES; -} - -- (BOOL)handleUpArrowKeyPressed { - if (self.currentMode == FLEXExplorerModeMove) { - CGRect frame = self.selectedView.frame; - frame.origin.y -= 1.0 / UIScreen.mainScreen.scale; - self.selectedView.frame = frame; - } else if (self.currentMode == FLEXExplorerModeSelect && self.viewsAtTapPoint.count > 0) { - NSInteger selectedViewIndex = [self.viewsAtTapPoint indexOfObject:self.selectedView]; - if (selectedViewIndex < self.viewsAtTapPoint.count - 1) { - self.selectedView = [self.viewsAtTapPoint objectAtIndex:selectedViewIndex + 1]; - } - } else { - return NO; - } - - return YES; -} - -- (BOOL)handleRightArrowKeyPressed { - if (self.currentMode == FLEXExplorerModeMove) { - CGRect frame = self.selectedView.frame; - frame.origin.x += 1.0 / UIScreen.mainScreen.scale; - self.selectedView.frame = frame; - return YES; - } - - return NO; -} - -- (BOOL)handleLeftArrowKeyPressed { - if (self.currentMode == FLEXExplorerModeMove) { - CGRect frame = self.selectedView.frame; - frame.origin.x -= 1.0 / UIScreen.mainScreen.scale; - self.selectedView.frame = frame; - return YES; - } - - return NO; -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.h b/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.h deleted file mode 100644 index b2d9ec4c..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXViewControllersViewController.h -// FLEX -// -// Created by Tanner Bennett on 2/13/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXViewControllersViewController : FLEXFilteringTableViewController - -+ (instancetype)controllersForViews:(NSArray *)views; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.m b/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.m deleted file mode 100644 index 956f1ea7..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXViewControllersViewController.m +++ /dev/null @@ -1,79 +0,0 @@ -// -// FLEXViewControllersViewController.m -// FLEX -// -// Created by Tanner Bennett on 2/13/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXViewControllersViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXMutableListSection.h" -#import "FLEXUtility.h" - -@interface FLEXViewControllersViewController () -@property (nonatomic, readonly) FLEXMutableListSection *section; -@property (nonatomic, readonly) NSArray *controllers; -@end - -@implementation FLEXViewControllersViewController -@dynamic sections, allSections; - -#pragma mark - Initialization - -+ (instancetype)controllersForViews:(NSArray *)views { - return [[self alloc] initWithViews:views]; -} - -- (id)initWithViews:(NSArray *)views { - NSParameterAssert(views.count); - - self = [self initWithStyle:UITableViewStylePlain]; - if (self) { - _controllers = [views flex_mapped:^id(UIView *view, NSUInteger idx) { - return [FLEXUtility viewControllerForView:view]; - }]; - } - - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"View Controllers at Tap"; - self.showsSearchBar = YES; - [self disableToolbar]; -} - -- (NSArray *)makeSections { - _section = [FLEXMutableListSection list:self.controllers - cellConfiguration:^(UITableViewCell *cell, UIViewController *controller, NSInteger row) { - cell.textLabel.text = [NSString - stringWithFormat:@"%@ — %p", NSStringFromClass(controller.class), controller - ]; - cell.detailTextLabel.text = controller.view.description; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.textLabel.lineBreakMode = NSLineBreakByTruncatingTail; - } filterMatcher:^BOOL(NSString *filterText, UIViewController *controller) { - return [NSStringFromClass(controller.class) localizedCaseInsensitiveContainsString:filterText]; - }]; - - self.section.selectionHandler = ^(UIViewController *host, UIViewController *controller) { - [host.navigationController pushViewController: - [FLEXObjectExplorerFactory explorerViewControllerForObject:controller] - animated:YES]; - }; - - self.section.customTitle = @"View Controllers"; - return @[self.section]; -} - - -#pragma mark - Private - -- (void)dismissAnimated { - [self dismissViewControllerAnimated:YES completion:nil]; -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXWindow.h b/BHTwitter/Classes/ExplorerInterface/FLEXWindow.h deleted file mode 100644 index 4de7ae46..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXWindow.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXWindow.h -// Flipboard -// -// Created by Ryan Olson on 4/13/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@protocol FLEXWindowEventDelegate - -- (BOOL)shouldHandleTouchAtPoint:(CGPoint)pointInWindow; -- (BOOL)canBecomeKeyWindow; - -@end - -#pragma mark - -@interface FLEXWindow : UIWindow - -@property (nonatomic, weak) id eventDelegate; - -/// Tracked so we can restore the key window after dismissing a modal. -/// We need to become key after modal presentation so we can correctly capture input. -/// If we're just showing the toolbar, we want the main app's window to remain key -/// so that we don't interfere with input, status bar, etc. -@property (nonatomic, readonly) UIWindow *previousKeyWindow; - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXWindow.m b/BHTwitter/Classes/ExplorerInterface/FLEXWindow.m deleted file mode 100644 index 48fc1cf3..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXWindow.m +++ /dev/null @@ -1,72 +0,0 @@ -// -// FLEXWindow.m -// Flipboard -// -// Created by Ryan Olson on 4/13/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXWindow.h" -#import "FLEXUtility.h" -#import - -@implementation FLEXWindow - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - // Some apps have windows at UIWindowLevelStatusBar + n. - // If we make the window level too high, we block out UIAlertViews. - // There's a balance between staying above the app's windows and staying below alerts. - // UIWindowLevelStatusBar + 100 seems to hit that balance. - self.windowLevel = UIWindowLevelStatusBar + 100.0; - } - return self; -} - -- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { - BOOL pointInside = NO; - if ([self.eventDelegate shouldHandleTouchAtPoint:point]) { - pointInside = [super pointInside:point withEvent:event]; - } - return pointInside; -} - -- (BOOL)shouldAffectStatusBarAppearance { - return [self isKeyWindow]; -} - -- (BOOL)canBecomeKeyWindow { - return [self.eventDelegate canBecomeKeyWindow]; -} - -- (void)makeKeyWindow { - _previousKeyWindow = FLEXUtility.appKeyWindow; - [super makeKeyWindow]; -} - -- (void)resignKeyWindow { - [super resignKeyWindow]; - _previousKeyWindow = nil; -} - -+ (void)initialize { - // This adds a method (superclass override) at runtime which gives us the status bar behavior we want. - // The FLEX window is intended to be an overlay that generally doesn't affect the app underneath. - // Most of the time, we want the app's main window(s) to be in control of status bar behavior. - // Done at runtime with an obfuscated selector because it is private API. But you shouldn't ship this to the App Store anyways... - NSString *canAffectSelectorString = [@[@"_can", @"Affect", @"Status", @"Bar", @"Appearance"] componentsJoinedByString:@""]; - SEL canAffectSelector = NSSelectorFromString(canAffectSelectorString); - Method shouldAffectMethod = class_getInstanceMethod(self, @selector(shouldAffectStatusBarAppearance)); - IMP canAffectImplementation = method_getImplementation(shouldAffectMethod); - class_addMethod(self, canAffectSelector, canAffectImplementation, method_getTypeEncoding(shouldAffectMethod)); - - // One more... - NSString *canBecomeKeySelectorString = [NSString stringWithFormat:@"_%@", NSStringFromSelector(@selector(canBecomeKeyWindow))]; - SEL canBecomeKeySelector = NSSelectorFromString(canBecomeKeySelectorString); - Method canBecomeKeyMethod = class_getInstanceMethod(self, @selector(canBecomeKeyWindow)); - IMP canBecomeKeyImplementation = method_getImplementation(canBecomeKeyMethod); - class_addMethod(self, canBecomeKeySelector, canBecomeKeyImplementation, method_getTypeEncoding(canBecomeKeyMethod)); -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.h b/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.h deleted file mode 100644 index d0dd05e7..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXWindowManagerController.h -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXWindowManagerController : FLEXTableViewController - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.m b/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.m deleted file mode 100644 index 1c9846d7..00000000 --- a/BHTwitter/Classes/ExplorerInterface/FLEXWindowManagerController.m +++ /dev/null @@ -1,302 +0,0 @@ -// -// FLEXWindowManagerController.m -// FLEX -// -// Created by Tanner on 2/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXWindowManagerController.h" -#import "FLEXManager+Private.h" -#import "FLEXUtility.h" -#import "FLEXObjectExplorerFactory.h" - -@interface FLEXWindowManagerController () -@property (nonatomic) UIWindow *keyWindow; -@property (nonatomic, copy) NSString *keyWindowSubtitle; -@property (nonatomic, copy) NSArray *windows; -@property (nonatomic, copy) NSArray *windowSubtitles; -@property (nonatomic, copy) NSArray *scenes API_AVAILABLE(ios(13)); -@property (nonatomic, copy) NSArray *sceneSubtitles; -@property (nonatomic, copy) NSArray *sections; -@end - -@implementation FLEXWindowManagerController - -#pragma mark - Initialization - -- (id)init { - return [self initWithStyle:UITableViewStylePlain]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Windows"; - if (@available(iOS 13, *)) { - self.title = @"Windows and Scenes"; - } - - [self disableToolbar]; - [self reloadData]; -} - - -#pragma mark - Private - -- (void)reloadData { - self.keyWindow = UIApplication.sharedApplication.keyWindow; - self.windows = UIApplication.sharedApplication.windows; - self.keyWindowSubtitle = self.windowSubtitles[[self.windows indexOfObject:self.keyWindow]]; - self.windowSubtitles = [self.windows flex_mapped:^id(UIWindow *window, NSUInteger idx) { - return [NSString stringWithFormat:@"Level: %@ — Root: %@", - @(window.windowLevel), window.rootViewController - ]; - }]; - - if (@available(iOS 13, *)) { - self.scenes = UIApplication.sharedApplication.connectedScenes.allObjects; - self.sceneSubtitles = [self.scenes flex_mapped:^id(UIScene *scene, NSUInteger idx) { - return [self sceneDescription:scene]; - }]; - - self.sections = @[@[self.keyWindow], self.windows, self.scenes]; - } else { - self.sections = @[@[self.keyWindow], self.windows]; - } - - [self.tableView reloadData]; -} - -- (void)dismissAnimated { - [self dismissViewControllerAnimated:YES completion:nil]; -} - -- (void)showRevertOrDismissAlert:(void(^)(void))revertBlock { - [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; - [self reloadData]; - [self.tableView reloadData]; - - UIWindow *highestWindow = UIApplication.sharedApplication.keyWindow; - UIWindowLevel maxLevel = 0; - for (UIWindow *window in UIApplication.sharedApplication.windows) { - if (window.windowLevel > maxLevel) { - maxLevel = window.windowLevel; - highestWindow = window; - } - } - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Keep Changes?"); - make.message(@"If you do not wish to keep these settings, choose 'Revert Changes' below."); - - make.button(@"Keep Changes").destructiveStyle(); - make.button(@"Keep Changes and Dismiss").destructiveStyle().handler(^(NSArray *strings) { - [self dismissAnimated]; - }); - make.button(@"Revert Changes").cancelStyle().handler(^(NSArray *strings) { - revertBlock(); - [self reloadData]; - [self.tableView reloadData]; - }); - } showFrom:[FLEXUtility topViewControllerInWindow:highestWindow]]; -} - -- (NSString *)sceneDescription:(UIScene *)scene API_AVAILABLE(ios(13)) { - NSString *state = [self stringFromSceneState:scene.activationState]; - NSString *title = scene.title.length ? scene.title : nil; - NSString *suffix = nil; - - if ([scene isKindOfClass:[UIWindowScene class]]) { - UIWindowScene *windowScene = (id)scene; - suffix = FLEXPluralString(windowScene.windows.count, @"windows", @"window"); - } - - NSMutableString *description = state.mutableCopy; - if (title) { - [description appendFormat:@" — %@", title]; - } - if (suffix) { - [description appendFormat:@" — %@", suffix]; - } - - return description.copy; -} - -- (NSString *)stringFromSceneState:(UISceneActivationState)state API_AVAILABLE(ios(13)) { - switch (state) { - case UISceneActivationStateUnattached: - return @"Unattached"; - case UISceneActivationStateForegroundActive: - return @"Active"; - case UISceneActivationStateForegroundInactive: - return @"Inactive"; - case UISceneActivationStateBackground: - return @"Backgrounded"; - } - - return [NSString stringWithFormat:@"Unknown state: %@", @(state)]; -} - - -#pragma mark - Table View Data Source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return self.sections.count; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.sections[section].count; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - switch (section) { - case 0: return @"Key Window"; - case 1: return @"Windows"; - case 2: return @"Connected Scenes"; - } - - return nil; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXDetailCell forIndexPath:indexPath]; - cell.accessoryType = UITableViewCellAccessoryDetailButton; - cell.textLabel.lineBreakMode = NSLineBreakByTruncatingTail; - - UIWindow *window = nil; - NSString *subtitle = nil; - - switch (indexPath.section) { - case 0: - window = self.keyWindow; - subtitle = self.keyWindowSubtitle; - break; - case 1: - window = self.windows[indexPath.row]; - subtitle = self.windowSubtitles[indexPath.row]; - break; - case 2: - if (@available(iOS 13, *)) { - UIScene *scene = self.scenes[indexPath.row]; - cell.textLabel.text = scene.description; - cell.detailTextLabel.text = self.sceneSubtitles[indexPath.row]; - return cell; - } - } - - cell.textLabel.text = window.description; - cell.detailTextLabel.text = [NSString - stringWithFormat:@"Level: %@ — Root: %@", - @((NSInteger)window.windowLevel), window.rootViewController.class - ]; - - return cell; -} - - -#pragma mark - Table View Delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - UIWindow *window = nil; - NSString *subtitle = nil; - FLEXWindow *flex = FLEXManager.sharedManager.explorerWindow; - - id cancelHandler = ^{ - [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; - }; - - switch (indexPath.section) { - case 0: - window = self.keyWindow; - subtitle = self.keyWindowSubtitle; - break; - case 1: - window = self.windows[indexPath.row]; - subtitle = self.windowSubtitles[indexPath.row]; - break; - case 2: - if (@available(iOS 13, *)) { - UIScene *scene = self.scenes[indexPath.row]; - UIWindowScene *oldScene = flex.windowScene; - BOOL isWindowScene = [scene isKindOfClass:[UIWindowScene class]]; - BOOL isFLEXScene = isWindowScene ? flex.windowScene == scene : NO; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(NSStringFromClass(scene.class)); - - if (isWindowScene) { - if (isFLEXScene) { - make.message(@"Already the FLEX window scene"); - } - - make.button(@"Set as FLEX Window Scene") - .handler(^(NSArray *strings) { - flex.windowScene = (id)scene; - [self showRevertOrDismissAlert:^{ - flex.windowScene = oldScene; - }]; - }).enabled(!isFLEXScene); - make.button(@"Cancel").cancelStyle(); - } else { - make.message(@"Not a UIWindowScene"); - make.button(@"Dismiss").cancelStyle().handler(cancelHandler); - } - } showFrom:self]; - } - } - - __block UIWindow *targetWindow = nil, *oldKeyWindow = nil; - __block UIWindowLevel oldLevel; - __block BOOL wasVisible; - - subtitle = [subtitle stringByAppendingString: - @"\n\n1) Adjust the FLEX window level relative to this window,\n" - "2) adjust this window's level relative to the FLEX window,\n" - "3) set this window's level to a specific value, or\n" - "4) make this window the key window if it isn't already." - ]; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(NSStringFromClass(window.class)).message(subtitle); - make.button(@"Adjust FLEX Window Level").handler(^(NSArray *strings) { - targetWindow = flex; oldLevel = flex.windowLevel; - flex.windowLevel = window.windowLevel + strings.firstObject.integerValue; - - [self showRevertOrDismissAlert:^{ targetWindow.windowLevel = oldLevel; }]; - }); - make.button(@"Adjust This Window's Level").handler(^(NSArray *strings) { - targetWindow = window; oldLevel = window.windowLevel; - window.windowLevel = flex.windowLevel + strings.firstObject.integerValue; - - [self showRevertOrDismissAlert:^{ targetWindow.windowLevel = oldLevel; }]; - }); - make.button(@"Set This Window's Level").handler(^(NSArray *strings) { - targetWindow = window; oldLevel = window.windowLevel; - window.windowLevel = strings.firstObject.integerValue; - - [self showRevertOrDismissAlert:^{ targetWindow.windowLevel = oldLevel; }]; - }); - make.button(@"Make Key And Visible").handler(^(NSArray *strings) { - oldKeyWindow = UIApplication.sharedApplication.keyWindow; - wasVisible = window.hidden; - [window makeKeyAndVisible]; - - [self showRevertOrDismissAlert:^{ - window.hidden = wasVisible; - [oldKeyWindow makeKeyWindow]; - }]; - }).enabled(!window.isKeyWindow && !window.hidden); - make.button(@"Cancel").cancelStyle().handler(cancelHandler); - - make.textField(@"+/- window level, i.e. 5 or -10"); - } showFrom:self]; -} - -- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)ip { - [self.navigationController pushViewController: - [FLEXObjectExplorerFactory explorerViewControllerForObject:self.sections[ip.section][ip.row]] - animated:YES]; -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.h b/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.h deleted file mode 100644 index 24f21548..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.h +++ /dev/null @@ -1,45 +0,0 @@ -// -// FLEXTabList.h -// FLEX -// -// Created by Tanner on 2/1/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXTabList : NSObject - -@property (nonatomic, readonly, class) FLEXTabList *sharedList; - -@property (nonatomic, readonly, nullable) UINavigationController *activeTab; -@property (nonatomic, readonly) NSArray *openTabs; -/// Snapshots of each tab when they were last active. -@property (nonatomic, readonly) NSArray *openTabSnapshots; -/// \c NSNotFound if no tabs are present. -/// Setting this property changes the active tab to one of the already open tabs. -@property (nonatomic) NSInteger activeTabIndex; - -/// Adds a new tab and sets the new tab as the active tab. -- (void)addTab:(UINavigationController *)newTab; -/// Closes the given tab. If this tab was the active tab, -/// the most recent tab before that becomes the active tab. -- (void)closeTab:(UINavigationController *)tab; -/// Closes a tab at the given index. If this tab was the active tab, -/// the most recent tab before that becomes the active tab. -- (void)closeTabAtIndex:(NSInteger)idx; -/// Closes all of the tabs at the given indexes. If the active tab -/// is included, the most recent still-open tab becomes the active tab. -- (void)closeTabsAtIndexes:(NSIndexSet *)indexes; -/// A shortcut to close the active tab. -- (void)closeActiveTab; -/// A shortcut to close \e every tab. -- (void)closeAllTabs; - -- (void)updateSnapshotForActiveTab; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.m b/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.m deleted file mode 100644 index cb4f006c..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabList.m +++ /dev/null @@ -1,133 +0,0 @@ -// -// FLEXTabList.m -// FLEX -// -// Created by Tanner on 2/1/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTabList.h" -#import "FLEXUtility.h" - -@interface FLEXTabList () { - NSMutableArray *_openTabs; - NSMutableArray *_openTabSnapshots; -} -@end -#pragma mark - -@implementation FLEXTabList - -#pragma mark Initialization - -+ (FLEXTabList *)sharedList { - static FLEXTabList *sharedList = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedList = [self new]; - }); - - return sharedList; -} - -- (id)init { - self = [super init]; - if (self) { - _openTabs = [NSMutableArray new]; - _openTabSnapshots = [NSMutableArray new]; - _activeTabIndex = NSNotFound; - } - - return self; -} - - -#pragma mark Private - -- (void)chooseNewActiveTab { - if (self.openTabs.count) { - self.activeTabIndex = self.openTabs.count - 1; - } else { - self.activeTabIndex = NSNotFound; - } -} - - -#pragma mark Public - -- (void)setActiveTabIndex:(NSInteger)idx { - NSParameterAssert(idx < self.openTabs.count || idx == NSNotFound); - if (_activeTabIndex == idx) return; - - _activeTabIndex = idx; - _activeTab = (idx == NSNotFound) ? nil : self.openTabs[idx]; -} - -- (void)addTab:(UINavigationController *)newTab { - NSParameterAssert(newTab); - - // Update snapshot of the last active tab - if (self.activeTab) { - [self updateSnapshotForActiveTab]; - } - - // Add new tab and snapshot, - // update active tab and index - [_openTabs addObject:newTab]; - [_openTabSnapshots addObject:[FLEXUtility previewImageForView:newTab.view]]; - _activeTab = newTab; - _activeTabIndex = self.openTabs.count - 1; -} - -- (void)closeTab:(UINavigationController *)tab { - NSParameterAssert(tab); - NSInteger idx = [self.openTabs indexOfObject:tab]; - if (idx != NSNotFound) { - [self closeTabAtIndex:idx]; - } -} - -- (void)closeTabAtIndex:(NSInteger)idx { - NSParameterAssert(idx < self.openTabs.count); - - // Remove old tab and snapshot - [_openTabs removeObjectAtIndex:idx]; - [_openTabSnapshots removeObjectAtIndex:idx]; - - // Update active tab and index if needed - if (self.activeTabIndex == idx) { - [self chooseNewActiveTab]; - } -} - -- (void)closeTabsAtIndexes:(NSIndexSet *)indexes { - // Remove old tabs and snapshot - [_openTabs removeObjectsAtIndexes:indexes]; - [_openTabSnapshots removeObjectsAtIndexes:indexes]; - - // Update active tab and index if needed - if ([indexes containsIndex:self.activeTabIndex]) { - [self chooseNewActiveTab]; - } -} - -- (void)closeActiveTab { - [self closeTab:self.activeTab]; -} - -- (void)closeAllTabs { - // Remove tabs and snapshots - [_openTabs removeAllObjects]; - [_openTabSnapshots removeAllObjects]; - - // Update active tab index - self.activeTabIndex = NSNotFound; -} - -- (void)updateSnapshotForActiveTab { - if (self.activeTabIndex != NSNotFound) { - UIImage *newSnapshot = [FLEXUtility previewImageForView:self.activeTab.view]; - [_openTabSnapshots replaceObjectAtIndex:self.activeTabIndex withObject:newSnapshot]; - } -} - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h b/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h deleted file mode 100644 index f288a0aa..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXTabsViewController.h -// FLEX -// -// Created by Tanner on 2/4/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" - -@interface FLEXTabsViewController : FLEXTableViewController - -@end diff --git a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.m b/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.m deleted file mode 100644 index 9f220461..00000000 --- a/BHTwitter/Classes/ExplorerInterface/Tabs/FLEXTabsViewController.m +++ /dev/null @@ -1,335 +0,0 @@ -// -// FLEXTabsViewController.m -// FLEX -// -// Created by Tanner on 2/4/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTabsViewController.h" -#import "FLEXNavigationController.h" -#import "FLEXTabList.h" -#import "FLEXBookmarkManager.h" -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" -#import "UIBarButtonItem+FLEX.h" -#import "FLEXExplorerViewController.h" -#import "FLEXGlobalsViewController.h" -#import "FLEXBookmarksViewController.h" - -@interface FLEXTabsViewController () -@property (nonatomic, copy) NSArray *openTabs; -@property (nonatomic, copy) NSArray *tabSnapshots; -@property (nonatomic) NSInteger activeIndex; -@property (nonatomic) BOOL presentNewActiveTabOnDismiss; - -@property (nonatomic, readonly) FLEXExplorerViewController *corePresenter; -@end - -@implementation FLEXTabsViewController - -#pragma mark - Initialization - -- (id)init { - return [self initWithStyle:UITableViewStylePlain]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Open Tabs"; - self.navigationController.hidesBarsOnSwipe = NO; - self.tableView.allowsMultipleSelectionDuringEditing = YES; - - [self reloadData:NO]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self setupDefaultBarItems]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - // Instead of updating the active snapshot before we present, - // we update it after we present to avoid pre-presenation latency - dispatch_async(dispatch_get_main_queue(), ^{ - [FLEXTabList.sharedList updateSnapshotForActiveTab]; - [self reloadData:NO]; - [self.tableView reloadData]; - }); -} - - -#pragma mark - Private - -/// @param trackActiveTabDelta whether to check if the active -/// tab changed and needs to be presented upon "Done" dismissal. -/// @return whether the active tab changed or not (if there are any tabs left) -- (BOOL)reloadData:(BOOL)trackActiveTabDelta { - BOOL activeTabDidChange = NO; - FLEXTabList *list = FLEXTabList.sharedList; - - // Flag to enable check to determine whether - if (trackActiveTabDelta) { - NSInteger oldActiveIndex = self.activeIndex; - if (oldActiveIndex != list.activeTabIndex && list.activeTabIndex != NSNotFound) { - self.presentNewActiveTabOnDismiss = YES; - activeTabDidChange = YES; - } else if (self.presentNewActiveTabOnDismiss) { - // If we had something to present before, now we don't - // (i.e. activeTabIndex == NSNotFound) - self.presentNewActiveTabOnDismiss = NO; - } - } - - // We assume the tabs aren't going to change out from under us, since - // presenting any other tool via keyboard shortcuts should dismiss us first - self.openTabs = list.openTabs; - self.tabSnapshots = list.openTabSnapshots; - self.activeIndex = list.activeTabIndex; - - return activeTabDidChange; -} - -- (void)reloadActiveTabRowIfChanged:(BOOL)activeTabChanged { - // Refresh the newly active tab row if needed - if (activeTabChanged) { - NSIndexPath *active = [NSIndexPath - indexPathForRow:self.activeIndex inSection:0 - ]; - [self.tableView reloadRowsAtIndexPaths:@[active] withRowAnimation:UITableViewRowAnimationNone]; - } -} - -- (void)setupDefaultBarItems { - self.navigationItem.rightBarButtonItem = FLEXBarButtonItemSystem(Done, self, @selector(dismissAnimated)); - self.toolbarItems = @[ - UIBarButtonItem.flex_fixedSpace, - UIBarButtonItem.flex_flexibleSpace, - FLEXBarButtonItemSystem(Add, self, @selector(addTabButtonPressed:)), - UIBarButtonItem.flex_flexibleSpace, - FLEXBarButtonItemSystem(Edit, self, @selector(toggleEditing)), - ]; - - // Disable editing if no tabs available - self.toolbarItems.lastObject.enabled = self.openTabs.count > 0; -} - -- (void)setupEditingBarItems { - self.navigationItem.rightBarButtonItem = nil; - self.toolbarItems = @[ - [UIBarButtonItem flex_itemWithTitle:@"Close All" target:self action:@selector(closeAllButtonPressed:)], - UIBarButtonItem.flex_flexibleSpace, - [UIBarButtonItem flex_disabledSystemItem:UIBarButtonSystemItemAdd], - UIBarButtonItem.flex_flexibleSpace, - // We use a non-system done item because we change its title dynamically - [UIBarButtonItem flex_doneStyleitemWithTitle:@"Done" target:self action:@selector(toggleEditing)] - ]; - - self.toolbarItems.firstObject.tintColor = FLEXColor.destructiveColor; -} - -- (FLEXExplorerViewController *)corePresenter { - // We must be presented by a FLEXExplorerViewController, or presented - // by another view controller that was presented by FLEXExplorerViewController - FLEXExplorerViewController *presenter = (id)self.presentingViewController; - presenter = (id)presenter.presentingViewController ?: presenter; - NSAssert( - [presenter isKindOfClass:[FLEXExplorerViewController class]], - @"The tabs view controller expects to be presented by the explorer controller" - ); - return presenter; -} - - -#pragma mark Button Actions - -- (void)dismissAnimated { - if (self.presentNewActiveTabOnDismiss) { - // The active tab was closed so we need to present the new one - UIViewController *activeTab = FLEXTabList.sharedList.activeTab; - FLEXExplorerViewController *presenter = self.corePresenter; - [presenter dismissViewControllerAnimated:YES completion:^{ - [presenter presentViewController:activeTab animated:YES completion:nil]; - }]; - } else if (self.activeIndex == NSNotFound) { - // The only tab was closed, so dismiss everything - [self.corePresenter dismissViewControllerAnimated:YES completion:nil]; - } else { - // Simple dismiss with the same active tab, only dismiss myself - [self dismissViewControllerAnimated:YES completion:nil]; - } -} - -- (void)toggleEditing { - NSArray *selected = self.tableView.indexPathsForSelectedRows; - self.editing = !self.editing; - - if (self.isEditing) { - [self setupEditingBarItems]; - } else { - [self setupDefaultBarItems]; - - // Get index set of tabs to close - NSMutableIndexSet *indexes = [NSMutableIndexSet new]; - for (NSIndexPath *ip in selected) { - [indexes addIndex:ip.row]; - } - - if (selected.count) { - // Close tabs and update data source - [FLEXTabList.sharedList closeTabsAtIndexes:indexes]; - BOOL activeTabChanged = [self reloadData:YES]; - - // Remove deleted rows - [self.tableView deleteRowsAtIndexPaths:selected withRowAnimation:UITableViewRowAnimationAutomatic]; - - // Refresh the newly active tab row if needed - [self reloadActiveTabRowIfChanged:activeTabChanged]; - } - } -} - -- (void)addTabButtonPressed:(UIBarButtonItem *)sender { - if (FLEXBookmarkManager.bookmarks.count) { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - make.title(@"New Tab"); - make.button(@"Main Menu").handler(^(NSArray *strings) { - [self addTabAndDismiss:[FLEXNavigationController - withRootViewController:[FLEXGlobalsViewController new] - ]]; - }); - make.button(@"Choose from Bookmarks").handler(^(NSArray *strings) { - [self presentViewController:[FLEXNavigationController - withRootViewController:[FLEXBookmarksViewController new] - ] animated:YES completion:nil]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; - } else { - // No bookmarks, just open the main menu - [self addTabAndDismiss:[FLEXNavigationController - withRootViewController:[FLEXGlobalsViewController new] - ]]; - } -} - -- (void)addTabAndDismiss:(UINavigationController *)newTab { - FLEXExplorerViewController *presenter = self.corePresenter; - [presenter dismissViewControllerAnimated:YES completion:^{ - [presenter presentViewController:newTab animated:YES completion:nil]; - }]; -} - -- (void)closeAllButtonPressed:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - NSInteger count = self.openTabs.count; - NSString *title = FLEXPluralFormatString(count, @"Close %@ tabs", @"Close %@ tab"); - make.button(title).destructiveStyle().handler(^(NSArray *strings) { - [self closeAll]; - [self toggleEditing]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - -- (void)closeAll { - NSInteger rowCount = self.openTabs.count; - - // Close tabs and update data source - [FLEXTabList.sharedList closeAllTabs]; - [self reloadData:YES]; - - // Delete rows from table view - NSArray *allRows = [NSArray flex_forEachUpTo:rowCount map:^id(NSUInteger row) { - return [NSIndexPath indexPathForRow:row inSection:0]; - }]; - [self.tableView deleteRowsAtIndexPaths:allRows withRowAnimation:UITableViewRowAnimationAutomatic]; -} - - -#pragma mark - Table View Data Source - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.openTabs.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXDetailCell forIndexPath:indexPath]; - - UINavigationController *tab = self.openTabs[indexPath.row]; - cell.imageView.image = self.tabSnapshots[indexPath.row]; - cell.textLabel.text = tab.topViewController.title; - cell.detailTextLabel.text = FLEXPluralString(tab.viewControllers.count, @"pages", @"page"); - - if (!cell.tag) { - cell.textLabel.lineBreakMode = NSLineBreakByTruncatingTail; - cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; - cell.detailTextLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; - cell.tag = 1; - } - - if (indexPath.row == self.activeIndex) { - cell.backgroundColor = FLEXColor.secondaryBackgroundColor; - } else { - cell.backgroundColor = FLEXColor.primaryBackgroundColor; - } - - return cell; -} - - -#pragma mark - Table View Delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (self.editing) { - // Case: editing with multi-select - self.toolbarItems.lastObject.title = @"Close Selected"; - self.toolbarItems.lastObject.tintColor = FLEXColor.destructiveColor; - } else { - if (self.activeIndex == indexPath.row && self.corePresenter != self.presentingViewController) { - // Case: selected the already active tab - [self dismissAnimated]; - } else { - // Case: selected a different tab, - // or selected a tab when presented from the FLEX toolbar - FLEXTabList.sharedList.activeTabIndex = indexPath.row; - self.presentNewActiveTabOnDismiss = YES; - [self dismissAnimated]; - } - } -} - -- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath { - NSParameterAssert(self.editing); - - if (tableView.indexPathsForSelectedRows.count == 0) { - self.toolbarItems.lastObject.title = @"Done"; - self.toolbarItems.lastObject.tintColor = self.view.tintColor; - } -} - -- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (void)tableView:(UITableView *)table -commitEditingStyle:(UITableViewCellEditingStyle)edit -forRowAtIndexPath:(NSIndexPath *)indexPath { - NSParameterAssert(edit == UITableViewCellEditingStyleDelete); - - // Close tab and update data source - [FLEXTabList.sharedList closeTab:self.openTabs[indexPath.row]]; - BOOL activeTabChanged = [self reloadData:YES]; - - // Delete row from table view - [table deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; - - // Refresh the newly active tab row if needed - [self reloadActiveTabRowIfChanged:activeTabChanged]; -} - -@end diff --git a/BHTwitter/Classes/FLEX-Categories.h b/BHTwitter/Classes/FLEX-Categories.h deleted file mode 100644 index 024b1161..00000000 --- a/BHTwitter/Classes/FLEX-Categories.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// FLEX-Categories.h -// FLEX -// -// Created by Tanner on 3/12/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - - - -#import "UIBarButtonItem+FLEX.h" -#import "CALayer+FLEX.h" -#import "UIFont+FLEX.h" -#import "UIGestureRecognizer+Blocks.h" -#import "UIPasteboard+FLEX.h" -#import "UIMenu+FLEX.h" -#import "UITextField+Range.h" - -#import "NSObject+FLEX_Reflection.h" -#import "NSArray+FLEX.h" -#import "NSUserDefaults+FLEX.h" -#import "NSTimer+FLEX.h" diff --git a/BHTwitter/Classes/FLEX-Core.h b/BHTwitter/Classes/FLEX-Core.h deleted file mode 100644 index db98641a..00000000 --- a/BHTwitter/Classes/FLEX-Core.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// FLEX-Core.h -// FLEX -// -// Created by Tanner on 3/11/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" -#import "FLEXNavigationController.h" -#import "FLEXTableViewController.h" -#import "FLEXTableView.h" - -#import "FLEXSingleRowSection.h" -#import "FLEXTableViewSection.h" - -#import "FLEXCodeFontCell.h" -#import "FLEXSubtitleTableViewCell.h" -#import "FLEXTableViewCell.h" -#import "FLEXMultilineTableViewCell.h" -#import "FLEXKeyValueTableViewCell.h" - diff --git a/BHTwitter/Classes/FLEX-ObjectExploring.h b/BHTwitter/Classes/FLEX-ObjectExploring.h deleted file mode 100644 index 82773e50..00000000 --- a/BHTwitter/Classes/FLEX-ObjectExploring.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// FLEX-ObjectExploring.h -// FLEX -// -// Created by Tanner on 3/11/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectExplorerViewController.h" - -#import "FLEXObjectExplorer.h" - -#import "FLEXShortcut.h" -#import "FLEXShortcutsSection.h" - -#import "FLEXCollectionContentSection.h" -#import "FLEXColorPreviewSection.h" -#import "FLEXDefaultsContentSection.h" -#import "FLEXMetadataSection.h" -#import "FLEXMutableListSection.h" -#import "FLEXObjectInfoSection.h" diff --git a/BHTwitter/Classes/FLEX-Runtime.h b/BHTwitter/Classes/FLEX-Runtime.h deleted file mode 100644 index 9fc8a69e..00000000 --- a/BHTwitter/Classes/FLEX-Runtime.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEX-Runtime.h -// FLEX -// -// Created by Tanner on 3/11/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjcInternal.h" -#import "FLEXRuntimeSafety.h" -#import "FLEXBlockDescription.h" -#import "FLEXTypeEncodingParser.h" - -#import "FLEXMirror.h" -#import "FLEXProtocol.h" -#import "FLEXProperty.h" -#import "FLEXIvar.h" -#import "FLEXMethodBase.h" -#import "FLEXMethod.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXRuntime+Compare.h" -#import "FLEXRuntime+UIKitHelpers.h" - -#import "FLEXProtocolBuilder.h" -#import "FLEXClassBuilder.h" diff --git a/BHTwitter/Classes/FLEX.h b/BHTwitter/Classes/FLEX.h deleted file mode 100644 index 6172068d..00000000 --- a/BHTwitter/Classes/FLEX.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEX.h -// FLEX -// -// Created by Eric Horacek on 7/18/15. -// Modified by Tanner Bennett on 3/12/20. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager.h" -#import "FLEXManager+Extensibility.h" -#import "FLEXManager+Networking.h" - -#import "FLEXExplorerToolbar.h" -#import "FLEXExplorerToolbarItem.h" -#import "FLEXGlobalsEntry.h" - -#import "FLEX-Core.h" -#import "FLEX-Runtime.h" -#import "FLEX-Categories.h" -#import "FLEX-ObjectExploring.h" - -#import "FLEXMacros.h" -#import "FLEXAlert.h" -#import "FLEXResources.h" diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.h deleted file mode 100644 index 3d9dd02e..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// FLEXDBQueryRowCell.h -// FLEX -// -// Created by Peng Tao on 15/11/24. -// Copyright © 2015年 f. All rights reserved. -// - -#import - -@class FLEXDBQueryRowCell; - -extern NSString * const kFLEXDBQueryRowCellReuse; - -@protocol FLEXDBQueryRowCellLayoutSource - -- (CGFloat)dbQueryRowCell:(FLEXDBQueryRowCell *)dbQueryRowCell minXForColumn:(NSUInteger)column; -- (CGFloat)dbQueryRowCell:(FLEXDBQueryRowCell *)dbQueryRowCell widthForColumn:(NSUInteger)column; - -@end - -@interface FLEXDBQueryRowCell : UITableViewCell - -/// An array of NSString, NSNumber, or NSData objects -@property (nonatomic) NSArray *data; -@property (nonatomic, weak) id layoutSource; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.m deleted file mode 100644 index 486cc983..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDBQueryRowCell.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// FLEXDBQueryRowCell.m -// FLEX -// -// Created by Peng Tao on 15/11/24. -// Copyright © 2015年 f. All rights reserved. -// - -#import "FLEXDBQueryRowCell.h" -#import "FLEXMultiColumnTableView.h" -#import "NSArray+FLEX.h" -#import "UIFont+FLEX.h" -#import "FLEXColor.h" - -NSString * const kFLEXDBQueryRowCellReuse = @"kFLEXDBQueryRowCellReuse"; - -@interface FLEXDBQueryRowCell () -@property (nonatomic) NSInteger columnCount; -@property (nonatomic) NSArray *labels; -@end - -@implementation FLEXDBQueryRowCell - -- (void)setData:(NSArray *)data { - _data = data; - self.columnCount = data.count; - - [self.labels flex_forEach:^(UILabel *label, NSUInteger idx) { - id content = self.data[idx]; - - if ([content isKindOfClass:[NSString class]]) { - label.text = content; - } else if (content == NSNull.null) { - label.text = @""; - label.textColor = FLEXColor.deemphasizedTextColor; - } else { - label.text = [content description]; - } - }]; -} - -- (void)setColumnCount:(NSInteger)columnCount { - if (columnCount != _columnCount) { - _columnCount = columnCount; - - // Remove existing labels - for (UILabel *l in self.labels) { - [l removeFromSuperview]; - } - - // Create new labels - self.labels = [NSArray flex_forEachUpTo:columnCount map:^id(NSUInteger i) { - UILabel *label = [UILabel new]; - label.font = UIFont.flex_defaultTableCellFont; - label.textAlignment = NSTextAlignmentLeft; - [self.contentView addSubview:label]; - - return label; - }]; - } -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat height = self.contentView.frame.size.height; - - [self.labels flex_forEach:^(UILabel *label, NSUInteger i) { - CGFloat width = [self.layoutSource dbQueryRowCell:self widthForColumn:i]; - CGFloat minX = [self.layoutSource dbQueryRowCell:self minXForColumn:i]; - label.frame = CGRectMake(minX + 5, 0, (width - 10), height); - }]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h deleted file mode 100644 index c8e37b1f..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXDatabaseManager.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// PTDatabaseManager.h -// Derived from: -// -// FMDatabase.h -// FMDB( https://github.com/ccgus/fmdb ) -// -// Created by Peng Tao on 15/11/23. -// -// Licensed to Flying Meat Inc. under one or more contributor license agreements. -// See the LICENSE file distributed with this work for the terms under -// which Flying Meat Inc. licenses this file to you. - -#import -#import "FLEXSQLResult.h" - -/// Conformers should automatically open and close the database -@protocol FLEXDatabaseManager - -@required - -/// @return \c nil if the database couldn't be opened -+ (instancetype)managerForDatabase:(NSString *)path; - -/// @return a list of all table names -- (NSArray *)queryAllTables; -- (NSArray *)queryAllColumnsOfTable:(NSString *)tableName; -- (NSArray *)queryAllDataInTable:(NSString *)tableName; - -@optional - -- (NSArray *)queryRowIDsInTable:(NSString *)tableName; -- (FLEXSQLResult *)executeStatement:(NSString *)SQLStatement; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h deleted file mode 100644 index 15b9d0fb..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// PTMultiColumnTableView.h -// PTMultiColumnTableViewDemo -// -// Created by Peng Tao on 15/11/16. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import -#import "FLEXTableColumnHeader.h" - -@class FLEXMultiColumnTableView; - -@protocol FLEXMultiColumnTableViewDelegate - -@required -- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didSelectRow:(NSInteger)row; -- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didSelectHeaderForColumn:(NSInteger)column sortType:(FLEXTableColumnHeaderSortType)sortType; - -@end - -@protocol FLEXMultiColumnTableViewDataSource - -@required - -- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView; -- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView; -- (NSString *)columnTitle:(NSInteger)column; -- (NSString *)rowTitle:(NSInteger)row; -- (NSArray *)contentForRow:(NSInteger)row; - -- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView minWidthForContentCellInColumn:(NSInteger)column; -- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView heightForContentCellInRow:(NSInteger)row; -- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView; -- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView; - -@end - - -@interface FLEXMultiColumnTableView : UIView - -@property (nonatomic, weak) id dataSource; -@property (nonatomic, weak) id delegate; - -- (void)reloadData; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m deleted file mode 100644 index 5f4116ea..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXMultiColumnTableView.m +++ /dev/null @@ -1,339 +0,0 @@ -// -// PTMultiColumnTableView.m -// PTMultiColumnTableViewDemo -// -// Created by Peng Tao on 15/11/16. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import "FLEXMultiColumnTableView.h" -#import "FLEXDBQueryRowCell.h" -#import "FLEXTableLeftCell.h" -#import "NSArray+FLEX.h" -#import "FLEXColor.h" - -@interface FLEXMultiColumnTableView () < - UITableViewDataSource, UITableViewDelegate, - UIScrollViewDelegate, FLEXDBQueryRowCellLayoutSource -> - -@property (nonatomic) UIScrollView *contentScrollView; -@property (nonatomic) UIScrollView *headerScrollView; -@property (nonatomic) UITableView *leftTableView; -@property (nonatomic) UITableView *contentTableView; -@property (nonatomic) UIView *leftHeader; - -@property (nonatomic) NSArray *headerViews; - -/// \c NSNotFound if no column selected -@property (nonatomic) NSInteger sortColumn; -@property (nonatomic) FLEXTableColumnHeaderSortType sortType; - -@property (nonatomic, readonly) NSInteger numberOfColumns; -@property (nonatomic, readonly) NSInteger numberOfRows; -@property (nonatomic, readonly) CGFloat topHeaderHeight; -@property (nonatomic, readonly) CGFloat leftHeaderWidth; -@property (nonatomic, readonly) CGFloat columnMargin; - -@end - -static const CGFloat kColumnMargin = 1; - -@implementation FLEXMultiColumnTableView - -#pragma mark - Initialization - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.autoresizingMask |= UIViewAutoresizingFlexibleWidth; - self.autoresizingMask |= UIViewAutoresizingFlexibleHeight; - self.autoresizingMask |= UIViewAutoresizingFlexibleTopMargin; - self.backgroundColor = FLEXColor.groupedBackgroundColor; - - [self loadHeaderScrollView]; - [self loadContentScrollView]; - [self loadLeftView]; - } - - return self; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGFloat width = self.frame.size.width; - CGFloat height = self.frame.size.height; - CGFloat topheaderHeight = self.topHeaderHeight; - CGFloat leftHeaderWidth = self.leftHeaderWidth; - CGFloat topInsets = 0.f; - - if (@available (iOS 11.0, *)) { - topInsets = self.safeAreaInsets.top; - } - - CGFloat contentWidth = 0.0; - NSInteger columnsCount = self.numberOfColumns; - for (int i = 0; i < columnsCount; i++) { - contentWidth += CGRectGetWidth(self.headerViews[i].bounds); - } - - CGFloat contentHeight = height - topheaderHeight - topInsets; - - self.leftHeader.frame = CGRectMake(0, topInsets, self.leftHeaderWidth, self.topHeaderHeight); - self.leftTableView.frame = CGRectMake( - 0, topheaderHeight + topInsets, leftHeaderWidth, contentHeight - ); - self.headerScrollView.frame = CGRectMake( - leftHeaderWidth, topInsets, width - leftHeaderWidth, topheaderHeight - ); - self.headerScrollView.contentSize = CGSizeMake( - self.contentTableView.frame.size.width, self.headerScrollView.frame.size.height - ); - self.contentTableView.frame = CGRectMake( - 0, 0, contentWidth + self.numberOfColumns * self.columnMargin , contentHeight - ); - self.contentScrollView.frame = CGRectMake( - leftHeaderWidth, topheaderHeight + topInsets, width - leftHeaderWidth, contentHeight - ); - self.contentScrollView.contentSize = self.contentTableView.frame.size; -} - - -#pragma mark - UI - -- (void)loadHeaderScrollView { - UIScrollView *headerScrollView = [UIScrollView new]; - headerScrollView.delegate = self; - headerScrollView.backgroundColor = FLEXColor.secondaryGroupedBackgroundColor; - self.headerScrollView = headerScrollView; - - [self addSubview:headerScrollView]; -} - -- (void)loadContentScrollView { - UIScrollView *scrollView = [UIScrollView new]; - scrollView.bounces = NO; - scrollView.delegate = self; - - UITableView *tableView = [UITableView new]; - tableView.delegate = self; - tableView.dataSource = self; - tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - [tableView registerClass:[FLEXDBQueryRowCell class] - forCellReuseIdentifier:kFLEXDBQueryRowCellReuse - ]; - - [scrollView addSubview:tableView]; - [self addSubview:scrollView]; - - self.contentScrollView = scrollView; - self.contentTableView = tableView; -} - -- (void)loadLeftView { - UITableView *leftTableView = [UITableView new]; - leftTableView.delegate = self; - leftTableView.dataSource = self; - leftTableView.separatorStyle = UITableViewCellSeparatorStyleNone; - self.leftTableView = leftTableView; - [self addSubview:leftTableView]; - - UIView *leftHeader = [UIView new]; - leftHeader.backgroundColor = FLEXColor.secondaryBackgroundColor; - self.leftHeader = leftHeader; - [self addSubview:leftHeader]; -} - - -#pragma mark - Data - -- (void)reloadData { - [self loadHeaderData]; - [self loadLeftViewData]; - [self loadContentData]; -} - -- (void)loadHeaderData { - // Remove existing headers, if any - for (UIView *subview in self.headerViews) { - [subview removeFromSuperview]; - } - - __block CGFloat xOffset = 0; - - self.headerViews = [NSArray flex_forEachUpTo:self.numberOfColumns map:^id(NSUInteger column) { - FLEXTableColumnHeader *header = [FLEXTableColumnHeader new]; - header.titleLabel.text = [self columnTitle:column]; - - CGSize fittingSize = CGSizeMake(CGFLOAT_MAX, self.topHeaderHeight - 1); - CGFloat width = self.columnMargin + MAX( - [self minContentWidthForColumn:column], - [header sizeThatFits:fittingSize].width - ); - header.frame = CGRectMake(xOffset, 0, width, self.topHeaderHeight - 1); - - if (column == self.sortColumn) { - header.sortType = self.sortType; - } - - // Header tap gesture - UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(contentHeaderTap:) - ]; - [header addGestureRecognizer:gesture]; - header.userInteractionEnabled = YES; - - xOffset += width; - [self.headerScrollView addSubview:header]; - return header; - }]; -} - -- (void)contentHeaderTap:(UIGestureRecognizer *)gesture { - NSInteger newSortColumn = [self.headerViews indexOfObject:gesture.view]; - FLEXTableColumnHeaderSortType newType = FLEXNextTableColumnHeaderSortType(self.sortType); - - // Reset old header - FLEXTableColumnHeader *oldHeader = (id)self.headerViews[self.sortColumn]; - oldHeader.sortType = FLEXTableColumnHeaderSortTypeNone; - - // Update new header - FLEXTableColumnHeader *newHeader = (id)self.headerViews[newSortColumn]; - newHeader.sortType = newType; - - // Update self - self.sortColumn = newSortColumn; - self.sortType = newType; - - // Notify delegate - [self.delegate multiColumnTableView:self didSelectHeaderForColumn:newSortColumn sortType:newType]; -} - -- (void)loadContentData { - [self.contentTableView reloadData]; -} - -- (void)loadLeftViewData { - [self.leftTableView reloadData]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - // Alternating background color - UIColor *backgroundColor = FLEXColor.primaryBackgroundColor; - if (indexPath.row % 2 != 0) { - backgroundColor = FLEXColor.secondaryBackgroundColor; - } - - // Left side table view for row numbers - if (tableView == self.leftTableView) { - FLEXTableLeftCell *cell = [FLEXTableLeftCell cellWithTableView:tableView]; - cell.contentView.backgroundColor = backgroundColor; - cell.titlelabel.text = [self rowTitle:indexPath.row]; - return cell; - } - // Right side table view for data - else { - FLEXDBQueryRowCell *cell = [tableView - dequeueReusableCellWithIdentifier:kFLEXDBQueryRowCellReuse forIndexPath:indexPath - ]; - - cell.contentView.backgroundColor = backgroundColor; - cell.data = [self.dataSource contentForRow:indexPath.row]; - cell.layoutSource = self; - NSAssert(cell.data.count == self.numberOfColumns, @"Count of data provided was incorrect"); - return cell; - } -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return [self.dataSource numberOfRowsInTableView:self]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - return [self.dataSource multiColumnTableView:self heightForContentCellInRow:indexPath.row]; -} - -// Scroll all scroll views in sync -- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (scrollView == self.contentScrollView) { - self.headerScrollView.contentOffset = scrollView.contentOffset; - } - else if (scrollView == self.headerScrollView) { - self.contentScrollView.contentOffset = scrollView.contentOffset; - } - else if (scrollView == self.leftTableView) { - self.contentTableView.contentOffset = scrollView.contentOffset; - } - else if (scrollView == self.contentTableView) { - self.leftTableView.contentOffset = scrollView.contentOffset; - } -} - - -#pragma mark UITableView Delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (tableView == self.leftTableView) { - [self.contentTableView - selectRowAtIndexPath:indexPath - animated:NO - scrollPosition:UITableViewScrollPositionNone - ]; - } - else if (tableView == self.contentTableView) { - [self.delegate multiColumnTableView:self didSelectRow:indexPath.row]; - } -} - - -#pragma mark FLEXDBQueryRowCellLayoutSource - -- (CGFloat)dbQueryRowCell:(FLEXDBQueryRowCell *)dbQueryRowCell minXForColumn:(NSUInteger)column { - return CGRectGetMinX(self.headerViews[column].frame); -} - -- (CGFloat)dbQueryRowCell:(FLEXDBQueryRowCell *)dbQueryRowCell widthForColumn:(NSUInteger)column { - return CGRectGetWidth(self.headerViews[column].bounds); -} - - -#pragma mark DataSource Accessor - -- (NSInteger)numberOfRows { - return [self.dataSource numberOfRowsInTableView:self]; -} - -- (NSInteger)numberOfColumns { - return [self.dataSource numberOfColumnsInTableView:self]; -} - -- (NSString *)columnTitle:(NSInteger)column { - return [self.dataSource columnTitle:column]; -} - -- (NSString *)rowTitle:(NSInteger)row { - return [self.dataSource rowTitle:row]; -} - -- (CGFloat)minContentWidthForColumn:(NSInteger)column { - return [self.dataSource multiColumnTableView:self minWidthForContentCellInColumn:column]; -} - -- (CGFloat)contentHeightForRow:(NSInteger)row { - return [self.dataSource multiColumnTableView:self heightForContentCellInRow:row]; -} - -- (CGFloat)topHeaderHeight { - return [self.dataSource heightForTopHeaderInTableView:self]; -} - -- (CGFloat)leftHeaderWidth { - return [self.dataSource widthForLeftHeaderInTableView:self]; -} - -- (CGFloat)columnMargin { - return kColumnMargin; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h deleted file mode 100644 index 44c78fb3..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXRealmDatabaseManager.h -// FLEX -// -// Created by Tim Oliver on 28/01/2016. -// Copyright © 2016 Realm. All rights reserved. -// - -#import -#import "FLEXDatabaseManager.h" - -@interface FLEXRealmDatabaseManager : NSObject - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m deleted file mode 100644 index d7da829f..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDatabaseManager.m +++ /dev/null @@ -1,102 +0,0 @@ -// -// FLEXRealmDatabaseManager.m -// FLEX -// -// Created by Tim Oliver on 28/01/2016. -// Copyright © 2016 Realm. All rights reserved. -// - -#import "FLEXRealmDatabaseManager.h" -#import "NSArray+FLEX.h" -#import "FLEXSQLResult.h" - -#if __has_include() -#import -#import -#else -#import "FLEXRealmDefines.h" -#endif - -@interface FLEXRealmDatabaseManager () - -@property (nonatomic, copy) NSString *path; -@property (nonatomic) RLMRealm *realm; - -@end - -@implementation FLEXRealmDatabaseManager -static Class RLMRealmClass = nil; - -+ (void)load { - RLMRealmClass = NSClassFromString(@"RLMRealm"); -} - -+ (instancetype)managerForDatabase:(NSString *)path { - return [[self alloc] initWithPath:path]; -} - -- (instancetype)initWithPath:(NSString *)path { - if (!RLMRealmClass) { - return nil; - } - - self = [super init]; - if (self) { - _path = path; - - if (![self open]) { - return nil; - } - } - - return self; -} - -- (BOOL)open { - Class configurationClass = NSClassFromString(@"RLMRealmConfiguration"); - if (!RLMRealmClass || !configurationClass) { - return NO; - } - - NSError *error = nil; - id configuration = [configurationClass new]; - [(RLMRealmConfiguration *)configuration setFileURL:[NSURL fileURLWithPath:self.path]]; - self.realm = [RLMRealmClass realmWithConfiguration:configuration error:&error]; - - return (error == nil); -} - -- (NSArray *)queryAllTables { - // Map each schema to its name - NSArray *tableNames = [self.realm.schema.objectSchema flex_mapped:^id(RLMObjectSchema *schema, NSUInteger idx) { - return schema.className ?: nil; - }]; - - return [tableNames sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; -} - -- (NSArray *)queryAllColumnsOfTable:(NSString *)tableName { - RLMObjectSchema *objectSchema = [self.realm.schema schemaForClassName:tableName]; - // Map each column to its name - return [objectSchema.properties flex_mapped:^id(RLMProperty *property, NSUInteger idx) { - return property.name; - }]; -} - -- (NSArray *)queryAllDataInTable:(NSString *)tableName { - RLMObjectSchema *objectSchema = [self.realm.schema schemaForClassName:tableName]; - RLMResults *results = [self.realm allObjects:tableName]; - if (results.count == 0 || !objectSchema) { - return nil; - } - - // Map results to an array of rows - return [NSArray flex_mapped:results block:^id(RLMObject *result, NSUInteger idx) { - // Map each row to an array of the values of its properties - return [objectSchema.properties flex_mapped:^id(RLMProperty *property, NSUInteger idx) { - return [result valueForKey:property.name] ?: NSNull.null; - }]; - }]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h deleted file mode 100644 index 992429a9..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXRealmDefines.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// Realm.h -// FLEX -// -// Created by Tim Oliver on 16/02/2016. -// Copyright © 2016 Realm. All rights reserved. -// - -#if __has_include() -#else - -@class RLMObject, RLMResults, RLMRealm, RLMRealmConfiguration, RLMSchema, RLMObjectSchema, RLMProperty; - -@interface RLMRealmConfiguration : NSObject -@property (nonatomic, copy) NSURL *fileURL; -@end - -@interface RLMRealm : NSObject -@property (nonatomic, readonly) RLMSchema *schema; -+ (RLMRealm *)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error; -- (RLMResults *)allObjects:(NSString *)className; -@end - -@interface RLMSchema : NSObject -@property (nonatomic, readonly) NSArray *objectSchema; -- (RLMObjectSchema *)schemaForClassName:(NSString *)className; -@end - -@interface RLMObjectSchema : NSObject -@property (nonatomic, readonly) NSString *className; -@property (nonatomic, readonly) NSArray *properties; -@end - -@interface RLMProperty : NSString -@property (nonatomic, readonly) NSString *name; -@end - -@interface RLMResults : NSObject -@property (nonatomic, readonly) NSInteger count; -@end - -@interface RLMObject : NSObject - -@end - -#endif diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h deleted file mode 100644 index 4fece3a7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// FLEXSQLResult.h -// FLEX -// -// Created by Tanner on 3/3/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXSQLResult : NSObject - -/// Describes the result of a non-select query, or an error of any kind of query -+ (instancetype)message:(NSString *)message; -/// Describes the result of a known failed execution -+ (instancetype)error:(NSString *)message; - -/// @param rowData A list of rows, where each element in the row -/// corresponds to the column given in /c columnNames -+ (instancetype)columns:(NSArray *)columnNames - rows:(NSArray *> *)rowData; - -@property (nonatomic, readonly, nullable) NSString *message; - -/// A value of YES means this is surely an error, -/// but it still might be an error even with a value of NO -@property (nonatomic, readonly) BOOL isError; - -/// A list of column names -@property (nonatomic, readonly, nullable) NSArray *columns; -/// A list of rows, where each element in the row corresponds -/// to the value of the column at the same index in \c columns. -/// -/// That is, given a row, looping over the contents of the row and -/// the contents of \c columns will give you key-value pairs of -/// column names to column values for that row. -@property (nonatomic, readonly, nullable) NSArray *> *rows; -/// A list of rows where the fields are paired to column names. -/// -/// This property is lazily constructed by looping over -/// the rows and columns present in the other two properties. -@property (nonatomic, readonly, nullable) NSArray *> *keyedRows; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.m deleted file mode 100644 index a6b19fdb..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLResult.m +++ /dev/null @@ -1,53 +0,0 @@ -// -// FLEXSQLResult.m -// FLEX -// -// Created by Tanner on 3/3/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSQLResult.h" -#import "NSArray+FLEX.h" - -@implementation FLEXSQLResult -@synthesize keyedRows = _keyedRows; - -+ (instancetype)message:(NSString *)message { - return [[self alloc] initWithmessage:message columns:nil rows:nil]; -} - -+ (instancetype)error:(NSString *)message { - FLEXSQLResult *result = [self message:message]; - result->_isError = YES; - return result; -} - -+ (instancetype)columns:(NSArray *)columnNames rows:(NSArray *> *)rowData { - return [[self alloc] initWithmessage:nil columns:columnNames rows:rowData]; -} - -- (id)initWithmessage:(NSString *)message columns:(NSArray *)columns rows:(NSArray *)rows { - NSParameterAssert(message || (columns && rows)); - NSParameterAssert(columns.count == rows.firstObject.count); - - self = [super init]; - if (self) { - _message = message; - _columns = columns; - _rows = rows; - } - - return self; -} - -- (NSArray *> *)keyedRows { - if (!_keyedRows) { - _keyedRows = [self.rows flex_mapped:^id(NSArray *row, NSUInteger idx) { - return [NSDictionary dictionaryWithObjects:row forKeys:self.columns]; - }]; - } - - return _keyedRows; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h deleted file mode 100644 index 50dc4cd7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.h +++ /dev/null @@ -1,32 +0,0 @@ -// -// PTDatabaseManager.h -// Derived from: -// -// FMDatabase.h -// FMDB( https://github.com/ccgus/fmdb ) -// -// Created by Peng Tao on 15/11/23. -// -// Licensed to Flying Meat Inc. under one or more contributor license agreements. -// See the LICENSE file distributed with this work for the terms under -// which Flying Meat Inc. licenses this file to you. - -#import -#import "FLEXDatabaseManager.h" -#import "FLEXSQLResult.h" - -@interface FLEXSQLiteDatabaseManager : NSObject - -/// Contains the result of the last operation, which may be an error -@property (nonatomic, readonly) FLEXSQLResult *lastResult; -/// Calls into \c sqlite3_last_insert_rowid() -@property (nonatomic, readonly) NSInteger lastRowID; - -/// Given a statement like 'SELECT * from @table where @col = @val' and arguments -/// like { @"table": @"Album", @"col": @"year", @"val" @1 } this method will -/// invoke the statement and properly bind the given arguments to the statement. -/// -/// You may pass NSStrings, NSData, NSNumbers, or NSNulls as values. -- (FLEXSQLResult *)executeStatement:(NSString *)statement arguments:(NSDictionary *)args; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m deleted file mode 100644 index 32648ec7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXSQLiteDatabaseManager.m +++ /dev/null @@ -1,313 +0,0 @@ -// -// PTDatabaseManager.m -// PTDatabaseReader -// -// Created by Peng Tao on 15/11/23. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import "FLEXSQLiteDatabaseManager.h" -#import "FLEXManager.h" -#import "NSArray+FLEX.h" -#import "FLEXRuntimeConstants.h" -#import - -static NSString * const QUERY_TABLENAMES = @"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name"; - -@interface FLEXSQLiteDatabaseManager () -@property (nonatomic) sqlite3 *db; -@property (nonatomic, copy) NSString *path; -@end - -@implementation FLEXSQLiteDatabaseManager - -#pragma mark - FLEXDatabaseManager - -+ (instancetype)managerForDatabase:(NSString *)path { - return [[self alloc] initWithPath:path]; -} - -- (instancetype)initWithPath:(NSString *)path { - self = [super init]; - if (self) { - self.path = path; - } - - return self; -} - -- (void)dealloc { - [self close]; -} - -- (BOOL)open { - if (self.db) { - return YES; - } - - int err = sqlite3_open(self.path.UTF8String, &_db); - -#if SQLITE_HAS_CODEC - NSString *defaultSqliteDatabasePassword = FLEXManager.sharedManager.defaultSqliteDatabasePassword; - if (defaultSqliteDatabasePassword) { - const char *key = defaultSqliteDatabasePassword.UTF8String; - sqlite3_key(_db, key, (int)strlen(key)); - } -#endif - - if (err != SQLITE_OK) { - return [self storeErrorForLastTask:@"Open"]; - } - - return YES; -} - -- (BOOL)close { - if (!self.db) { - return YES; - } - - int rc; - BOOL retry, triedFinalizingOpenStatements = NO; - - do { - retry = NO; - rc = sqlite3_close(_db); - if (SQLITE_BUSY == rc || SQLITE_LOCKED == rc) { - if (!triedFinalizingOpenStatements) { - triedFinalizingOpenStatements = YES; - sqlite3_stmt *pStmt; - while ((pStmt = sqlite3_next_stmt(_db, nil)) !=0) { - NSLog(@"Closing leaked statement"); - sqlite3_finalize(pStmt); - retry = YES; - } - } - } else if (SQLITE_OK != rc) { - [self storeErrorForLastTask:@"Close"]; - self.db = nil; - return NO; - } - } while (retry); - - self.db = nil; - return YES; -} - -- (NSInteger)lastRowID { - return (NSInteger)sqlite3_last_insert_rowid(self.db); -} - -- (NSArray *)queryAllTables { - return [[self executeStatement:QUERY_TABLENAMES].rows flex_mapped:^id(NSArray *table, NSUInteger idx) { - return table.firstObject; - }] ?: @[]; -} - -- (NSArray *)queryAllColumnsOfTable:(NSString *)tableName { - NSString *sql = [NSString stringWithFormat:@"PRAGMA table_info('%@')",tableName]; - FLEXSQLResult *results = [self executeStatement:sql]; - - return [results.keyedRows flex_mapped:^id(NSDictionary *column, NSUInteger idx) { - return column[@"name"]; - }] ?: @[]; -} - -- (NSArray *)queryAllDataInTable:(NSString *)tableName { - NSString *command = [NSString stringWithFormat:@"SELECT * FROM \"%@\"", tableName]; - return [self executeStatement:command].rows ?: @[]; -} - -- (NSArray *)queryRowIDsInTable:(NSString *)tableName { - NSString *command = [NSString stringWithFormat:@"SELECT rowid FROM \"%@\"", tableName]; - NSArray *> *data = [self executeStatement:command].rows ?: @[]; - - return [data flex_mapped:^id(NSArray *obj, NSUInteger idx) { - return obj.firstObject; - }]; -} - -- (FLEXSQLResult *)executeStatement:(NSString *)sql { - return [self executeStatement:sql arguments:nil]; -} - -- (FLEXSQLResult *)executeStatement:(NSString *)sql arguments:(NSDictionary *)args { - [self open]; - - FLEXSQLResult *result = nil; - - sqlite3_stmt *pstmt; - int status; - if ((status = sqlite3_prepare_v2(_db, sql.UTF8String, -1, &pstmt, 0)) == SQLITE_OK) { - NSMutableArray *rows = [NSMutableArray new]; - - // Bind parameters, if any - if (![self bindParameters:args toStatement:pstmt]) { - return self.lastResult; - } - - // Grab columns - int columnCount = sqlite3_column_count(pstmt); - NSArray *columns = [NSArray flex_forEachUpTo:columnCount map:^id(NSUInteger i) { - return @(sqlite3_column_name(pstmt, (int)i)); - }]; - - // Execute statement - while ((status = sqlite3_step(pstmt)) == SQLITE_ROW) { - // Grab rows if this is a selection query - int dataCount = sqlite3_data_count(pstmt); - if (dataCount > 0) { - [rows addObject:[NSArray flex_forEachUpTo:columnCount map:^id(NSUInteger i) { - return [self objectForColumnIndex:(int)i stmt:pstmt]; - }]]; - } - } - - if (status == SQLITE_DONE) { - if (rows.count) { - // We selected some rows - result = _lastResult = [FLEXSQLResult columns:columns rows:rows]; - } else { - // We executed a query like INSERT, UDPATE, or DELETE - int rowsAffected = sqlite3_changes(_db); - NSString *message = [NSString stringWithFormat:@"%d row(s) affected", rowsAffected]; - result = _lastResult = [FLEXSQLResult message:message]; - } - } else { - // An error occured executing the query - result = _lastResult = [self errorResult:@"Execution"]; - } - } else { - // An error occurred creating the prepared statement - result = _lastResult = [self errorResult:@"Prepared statement"]; - } - - sqlite3_finalize(pstmt); - return result; -} - - -#pragma mark - Private - -/// @return YES on success, NO if an error was encountered and stored in \c lastResult -- (BOOL)bindParameters:(NSDictionary *)args toStatement:(sqlite3_stmt *)pstmt { - for (NSString *param in args.allKeys) { - int status = SQLITE_OK, idx = sqlite3_bind_parameter_index(pstmt, param.UTF8String); - id value = args[param]; - - if (idx == 0) { - // No parameter matching that arg - @throw NSInternalInconsistencyException; - } - - // Null - if ([value isKindOfClass:[NSNull class]]) { - status = sqlite3_bind_null(pstmt, idx); - } - // String params - else if ([value isKindOfClass:[NSString class]]) { - const char *str = [value UTF8String]; - status = sqlite3_bind_text(pstmt, idx, str, (int)strlen(str), SQLITE_TRANSIENT); - } - // Data params - else if ([value isKindOfClass:[NSData class]]) { - const void *blob = [value bytes]; - status = sqlite3_bind_blob64(pstmt, idx, blob, [value length], SQLITE_TRANSIENT); - } - // Primitive params - else if ([value isKindOfClass:[NSNumber class]]) { - FLEXTypeEncoding type = [value objCType][0]; - switch (type) { - case FLEXTypeEncodingCBool: - case FLEXTypeEncodingChar: - case FLEXTypeEncodingUnsignedChar: - case FLEXTypeEncodingShort: - case FLEXTypeEncodingUnsignedShort: - case FLEXTypeEncodingInt: - case FLEXTypeEncodingUnsignedInt: - case FLEXTypeEncodingLong: - case FLEXTypeEncodingUnsignedLong: - case FLEXTypeEncodingLongLong: - case FLEXTypeEncodingUnsignedLongLong: - status = sqlite3_bind_int64(pstmt, idx, (sqlite3_int64)[value longValue]); - break; - - case FLEXTypeEncodingFloat: - case FLEXTypeEncodingDouble: - status = sqlite3_bind_double(pstmt, idx, [value doubleValue]); - break; - - default: - @throw NSInternalInconsistencyException; - break; - } - } - // Unsupported type - else { - @throw NSInternalInconsistencyException; - } - - if (status != SQLITE_OK) { - return [self storeErrorForLastTask: - [NSString stringWithFormat:@"Binding param named '%@'", param] - ]; - } - } - - return YES; -} - -- (BOOL)storeErrorForLastTask:(NSString *)action { - _lastResult = [self errorResult:action]; - return NO; -} - -- (FLEXSQLResult *)errorResult:(NSString *)description { - const char *error = sqlite3_errmsg(_db); - NSString *message = error ? @(error) : [NSString - stringWithFormat:@"(%@: empty error)", description - ]; - - return [FLEXSQLResult error:message]; -} - -- (id)objectForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt*)stmt { - int columnType = sqlite3_column_type(stmt, columnIdx); - - switch (columnType) { - case SQLITE_INTEGER: - return @(sqlite3_column_int64(stmt, columnIdx)).stringValue; - case SQLITE_FLOAT: - return @(sqlite3_column_double(stmt, columnIdx)).stringValue; - case SQLITE_BLOB: - return [NSString stringWithFormat:@"Data (%@ bytes)", - @([self dataForColumnIndex:columnIdx stmt:stmt].length) - ]; - - default: - // Default to a string for everything else - return [self stringForColumnIndex:columnIdx stmt:stmt] ?: NSNull.null; - } -} - -- (NSString *)stringForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt { - if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || columnIdx < 0) { - return nil; - } - - const char *text = (const char *)sqlite3_column_text(stmt, columnIdx); - return text ? @(text) : nil; -} - -- (NSData *)dataForColumnIndex:(int)columnIdx stmt:(sqlite3_stmt *)stmt { - if (sqlite3_column_type(stmt, columnIdx) == SQLITE_NULL || (columnIdx < 0)) { - return nil; - } - - const void *blob = sqlite3_column_blob(stmt, columnIdx); - NSInteger size = (NSInteger)sqlite3_column_bytes(stmt, columnIdx); - - return blob ? [NSData dataWithBytes:blob length:size] : nil; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h deleted file mode 100644 index 474a8702..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// FLEXTableContentHeaderCell.h -// FLEX -// -// Created by Peng Tao on 15/11/26. -// Copyright © 2015年 f. All rights reserved. -// - -#import - -typedef NS_ENUM(NSUInteger, FLEXTableColumnHeaderSortType) { - FLEXTableColumnHeaderSortTypeNone = 0, - FLEXTableColumnHeaderSortTypeAsc, - FLEXTableColumnHeaderSortTypeDesc, -}; - -NS_INLINE FLEXTableColumnHeaderSortType FLEXNextTableColumnHeaderSortType( - FLEXTableColumnHeaderSortType current) { - switch (current) { - case FLEXTableColumnHeaderSortTypeAsc: - return FLEXTableColumnHeaderSortTypeDesc; - case FLEXTableColumnHeaderSortTypeNone: - case FLEXTableColumnHeaderSortTypeDesc: - return FLEXTableColumnHeaderSortTypeAsc; - } - - return FLEXTableColumnHeaderSortTypeNone; -} - -@interface FLEXTableColumnHeader : UIView - -@property (nonatomic) NSInteger index; -@property (nonatomic, readonly) UILabel *titleLabel; - -@property (nonatomic) FLEXTableColumnHeaderSortType sortType; - -@end - diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m deleted file mode 100644 index 9adaec42..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableColumnHeader.m +++ /dev/null @@ -1,78 +0,0 @@ -// -// FLEXTableContentHeaderCell.m -// FLEX -// -// Created by Peng Tao on 15/11/26. -// Copyright © 2015年 f. All rights reserved. -// - -#import "FLEXTableColumnHeader.h" -#import "FLEXColor.h" -#import "UIFont+FLEX.h" -#import "FLEXUtility.h" - -static const CGFloat kMargin = 5; -static const CGFloat kArrowWidth = 20; - -@interface FLEXTableColumnHeader () -@property (nonatomic, readonly) UILabel *arrowLabel; -@property (nonatomic, readonly) UIView *lineView; -@end - -@implementation FLEXTableColumnHeader - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - self.backgroundColor = FLEXColor.secondaryBackgroundColor; - - _titleLabel = [UILabel new]; - _titleLabel.font = UIFont.flex_defaultTableCellFont; - [self addSubview:_titleLabel]; - - _arrowLabel = [UILabel new]; - _arrowLabel.font = UIFont.flex_defaultTableCellFont; - [self addSubview:_arrowLabel]; - - _lineView = [UIView new]; - _lineView.backgroundColor = FLEXColor.hairlineColor; - [self addSubview:_lineView]; - - } - return self; -} - -- (void)setSortType:(FLEXTableColumnHeaderSortType)type { - _sortType = type; - - switch (type) { - case FLEXTableColumnHeaderSortTypeNone: - _arrowLabel.text = @""; - break; - case FLEXTableColumnHeaderSortTypeAsc: - _arrowLabel.text = @"⬆️"; - break; - case FLEXTableColumnHeaderSortTypeDesc: - _arrowLabel.text = @"⬇️"; - break; - } -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGSize size = self.frame.size; - - self.titleLabel.frame = CGRectMake(kMargin, 0, size.width - kArrowWidth - kMargin, size.height); - self.arrowLabel.frame = CGRectMake(size.width - kArrowWidth, 0, kArrowWidth, size.height); - self.lineView.frame = CGRectMake(size.width - 1, 2, FLEXPointsToPixels(1), size.height - 4); -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat margins = kArrowWidth - 2 * kMargin; - size = CGSizeMake(size.width - margins, size.height); - CGFloat width = [_titleLabel sizeThatFits:size].width + margins; - return CGSizeMake(width, size.height); -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h deleted file mode 100644 index 4863aa84..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// PTTableContentViewController.h -// PTDatabaseReader -// -// Created by Peng Tao on 15/11/23. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import -#import "FLEXDatabaseManager.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXTableContentViewController : UIViewController - -/// Display a table with the given columns, rows, and name. -/// @param databaseManager an optional manager to allow modifying the table. -+ (instancetype)columns:(NSArray *)columnNames - rows:(NSArray *> *)rowData - rowIDs:(nullable NSArray *)rowIds - tableName:(NSString *)tableName - database:(nullable id)databaseManager; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m deleted file mode 100755 index 365ef547..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableContentViewController.m +++ /dev/null @@ -1,264 +0,0 @@ -// -// PTTableContentViewController.m -// PTDatabaseReader -// -// Created by Peng Tao on 15/11/23. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import "FLEXTableContentViewController.h" -#import "FLEXMultiColumnTableView.h" -#import "FLEXWebViewController.h" -#import "FLEXUtility.h" -#import "UIBarButtonItem+FLEX.h" - -@interface FLEXTableContentViewController () < - FLEXMultiColumnTableViewDataSource, FLEXMultiColumnTableViewDelegate -> -@property (nonatomic, readonly) NSArray *columns; -@property (nonatomic) NSMutableArray *rows; -@property (nonatomic, readonly) NSString *tableName; -@property (nonatomic, nullable) NSMutableArray *rowIDs; -@property (nonatomic, readonly, nullable) id databaseManager; - -@property (nonatomic) FLEXMultiColumnTableView *multiColumnView; -@end - -@implementation FLEXTableContentViewController - -+ (instancetype)columns:(NSArray *)columnNames - rows:(NSArray *> *)rowData - rowIDs:(nullable NSArray *)rowIDs - tableName:(NSString *)tableName - database:(nullable id)databaseManager { - FLEXTableContentViewController *controller = [self new]; - controller->_columns = columnNames.copy; - controller->_rows = rowData.mutableCopy; - controller->_rowIDs = rowIDs.mutableCopy; - controller->_tableName = tableName.copy; - controller->_databaseManager = databaseManager; - return controller; -} - -- (void)loadView { - [super loadView]; - - [self.view addSubview:self.multiColumnView]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - self.title = self.tableName; - self.edgesForExtendedLayout = UIRectEdgeNone; - [self.multiColumnView reloadData]; - [self setupToolbarItems]; -} - -- (FLEXMultiColumnTableView *)multiColumnView { - if (!_multiColumnView) { - _multiColumnView = [[FLEXMultiColumnTableView alloc] - initWithFrame:FLEXRectSetSize(CGRectZero, self.view.frame.size) - ]; - - _multiColumnView.dataSource = self; - _multiColumnView.delegate = self; - } - - return _multiColumnView; -} - -#pragma mark MultiColumnTableView DataSource - -- (NSInteger)numberOfColumnsInTableView:(FLEXMultiColumnTableView *)tableView { - return self.columns.count; -} - -- (NSInteger)numberOfRowsInTableView:(FLEXMultiColumnTableView *)tableView { - return self.rows.count; -} - -- (NSString *)columnTitle:(NSInteger)column { - return self.columns[column]; -} - -- (NSString *)rowTitle:(NSInteger)row { - return @(row).stringValue; -} - -- (NSArray *)contentForRow:(NSInteger)row { - return self.rows[row]; -} - -- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView - heightForContentCellInRow:(NSInteger)row { - return 40; -} - -- (CGFloat)multiColumnTableView:(FLEXMultiColumnTableView *)tableView - minWidthForContentCellInColumn:(NSInteger)column { - return 100; -} - -- (CGFloat)heightForTopHeaderInTableView:(FLEXMultiColumnTableView *)tableView { - return 40; -} - -- (CGFloat)widthForLeftHeaderInTableView:(FLEXMultiColumnTableView *)tableView { - NSString *str = [NSString stringWithFormat:@"%lu",(unsigned long)self.rows.count]; - NSDictionary *attrs = @{ NSFontAttributeName : [UIFont systemFontOfSize:17.0] }; - CGSize size = [str boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, 14) - options:NSStringDrawingUsesLineFragmentOrigin - attributes:attrs context:nil - ].size; - - return size.width + 20; -} - - -#pragma mark MultiColumnTableView Delegate - -- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView didSelectRow:(NSInteger)row { - NSArray *fields = [self.rows[row] flex_mapped:^id(NSString *field, NSUInteger idx) { - return [NSString stringWithFormat:@"%@:\n%@", self.columns[idx], field]; - }]; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title([@"Row " stringByAppendingString:@(row).stringValue]); - NSString *message = [fields componentsJoinedByString:@"\n\n"]; - make.message(message); - make.button(@"Copy").handler(^(NSArray *strings) { - UIPasteboard.generalPasteboard.string = message; - }); - - // Option to delete row - BOOL hasRowID = self.rows.count && row < self.rows.count; - if (hasRowID) { - make.button(@"Delete").destructiveStyle().handler(^(NSArray *strings) { - NSString *deleteRow = [NSString stringWithFormat: - @"DELETE FROM %@ WHERE rowid = %@", - self.tableName, self.rowIDs[row] - ]; - - [self executeStatementAndShowResult:deleteRow completion:^(BOOL success) { - // Remove deleted row and reload view - if (success) { - [self.rowIDs removeObjectAtIndex:row]; - [self.rows removeObjectAtIndex:row]; - [self.multiColumnView reloadData]; - } - }]; - }); - } - - make.button(@"Dismiss").cancelStyle(); - } showFrom:self]; -} - -- (void)multiColumnTableView:(FLEXMultiColumnTableView *)tableView - didSelectHeaderForColumn:(NSInteger)column - sortType:(FLEXTableColumnHeaderSortType)sortType { - - NSArray *sortContentData = [self.rows - sortedArrayWithOptions:NSSortStable - usingComparator:^NSComparisonResult(NSArray *obj1, NSArray *obj2) { - id a = obj1[column], b = obj2[column]; - if (a == NSNull.null) { - return NSOrderedAscending; - } - if (b == NSNull.null) { - return NSOrderedDescending; - } - - if ([a respondsToSelector:@selector(compare:options:)] && - [b respondsToSelector:@selector(compare:options:)]) { - return [a compare:b options:NSNumericSearch]; - } - - if ([a respondsToSelector:@selector(compare:)] && [b respondsToSelector:@selector(compare:)]) { - return [a compare:b]; - } - - return NSOrderedSame; - } - ]; - - if (sortType == FLEXTableColumnHeaderSortTypeDesc) { - sortContentData = sortContentData.reverseObjectEnumerator.allObjects.copy; - } - - self.rows = sortContentData.mutableCopy; - [self.multiColumnView reloadData]; -} - -#pragma mark - About Transition - -- (void)willTransitionToTraitCollection:(UITraitCollection *)newCollection - withTransitionCoordinator:(id )coordinator { - [super willTransitionToTraitCollection:newCollection withTransitionCoordinator:coordinator]; - - [coordinator animateAlongsideTransition:^(id context) { - if (newCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) { - self.multiColumnView.frame = CGRectMake(0, 32, self.view.frame.size.width, self.view.frame.size.height - 32); - } - else { - self.multiColumnView.frame = CGRectMake(0, 64, self.view.frame.size.width, self.view.frame.size.height - 64); - } - - [self.view setNeedsLayout]; - } completion:nil]; -} - -#pragma mark - Toolbar - -- (void)setupToolbarItems { - // We do not support modifying realm databases - if (![self.databaseManager respondsToSelector:@selector(executeStatement:)]) { - return; - } - - UIBarButtonItem *trashButton = [FLEXBarButtonItemSystem(Trash, self, @selector(trashPressed)) - flex_withTintColor:UIColor.redColor - ]; - trashButton.enabled = self.databaseManager && self.rows.count; - self.toolbarItems = @[UIBarButtonItem.flex_flexibleSpace, trashButton]; -} - -- (void)trashPressed { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Delete All Rows"); - make.message(@"All rows in this table will be permanently deleted.\nDo you want to proceed?"); - - make.button(@"Yes, I'm sure").destructiveStyle().handler(^(NSArray *strings) { - NSString *deleteAll = [NSString stringWithFormat:@"DELETE FROM %@", self.tableName]; - [self executeStatementAndShowResult:deleteAll completion:^(BOOL success) { - // Only dismiss on success - if (success) { - [self.navigationController popViewControllerAnimated:YES]; - } - }]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; -} - -#pragma mark - Helpers - -- (void)executeStatementAndShowResult:(NSString *)statement completion:(void (^_Nullable)(BOOL success))completion { - FLEXSQLResult *result = [self.databaseManager executeStatement:statement]; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - if (result.isError) { - make.title(@"Error"); - } - - make.message(result.message ?: @""); - make.button(@"Dismiss").cancelStyle().handler(^(NSArray *_) { - if (completion) { - completion(!result.isError); - } - }); - } showFrom:self]; -} - - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h deleted file mode 100644 index e3510729..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXTableLeftCell.h -// FLEX -// -// Created by Peng Tao on 15/11/24. -// Copyright © 2015年 f. All rights reserved. -// - -#import - -@interface FLEXTableLeftCell : UITableViewCell - -@property (nonatomic) UILabel *titlelabel; - -+ (instancetype)cellWithTableView:(UITableView *)tableView; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m deleted file mode 100644 index b99404e1..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableLeftCell.m +++ /dev/null @@ -1,33 +0,0 @@ -// -// FLEXTableLeftCell.m -// FLEX -// -// Created by Peng Tao on 15/11/24. -// Copyright © 2015年 f. All rights reserved. -// - -#import "FLEXTableLeftCell.h" - -@implementation FLEXTableLeftCell - -+ (instancetype)cellWithTableView:(UITableView *)tableView { - static NSString *identifier = @"FLEXTableLeftCell"; - FLEXTableLeftCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; - - if (!cell) { - cell = [[FLEXTableLeftCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]; - UILabel *textLabel = [UILabel new]; - textLabel.textAlignment = NSTextAlignmentCenter; - textLabel.font = [UIFont systemFontOfSize:13.0]; - [cell.contentView addSubview:textLabel]; - cell.titlelabel = textLabel; - } - - return cell; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - self.titlelabel.frame = self.contentView.frame; -} -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h deleted file mode 100644 index b8662028..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// PTTableListViewController.h -// PTDatabaseReader -// -// Created by Peng Tao on 15/11/23. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" - -@interface FLEXTableListViewController : FLEXFilteringTableViewController - -+ (BOOL)supportsExtension:(NSString *)extension; -- (instancetype)initWithPath:(NSString *)path; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m deleted file mode 100644 index 1ecc072a..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/FLEXTableListViewController.m +++ /dev/null @@ -1,165 +0,0 @@ -// -// PTTableListViewController.m -// PTDatabaseReader -// -// Created by Peng Tao on 15/11/23. -// Copyright © 2015年 Peng Tao. All rights reserved. -// - -#import "FLEXTableListViewController.h" -#import "FLEXDatabaseManager.h" -#import "FLEXSQLiteDatabaseManager.h" -#import "FLEXRealmDatabaseManager.h" -#import "FLEXTableContentViewController.h" -#import "FLEXMutableListSection.h" -#import "NSArray+FLEX.h" -#import "FLEXAlert.h" -#import "FLEXMacros.h" - -@interface FLEXTableListViewController () -@property (nonatomic, readonly) id dbm; -@property (nonatomic, readonly) NSString *path; - -@property (nonatomic, readonly) FLEXMutableListSection *tables; - -+ (NSArray *)supportedSQLiteExtensions; -+ (NSArray *)supportedRealmExtensions; - -@end - -@implementation FLEXTableListViewController - -- (instancetype)initWithPath:(NSString *)path { - self = [super initWithStyle:UITableViewStyleGrouped]; - if (self) { - _path = path.copy; - _dbm = [self databaseManagerForFileAtPath:path]; - } - - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; - - // Compose query button // - - UIBarButtonItem *composeQuery = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemCompose - target:self - action:@selector(queryButtonPressed) - ]; - // Cannot run custom queries on realm databases - composeQuery.enabled = [self.dbm - respondsToSelector:@selector(executeStatement:) - ]; - - [self addToolbarItems:@[composeQuery]]; -} - -- (NSArray *)makeSections { - _tables = [FLEXMutableListSection list:[self.dbm queryAllTables] - cellConfiguration:^(__kindof UITableViewCell *cell, NSString *tableName, NSInteger row) { - cell.textLabel.text = tableName; - } filterMatcher:^BOOL(NSString *filterText, NSString *tableName) { - return [tableName localizedCaseInsensitiveContainsString:filterText]; - } - ]; - - self.tables.selectionHandler = ^(FLEXTableListViewController *host, NSString *tableName) { - NSArray *rows = [host.dbm queryAllDataInTable:tableName]; - NSArray *columns = [host.dbm queryAllColumnsOfTable:tableName]; - NSArray *rowIDs = nil; - if ([host.dbm respondsToSelector:@selector(queryRowIDsInTable:)]) { - rowIDs = [host.dbm queryRowIDsInTable:tableName]; - } - UIViewController *resultsScreen = [FLEXTableContentViewController - columns:columns rows:rows rowIDs:rowIDs tableName:tableName database:host.dbm - ]; - [host.navigationController pushViewController:resultsScreen animated:YES]; - }; - - return @[self.tables]; -} - -- (void)reloadData { - self.tables.customTitle = [NSString - stringWithFormat:@"Tables (%@)", @(self.tables.filteredList.count) - ]; - - [super reloadData]; -} - -- (void)queryButtonPressed { - FLEXSQLiteDatabaseManager *database = self.dbm; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Execute an SQL query"); - make.textField(nil); - make.button(@"Run").handler(^(NSArray *strings) { - FLEXSQLResult *result = [database executeStatement:strings[0]]; - - if (result.message) { - [FLEXAlert showAlert:@"Message" message:result.message from:self]; - } else { - UIViewController *resultsScreen = [FLEXTableContentViewController - columns:result.columns rows:result.rows rowIDs:nil tableName:@"" database:nil - ]; - - [self.navigationController pushViewController:resultsScreen animated:YES]; - } - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; -} - -- (id)databaseManagerForFileAtPath:(NSString *)path { - NSString *pathExtension = path.pathExtension.lowercaseString; - - NSArray *sqliteExtensions = FLEXTableListViewController.supportedSQLiteExtensions; - if ([sqliteExtensions indexOfObject:pathExtension] != NSNotFound) { - return [FLEXSQLiteDatabaseManager managerForDatabase:path]; - } - - NSArray *realmExtensions = FLEXTableListViewController.supportedRealmExtensions; - if (realmExtensions != nil && [realmExtensions indexOfObject:pathExtension] != NSNotFound) { - return [FLEXRealmDatabaseManager managerForDatabase:path]; - } - - return nil; -} - - -#pragma mark - FLEXTableListViewController - -+ (BOOL)supportsExtension:(NSString *)extension { - extension = extension.lowercaseString; - - NSArray *sqliteExtensions = FLEXTableListViewController.supportedSQLiteExtensions; - if (sqliteExtensions.count > 0 && [sqliteExtensions indexOfObject:extension] != NSNotFound) { - return YES; - } - - NSArray *realmExtensions = FLEXTableListViewController.supportedRealmExtensions; - if (realmExtensions.count > 0 && [realmExtensions indexOfObject:extension] != NSNotFound) { - return YES; - } - - return NO; -} - -+ (NSArray *)supportedSQLiteExtensions { - return @[@"db", @"sqlite", @"sqlite3"]; -} - -+ (NSArray *)supportedRealmExtensions { - if (NSClassFromString(@"RLMRealm") == nil) { - return nil; - } - - return @[@"realm"]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/LICENSE b/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/LICENSE deleted file mode 100644 index fad3577c..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/DatabaseBrowser/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -FMDB -Copyright (c) 2008-2014 Flying Meat Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.h deleted file mode 100644 index 16d94018..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXAddressExplorerCoordinator.h -// FLEX -// -// Created by Tanner Bennett on 7/10/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsEntry.h" - -@interface FLEXAddressExplorerCoordinator : NSObject - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.m deleted file mode 100644 index 78356681..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXAddressExplorerCoordinator.m +++ /dev/null @@ -1,95 +0,0 @@ -// -// FLEXAddressExplorerCoordinator.m -// FLEX -// -// Created by Tanner Bennett on 7/10/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXAddressExplorerCoordinator.h" -#import "FLEXGlobalsViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXUtility.h" - -@interface UITableViewController (FLEXAddressExploration) -- (void)deselectSelectedRow; -- (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely; -@end - -@implementation FLEXAddressExplorerCoordinator - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"🔎 Address Explorer"; -} - -+ (FLEXGlobalsEntryRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row { - return ^(UITableViewController *host) { - - NSString *title = @"Explore Object at Address"; - NSString *message = @"Paste a hexadecimal address below, starting with '0x'. " - "Use the unsafe option if you need to bypass pointer validation, " - "but know that it may crash the app if the address is invalid."; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(title).message(message); - make.configuredTextField(^(UITextField *textField) { - NSString *copied = UIPasteboard.generalPasteboard.string; - textField.placeholder = @"0x00000070deadbeef"; - // Go ahead and paste our clipboard if we have an address copied - if ([copied hasPrefix:@"0x"]) { - textField.text = copied; - [textField selectAll:nil]; - } - }); - make.button(@"Explore").handler(^(NSArray *strings) { - [host tryExploreAddress:strings.firstObject safely:YES]; - }); - make.button(@"Unsafe Explore").destructiveStyle().handler(^(NSArray *strings) { - [host tryExploreAddress:strings.firstObject safely:NO]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:host]; - - }; -} - -@end - -@implementation UITableViewController (FLEXAddressExploration) - -- (void)deselectSelectedRow { - NSIndexPath *selected = self.tableView.indexPathForSelectedRow; - [self.tableView deselectRowAtIndexPath:selected animated:YES]; -} - -- (void)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely { - NSScanner *scanner = [NSScanner scannerWithString:addressString]; - unsigned long long hexValue = 0; - BOOL didParseAddress = [scanner scanHexLongLong:&hexValue]; - const void *pointerValue = (void *)hexValue; - - NSString *error = nil; - - if (didParseAddress) { - if (safely && ![FLEXRuntimeUtility pointerIsValidObjcObject:pointerValue]) { - error = @"The given address is unlikely to be a valid object."; - } - } else { - error = @"Malformed address. Make sure it's not too long and starts with '0x'."; - } - - if (!error) { - id object = (__bridge id)pointerValue; - FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:object]; - [self.navigationController pushViewController:explorer animated:YES]; - } else { - [FLEXAlert showAlert:@"Uh-oh" message:error from:self]; - [self deselectSelectedRow]; - } -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.h deleted file mode 100644 index 40bdaba7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXCookiesViewController.h -// FLEX -// -// Created by Rich Robinson on 19/10/2015. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsEntry.h" -#import "FLEXFilteringTableViewController.h" - -@interface FLEXCookiesViewController : FLEXFilteringTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.m deleted file mode 100644 index 886d9026..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXCookiesViewController.m +++ /dev/null @@ -1,76 +0,0 @@ -// -// FLEXCookiesViewController.m -// FLEX -// -// Created by Rich Robinson on 19/10/2015. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCookiesViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXMutableListSection.h" -#import "FLEXUtility.h" - -@interface FLEXCookiesViewController () -@property (nonatomic, readonly) FLEXMutableListSection *cookies; -@property (nonatomic) NSString *headerTitle; -@end - -@implementation FLEXCookiesViewController - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"Cookies"; -} - -- (NSArray *)makeSections { - NSSortDescriptor *nameSortDescriptor = [[NSSortDescriptor alloc] - initWithKey:@"name" ascending:YES selector:@selector(caseInsensitiveCompare:) - ]; - NSArray *cookies = [NSHTTPCookieStorage.sharedHTTPCookieStorage.cookies - sortedArrayUsingDescriptors:@[nameSortDescriptor] - ]; - - _cookies = [FLEXMutableListSection list:cookies - cellConfiguration:^(UITableViewCell *cell, NSHTTPCookie *cookie, NSInteger row) { - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.textLabel.text = [cookie.name stringByAppendingFormat:@" (%@)", cookie.value]; - cell.detailTextLabel.text = [cookie.domain stringByAppendingFormat:@" — %@", cookie.path]; - } filterMatcher:^BOOL(NSString *filterText, NSHTTPCookie *cookie) { - return [cookie.name localizedCaseInsensitiveContainsString:filterText] || - [cookie.value localizedCaseInsensitiveContainsString:filterText] || - [cookie.domain localizedCaseInsensitiveContainsString:filterText] || - [cookie.path localizedCaseInsensitiveContainsString:filterText]; - } - ]; - - self.cookies.selectionHandler = ^(UIViewController *host, NSHTTPCookie *cookie) { - [host.navigationController pushViewController:[ - FLEXObjectExplorerFactory explorerViewControllerForObject:cookie - ] animated:YES]; - }; - - return @[self.cookies]; -} - -- (void)reloadData { - self.headerTitle = [NSString stringWithFormat: - @"%@ cookies", @(self.cookies.filteredList.count) - ]; - [super reloadData]; -} - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"🍪 Cookies"; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - return [self new]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.h deleted file mode 100644 index a4060776..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXLiveObjectsController.h -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" -#import "FLEXGlobalsEntry.h" - -@interface FLEXLiveObjectsController : FLEXTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m deleted file mode 100644 index fce0f8c6..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXLiveObjectsController.m +++ /dev/null @@ -1,236 +0,0 @@ -// -// FLEXLiveObjectsController.m -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXLiveObjectsController.h" -#import "FLEXHeapEnumerator.h" -#import "FLEXObjectListViewController.h" -#import "FLEXUtility.h" -#import "FLEXScopeCarousel.h" -#import "FLEXTableView.h" -#import - -static const NSInteger kFLEXLiveObjectsSortAlphabeticallyIndex = 0; -static const NSInteger kFLEXLiveObjectsSortByCountIndex = 1; -static const NSInteger kFLEXLiveObjectsSortBySizeIndex = 2; - -@interface FLEXLiveObjectsController () - -@property (nonatomic) NSDictionary *instanceCountsForClassNames; -@property (nonatomic) NSDictionary *instanceSizesForClassNames; -@property (nonatomic, readonly) NSArray *allClassNames; -@property (nonatomic) NSArray *filteredClassNames; -@property (nonatomic) NSString *headerTitle; - -@end - -@implementation FLEXLiveObjectsController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; - self.showSearchBarInitially = YES; - self.activatesSearchBarAutomatically = YES; - self.searchBarDebounceInterval = kFLEXDebounceInstant; - self.showsCarousel = YES; - self.carousel.items = @[@"A→Z", @"Count", @"Size"]; - - self.refreshControl = [UIRefreshControl new]; - [self.refreshControl addTarget:self action:@selector(refreshControlDidRefresh:) forControlEvents:UIControlEventValueChanged]; - - [self reloadTableData]; -} - -- (NSArray *)allClassNames { - return self.instanceCountsForClassNames.allKeys; -} - -- (void)reloadTableData { - // Set up a CFMutableDictionary with class pointer keys and NSUInteger values. - // We abuse CFMutableDictionary a little to have primitive keys through judicious casting, but it gets the job done. - // The dictionary is intialized with a 0 count for each class so that it doesn't have to expand during enumeration. - // While it might be a little cleaner to populate an NSMutableDictionary with class name string keys to NSNumber counts, - // we choose the CF/primitives approach because it lets us enumerate the objects in the heap without allocating any memory during enumeration. - // The alternative of creating one NSString/NSNumber per object on the heap ends up polluting the count of live objects quite a bit. - unsigned int classCount = 0; - Class *classes = objc_copyClassList(&classCount); - CFMutableDictionaryRef mutableCountsForClasses = CFDictionaryCreateMutable(NULL, classCount, NULL, NULL); - for (unsigned int i = 0; i < classCount; i++) { - CFDictionarySetValue(mutableCountsForClasses, (__bridge const void *)classes[i], (const void *)0); - } - - // Enumerate all objects on the heap to build the counts of instances for each class. - [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id object, __unsafe_unretained Class actualClass) { - NSUInteger instanceCount = (NSUInteger)CFDictionaryGetValue(mutableCountsForClasses, (__bridge const void *)actualClass); - instanceCount++; - CFDictionarySetValue(mutableCountsForClasses, (__bridge const void *)actualClass, (const void *)instanceCount); - }]; - - // Convert our CF primitive dictionary into a nicer mapping of class name strings to counts that we will use as the table's model. - NSMutableDictionary *mutableCountsForClassNames = [NSMutableDictionary new]; - NSMutableDictionary *mutableSizesForClassNames = [NSMutableDictionary new]; - for (unsigned int i = 0; i < classCount; i++) { - Class class = classes[i]; - NSUInteger instanceCount = (NSUInteger)CFDictionaryGetValue(mutableCountsForClasses, (__bridge const void *)(class)); - NSString *className = @(class_getName(class)); - if (instanceCount > 0) { - [mutableCountsForClassNames setObject:@(instanceCount) forKey:className]; - } - [mutableSizesForClassNames setObject:@(class_getInstanceSize(class)) forKey:className]; - } - free(classes); - - self.instanceCountsForClassNames = mutableCountsForClassNames; - self.instanceSizesForClassNames = mutableSizesForClassNames; - - [self updateSearchResults:nil]; -} - -- (void)refreshControlDidRefresh:(id)sender { - [self reloadTableData]; - [self.refreshControl endRefreshing]; -} - -- (void)updateHeaderTitle { - NSUInteger totalCount = 0; - NSUInteger totalSize = 0; - for (NSString *className in self.allClassNames) { - NSUInteger count = self.instanceCountsForClassNames[className].unsignedIntegerValue; - totalCount += count; - totalSize += count * self.instanceSizesForClassNames[className].unsignedIntegerValue; - } - - NSUInteger filteredCount = 0; - NSUInteger filteredSize = 0; - for (NSString *className in self.filteredClassNames) { - NSUInteger count = self.instanceCountsForClassNames[className].unsignedIntegerValue; - filteredCount += count; - filteredSize += count * self.instanceSizesForClassNames[className].unsignedIntegerValue; - } - - if (filteredCount == totalCount) { - // Unfiltered - self.headerTitle = [NSString - stringWithFormat:@"%@ objects, %@", - @(totalCount), [NSByteCountFormatter - stringFromByteCount:totalSize - countStyle:NSByteCountFormatterCountStyleFile - ] - ]; - } else { - self.headerTitle = [NSString - stringWithFormat:@"%@ of %@ objects, %@", - @(filteredCount), @(totalCount), [NSByteCountFormatter - stringFromByteCount:filteredSize - countStyle:NSByteCountFormatterCountStyleFile - ] - ]; - } -} - - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"💩 Heap Objects"; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - FLEXLiveObjectsController *liveObjectsViewController = [self new]; - liveObjectsViewController.title = [self globalsEntryTitle:row]; - - return liveObjectsViewController; -} - - -#pragma mark - Search bar - -- (void)updateSearchResults:(NSString *)filter { - NSInteger selectedScope = self.selectedScope; - - if (filter.length) { - NSPredicate *searchPredicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[cd] %@", filter]; - self.filteredClassNames = [self.allClassNames filteredArrayUsingPredicate:searchPredicate]; - } else { - self.filteredClassNames = self.allClassNames; - } - - if (selectedScope == kFLEXLiveObjectsSortAlphabeticallyIndex) { - self.filteredClassNames = [self.filteredClassNames sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - } else if (selectedScope == kFLEXLiveObjectsSortByCountIndex) { - self.filteredClassNames = [self.filteredClassNames sortedArrayUsingComparator:^NSComparisonResult(NSString *className1, NSString *className2) { - NSNumber *count1 = self.instanceCountsForClassNames[className1]; - NSNumber *count2 = self.instanceCountsForClassNames[className2]; - // Reversed for descending counts. - return [count2 compare:count1]; - }]; - } else if (selectedScope == kFLEXLiveObjectsSortBySizeIndex) { - self.filteredClassNames = [self.filteredClassNames sortedArrayUsingComparator:^NSComparisonResult(NSString *className1, NSString *className2) { - NSNumber *count1 = self.instanceCountsForClassNames[className1]; - NSNumber *count2 = self.instanceCountsForClassNames[className2]; - NSNumber *size1 = self.instanceSizesForClassNames[className1]; - NSNumber *size2 = self.instanceSizesForClassNames[className2]; - // Reversed for descending sizes. - return [@(count2.integerValue * size2.integerValue) compare:@(count1.integerValue * size1.integerValue)]; - }]; - } - - [self updateHeaderTitle]; - [self.tableView reloadData]; -} - - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.filteredClassNames.count; -} - -- (UITableViewCell *)tableView:(__kindof UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView - dequeueReusableCellWithIdentifier:kFLEXDefaultCell - forIndexPath:indexPath - ]; - - NSString *className = self.filteredClassNames[indexPath.row]; - NSNumber *count = self.instanceCountsForClassNames[className]; - NSNumber *size = self.instanceSizesForClassNames[className]; - unsigned long totalSize = count.unsignedIntegerValue * size.unsignedIntegerValue; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.textLabel.text = [NSString stringWithFormat:@"%@ (%ld, %@)", - className, (long)[count integerValue], - [NSByteCountFormatter - stringFromByteCount:totalSize - countStyle:NSByteCountFormatterCountStyleFile - ] - ]; - - return cell; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return self.headerTitle; -} - - -#pragma mark - Table view delegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - NSString *className = self.filteredClassNames[indexPath.row]; - UIViewController *instances = [FLEXObjectListViewController - instancesOfClassWithName:className - retained:YES - ]; - [self.navigationController pushViewController:instances animated:YES]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.h deleted file mode 100644 index 5dc1985b..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXObjectListViewController.h -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" - -@interface FLEXObjectListViewController : FLEXFilteringTableViewController - -/// This will either return a list of the instances, or take you straight -/// to the explorer itself if there is only one instance. -+ (UIViewController *)instancesOfClassWithName:(NSString *)className retained:(BOOL)retain; -+ (instancetype)subclassesOfClassWithName:(NSString *)className; -+ (instancetype)objectsWithReferencesToObject:(id)object retained:(BOOL)retain; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.m deleted file mode 100644 index 0887c0e5..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectListViewController.m +++ /dev/null @@ -1,250 +0,0 @@ -// -// FLEXObjectListViewController.m -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectListViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXMutableListSection.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXUtility.h" -#import "FLEXHeapEnumerator.h" -#import "FLEXObjectRef.h" -#import "NSString+FLEX.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXTableViewCell.h" -#import - - -typedef NS_ENUM(NSUInteger, FLEXObjectReferenceSection) { - FLEXObjectReferenceSectionMain, - FLEXObjectReferenceSectionAutoLayout, - FLEXObjectReferenceSectionKVO, - FLEXObjectReferenceSectionFLEX, - - FLEXObjectReferenceSectionCount -}; - -@interface FLEXObjectListViewController () - -@property (nonatomic, readonly, class) NSArray *defaultPredicates; -@property (nonatomic, readonly, class) NSArray *defaultSectionTitles; - - -@property (nonatomic, copy) NSArray *sections; -@property (nonatomic, copy) NSArray *allSections; - -@property (nonatomic, readonly, nullable) NSArray *references; -@property (nonatomic, readonly) NSArray *predicates; -@property (nonatomic, readonly) NSArray *sectionTitles; - -@end - -@implementation FLEXObjectListViewController -@dynamic sections, allSections; - -#pragma mark - Reference Grouping - -+ (NSPredicate *)defaultPredicateForSection:(NSInteger)section { - // These are the types of references that we typically don't care about. - // We want this list of "object-ivar pairs" split into two sections. - BOOL(^isKVORelated)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { - NSString *row = ref.reference; - return [row isEqualToString:@"__NSObserver object"] || - [row isEqualToString:@"_CFXNotificationObjcObserverRegistration _object"]; - }; - - /// These are common AutoLayout related references we also rarely care about. - BOOL(^isConstraintRelated)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { - static NSSet *ignored = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - ignored = [NSSet setWithArray:@[ - @"NSLayoutConstraint _container", - @"NSContentSizeLayoutConstraint _container", - @"NSAutoresizingMaskLayoutConstraint _container", - @"MASViewConstraint _installedView", - @"MASLayoutConstraint _container", - @"MASViewAttribute _view" - ]]; - }); - - NSString *row = ref.reference; - return ([row hasPrefix:@"NSLayout"] && [row hasSuffix:@" _referenceItem"]) || - ([row hasPrefix:@"NSIS"] && [row hasSuffix:@" _delegate"]) || - ([row hasPrefix:@"_NSAutoresizingMask"] && [row hasSuffix:@" _referenceItem"]) || - [ignored containsObject:row]; - }; - - /// These are FLEX classes and usually you aren't looking for FLEX references inside FLEX itself - BOOL(^isFLEXClass)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { - return [ref.reference hasPrefix:@"FLEX"]; - }; - - BOOL(^isEssential)(FLEXObjectRef *, NSDictionary *) = ^BOOL(FLEXObjectRef *ref, NSDictionary *bindings) { - return !( - isKVORelated(ref, bindings) || - isConstraintRelated(ref, bindings) || - isFLEXClass(ref, bindings) - ); - }; - - switch (section) { - case FLEXObjectReferenceSectionMain: - return [NSPredicate predicateWithBlock:isEssential]; - case FLEXObjectReferenceSectionAutoLayout: - return [NSPredicate predicateWithBlock:isConstraintRelated]; - case FLEXObjectReferenceSectionKVO: - return [NSPredicate predicateWithBlock:isKVORelated]; - case FLEXObjectReferenceSectionFLEX: - return [NSPredicate predicateWithBlock:isFLEXClass]; - - default: return nil; - } -} - -+ (NSArray *)defaultPredicates { - return [NSArray flex_forEachUpTo:FLEXObjectReferenceSectionCount map:^id(NSUInteger i) { - return [self defaultPredicateForSection:i]; - }]; -} - -+ (NSArray *)defaultSectionTitles { - return @[ - @"", @"AutoLayout", @"Key-Value Observing", @"FLEX" - ]; -} - - -#pragma mark - Initialization - -- (id)initWithReferences:(nullable NSArray *)references { - return [self initWithReferences:references predicates:nil sectionTitles:nil]; -} - -- (id)initWithReferences:(NSArray *)references - predicates:(NSArray *)predicates - sectionTitles:(NSArray *)sectionTitles { - NSParameterAssert(predicates.count == sectionTitles.count); - - self = [super initWithStyle:UITableViewStylePlain]; - if (self) { - _references = references; - _predicates = predicates; - _sectionTitles = sectionTitles; - } - - return self; -} - -+ (UIViewController *)instancesOfClassWithName:(NSString *)className retained:(BOOL)retain { - NSArray *references = [FLEXHeapEnumerator - instancesOfClassWithName:className retained:retain - ]; - - if (references.count == 1) { - return [FLEXObjectExplorerFactory - explorerViewControllerForObject:references.firstObject.object - ]; - } - - FLEXObjectListViewController *controller = [[self alloc] initWithReferences:references]; - controller.title = [NSString stringWithFormat:@"%@ (%@)", className, @(references.count)]; - return controller; -} - -+ (instancetype)subclassesOfClassWithName:(NSString *)className { - NSArray *references = [FLEXHeapEnumerator subclassesOfClassWithName:className]; - FLEXObjectListViewController *controller = [[self alloc] initWithReferences:references]; - controller.title = [NSString stringWithFormat:@"Subclasses of %@ (%@)", - className, @(references.count) - ]; - - return controller; -} - -+ (instancetype)objectsWithReferencesToObject:(id)object retained:(BOOL)retain { - static Class SwiftObjectClass = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - SwiftObjectClass = NSClassFromString(@"SwiftObject"); - if (!SwiftObjectClass) { - SwiftObjectClass = NSClassFromString(@"Swift._SwiftObject"); - } - }); - - NSArray *instances = [FLEXHeapEnumerator - objectsWithReferencesToObject:object retained:retain - ]; - - FLEXObjectListViewController *viewController = [[self alloc] - initWithReferences:instances - predicates:self.defaultPredicates - sectionTitles:self.defaultSectionTitles - ]; - viewController.title = [NSString stringWithFormat:@"Referencing %@ %p", - [FLEXRuntimeUtility safeClassNameForObject:object], object - ]; - return viewController; -} - - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; -} - -- (NSArray *)makeSections { - if (self.predicates.count) { - return [self buildSections:self.sectionTitles predicates:self.predicates]; - } else { - return @[[self makeSection:self.references title:nil]]; - } -} - - -#pragma mark - Private - -- (NSArray *)buildSections:(NSArray *)titles predicates:(NSArray *)predicates { - NSParameterAssert(titles.count == predicates.count); - NSParameterAssert(titles); NSParameterAssert(predicates); - - return [NSArray flex_forEachUpTo:titles.count map:^id(NSUInteger i) { - NSArray *rows = [self.references filteredArrayUsingPredicate:predicates[i]]; - return [self makeSection:rows title:titles[i]]; - }]; -} - -- (FLEXMutableListSection *)makeSection:(NSArray *)rows title:(NSString *)title { weakify(self) - FLEXMutableListSection *section = [FLEXMutableListSection list:rows - cellConfiguration:^(FLEXTableViewCell *cell, FLEXObjectRef *ref, NSInteger row) { - cell.textLabel.text = ref.reference; - cell.detailTextLabel.text = ref.summary; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } filterMatcher:^BOOL(NSString *filterText, FLEXObjectRef *ref) { - if (ref.summary && [ref.summary localizedCaseInsensitiveContainsString:filterText]) { - return YES; - } - - return [ref.reference localizedCaseInsensitiveContainsString:filterText]; - } - ]; - - section.selectionHandler = ^(UIViewController *host, FLEXObjectRef *ref) { strongify(self) - [self.navigationController pushViewController:[ - FLEXObjectExplorerFactory explorerViewControllerForObject:ref.object - ] animated:YES]; - }; - - section.customTitle = title; - return section; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.h deleted file mode 100644 index 2de3c5e7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// FLEXObjectRef.h -// FLEX -// -// Created by Tanner Bennett on 7/24/18. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXObjectRef : NSObject - -/// Reference an object without affecting its lifespan or or emitting reference-counting operations. -+ (instancetype)unretained:(__unsafe_unretained id)object; -+ (instancetype)unretained:(__unsafe_unretained id)object ivar:(NSString *)ivarName; - -/// Reference an object and control its lifespan. -+ (instancetype)retained:(id)object; -+ (instancetype)retained:(id)object ivar:(NSString *)ivarName; - -/// Reference an object and conditionally choose to retain it or not. -+ (instancetype)referencing:(__unsafe_unretained id)object retained:(BOOL)retain; -+ (instancetype)referencing:(__unsafe_unretained id)object ivar:(NSString *)ivarName retained:(BOOL)retain; - -+ (NSArray *)referencingAll:(NSArray *)objects retained:(BOOL)retain; -/// Classes do not have a summary, and the reference is just the class name. -+ (NSArray *)referencingClasses:(NSArray *)classes; - -/// For example, "NSString 0x1d4085d0" or "NSLayoutConstraint _object" -@property (nonatomic, readonly) NSString *reference; -/// For instances, this is the result of -[FLEXRuntimeUtility summaryForObject:] -/// For classes, there is no summary. -@property (nonatomic, readonly) NSString *summary; -@property (nonatomic, readonly, unsafe_unretained) id object; - -/// Retains the referenced object if it is not already retained -- (void)retainObject; -/// Releases the referenced object if it is already retained -- (void)releaseObject; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.m deleted file mode 100644 index 925c89f0..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXObjectRef.m +++ /dev/null @@ -1,112 +0,0 @@ -// -// FLEXObjectRef.m -// FLEX -// -// Created by Tanner Bennett on 7/24/18. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectRef.h" -#import "FLEXRuntimeUtility.h" -#import "NSArray+FLEX.h" - -@interface FLEXObjectRef () { - /// Used to retain the object if desired - id _retainer; -} -@property (nonatomic, readonly) BOOL wantsSummary; -@end - -@implementation FLEXObjectRef -@synthesize summary = _summary; - -+ (instancetype)unretained:(__unsafe_unretained id)object { - return [self referencing:object showSummary:YES retained:NO]; -} - -+ (instancetype)unretained:(__unsafe_unretained id)object ivar:(NSString *)ivarName { - return [[self alloc] initWithObject:object ivarName:ivarName showSummary:YES retained:NO]; -} - -+ (instancetype)retained:(id)object { - return [self referencing:object showSummary:YES retained:YES]; -} - -+ (instancetype)retained:(id)object ivar:(NSString *)ivarName { - return [[self alloc] initWithObject:object ivarName:ivarName showSummary:YES retained:YES]; -} - -+ (instancetype)referencing:(__unsafe_unretained id)object retained:(BOOL)retain { - return retain ? [self retained:object] : [self unretained:object]; -} - -+ (instancetype)referencing:(__unsafe_unretained id)object ivar:(NSString *)ivarName retained:(BOOL)retain { - return retain ? [self retained:object ivar:ivarName] : [self unretained:object ivar:ivarName]; -} - -+ (instancetype)referencing:(__unsafe_unretained id)object showSummary:(BOOL)showSummary retained:(BOOL)retain { - return [[self alloc] initWithObject:object ivarName:nil showSummary:showSummary retained:retain]; -} - -+ (NSArray *)referencingAll:(NSArray *)objects retained:(BOOL)retain { - return [objects flex_mapped:^id(id obj, NSUInteger idx) { - return [self referencing:obj showSummary:YES retained:retain]; - }]; -} - -+ (NSArray *)referencingClasses:(NSArray *)classes { - return [classes flex_mapped:^id(id obj, NSUInteger idx) { - return [self referencing:obj showSummary:NO retained:NO]; - }]; -} - -- (id)initWithObject:(__unsafe_unretained id)object - ivarName:(NSString *)ivar - showSummary:(BOOL)showSummary - retained:(BOOL)retain { - self = [super init]; - if (self) { - _object = object; - _wantsSummary = showSummary; - - if (retain) { - _retainer = object; - } - - NSString *class = [FLEXRuntimeUtility safeClassNameForObject:object]; - if (ivar) { - _reference = [NSString stringWithFormat:@"%@ %@", class, ivar]; - } else if (showSummary) { - _reference = [NSString stringWithFormat:@"%@ %p", class, object]; - } else { - _reference = class; - } - } - - return self; -} - -- (NSString *)summary { - if (self.wantsSummary) { - if (!_summary) { - _summary = [FLEXRuntimeUtility summaryForObject:self.object]; - } - - return _summary; - } - else { - return nil; - } -} - -- (void)retainObject { - if (!_retainer) { - _retainer = _object; - } -} - -- (void)releaseObject { - _retainer = nil; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.h b/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.h deleted file mode 100644 index e65bd0f8..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXWebViewController.m -// Flipboard -// -// Created by Ryan Olson on 6/10/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXWebViewController : UIViewController - -- (id)initWithURL:(NSURL *)url; -- (id)initWithText:(NSString *)text; - -+ (BOOL)supportsPathExtension:(NSString *)extension; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.m b/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.m deleted file mode 100644 index 1196362a..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FLEXWebViewController.m +++ /dev/null @@ -1,124 +0,0 @@ -// -// FLEXWebViewController.m -// Flipboard -// -// Created by Ryan Olson on 6/10/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXWebViewController.h" -#import "FLEXUtility.h" -#import - -@interface FLEXWebViewController () - -@property (nonatomic) WKWebView *webView; -@property (nonatomic) NSString *originalText; - -@end - -@implementation FLEXWebViewController - -- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { - self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; - if (self) { - WKWebViewConfiguration *configuration = [WKWebViewConfiguration new]; - - if (@available(iOS 10.0, *)) { - configuration.dataDetectorTypes = WKDataDetectorTypeLink; - } - - self.webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configuration]; - self.webView.navigationDelegate = self; - } - return self; -} - -- (id)initWithText:(NSString *)text { - self = [self initWithNibName:nil bundle:nil]; - if (self) { - self.originalText = text; - NSString *htmlString = [NSString stringWithFormat:@"
%@
", [FLEXUtility stringByEscapingHTMLEntitiesInString:text]]; - [self.webView loadHTMLString:htmlString baseURL:nil]; - } - return self; -} - -- (id)initWithURL:(NSURL *)url { - self = [self initWithNibName:nil bundle:nil]; - if (self) { - NSURLRequest *request = [NSURLRequest requestWithURL:url]; - [self.webView loadRequest:request]; - } - return self; -} - -- (void)dealloc { - // WKWebView's delegate is assigned so we need to clear it manually. - if (_webView.navigationDelegate == self) { - _webView.navigationDelegate = nil; - } -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [self.view addSubview:self.webView]; - self.webView.frame = self.view.bounds; - self.webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - if (self.originalText.length > 0) { - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Copy" style:UIBarButtonItemStylePlain target:self action:@selector(copyButtonTapped:)]; - } -} - -- (void)copyButtonTapped:(id)sender { - [UIPasteboard.generalPasteboard setString:self.originalText]; -} - - -#pragma mark - WKWebView Delegate - -- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler { - WKNavigationActionPolicy policy = WKNavigationActionPolicyCancel; - if (navigationAction.navigationType == WKNavigationTypeOther) { - // Allow the initial load - policy = WKNavigationActionPolicyAllow; - } else { - // For clicked links, push another web view controller onto the navigation stack so that hitting the back button works as expected. - // Don't allow the current web view to handle the navigation. - NSURLRequest *request = navigationAction.request; - FLEXWebViewController *webVC = [[[self class] alloc] initWithURL:[request URL]]; - webVC.title = [[request URL] absoluteString]; - [self.navigationController pushViewController:webVC animated:YES]; - } - decisionHandler(policy); -} - - -#pragma mark - Class Helpers - -+ (BOOL)supportsPathExtension:(NSString *)extension { - BOOL supported = NO; - NSSet *supportedExtensions = [self webViewSupportedPathExtensions]; - if ([supportedExtensions containsObject:[extension lowercaseString]]) { - supported = YES; - } - return supported; -} - -+ (NSSet *)webViewSupportedPathExtensions { - static NSSet *pathExtensions = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // Note that this is not exhaustive, but all these extensions should work well in the web view. - // See https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingContentforSafarioniPhone/CreatingContentforSafarioniPhone.html#//apple_ref/doc/uid/TP40006482-SW7 - pathExtensions = [NSSet setWithArray:@[@"jpg", @"jpeg", @"png", @"gif", @"pdf", @"svg", @"tiff", @"3gp", @"3gpp", @"3g2", - @"3gp2", @"aiff", @"aif", @"aifc", @"cdda", @"amr", @"mp3", @"swa", @"mp4", @"mpeg", - @"mpg", @"mp3", @"wav", @"bwf", @"m4a", @"m4b", @"m4p", @"mov", @"qt", @"mqv", @"m4v"]]; - - }); - return pathExtensions; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h b/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h deleted file mode 100644 index 29dae965..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXFileBrowserController.h -// Flipboard -// -// Created by Ryan Olson on 6/9/14. -// Based on previous work by Evan Doll -// - -#import "FLEXTableViewController.h" -#import "FLEXGlobalsEntry.h" -#import "FLEXFileBrowserSearchOperation.h" - -@interface FLEXFileBrowserController : FLEXTableViewController - -+ (instancetype)path:(NSString *)path; -- (id)initWithPath:(NSString *)path; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.m b/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.m deleted file mode 100644 index c8e6f0fb..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserController.m +++ /dev/null @@ -1,560 +0,0 @@ -// -// FLEXFileBrowserController.m -// Flipboard -// -// Created by Ryan Olson on 6/9/14. -// -// - -#import "FLEXFileBrowserController.h" -#import "FLEXUtility.h" -#import "FLEXWebViewController.h" -#import "FLEXImagePreviewViewController.h" -#import "FLEXTableListViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectExplorerViewController.h" -#import - -@interface FLEXFileBrowserTableViewCell : UITableViewCell -@end - -typedef NS_ENUM(NSUInteger, FLEXFileBrowserSortAttribute) { - FLEXFileBrowserSortAttributeNone = 0, - FLEXFileBrowserSortAttributeName, - FLEXFileBrowserSortAttributeCreationDate, -}; - -@interface FLEXFileBrowserController () - -@property (nonatomic, copy) NSString *path; -@property (nonatomic, copy) NSArray *childPaths; -@property (nonatomic) NSArray *searchPaths; -@property (nonatomic) NSNumber *recursiveSize; -@property (nonatomic) NSNumber *searchPathsSize; -@property (nonatomic) NSOperationQueue *operationQueue; -@property (nonatomic) UIDocumentInteractionController *documentController; -@property (nonatomic) FLEXFileBrowserSortAttribute sortAttribute; - -@end - -@implementation FLEXFileBrowserController - -+ (instancetype)path:(NSString *)path { - return [[self alloc] initWithPath:path]; -} - -- (id)init { - return [self initWithPath:NSHomeDirectory()]; -} - -- (id)initWithPath:(NSString *)path { - self = [super init]; - if (self) { - self.path = path; - self.title = [path lastPathComponent]; - self.operationQueue = [NSOperationQueue new]; - - // Compute path size - weakify(self) - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSFileManager *fileManager = NSFileManager.defaultManager; - NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:NULL]; - uint64_t totalSize = [attributes fileSize]; - - for (NSString *fileName in [fileManager enumeratorAtPath:path]) { - attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL]; - totalSize += [attributes fileSize]; - - // Bail if the interested view controller has gone away - if (!self) { - return; - } - } - - dispatch_async(dispatch_get_main_queue(), ^{ strongify(self) - self.recursiveSize = @(totalSize); - [self.tableView reloadData]; - }); - }); - - [self reloadCurrentPath]; - } - return self; -} - -#pragma mark - UIViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; - self.searchBarDebounceInterval = kFLEXDebounceForAsyncSearch; - [self addToolbarItems:@[ - [[UIBarButtonItem alloc] initWithTitle:@"Sort" - style:UIBarButtonItemStylePlain - target:self - action:@selector(sortDidTouchUpInside:)] - ]]; -} - -- (void)sortDidTouchUpInside:(UIBarButtonItem *)sortButton { - UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Sort" - message:nil - preferredStyle:UIAlertControllerStyleActionSheet]; - [alertController addAction:[UIAlertAction actionWithTitle:@"None" - style:UIAlertActionStyleCancel - handler:^(UIAlertAction * _Nonnull action) { - [self sortWithAttribute:FLEXFileBrowserSortAttributeNone]; - }]]; - [alertController addAction:[UIAlertAction actionWithTitle:@"Name" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * _Nonnull action) { - [self sortWithAttribute:FLEXFileBrowserSortAttributeName]; - }]]; - [alertController addAction:[UIAlertAction actionWithTitle:@"Creation Date" - style:UIAlertActionStyleDefault - handler:^(UIAlertAction * _Nonnull action) { - [self sortWithAttribute:FLEXFileBrowserSortAttributeCreationDate]; - }]]; - [self presentViewController:alertController animated:YES completion:nil]; -} - -- (void)sortWithAttribute:(FLEXFileBrowserSortAttribute)attribute { - self.sortAttribute = attribute; - [self reloadDisplayedPaths]; -} - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowBrowseBundle: return @"📁 Browse Bundle Directory"; - case FLEXGlobalsRowBrowseContainer: return @"📁 Browse Container Directory"; - default: return nil; - } -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowBrowseBundle: return [[self alloc] initWithPath:NSBundle.mainBundle.bundlePath]; - case FLEXGlobalsRowBrowseContainer: return [[self alloc] initWithPath:NSHomeDirectory()]; - default: return [self new]; - } -} - -#pragma mark - FLEXFileBrowserSearchOperationDelegate - -- (void)fileBrowserSearchOperationResult:(NSArray *)searchResult size:(uint64_t)size { - self.searchPaths = searchResult; - self.searchPathsSize = @(size); - [self.tableView reloadData]; -} - -#pragma mark - Search bar - -- (void)updateSearchResults:(NSString *)newText { - [self reloadDisplayedPaths]; -} - -#pragma mark UISearchControllerDelegate - -- (void)willDismissSearchController:(UISearchController *)searchController { - [self.operationQueue cancelAllOperations]; - [self reloadCurrentPath]; - [self.tableView reloadData]; -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.searchController.isActive ? self.searchPaths.count : self.childPaths.count; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - BOOL isSearchActive = self.searchController.isActive; - NSNumber *currentSize = isSearchActive ? self.searchPathsSize : self.recursiveSize; - NSArray *currentPaths = isSearchActive ? self.searchPaths : self.childPaths; - - NSString *sizeString = nil; - if (!currentSize) { - sizeString = @"Computing size…"; - } else { - sizeString = [NSByteCountFormatter stringFromByteCount:[currentSize longLongValue] countStyle:NSByteCountFormatterCountStyleFile]; - } - - return [NSString stringWithFormat:@"%lu files (%@)", (unsigned long)currentPaths.count, sizeString]; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - NSString *fullPath = [self filePathAtIndexPath:indexPath]; - NSDictionary *attributes = [NSFileManager.defaultManager attributesOfItemAtPath:fullPath error:NULL]; - BOOL isDirectory = [attributes.fileType isEqual:NSFileTypeDirectory]; - NSString *subtitle = nil; - if (isDirectory) { - NSUInteger count = [NSFileManager.defaultManager contentsOfDirectoryAtPath:fullPath error:NULL].count; - subtitle = [NSString stringWithFormat:@"%lu item%@", (unsigned long)count, (count == 1 ? @"" : @"s")]; - } else { - NSString *sizeString = [NSByteCountFormatter stringFromByteCount:attributes.fileSize countStyle:NSByteCountFormatterCountStyleFile]; - subtitle = [NSString stringWithFormat:@"%@ - %@", sizeString, attributes.fileModificationDate ?: @"Never modified"]; - } - - static NSString *textCellIdentifier = @"textCell"; - static NSString *imageCellIdentifier = @"imageCell"; - UITableViewCell *cell = nil; - - // Separate image and text only cells because otherwise the separator lines get out-of-whack on image cells reused with text only. - UIImage *image = [UIImage imageWithContentsOfFile:fullPath]; - NSString *cellIdentifier = image ? imageCellIdentifier : textCellIdentifier; - - if (!cell) { - cell = [[FLEXFileBrowserTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; - cell.textLabel.font = UIFont.flex_defaultTableCellFont; - cell.detailTextLabel.font = UIFont.flex_defaultTableCellFont; - cell.detailTextLabel.textColor = UIColor.grayColor; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } - NSString *cellTitle = [fullPath lastPathComponent]; - cell.textLabel.text = cellTitle; - cell.detailTextLabel.text = subtitle; - - if (image) { - cell.imageView.contentMode = UIViewContentModeScaleAspectFit; - cell.imageView.image = image; - } - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; - - NSString *fullPath = [self filePathAtIndexPath:indexPath]; - NSString *subpath = fullPath.lastPathComponent; - NSString *pathExtension = subpath.pathExtension; - - BOOL isDirectory = NO; - BOOL stillExists = [NSFileManager.defaultManager fileExistsAtPath:fullPath isDirectory:&isDirectory]; - UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; - UIImage *image = cell.imageView.image; - - if (!stillExists) { - [FLEXAlert showAlert:@"File Not Found" message:@"The file at the specified path no longer exists." from:self]; - [self reloadDisplayedPaths]; - return; - } - - UIViewController *drillInViewController = nil; - if (isDirectory) { - drillInViewController = [[[self class] alloc] initWithPath:fullPath]; - } else if (image) { - drillInViewController = [FLEXImagePreviewViewController forImage:image]; - } else { - NSData *fileData = [NSData dataWithContentsOfFile:fullPath]; - if (!fileData.length) { - [FLEXAlert showAlert:@"Empty File" message:@"No data returned from the file." from:self]; - return; - } - - // Special case keyed archives, json, and plists to get more readable data. - NSString *prettyString = nil; - if ([pathExtension isEqualToString:@"json"]) { - prettyString = [FLEXUtility prettyJSONStringFromData:fileData]; - } else { - // Regardless of file extension... - - id object = nil; - @try { - // Try to decode an archived object regardless of file extension - object = [NSKeyedUnarchiver unarchiveObjectWithData:fileData]; - } @catch (NSException *e) { } - - // Try to decode other things instead - object = object ?: [NSPropertyListSerialization - propertyListWithData:fileData - options:0 - format:NULL - error:NULL - ] ?: [NSDictionary dictionaryWithContentsOfFile:fullPath] - ?: [NSArray arrayWithContentsOfFile:fullPath]; - - if (object) { - drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:object]; - } else { - // Is it possibly a mach-O file? - if (fileData.length > sizeof(struct mach_header_64)) { - struct mach_header_64 header; - [fileData getBytes:&header length:sizeof(struct mach_header_64)]; - - // Does it have the mach header magic number? - if (header.magic == MH_MAGIC_64) { - // See if we can get some classes out of it... - unsigned int count = 0; - const char **classList = objc_copyClassNamesForImage( - fullPath.UTF8String, &count - ); - - if (count > 0) { - NSArray *classNames = [NSArray flex_forEachUpTo:count map:^id(NSUInteger i) { - return objc_getClass(classList[i]); - }]; - drillInViewController = [FLEXObjectExplorerFactory explorerViewControllerForObject:classNames]; - } - } - } - } - } - - if (prettyString.length) { - drillInViewController = [[FLEXWebViewController alloc] initWithText:prettyString]; - } else if ([FLEXWebViewController supportsPathExtension:pathExtension]) { - drillInViewController = [[FLEXWebViewController alloc] initWithURL:[NSURL fileURLWithPath:fullPath]]; - } else if ([FLEXTableListViewController supportsExtension:pathExtension]) { - drillInViewController = [[FLEXTableListViewController alloc] initWithPath:fullPath]; - } - else if (!drillInViewController) { - NSString *fileString = [NSString stringWithUTF8String:fileData.bytes]; - if (fileString.length) { - drillInViewController = [[FLEXWebViewController alloc] initWithText:fileString]; - } - } - } - - if (drillInViewController) { - drillInViewController.title = subpath.lastPathComponent; - [self.navigationController pushViewController:drillInViewController animated:YES]; - } else { - // Share the file otherwise - [self openFileController:fullPath]; - } -} - -- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { - UIMenuItem *rename = [[UIMenuItem alloc] initWithTitle:@"Rename" action:@selector(fileBrowserRename:)]; - UIMenuItem *delete = [[UIMenuItem alloc] initWithTitle:@"Delete" action:@selector(fileBrowserDelete:)]; - UIMenuItem *copyPath = [[UIMenuItem alloc] initWithTitle:@"Copy Path" action:@selector(fileBrowserCopyPath:)]; - UIMenuItem *share = [[UIMenuItem alloc] initWithTitle:@"Share" action:@selector(fileBrowserShare:)]; - - UIMenuController.sharedMenuController.menuItems = @[rename, delete, copyPath, share]; - - return YES; -} - -- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - return action == @selector(fileBrowserDelete:) - || action == @selector(fileBrowserRename:) - || action == @selector(fileBrowserCopyPath:) - || action == @selector(fileBrowserShare:); -} - -- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - // Empty, but has to exist for the menu to show - // The table view only calls this method for actions in the UIResponderStandardEditActions informal protocol. - // Since our actions are outside of that protocol, we need to manually handle the action forwarding from the cells. -} - -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView -contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - point:(CGPoint)point __IOS_AVAILABLE(13.0) { - weakify(self) - return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil - actionProvider:^UIMenu *(NSArray *suggestedActions) { - UITableViewCell * const cell = [tableView cellForRowAtIndexPath:indexPath]; - UIAction *rename = [UIAction actionWithTitle:@"Rename" image:nil identifier:@"Rename" - handler:^(UIAction *action) { strongify(self) - [self fileBrowserRename:cell]; - } - ]; - UIAction *delete = [UIAction actionWithTitle:@"Delete" image:nil identifier:@"Delete" - handler:^(UIAction *action) { strongify(self) - [self fileBrowserDelete:cell]; - } - ]; - UIAction *copyPath = [UIAction actionWithTitle:@"Copy Path" image:nil identifier:@"Copy Path" - handler:^(UIAction *action) { strongify(self) - [self fileBrowserCopyPath:cell]; - } - ]; - UIAction *share = [UIAction actionWithTitle:@"Share" image:nil identifier:@"Share" - handler:^(UIAction *action) { strongify(self) - [self fileBrowserShare:cell]; - } - ]; - - return [UIMenu menuWithTitle:@"Manage File" image:nil - identifier:@"Manage File" - options:UIMenuOptionsDisplayInline - children:@[rename, delete, copyPath, share] - ]; - } - ]; -} - -- (void)openFileController:(NSString *)fullPath { - UIDocumentInteractionController *controller = [UIDocumentInteractionController new]; - controller.URL = [NSURL fileURLWithPath:fullPath]; - - [controller presentOptionsMenuFromRect:self.view.bounds inView:self.view animated:YES]; - self.documentController = controller; -} - -- (void)fileBrowserRename:(UITableViewCell *)sender { - NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; - NSString *fullPath = [self filePathAtIndexPath:indexPath]; - - BOOL stillExists = [NSFileManager.defaultManager fileExistsAtPath:self.path isDirectory:NULL]; - if (stillExists) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title([NSString stringWithFormat:@"Rename %@?", fullPath.lastPathComponent]); - make.configuredTextField(^(UITextField *textField) { - textField.placeholder = @"New file name"; - textField.text = fullPath.lastPathComponent; - }); - make.button(@"Rename").handler(^(NSArray *strings) { - NSString *newFileName = strings.firstObject; - NSString *newPath = [fullPath.stringByDeletingLastPathComponent stringByAppendingPathComponent:newFileName]; - [NSFileManager.defaultManager moveItemAtPath:fullPath toPath:newPath error:NULL]; - [self reloadDisplayedPaths]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; - } else { - [FLEXAlert showAlert:@"File Removed" message:@"The file at the specified path no longer exists." from:self]; - } -} - -- (void)fileBrowserDelete:(UITableViewCell *)sender { - NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; - NSString *fullPath = [self filePathAtIndexPath:indexPath]; - - BOOL isDirectory = NO; - BOOL stillExists = [NSFileManager.defaultManager fileExistsAtPath:fullPath isDirectory:&isDirectory]; - if (stillExists) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Confirm Deletion"); - make.message([NSString stringWithFormat: - @"The %@ '%@' will be deleted. This operation cannot be undone", - (isDirectory ? @"directory" : @"file"), fullPath.lastPathComponent - ]); - make.button(@"Delete").destructiveStyle().handler(^(NSArray *strings) { - [NSFileManager.defaultManager removeItemAtPath:fullPath error:NULL]; - [self reloadDisplayedPaths]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; - } else { - [FLEXAlert showAlert:@"File Removed" message:@"The file at the specified path no longer exists." from:self]; - } -} - -- (void)fileBrowserCopyPath:(UITableViewCell *)sender { - NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; - NSString *fullPath = [self filePathAtIndexPath:indexPath]; - UIPasteboard.generalPasteboard.string = fullPath; -} - -- (void)fileBrowserShare:(UITableViewCell *)sender { - NSIndexPath *indexPath = [self.tableView indexPathForCell:sender]; - NSString *pathString = [self filePathAtIndexPath:indexPath]; - NSURL *filePath = [NSURL fileURLWithPath:pathString]; - - BOOL isDirectory = NO; - [NSFileManager.defaultManager fileExistsAtPath:pathString isDirectory:&isDirectory]; - - if (isDirectory) { - // UIDocumentInteractionController for folders - [self openFileController:pathString]; - } else { - // Share sheet for files - UIActivityViewController *shareSheet = [[UIActivityViewController alloc] initWithActivityItems:@[filePath] applicationActivities:nil]; - if (UIDevice.currentDevice.userInterfaceIdiom == UIUserInterfaceIdiomPad) { - shareSheet.popoverPresentationController.sourceView = sender; - } - [self presentViewController:shareSheet animated:true completion:nil]; - } -} - -- (void)reloadDisplayedPaths { - if (self.searchController.isActive) { - [self updateSearchPaths]; - } else { - [self reloadCurrentPath]; - [self.tableView reloadData]; - } -} - -- (void)reloadCurrentPath { - NSMutableArray *childPaths = [NSMutableArray new]; - NSArray *subpaths = [NSFileManager.defaultManager contentsOfDirectoryAtPath:self.path error:NULL]; - for (NSString *subpath in subpaths) { - [childPaths addObject:[self.path stringByAppendingPathComponent:subpath]]; - } - if (self.sortAttribute != FLEXFileBrowserSortAttributeNone) { - [childPaths sortUsingComparator:^NSComparisonResult(NSString *path1, NSString *path2) { - switch (self.sortAttribute) { - case FLEXFileBrowserSortAttributeNone: - // invalid state - return NSOrderedSame; - case FLEXFileBrowserSortAttributeName: - return [path1 compare:path2]; - case FLEXFileBrowserSortAttributeCreationDate: { - NSDictionary *path1Attributes = [NSFileManager.defaultManager attributesOfItemAtPath:path1 - error:NULL]; - NSDictionary *path2Attributes = [NSFileManager.defaultManager attributesOfItemAtPath:path2 - error:NULL]; - NSDate *path1Date = path1Attributes[NSFileCreationDate]; - NSDate *path2Date = path2Attributes[NSFileCreationDate]; - - return [path1Date compare:path2Date]; - } - } - }]; - } - self.childPaths = childPaths; -} - -- (void)updateSearchPaths { - self.searchPaths = nil; - self.searchPathsSize = nil; - - //clear pre search request and start a new one - [self.operationQueue cancelAllOperations]; - FLEXFileBrowserSearchOperation *newOperation = [[FLEXFileBrowserSearchOperation alloc] initWithPath:self.path searchString:self.searchText]; - newOperation.delegate = self; - [self.operationQueue addOperation:newOperation]; -} - -- (NSString *)filePathAtIndexPath:(NSIndexPath *)indexPath { - return self.searchController.isActive ? self.searchPaths[indexPath.row] : self.childPaths[indexPath.row]; -} - -@end - - -@implementation FLEXFileBrowserTableViewCell - -- (void)forwardAction:(SEL)action withSender:(id)sender { - id target = [self.nextResponder targetForAction:action withSender:sender]; - [UIApplication.sharedApplication sendAction:action to:target from:self forEvent:nil]; -} - -- (void)fileBrowserRename:(UIMenuController *)sender { - [self forwardAction:_cmd withSender:sender]; -} - -- (void)fileBrowserDelete:(UIMenuController *)sender { - [self forwardAction:_cmd withSender:sender]; -} - -- (void)fileBrowserCopyPath:(UIMenuController *)sender { - [self forwardAction:_cmd withSender:sender]; -} - -- (void)fileBrowserShare:(UIMenuController *)sender { - [self forwardAction:_cmd withSender:sender]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.h b/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.h deleted file mode 100644 index a9fa486d..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEXFileBrowserSearchOperation.h -// FLEX -// -// Created by 啟倫 陳 on 2014/8/4. -// Copyright (c) 2014年 f. All rights reserved. -// - -#import - -@protocol FLEXFileBrowserSearchOperationDelegate; - -@interface FLEXFileBrowserSearchOperation : NSOperation - -@property (nonatomic, weak) id delegate; - -- (id)initWithPath:(NSString *)currentPath searchString:(NSString *)searchString; - -@end - -@protocol FLEXFileBrowserSearchOperationDelegate - -- (void)fileBrowserSearchOperationResult:(NSArray *)searchResult size:(uint64_t)size; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.m b/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.m deleted file mode 100644 index a61c5409..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/FileBrowser/FLEXFileBrowserSearchOperation.m +++ /dev/null @@ -1,118 +0,0 @@ -// -// FLEXFileBrowserSearchOperation.m -// FLEX -// -// Created by 啟倫 陳 on 2014/8/4. -// Copyright (c) 2014年 f. All rights reserved. -// - -#import "FLEXFileBrowserSearchOperation.h" - -@implementation NSMutableArray (FLEXStack) - -- (void)flex_push:(id)anObject { - [self addObject:anObject]; -} - -- (id)flex_pop { - id anObject = self.lastObject; - [self removeLastObject]; - return anObject; -} - -@end - -@interface FLEXFileBrowserSearchOperation () - -@property (nonatomic) NSString *path; -@property (nonatomic) NSString *searchString; - -@end - -@implementation FLEXFileBrowserSearchOperation - -#pragma mark - private - -- (uint64_t)totalSizeAtPath:(NSString *)path { - NSFileManager *fileManager = NSFileManager.defaultManager; - NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:NULL]; - uint64_t totalSize = [attributes fileSize]; - - for (NSString *fileName in [fileManager enumeratorAtPath:path]) { - attributes = [fileManager attributesOfItemAtPath:[path stringByAppendingPathComponent:fileName] error:NULL]; - totalSize += [attributes fileSize]; - } - return totalSize; -} - -#pragma mark - instance method - -- (id)initWithPath:(NSString *)currentPath searchString:(NSString *)searchString { - self = [super init]; - if (self) { - self.path = currentPath; - self.searchString = searchString; - } - return self; -} - -#pragma mark - methods to override - -- (void)main { - NSFileManager *fileManager = NSFileManager.defaultManager; - NSMutableArray *searchPaths = [NSMutableArray new]; - NSMutableDictionary *sizeMapping = [NSMutableDictionary new]; - uint64_t totalSize = 0; - NSMutableArray *stack = [NSMutableArray new]; - [stack flex_push:self.path]; - - //recursive found all match searchString paths, and precomputing there size - while (stack.count) { - NSString *currentPath = [stack flex_pop]; - NSArray *directoryPath = [fileManager contentsOfDirectoryAtPath:currentPath error:nil]; - - for (NSString *subPath in directoryPath) { - NSString *fullPath = [currentPath stringByAppendingPathComponent:subPath]; - - if ([[subPath lowercaseString] rangeOfString:[self.searchString lowercaseString]].location != NSNotFound) { - [searchPaths addObject:fullPath]; - if (!sizeMapping[fullPath]) { - uint64_t fullPathSize = [self totalSizeAtPath:fullPath]; - totalSize += fullPathSize; - [sizeMapping setObject:@(fullPathSize) forKey:fullPath]; - } - } - BOOL isDirectory; - if ([fileManager fileExistsAtPath:fullPath isDirectory:&isDirectory] && isDirectory) { - [stack flex_push:fullPath]; - } - - if ([self isCancelled]) { - return; - } - } - } - - //sort - NSArray *sortedArray = [searchPaths sortedArrayUsingComparator:^NSComparisonResult(NSString *path1, NSString *path2) { - uint64_t pathSize1 = [sizeMapping[path1] unsignedLongLongValue]; - uint64_t pathSize2 = [sizeMapping[path2] unsignedLongLongValue]; - if (pathSize1 < pathSize2) { - return NSOrderedAscending; - } else if (pathSize1 > pathSize2) { - return NSOrderedDescending; - } else { - return NSOrderedSame; - } - }]; - - if ([self isCancelled]) { - return; - } - - dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate fileBrowserSearchOperationResult:sortedArray size:totalSize]; - }); -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h deleted file mode 100644 index 6b920b95..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h +++ /dev/null @@ -1,105 +0,0 @@ -// -// FLEXGlobalsEntry.h -// FLEX -// -// Created by Javier Soto on 7/26/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -typedef NS_ENUM(NSUInteger, FLEXGlobalsRow) { - FLEXGlobalsRowProcessInfo, - FLEXGlobalsRowNetworkHistory, - FLEXGlobalsRowSystemLog, - FLEXGlobalsRowLiveObjects, - FLEXGlobalsRowAddressInspector, - FLEXGlobalsRowCookies, - FLEXGlobalsRowBrowseRuntime, - FLEXGlobalsRowAppKeychainItems, - FLEXGlobalsRowAppDelegate, - FLEXGlobalsRowRootViewController, - FLEXGlobalsRowUserDefaults, - FLEXGlobalsRowMainBundle, - FLEXGlobalsRowBrowseBundle, - FLEXGlobalsRowBrowseContainer, - FLEXGlobalsRowApplication, - FLEXGlobalsRowKeyWindow, - FLEXGlobalsRowMainScreen, - FLEXGlobalsRowCurrentDevice, - FLEXGlobalsRowPasteboard, - FLEXGlobalsRowURLSession, - FLEXGlobalsRowURLCache, - FLEXGlobalsRowNotificationCenter, - FLEXGlobalsRowMenuController, - FLEXGlobalsRowFileManager, - FLEXGlobalsRowTimeZone, - FLEXGlobalsRowLocale, - FLEXGlobalsRowCalendar, - FLEXGlobalsRowMainRunLoop, - FLEXGlobalsRowMainThread, - FLEXGlobalsRowOperationQueue, - FLEXGlobalsRowCount -}; - -typedef NSString * _Nonnull (^FLEXGlobalsEntryNameFuture)(void); -/// Simply return a view controller to be pushed on the navigation stack -typedef UIViewController * _Nullable (^FLEXGlobalsEntryViewControllerFuture)(void); -/// Do something like present an alert, then use the host -/// view controller to present or push another view controller. -typedef void (^FLEXGlobalsEntryRowAction)(__kindof UITableViewController * _Nonnull host); - -/// For view controllers to conform to to indicate they support being used -/// in the globals table view controller. These methods help create concrete entries. -/// -/// Previously, the concrete entries relied on "futures" for the view controller and title. -/// With this protocol, the conforming class itself can act as a future, since the methods -/// will not be invoked until the title and view controller / row action are needed. -/// -/// Entries can implement \c globalsEntryViewController: to unconditionally provide a -/// view controller, or \c globalsEntryRowAction: to conditionally provide one and -/// perform some action (such as present an alert) if no view controller is available, -/// or both if there is a mix of rows where some are guaranteed to work and some are not. -/// Where both are implemented, \c globalsEntryRowAction: takes precedence; if it returns -/// an action for the requested row, that will be used instead of \c globalsEntryViewController: -@protocol FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row; - -// Must respond to at least one of the below. -// globalsEntryRowAction: takes precedence if both are implemented. -@optional - -+ (nullable UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row; -+ (nullable FLEXGlobalsEntryRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row; - -@end - -@interface FLEXGlobalsEntry : NSObject - -@property (nonatomic, readonly, nonnull) FLEXGlobalsEntryNameFuture entryNameFuture; -@property (nonatomic, readonly, nullable) FLEXGlobalsEntryViewControllerFuture viewControllerFuture; -@property (nonatomic, readonly, nullable) FLEXGlobalsEntryRowAction rowAction; - -+ (instancetype)entryWithEntry:(Class)entry row:(FLEXGlobalsRow)row; - -+ (instancetype)entryWithNameFuture:(FLEXGlobalsEntryNameFuture)nameFuture - viewControllerFuture:(FLEXGlobalsEntryViewControllerFuture)viewControllerFuture; - -+ (instancetype)entryWithNameFuture:(FLEXGlobalsEntryNameFuture)nameFuture - action:(FLEXGlobalsEntryRowAction)rowSelectedAction; - -@end - - -@interface NSObject (FLEXGlobalsEntry) - -/// @return The result of passing self to +[FLEXGlobalsEntry entryWithEntry:] -/// if the class conforms to FLEXGlobalsEntry, else, nil. -+ (nullable FLEXGlobalsEntry *)flex_concreteGlobalsEntry:(FLEXGlobalsRow)row; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.m b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.m deleted file mode 100644 index b93b2142..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.m +++ /dev/null @@ -1,86 +0,0 @@ -// -// FLEXGlobalsEntry.m -// FLEX -// -// Created by Javier Soto on 7/26/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsEntry.h" - -@implementation FLEXGlobalsEntry - -+ (instancetype)entryWithEntry:(Class)cls row:(FLEXGlobalsRow)row { - BOOL providesVCs = [cls respondsToSelector:@selector(globalsEntryViewController:)]; - BOOL providesActions = [cls respondsToSelector:@selector(globalsEntryRowAction:)]; - NSParameterAssert(cls); - NSParameterAssert(providesVCs || providesActions); - - FLEXGlobalsEntry *entry = [self new]; - entry->_entryNameFuture = ^{ return [cls globalsEntryTitle:row]; }; - - if (providesVCs) { - id action = providesActions ? [cls globalsEntryRowAction:row] : nil; - if (action) { - entry->_rowAction = action; - } else { - entry->_viewControllerFuture = ^{ return [cls globalsEntryViewController:row]; }; - } - } else { - entry->_rowAction = [cls globalsEntryRowAction:row]; - } - - return entry; -} - -+ (instancetype)entryWithNameFuture:(FLEXGlobalsEntryNameFuture)nameFuture - viewControllerFuture:(FLEXGlobalsEntryViewControllerFuture)viewControllerFuture { - NSParameterAssert(nameFuture); - NSParameterAssert(viewControllerFuture); - - FLEXGlobalsEntry *entry = [self new]; - entry->_entryNameFuture = [nameFuture copy]; - entry->_viewControllerFuture = [viewControllerFuture copy]; - - return entry; -} - -+ (instancetype)entryWithNameFuture:(FLEXGlobalsEntryNameFuture)nameFuture - action:(FLEXGlobalsEntryRowAction)rowSelectedAction { - NSParameterAssert(nameFuture); - NSParameterAssert(rowSelectedAction); - - FLEXGlobalsEntry *entry = [self new]; - entry->_entryNameFuture = [nameFuture copy]; - entry->_rowAction = [rowSelectedAction copy]; - - return entry; -} - -@end - -@interface FLEXGlobalsEntry (Debugging) -@property (nonatomic, readonly) NSString *name; -@end - -@implementation FLEXGlobalsEntry (Debugging) - -- (NSString *)name { - return self.entryNameFuture(); -} - -@end - -#pragma mark - flex_concreteGlobalsEntry - -@implementation NSObject (FLEXGlobalsEntry) - -+ (FLEXGlobalsEntry *)flex_concreteGlobalsEntry:(FLEXGlobalsRow)row { - if ([self conformsToProtocol:@protocol(FLEXGlobalsEntry)]) { - return [FLEXGlobalsEntry entryWithEntry:self row:row]; - } - - return nil; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.h b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.h deleted file mode 100644 index ae945532..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// FLEXGlobalsSection.h -// FLEX -// -// Created by Tanner Bennett on 7/11/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" -#import "FLEXGlobalsEntry.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXGlobalsSection : FLEXTableViewSection - -+ (instancetype)title:(NSString *)title rows:(NSArray *)rows; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m deleted file mode 100644 index abb97ea2..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsSection.m +++ /dev/null @@ -1,86 +0,0 @@ -// -// FLEXGlobalsSection.m -// FLEX -// -// Created by Tanner Bennett on 7/11/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsSection.h" -#import "NSArray+FLEX.h" -#import "UIFont+FLEX.h" - -@interface FLEXGlobalsSection () -/// Filtered rows -@property (nonatomic) NSArray *rows; -/// Unfiltered rows -@property (nonatomic) NSArray *allRows; -@end -@implementation FLEXGlobalsSection - -#pragma mark - Initialization - -+ (instancetype)title:(NSString *)title rows:(NSArray *)rows { - FLEXGlobalsSection *s = [self new]; - s->_title = title; - s.allRows = rows; - - return s; -} - -- (void)setAllRows:(NSArray *)allRows { - _allRows = allRows.copy; - [self reloadData]; -} - -#pragma mark - Overrides - -- (NSInteger)numberOfRows { - return self.rows.count; -} - -- (void)setFilterText:(NSString *)filterText { - super.filterText = filterText; - [self reloadData]; -} - -- (void)reloadData { - NSString *filterText = self.filterText; - - if (filterText.length) { - self.rows = [self.allRows flex_filtered:^BOOL(FLEXGlobalsEntry *entry, NSUInteger idx) { - return [entry.entryNameFuture() localizedCaseInsensitiveContainsString:filterText]; - }]; - } else { - self.rows = self.allRows; - } -} - -- (BOOL)canSelectRow:(NSInteger)row { - return YES; -} - -- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row { - return (id)self.rows[row].rowAction; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return self.rows[row].viewControllerFuture ? self.rows[row].viewControllerFuture() : nil; -} - -- (void)configureCell:(__kindof UITableViewCell *)cell forRow:(NSInteger)row { - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.textLabel.font = UIFont.flex_defaultTableCellFont; - cell.textLabel.text = self.rows[row].entryNameFuture(); -} - -@end - - -@implementation FLEXGlobalsSection (Subscripting) - -- (id)objectAtIndexedSubscript:(NSUInteger)idx { - return self.rows[idx]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h deleted file mode 100644 index b4b79b8c..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// FLEXGlobalsViewController.h -// Flipboard -// -// Created by Ryan Olson on 2014-05-03. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" -@protocol FLEXGlobalsTableViewControllerDelegate; - -typedef NS_ENUM(NSUInteger, FLEXGlobalsSectionKind) { - FLEXGlobalsSectionCustom, - /// NSProcessInfo, Network history, system log, - /// heap, address explorer, libraries, app classes - FLEXGlobalsSectionProcessAndEvents, - /// Browse container, browse bundle, NSBundle.main, - /// NSUserDefaults.standard, UIApplication, - /// app delegate, key window, root VC, cookies - FLEXGlobalsSectionAppShortcuts, - /// UIPasteBoard.general, UIScreen, UIDevice - FLEXGlobalsSectionMisc, - FLEXGlobalsSectionCount -}; - -@interface FLEXGlobalsViewController : FLEXFilteringTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m b/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m deleted file mode 100644 index f70406bd..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Globals/FLEXGlobalsViewController.m +++ /dev/null @@ -1,200 +0,0 @@ -// -// FLEXGlobalsViewController.m -// Flipboard -// -// Created by Ryan Olson on 2014-05-03. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsViewController.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXObjcRuntimeViewController.h" -#import "FLEXKeychainViewController.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXLiveObjectsController.h" -#import "FLEXFileBrowserController.h" -#import "FLEXCookiesViewController.h" -#import "FLEXGlobalsEntry.h" -#import "FLEXManager+Private.h" -#import "FLEXSystemLogViewController.h" -#import "FLEXNetworkMITMViewController.h" -#import "FLEXAddressExplorerCoordinator.h" -#import "FLEXGlobalsSection.h" -#import "UIBarButtonItem+FLEX.h" - -@interface FLEXGlobalsViewController () -/// Only displayed sections of the table view; empty sections are purged from this array. -@property (nonatomic) NSArray *sections; -/// Every section in the table view, regardless of whether or not a section is empty. -@property (nonatomic, readonly) NSArray *allSections; -@property (nonatomic, readonly) BOOL manuallyDeselectOnAppear; -@end - -@implementation FLEXGlobalsViewController -@dynamic sections, allSections; - -#pragma mark - Initialization - -+ (NSString *)globalsTitleForSection:(FLEXGlobalsSectionKind)section { - switch (section) { - case FLEXGlobalsSectionCustom: - return @"Custom Additions"; - case FLEXGlobalsSectionProcessAndEvents: - return @"Process and Events"; - case FLEXGlobalsSectionAppShortcuts: - return @"App Shortcuts"; - case FLEXGlobalsSectionMisc: - return @"Miscellaneous"; - - default: - @throw NSInternalInconsistencyException; - } -} - -+ (FLEXGlobalsEntry *)globalsEntryForRow:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowAppKeychainItems: - return [FLEXKeychainViewController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowAddressInspector: - return [FLEXAddressExplorerCoordinator flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowBrowseRuntime: - return [FLEXObjcRuntimeViewController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowLiveObjects: - return [FLEXLiveObjectsController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowCookies: - return [FLEXCookiesViewController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowBrowseBundle: - case FLEXGlobalsRowBrowseContainer: - return [FLEXFileBrowserController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowSystemLog: - return [FLEXSystemLogViewController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowNetworkHistory: - return [FLEXNetworkMITMViewController flex_concreteGlobalsEntry:row]; - case FLEXGlobalsRowKeyWindow: - case FLEXGlobalsRowRootViewController: - case FLEXGlobalsRowProcessInfo: - case FLEXGlobalsRowAppDelegate: - case FLEXGlobalsRowUserDefaults: - case FLEXGlobalsRowMainBundle: - case FLEXGlobalsRowApplication: - case FLEXGlobalsRowMainScreen: - case FLEXGlobalsRowCurrentDevice: - case FLEXGlobalsRowPasteboard: - case FLEXGlobalsRowURLSession: - case FLEXGlobalsRowURLCache: - case FLEXGlobalsRowNotificationCenter: - case FLEXGlobalsRowMenuController: - case FLEXGlobalsRowFileManager: - case FLEXGlobalsRowTimeZone: - case FLEXGlobalsRowLocale: - case FLEXGlobalsRowCalendar: - case FLEXGlobalsRowMainRunLoop: - case FLEXGlobalsRowMainThread: - case FLEXGlobalsRowOperationQueue: - return [FLEXObjectExplorerFactory flex_concreteGlobalsEntry:row]; - - default: - @throw [NSException - exceptionWithName:NSInternalInconsistencyException - reason:@"Missing globals case in switch" userInfo:nil - ]; - } -} - -+ (NSArray *)defaultGlobalSections { - static NSMutableArray *sections = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSDictionary *> *rowsBySection = @{ - @(FLEXGlobalsSectionProcessAndEvents) : @[ - [self globalsEntryForRow:FLEXGlobalsRowNetworkHistory], - [self globalsEntryForRow:FLEXGlobalsRowSystemLog], - [self globalsEntryForRow:FLEXGlobalsRowProcessInfo], - [self globalsEntryForRow:FLEXGlobalsRowLiveObjects], - [self globalsEntryForRow:FLEXGlobalsRowAddressInspector], - [self globalsEntryForRow:FLEXGlobalsRowBrowseRuntime], - ], - @(FLEXGlobalsSectionAppShortcuts) : @[ - [self globalsEntryForRow:FLEXGlobalsRowBrowseBundle], - [self globalsEntryForRow:FLEXGlobalsRowBrowseContainer], - [self globalsEntryForRow:FLEXGlobalsRowMainBundle], - [self globalsEntryForRow:FLEXGlobalsRowUserDefaults], - [self globalsEntryForRow:FLEXGlobalsRowAppKeychainItems], - [self globalsEntryForRow:FLEXGlobalsRowApplication], - [self globalsEntryForRow:FLEXGlobalsRowAppDelegate], - [self globalsEntryForRow:FLEXGlobalsRowKeyWindow], - [self globalsEntryForRow:FLEXGlobalsRowRootViewController], - [self globalsEntryForRow:FLEXGlobalsRowCookies], - ], - @(FLEXGlobalsSectionMisc) : @[ - [self globalsEntryForRow:FLEXGlobalsRowPasteboard], - [self globalsEntryForRow:FLEXGlobalsRowMainScreen], - [self globalsEntryForRow:FLEXGlobalsRowCurrentDevice], - [self globalsEntryForRow:FLEXGlobalsRowURLSession], - [self globalsEntryForRow:FLEXGlobalsRowURLCache], - [self globalsEntryForRow:FLEXGlobalsRowNotificationCenter], - [self globalsEntryForRow:FLEXGlobalsRowMenuController], - [self globalsEntryForRow:FLEXGlobalsRowFileManager], - [self globalsEntryForRow:FLEXGlobalsRowTimeZone], - [self globalsEntryForRow:FLEXGlobalsRowLocale], - [self globalsEntryForRow:FLEXGlobalsRowCalendar], - [self globalsEntryForRow:FLEXGlobalsRowMainRunLoop], - [self globalsEntryForRow:FLEXGlobalsRowMainThread], - [self globalsEntryForRow:FLEXGlobalsRowOperationQueue], - ] - }; - - sections = [NSMutableArray array]; - for (FLEXGlobalsSectionKind i = FLEXGlobalsSectionCustom + 1; i < FLEXGlobalsSectionCount; ++i) { - NSString *title = [self globalsTitleForSection:i]; - [sections addObject:[FLEXGlobalsSection title:title rows:rowsBySection[@(i)]]]; - } - }); - - return sections; -} - - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.title = @"💪 FLEX"; - self.showsSearchBar = YES; - self.searchBarDebounceInterval = kFLEXDebounceInstant; - self.navigationItem.backBarButtonItem = [UIBarButtonItem flex_backItemWithTitle:@"Back"]; - - _manuallyDeselectOnAppear = NSProcessInfo.processInfo.operatingSystemVersion.majorVersion < 10; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [self disableToolbar]; - - if (self.manuallyDeselectOnAppear) { - [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; - } -} - -- (NSArray *)makeSections { - NSMutableArray *sections = [NSMutableArray array]; - // Do we have custom sections to add? - if (FLEXManager.sharedManager.userGlobalEntries.count) { - NSString *title = [[self class] globalsTitleForSection:FLEXGlobalsSectionCustom]; - FLEXGlobalsSection *custom = [FLEXGlobalsSection - title:title - rows:FLEXManager.sharedManager.userGlobalEntries - ]; - [sections addObject:custom]; - } - - [sections addObjectsFromArray:[self.class defaultGlobalSections]]; - - return sections; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.h b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.h deleted file mode 100644 index 539b2f1d..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.h +++ /dev/null @@ -1,144 +0,0 @@ -// -// FLEXKeychain.h -// -// Derived from: -// SSKeychain.h in SSKeychain -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2010-2014 Sam Soffes. All rights reserved. -// - -#import - -/// Error code specific to FLEXKeychain that can be returned in NSError objects. -/// For codes returned by the operating system, refer to SecBase.h for your -/// platform. -typedef NS_ENUM(OSStatus, FLEXKeychainErrorCode) { - /// Some of the arguments were invalid. - FLEXKeychainErrorBadArguments = -1001, -}; - -/// FLEXKeychain error domain -extern NSString *const kFLEXKeychainErrorDomain; - -/// Account name. -extern NSString *const kFLEXKeychainAccountKey; - -/// Time the item was created. -/// -/// The value will be a string. -extern NSString *const kFLEXKeychainCreatedAtKey; - -/// Item class. -extern NSString *const kFLEXKeychainClassKey; - -/// Item description. -extern NSString *const kFLEXKeychainDescriptionKey; - -/// Item group. -extern NSString *const kFLEXKeychainGroupKey; - -/// Item label. -extern NSString *const kFLEXKeychainLabelKey; - -/// Time the item was last modified. -/// -/// The value will be a string. -extern NSString *const kFLEXKeychainLastModifiedKey; - -/// Where the item was created. -extern NSString *const kFLEXKeychainWhereKey; - -/// A simple wrapper for accessing accounts, getting passwords, -/// setting passwords, and deleting passwords using the system Keychain. -@interface FLEXKeychain : NSObject - -#pragma mark - Classic methods - -/// @param serviceName The service for which to return the corresponding password. -/// @param account The account for which to return the corresponding password. -/// @return Returns a string containing the password for a given account and service, -/// or `nil` if the Keychain doesn't have a password for the given parameters. -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account; -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/// Returns a nsdata containing the password for a given account and service, -/// or `nil` if the Keychain doesn't have a password for the given parameters. -/// -/// @param serviceName The service for which to return the corresponding password. -/// @param account The account for which to return the corresponding password. -/// @return Returns a nsdata containing the password for a given account and service, -/// or `nil` if the Keychain doesn't have a password for the given parameters. -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account; -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -/// Deletes a password from the Keychain. -/// -/// @param serviceName The service for which to delete the corresponding password. -/// @param account The account for which to delete the corresponding password. -/// @return Returns `YES` on success, or `NO` on failure. -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account; -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - - -/// Sets a password in the Keychain. -/// -/// @param password The password to store in the Keychain. -/// @param serviceName The service for which to set the corresponding password. -/// @param account The account for which to set the corresponding password. -/// @return Returns `YES` on success, or `NO` on failure. -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account; -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/// Sets a password in the Keychain. -/// -/// @param password The password to store in the Keychain. -/// @param serviceName The service for which to set the corresponding password. -/// @param account The account for which to set the corresponding password. -/// @return Returns `YES` on success, or `NO` on failure. -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account; -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error; - -/// @return An array of dictionaries containing the Keychain's accounts, or `nil` if -/// the Keychain doesn't have any accounts. The order of the objects in the array isn't defined. -/// -/// @note See the `NSString` constants declared in FLEXKeychain.h for a list of keys that -/// can be used when accessing the dictionaries returned by this method. -+ (NSArray *> *)allAccounts; -+ (NSArray *> *)allAccounts:(NSError *__autoreleasing *)error; - -/// @param serviceName The service for which to return the corresponding accounts. -/// @return An array of dictionaries containing the Keychain's accounts for a given `serviceName`, -/// or `nil` if the Keychain doesn't have any accounts for the given `serviceName`. -/// The order of the objects in the array isn't defined. -/// -/// @note See the `NSString` constants declared in FLEXKeychain.h for a list of keys that -/// can be used when accessing the dictionaries returned by this method. -+ (NSArray *> *)accountsForService:(NSString *)serviceName; -+ (NSArray *> *)accountsForService:(NSString *)serviceName error:(NSError *__autoreleasing *)error; - - -#pragma mark - Configuration - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -/// Returns the accessibility type for all future passwords saved to the Keychain. -/// -/// @return `NULL` or one of the "Keychain Item Accessibility -/// Constants" used for determining when a keychain item should be readable. -+ (CFTypeRef)accessibilityType; - -/// Sets the accessibility type for all future passwords saved to the Keychain. -/// -/// @param accessibilityType One of the "Keychain Item Accessibility Constants" -/// used for determining when a keychain item should be readable. -/// If the value is `NULL` (the default), the Keychain default will be used which -/// is highly insecure. You really should use at least `kSecAttrAccessibleAfterFirstUnlock` -/// for background applications or `kSecAttrAccessibleWhenUnlocked` for all -/// other applications. -/// -/// @note See Security/SecItem.h -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType; -#endif - -@end - diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.m b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.m deleted file mode 100644 index cc89ca15..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychain.m +++ /dev/null @@ -1,121 +0,0 @@ -// -// FLEXKeychain.m -// -// Forked from: -// SSKeychain.m in SSKeychain -// Created by Sam Soffes on 5/19/10. -// Copyright (c) 2010-2014 Sam Soffes. All rights reserved. -// - -#import "FLEXKeychain.h" -#import "FLEXKeychainQuery.h" - -NSString * const kFLEXKeychainErrorDomain = @"com.flipboard.flex"; -NSString * const kFLEXKeychainAccountKey = @"acct"; -NSString * const kFLEXKeychainCreatedAtKey = @"cdat"; -NSString * const kFLEXKeychainClassKey = @"labl"; -NSString * const kFLEXKeychainDescriptionKey = @"desc"; -NSString * const kFLEXKeychainGroupKey = @"agrp"; -NSString * const kFLEXKeychainLabelKey = @"labl"; -NSString * const kFLEXKeychainLastModifiedKey = @"mdat"; -NSString * const kFLEXKeychainWhereKey = @"svce"; - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -static CFTypeRef FLEXKeychainAccessibilityType = NULL; -#endif - -@implementation FLEXKeychain - -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account { - return [self passwordForService:serviceName account:account error:nil]; -} - -+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - query.account = account; - [query fetch:error]; - return query.password; -} - -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account { - return [self passwordDataForService:serviceName account:account error:nil]; -} - -+ (NSData *)passwordDataForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - query.account = account; - [query fetch:error]; - - return query.passwordData; -} - -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account { - return [self deletePasswordForService:serviceName account:account error:nil]; -} - -+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - query.account = account; - return [query deleteItem:error]; -} - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account { - return [self setPassword:password forService:serviceName account:account error:nil]; -} - -+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError *__autoreleasing *)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - query.account = account; - query.password = password; - return [query save:error]; -} - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account { - return [self setPasswordData:password forService:serviceName account:account error:nil]; -} - -+ (BOOL)setPasswordData:(NSData *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - query.account = account; - query.passwordData = password; - return [query save:error]; -} - -+ (NSArray *)allAccounts { - return [self allAccounts:nil] ?: @[]; -} - -+ (NSArray *)allAccounts:(NSError *__autoreleasing *)error { - return [self accountsForService:nil error:error]; -} - -+ (NSArray *)accountsForService:(NSString *)serviceName { - return [self accountsForService:serviceName error:nil]; -} - -+ (NSArray *)accountsForService:(NSString *)serviceName error:(NSError *__autoreleasing *)error { - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = serviceName; - return [query fetchAll:error]; -} - -#if __IPHONE_4_0 && TARGET_OS_IPHONE -+ (CFTypeRef)accessibilityType { - return FLEXKeychainAccessibilityType; -} - -+ (void)setAccessibilityType:(CFTypeRef)accessibilityType { - CFRetain(accessibilityType); - if (FLEXKeychainAccessibilityType) { - CFRelease(FLEXKeychainAccessibilityType); - } - FLEXKeychainAccessibilityType = accessibilityType; -} -#endif - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.h b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.h deleted file mode 100644 index e5500bfe..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.h +++ /dev/null @@ -1,112 +0,0 @@ -// -// FLEXKeychainQuery.h -// -// Derived from: -// SSKeychainQuery.h in SSKeychain -// Created by Caleb Davenport on 3/19/13. -// Copyright (c) 2010-2014 Sam Soffes. All rights reserved. -// - -#import -#import - -#if __IPHONE_7_0 || __MAC_10_9 -// Keychain synchronization available at compile time -#define FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE 1 -#endif - -#if __IPHONE_3_0 || __MAC_10_9 -// Keychain access group available at compile time -#define FLEXKEYCHAIN_ACCESS_GROUP_AVAILABLE 1 -#endif - -#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE -typedef NS_ENUM(NSUInteger, FLEXKeychainQuerySynchronizationMode) { - FLEXKeychainQuerySynchronizationModeAny, - FLEXKeychainQuerySynchronizationModeNo, - FLEXKeychainQuerySynchronizationModeYes -}; -#endif - -/// Simple interface for querying or modifying keychain items. -@interface FLEXKeychainQuery : NSObject - -/// kSecAttrAccount -@property (nonatomic, copy) NSString *account; - -/// kSecAttrService -@property (nonatomic, copy) NSString *service; - -/// kSecAttrLabel -@property (nonatomic, copy) NSString *label; - -#ifdef FLEXKEYCHAIN_ACCESS_GROUP_AVAILABLE -/// kSecAttrAccessGroup (only used on iOS) -@property (nonatomic, copy) NSString *accessGroup; -#endif - -#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE -/// kSecAttrSynchronizable -@property (nonatomic) FLEXKeychainQuerySynchronizationMode synchronizationMode; -#endif - -/// Root storage for password information -@property (nonatomic, copy) NSData *passwordData; - -/// This property automatically transitions between an object and the value of -/// `passwordData` using NSKeyedArchiver and NSKeyedUnarchiver. -@property (nonatomic, copy) id passwordObject; - -/// Convenience accessor for setting and getting a password string. Passes through -/// to `passwordData` using UTF-8 string encoding. -@property (nonatomic, copy) NSString *password; - - -#pragma mark Saving & Deleting - -/// Save the receiver's attributes as a keychain item. Existing items with the -/// given account, service, and access group will first be deleted. -/// -/// @param error Populated should an error occur. -/// @return `YES` if saving was successful, `NO` otherwise. -- (BOOL)save:(NSError **)error; - -/// Delete keychain items that match the given account, service, and access group. -/// -/// @param error Populated should an error occur. -/// @return `YES` if saving was successful, `NO` otherwise. -- (BOOL)deleteItem:(NSError **)error; - - -#pragma mark Fetching - -/// Fetch all keychain items that match the given account, service, and access -/// group. The values of `password` and `passwordData` are ignored when fetching. -/// -/// @param error Populated should an error occur. -/// @return An array of dictionaries that represent all matching keychain items, -/// or `nil` should an error occur. The order of the items is not determined. -- (NSArray *> *)fetchAll:(NSError **)error; - -/// Fetch the keychain item that matches the given account, service, and access -/// group. The `password` and `passwordData` properties will be populated unless -/// an error occurs. The values of `password` and `passwordData` are ignored when -/// fetching. -/// -/// @param error Populated should an error occur. -/// @return `YES` if fetching was successful, `NO` otherwise. -- (BOOL)fetch:(NSError **)error; - - -#pragma mark Synchronization Status - -#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE -/// Returns a boolean indicating if keychain synchronization is available on the device at runtime. -/// The #define FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE is only for compile time. -/// If you are checking for the presence of synchronization, you should use this method. -/// -/// @return A value indicating if keychain synchronization is available -+ (BOOL)isSynchronizationAvailable; -#endif - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.m b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.m deleted file mode 100644 index 38797015..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainQuery.m +++ /dev/null @@ -1,304 +0,0 @@ -// -// FLEXKeychainQuery.m -// FLEXKeychain -// -// Created by Caleb Davenport on 3/19/13. -// Copyright (c) 2013-2014 Sam Soffes. All rights reserved. -// - -#import "FLEXKeychainQuery.h" -#import "FLEXKeychain.h" - -@implementation FLEXKeychainQuery - -#pragma mark - Public - -- (BOOL)save:(NSError *__autoreleasing *)error { - OSStatus status = FLEXKeychainErrorBadArguments; - if (!self.service || !self.account || !self.passwordData) { - if (error) { - *error = [self errorWithCode:status]; - } - return NO; - } - - NSMutableDictionary *query = nil; - NSMutableDictionary * searchQuery = [self query]; - status = SecItemCopyMatching((__bridge CFDictionaryRef)searchQuery, nil); - if (status == errSecSuccess) {//item already exists, update it! - query = [[NSMutableDictionary alloc]init]; - query[(__bridge id)kSecValueData] = self.passwordData; -#if __IPHONE_4_0 && TARGET_OS_IPHONE - CFTypeRef accessibilityType = FLEXKeychain.accessibilityType; - if (accessibilityType) { - query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType; - } -#endif - status = SecItemUpdate((__bridge CFDictionaryRef)(searchQuery), (__bridge CFDictionaryRef)(query)); - }else if (status == errSecItemNotFound){//item not found, create it! - query = [self query]; - if (self.label) { - query[(__bridge id)kSecAttrLabel] = self.label; - } - query[(__bridge id)kSecValueData] = self.passwordData; -#if __IPHONE_4_0 && TARGET_OS_IPHONE - CFTypeRef accessibilityType = FLEXKeychain.accessibilityType; - if (accessibilityType) { - query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType; - } -#endif - status = SecItemAdd((__bridge CFDictionaryRef)query, NULL); - } - - if (status != errSecSuccess && error != NULL) { - *error = [self errorWithCode:status]; - } - - return (status == errSecSuccess); -} - - -- (BOOL)deleteItem:(NSError *__autoreleasing *)error { - OSStatus status = FLEXKeychainErrorBadArguments; - if (!self.service || !self.account) { - if (error) { - *error = [self errorWithCode:status]; - } - - return NO; - } - - NSMutableDictionary *query = [self query]; -#if TARGET_OS_IPHONE - status = SecItemDelete((__bridge CFDictionaryRef)query); -#else - // On Mac OS, SecItemDelete will not delete a key created in a different - // app, nor in a different version of the same app. - // - // To replicate the issue, save a password, change to the code and - // rebuild the app, and then attempt to delete that password. - // - // This was true in OS X 10.6 and probably later versions as well. - // - // Work around it by using SecItemCopyMatching and SecKeychainItemDelete. - CFTypeRef result = NULL; - query[(__bridge id)kSecReturnRef] = @YES; - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); - if (status == errSecSuccess) { - status = SecKeychainItemDelete((SecKeychainItemRef)result); - CFRelease(result); - } -#endif - - if (status != errSecSuccess && error != NULL) { - *error = [self errorWithCode:status]; - } - - return (status == errSecSuccess); -} - - -- (NSArray *)fetchAll:(NSError *__autoreleasing *)error { - NSMutableDictionary *query = [self query]; - query[(__bridge id)kSecReturnAttributes] = @YES; - query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitAll; -#if __IPHONE_4_0 && TARGET_OS_IPHONE - CFTypeRef accessibilityType = FLEXKeychain.accessibilityType; - if (accessibilityType) { - query[(__bridge id)kSecAttrAccessible] = (__bridge id)accessibilityType; - } -#endif - - CFTypeRef result = NULL; - OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); - if (status != errSecSuccess && error != NULL) { - *error = [self errorWithCode:status]; - return nil; - } - - return (__bridge_transfer NSArray *)result ?: @[]; -} - - -- (BOOL)fetch:(NSError *__autoreleasing *)error { - OSStatus status = FLEXKeychainErrorBadArguments; - if (!self.service || !self.account) { - if (error) { - *error = [self errorWithCode:status]; - } - return NO; - } - - CFTypeRef result = NULL; - NSMutableDictionary *query = [self query]; - query[(__bridge id)kSecReturnData] = @YES; - query[(__bridge id)kSecMatchLimit] = (__bridge id)kSecMatchLimitOne; - status = SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); - - if (status != errSecSuccess) { - if (error) { - *error = [self errorWithCode:status]; - } - return NO; - } - - self.passwordData = (__bridge_transfer NSData *)result; - return YES; -} - - -#pragma mark - Accessors - -- (void)setPasswordObject:(id)object { - self.passwordData = [NSKeyedArchiver archivedDataWithRootObject:object]; -} - - -- (id)passwordObject { - if (self.passwordData.length) { - return [NSKeyedUnarchiver unarchiveObjectWithData:self.passwordData]; - } - - return nil; -} - - -- (void)setPassword:(NSString *)password { - self.passwordData = [password dataUsingEncoding:NSUTF8StringEncoding]; -} - - -- (NSString *)password { - if (self.passwordData.length) { - return [[NSString alloc] initWithData:self.passwordData encoding:NSUTF8StringEncoding]; - } - - return nil; -} - - -#pragma mark - Synchronization Status - -#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE -+ (BOOL)isSynchronizationAvailable { -#if TARGET_OS_IPHONE - return YES; -#else - return floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4; -#endif -} -#endif - - -#pragma mark - Private - -- (NSMutableDictionary *)query { - NSMutableDictionary *dictionary = [NSMutableDictionary new]; - dictionary[(__bridge id)kSecClass] = (__bridge id)kSecClassGenericPassword; - - if (self.service) { - dictionary[(__bridge id)kSecAttrService] = self.service; - } - - if (self.account) { - dictionary[(__bridge id)kSecAttrAccount] = self.account; - } - -#ifdef FLEXKEYCHAIN_ACCESS_GROUP_AVAILABLE -#if !TARGET_IPHONE_SIMULATOR - if (self.accessGroup) { - dictionary[(__bridge id)kSecAttrAccessGroup] = self.accessGroup; - } -#endif -#endif - -#ifdef FLEXKEYCHAIN_SYNCHRONIZATION_AVAILABLE - if ([[self class] isSynchronizationAvailable]) { - id value; - - switch (self.synchronizationMode) { - case FLEXKeychainQuerySynchronizationModeNo: { - value = @NO; - break; - } - case FLEXKeychainQuerySynchronizationModeYes: { - value = @YES; - break; - } - case FLEXKeychainQuerySynchronizationModeAny: { - value = (__bridge id)(kSecAttrSynchronizableAny); - break; - } - } - - dictionary[(__bridge id)(kSecAttrSynchronizable)] = value; - } -#endif - - return dictionary; -} - -- (NSError *)errorWithCode:(OSStatus)code { - static dispatch_once_t onceToken; - static NSBundle *resourcesBundle = nil; - dispatch_once(&onceToken, ^{ - NSURL *url = [[NSBundle bundleForClass:[self class]] URLForResource:@"FLEXKeychain" withExtension:@"bundle"]; - resourcesBundle = [NSBundle bundleWithURL:url]; - }); - - NSString *message = nil; - switch (code) { - case errSecSuccess: return nil; - case FLEXKeychainErrorBadArguments: message = NSLocalizedStringFromTableInBundle(@"FLEXKeychainErrorBadArguments", @"FLEXKeychain", resourcesBundle, nil); break; - -#if TARGET_OS_IPHONE - case errSecUnimplemented: { - message = NSLocalizedStringFromTableInBundle(@"errSecUnimplemented", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecParam: { - message = NSLocalizedStringFromTableInBundle(@"errSecParam", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecAllocate: { - message = NSLocalizedStringFromTableInBundle(@"errSecAllocate", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecNotAvailable: { - message = NSLocalizedStringFromTableInBundle(@"errSecNotAvailable", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecDuplicateItem: { - message = NSLocalizedStringFromTableInBundle(@"errSecDuplicateItem", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecItemNotFound: { - message = NSLocalizedStringFromTableInBundle(@"errSecItemNotFound", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecInteractionNotAllowed: { - message = NSLocalizedStringFromTableInBundle(@"errSecInteractionNotAllowed", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecDecode: { - message = NSLocalizedStringFromTableInBundle(@"errSecDecode", @"FLEXKeychain", resourcesBundle, nil); - break; - } - case errSecAuthFailed: { - message = NSLocalizedStringFromTableInBundle(@"errSecAuthFailed", @"FLEXKeychain", resourcesBundle, nil); - break; - } - default: { - message = NSLocalizedStringFromTableInBundle(@"errSecDefault", @"FLEXKeychain", resourcesBundle, nil); - } -#else - default: - message = (__bridge_transfer NSString *)SecCopyErrorMessageString(code, NULL); -#endif - } - - NSDictionary *userInfo = message ? @{ NSLocalizedDescriptionKey : message } : nil; - return [NSError errorWithDomain:kFLEXKeychainErrorDomain code:code userInfo:userInfo]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.h b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.h deleted file mode 100644 index 3545d214..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXKeychainViewController.h -// FLEX -// -// Created by ray on 2019/8/17. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsEntry.h" -#import "FLEXFilteringTableViewController.h" - -@interface FLEXKeychainViewController : FLEXFilteringTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.m b/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.m deleted file mode 100644 index 745c33b9..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/FLEXKeychainViewController.m +++ /dev/null @@ -1,254 +0,0 @@ -// -// FLEXKeychainViewController.m -// FLEX -// -// Created by ray on 2019/8/17. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXKeychain.h" -#import "FLEXKeychainQuery.h" -#import "FLEXKeychainViewController.h" -#import "FLEXTableViewCell.h" -#import "FLEXMutableListSection.h" -#import "FLEXUtility.h" -#import "UIPasteboard+FLEX.h" -#import "UIBarButtonItem+FLEX.h" - -@interface FLEXKeychainViewController () -@property (nonatomic, readonly) FLEXMutableListSection *section; -@end - -@implementation FLEXKeychainViewController - -- (id)init { - return [self initWithStyle:UITableViewStyleGrouped]; -} - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - [self addToolbarItems:@[ - FLEXBarButtonItemSystem(Add, self, @selector(addPressed)), - [FLEXBarButtonItemSystem(Trash, self, @selector(trashPressed:)) flex_withTintColor:UIColor.redColor], - ]]; - - [self reloadData]; -} - -- (NSArray *)makeSections { - _section = [FLEXMutableListSection list:FLEXKeychain.allAccounts.mutableCopy - cellConfiguration:^(__kindof FLEXTableViewCell *cell, NSDictionary *item, NSInteger row) { - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - - id service = item[kFLEXKeychainWhereKey]; - if ([service isKindOfClass:[NSString class]]) { - cell.textLabel.text = service; - cell.detailTextLabel.text = [item[kFLEXKeychainAccountKey] description]; - } else { - cell.textLabel.text = [NSString stringWithFormat: - @"[%@]\n\n%@", - NSStringFromClass([service class]), - [service description] - ]; - } - } filterMatcher:^BOOL(NSString *filterText, NSDictionary *item) { - // Loop over contents of the keychain item looking for a match - for (NSString *field in item.allValues) { - if ([field isKindOfClass:[NSString class]]) { - if ([field localizedCaseInsensitiveContainsString:filterText]) { - return YES; - } - } - } - - return NO; - } - ]; - - return @[self.section]; -} - -/// We always want to show this section -- (NSArray *)nonemptySections { - return @[self.section]; -} - -- (void)reloadSections { - self.section.list = FLEXKeychain.allAccounts.mutableCopy; -} - -- (void)refreshSectionTitle { - self.section.customTitle = FLEXPluralString( - self.section.filteredList.count, @"items", @"item" - ); -} - -- (void)reloadData { - [self reloadSections]; - [self refreshSectionTitle]; - [super reloadData]; -} - - -#pragma mark - Private - -- (FLEXKeychainQuery *)queryForItemAtIndex:(NSInteger)idx { - NSDictionary *item = self.section.filteredList[idx]; - - FLEXKeychainQuery *query = [FLEXKeychainQuery new]; - query.service = [item[kFLEXKeychainWhereKey] description]; - query.account = [item[kFLEXKeychainAccountKey] description]; - query.accessGroup = [item[kFLEXKeychainGroupKey] description]; - [query fetch:nil]; - - return query; -} - -- (void)deleteItem:(NSDictionary *)item { - NSError *error = nil; - BOOL success = [FLEXKeychain - deletePasswordForService:item[kFLEXKeychainWhereKey] - account:item[kFLEXKeychainAccountKey] - error:&error - ]; - - if (!success) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Error Deleting Item"); - make.message(error.localizedDescription); - } showFrom:self]; - } -} - - -#pragma mark Buttons - -- (void)trashPressed:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - make.title(@"Clear Keychain"); - make.message(@"This will remove all keychain items for this app.\n"); - make.message(@"This action cannot be undone. Are you sure?"); - make.button(@"Yes, clear the keychain").destructiveStyle().handler(^(NSArray *strings) { - [self confirmClearKeychain]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - -- (void)confirmClearKeychain { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"ARE YOU SURE?"); - make.message(@"This action CANNOT BE UNDONE.\nAre you sure you want to continue?\n"); - make.message(@"If you're sure, scroll to confirm."); - make.button(@"Yes, clear the keychain").destructiveStyle().handler(^(NSArray *strings) { - for (id account in self.section.list) { - [self deleteItem:account]; - } - - [self reloadData]; - }); - make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); - make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); - make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); - make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); make.button(@"Cancel"); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; -} - -- (void)addPressed { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Add Keychain Item"); - make.textField(@"Service name, i.e. Instagram"); - make.textField(@"Account"); - make.textField(@"Password"); - make.button(@"Cancel").cancelStyle(); - make.button(@"Save").handler(^(NSArray *strings) { - // Display errors - NSError *error = nil; - if (![FLEXKeychain setPassword:strings[2] forService:strings[0] account:strings[1] error:&error]) { - [FLEXAlert showAlert:@"Error" message:error.localizedDescription from:self]; - } - - [self reloadData]; - }); - } showFrom:self]; -} - - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"🔑 Keychain"; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - FLEXKeychainViewController *viewController = [self new]; - viewController.title = [self globalsEntryTitle:row]; - - return viewController; -} - - -#pragma mark - Table View Data Source - -- (void)tableView:(UITableView *)tv commitEditingStyle:(UITableViewCellEditingStyle)style forRowAtIndexPath:(NSIndexPath *)ip { - if (style == UITableViewCellEditingStyleDelete) { - // Update the model - NSDictionary *toRemove = self.section.filteredList[ip.row]; - [self deleteItem:toRemove]; - [self.section mutate:^(NSMutableArray *list) { - [list removeObject:toRemove]; - }]; - - // Delete the row - [tv deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationAutomatic]; - - // Update the title by refreshing the section without disturbing the delete animation - // - // This is an ugly hack, but literally nothing else works, save for manually getting - // the header and setting its title, which I personally think is worse since it - // would need to make assumptions about the default style of the header (CAPS) - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [self refreshSectionTitle]; - [tv reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone]; - }); - } -} - - -#pragma mark - Table View Delegate - -- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXKeychainQuery *query = [self queryForItemAtIndex:indexPath.row]; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(query.service); - make.message(@"Service: ").message(query.service); - make.message(@"\nAccount: ").message(query.account); - make.message(@"\nPassword: ").message(query.password); - make.message(@"\nGroup: ").message(query.accessGroup); - - make.button(@"Copy Service").handler(^(NSArray *strings) { - [UIPasteboard.generalPasteboard flex_copy:query.service]; - }); - make.button(@"Copy Account").handler(^(NSArray *strings) { - [UIPasteboard.generalPasteboard flex_copy:query.account]; - }); - make.button(@"Copy Password").handler(^(NSArray *strings) { - [UIPasteboard.generalPasteboard flex_copy:query.password]; - }); - make.button(@"Dismiss").cancelStyle(); - - } showFrom:self]; - - [tableView deselectRowAtIndexPath:indexPath animated:YES]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/Keychain/SSKeychain_LICENSE b/BHTwitter/Classes/GlobalStateExplorers/Keychain/SSKeychain_LICENSE deleted file mode 100644 index b63e0772..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/Keychain/SSKeychain_LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2010-2012 Sam Soffes. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.h deleted file mode 100644 index 03f263d7..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.h +++ /dev/null @@ -1,54 +0,0 @@ -// -// FLEXRuntimeClient.h -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXSearchToken.h" -@class FLEXMethod; - -/// Accepts runtime queries given a token. -@interface FLEXRuntimeClient : NSObject - -@property (nonatomic, readonly, class) FLEXRuntimeClient *runtime; - -/// Called automatically when \c FLEXRuntime is first used. -/// You may call it again when you think a library has -/// been loaded since this method was first called. -- (void)reloadLibrariesList; - -/// You must call this method on the main thread -/// before you attempt to call \c copySafeClassList. -+ (void)initializeWebKitLegacy; - -/// Do not call unless you absolutely need all classes. This will cause -/// every class in the runtime to initialize itself, which is not common. -/// Before you call this method, call \c initializeWebKitLegacy on the main thread. -- (NSArray *)copySafeClassList; - -- (NSArray *)copyProtocolList; - -/// An array of strings representing the currently loaded libraries. -@property (nonatomic, readonly) NSArray *imageDisplayNames; - -/// "Image name" is the path of the bundle -- (NSString *)shortNameForImageName:(NSString *)imageName; -/// "Image name" is the path of the bundle -- (NSString *)imageNameForShortName:(NSString *)imageName; - -/// @return Bundle names for the UI -- (NSMutableArray *)bundleNamesForToken:(FLEXSearchToken *)token; -/// @return Bundle paths for more queries -- (NSMutableArray *)bundlePathsForToken:(FLEXSearchToken *)token; -/// @return Class names -- (NSMutableArray *)classesForToken:(FLEXSearchToken *)token - inBundles:(NSMutableArray *)bundlePaths; -/// @return A list of lists of \c FLEXMethods where -/// each list corresponds to one of the given classes -- (NSArray *> *)methodsForToken:(FLEXSearchToken *)token - instance:(NSNumber *)onlyInstanceMethods - inClasses:(NSArray *)classes; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.m deleted file mode 100644 index 34fac5ed..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeClient.m +++ /dev/null @@ -1,416 +0,0 @@ -// -// FLEXRuntimeClient.m -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeClient.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXMethod.h" -#import "NSArray+FLEX.h" -#import "FLEXRuntimeSafety.h" -#include - -#define Equals(a, b) ([a compare:b options:NSCaseInsensitiveSearch] == NSOrderedSame) -#define Contains(a, b) ([a rangeOfString:b options:NSCaseInsensitiveSearch].location != NSNotFound) -#define HasPrefix(a, b) ([a rangeOfString:b options:NSCaseInsensitiveSearch].location == 0) -#define HasSuffix(a, b) ([a rangeOfString:b options:NSCaseInsensitiveSearch].location == (a.length - b.length)) - - -@interface FLEXRuntimeClient () { - NSMutableArray *_imageDisplayNames; -} - -@property (nonatomic) NSMutableDictionary *bundles_pathToShort; -@property (nonatomic) NSMutableDictionary *bundles_shortToPath; -@property (nonatomic) NSCache *bundles_pathToClassNames; -@property (nonatomic) NSMutableArray *imagePaths; - -@end - -/// @return success if the map passes. -static inline NSString * TBWildcardMap_(NSString *token, NSString *candidate, NSString *success, TBWildcardOptions options) { - switch (options) { - case TBWildcardOptionsNone: - // Only "if equals" - if (Equals(candidate, token)) { - return success; - } - default: { - // Only "if contains" - if (options & TBWildcardOptionsPrefix && - options & TBWildcardOptionsSuffix) { - if (Contains(candidate, token)) { - return success; - } - } - // Only "if candidate ends with with token" - else if (options & TBWildcardOptionsPrefix) { - if (HasSuffix(candidate, token)) { - return success; - } - } - // Only "if candidate starts with with token" - else if (options & TBWildcardOptionsSuffix) { - // Case like "Bundle." where we want "" to match anything - if (!token.length) { - return success; - } - if (HasPrefix(candidate, token)) { - return success; - } - } - } - } - - return nil; -} - -/// @return candidate if the map passes. -static inline NSString * TBWildcardMap(NSString *token, NSString *candidate, TBWildcardOptions options) { - return TBWildcardMap_(token, candidate, candidate, options); -} - -@implementation FLEXRuntimeClient - -#pragma mark - Initialization - -+ (instancetype)runtime { - static FLEXRuntimeClient *runtime; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - runtime = [self new]; - [runtime reloadLibrariesList]; - }); - - return runtime; -} - -- (id)init { - self = [super init]; - if (self) { - _imagePaths = [NSMutableArray new]; - _bundles_pathToShort = [NSMutableDictionary new]; - _bundles_shortToPath = [NSMutableDictionary new]; - _bundles_pathToClassNames = [NSCache new]; - } - - return self; -} - -#pragma mark - Private - -- (void)reloadLibrariesList { - unsigned int imageCount = 0; - const char **imageNames = objc_copyImageNames(&imageCount); - - if (imageNames) { - NSMutableArray *imageNameStrings = [NSMutableArray flex_forEachUpTo:imageCount map:^NSString *(NSUInteger i) { - return @(imageNames[i]); - }]; - - self.imagePaths = imageNameStrings; - free(imageNames); - - // Sort alphabetically - [imageNameStrings sortUsingComparator:^NSComparisonResult(NSString *name1, NSString *name2) { - NSString *shortName1 = [self shortNameForImageName:name1]; - NSString *shortName2 = [self shortNameForImageName:name2]; - return [shortName1 caseInsensitiveCompare:shortName2]; - }]; - - // Cache image display names - _imageDisplayNames = [imageNameStrings flex_mapped:^id(NSString *path, NSUInteger idx) { - return [self shortNameForImageName:path]; - }]; - } -} - -- (NSString *)shortNameForImageName:(NSString *)imageName { - // Cache - NSString *shortName = _bundles_pathToShort[imageName]; - if (shortName) { - return shortName; - } - - NSArray *components = [imageName componentsSeparatedByString:@"/"]; - if (components.count >= 2) { - NSString *parentDir = components[components.count - 2]; - if ([parentDir hasSuffix:@".framework"] || [parentDir hasSuffix:@".axbundle"]) { - if ([imageName hasSuffix:@".dylib"]) { - shortName = imageName.lastPathComponent; - } else { - shortName = parentDir; - } - } - } - - if (!shortName) { - shortName = imageName.lastPathComponent; - } - - _bundles_pathToShort[imageName] = shortName; - _bundles_shortToPath[shortName] = imageName; - return shortName; -} - -- (NSString *)imageNameForShortName:(NSString *)imageName { - return _bundles_shortToPath[imageName]; -} - -- (NSMutableArray *)classNamesInImageAtPath:(NSString *)path { - // Check cache - NSMutableArray *classNameStrings = [_bundles_pathToClassNames objectForKey:path]; - if (classNameStrings) { - return classNameStrings.mutableCopy; - } - - unsigned int classCount = 0; - const char **classNames = objc_copyClassNamesForImage(path.UTF8String, &classCount); - - if (classNames) { - classNameStrings = [NSMutableArray flex_forEachUpTo:classCount map:^id(NSUInteger i) { - return @(classNames[i]); - }]; - - free(classNames); - - [classNameStrings sortUsingSelector:@selector(caseInsensitiveCompare:)]; - [_bundles_pathToClassNames setObject:classNameStrings forKey:path]; - - return classNameStrings.mutableCopy; - } - - return [NSMutableArray new]; -} - -#pragma mark - Public - -+ (void)initializeWebKitLegacy { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - void *handle = dlopen( - "/System/Library/PrivateFrameworks/WebKitLegacy.framework/WebKitLegacy", - RTLD_LAZY - ); - void (*WebKitInitialize)(void) = dlsym(handle, "WebKitInitialize"); - if (WebKitInitialize) { - NSAssert(NSThread.isMainThread, - @"WebKitInitialize can only be called on the main thread" - ); - WebKitInitialize(); - } - }); -} - -- (NSArray *)copySafeClassList { - unsigned int count = 0; - Class *classes = objc_copyClassList(&count); - return [NSArray flex_forEachUpTo:count map:^id(NSUInteger i) { - Class cls = classes[i]; - return FLEXClassIsSafe(cls) ? cls : nil; - }]; -} - -- (NSArray *)copyProtocolList { - unsigned int count = 0; - Protocol *__unsafe_unretained *protocols = objc_copyProtocolList(&count); - return [NSArray arrayWithObjects:protocols count:count]; -} - -- (NSMutableArray *)bundleNamesForToken:(FLEXSearchToken *)token { - if (self.imagePaths.count) { - TBWildcardOptions options = token.options; - NSString *query = token.string; - - // Optimization, avoid a loop - if (options == TBWildcardOptionsAny) { - return _imageDisplayNames; - } - - // No dot syntax because imageDisplayNames is only mutable internally - return [_imageDisplayNames flex_mapped:^id(NSString *binary, NSUInteger idx) { -// NSString *UIName = [self shortNameForImageName:binary]; - return TBWildcardMap(query, binary, options); - }]; - } - - return [NSMutableArray new]; -} - -- (NSMutableArray *)bundlePathsForToken:(FLEXSearchToken *)token { - if (self.imagePaths.count) { - TBWildcardOptions options = token.options; - NSString *query = token.string; - - // Optimization, avoid a loop - if (options == TBWildcardOptionsAny) { - return self.imagePaths; - } - - return [self.imagePaths flex_mapped:^id(NSString *binary, NSUInteger idx) { - NSString *UIName = [self shortNameForImageName:binary]; - // If query == UIName, -> binary - return TBWildcardMap_(query, UIName, binary, options); - }]; - } - - return [NSMutableArray new]; -} - -- (NSMutableArray *)classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray *)bundles { - // Edge case where token is the class we want already; return superclasses - if (token.isAbsolute) { - if (FLEXClassIsSafe(NSClassFromString(token.string))) { - return [NSMutableArray arrayWithObject:token.string]; - } - - return [NSMutableArray new]; - } - - if (bundles.count) { - // Get class names, remove unsafe classes - NSMutableArray *names = [self _classesForToken:token inBundles:bundles]; - return [names flex_mapped:^NSString *(NSString *name, NSUInteger idx) { - Class cls = NSClassFromString(name); - BOOL safe = FLEXClassIsSafe(cls); - return safe ? name : nil; - }]; - } - - return [NSMutableArray new]; -} - -- (NSMutableArray *)_classesForToken:(FLEXSearchToken *)token inBundles:(NSMutableArray *)bundles { - TBWildcardOptions options = token.options; - NSString *query = token.string; - - // Optimization, avoid unnecessary sorting - if (bundles.count == 1) { - // Optimization, avoid a loop - if (options == TBWildcardOptionsAny) { - return [self classNamesInImageAtPath:bundles.firstObject]; - } - - return [[self classNamesInImageAtPath:bundles.firstObject] flex_mapped:^id(NSString *className, NSUInteger idx) { - return TBWildcardMap(query, className, options); - }]; - } - else { - // Optimization, avoid a loop - if (options == TBWildcardOptionsAny) { - return [[bundles flex_flatmapped:^NSArray *(NSString *bundlePath, NSUInteger idx) { - return [self classNamesInImageAtPath:bundlePath]; - }] flex_sortedUsingSelector:@selector(caseInsensitiveCompare:)]; - } - - return [[bundles flex_flatmapped:^NSArray *(NSString *bundlePath, NSUInteger idx) { - return [[self classNamesInImageAtPath:bundlePath] flex_mapped:^id(NSString *className, NSUInteger idx) { - return TBWildcardMap(query, className, options); - }]; - }] flex_sortedUsingSelector:@selector(caseInsensitiveCompare:)]; - } -} - -- (NSArray *> *)methodsForToken:(FLEXSearchToken *)token - instance:(NSNumber *)checkInstance - inClasses:(NSArray *)classes { - if (classes.count) { - TBWildcardOptions options = token.options; - BOOL instance = checkInstance.boolValue; - NSString *selector = token.string; - - switch (options) { - // In practice I don't think this case is ever used with methods, - // since they will always have a suffix wildcard at the end - case TBWildcardOptionsNone: { - SEL sel = (SEL)selector.UTF8String; - return @[[classes flex_mapped:^id(NSString *name, NSUInteger idx) { - Class cls = NSClassFromString(name); - // Use metaclass if not instance - if (!instance) { - cls = object_getClass(cls); - } - - // Method is absolute - return [FLEXMethod selector:sel class:cls]; - }]]; - } - case TBWildcardOptionsAny: { - return [classes flex_mapped:^NSArray *(NSString *name, NSUInteger idx) { - // Any means `instance` was not specified - Class cls = NSClassFromString(name); - return [cls flex_allMethods]; - }]; - } - default: { - // Only "if contains" - if (options & TBWildcardOptionsPrefix && - options & TBWildcardOptionsSuffix) { - return [classes flex_mapped:^NSArray *(NSString *name, NSUInteger idx) { - Class cls = NSClassFromString(name); - return [[cls flex_allMethods] flex_mapped:^id(FLEXMethod *method, NSUInteger idx) { - - // Method is a prefix-suffix wildcard - if (Contains(method.selectorString, selector)) { - return method; - } - return nil; - }]; - }]; - } - // Only "if method ends with with selector" - else if (options & TBWildcardOptionsPrefix) { - return [classes flex_mapped:^NSArray *(NSString *name, NSUInteger idx) { - Class cls = NSClassFromString(name); - - return [[cls flex_allMethods] flex_mapped:^id(FLEXMethod *method, NSUInteger idx) { - // Method is a prefix wildcard - if (HasSuffix(method.selectorString, selector)) { - return method; - } - return nil; - }]; - }]; - } - // Only "if method starts with with selector" - else if (options & TBWildcardOptionsSuffix) { - assert(checkInstance); - - return [classes flex_mapped:^NSArray *(NSString *name, NSUInteger idx) { - Class cls = NSClassFromString(name); - - // Case like "Bundle.class.-" where we want "-" to match anything - if (!selector.length) { - if (instance) { - return [cls flex_allInstanceMethods]; - } else { - return [cls flex_allClassMethods]; - } - } - - id mapping = ^id(FLEXMethod *method) { - // Method is a suffix wildcard - if (HasPrefix(method.selectorString, selector)) { - return method; - } - return nil; - }; - - if (instance) { - return [[cls flex_allInstanceMethods] flex_mapped:mapping]; - } else { - return [[cls flex_allClassMethods] flex_mapped:mapping]; - } - }]; - } - } - } - } - - return [NSMutableArray new]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.h deleted file mode 100644 index 968c975d..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// FLEXRuntimeController.h -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeKeyPath.h" - -/// Wraps FLEXRuntimeClient and provides extra caching mechanisms -@interface FLEXRuntimeController : NSObject - -/// @return An array of strings if the key path only evaluates -/// to a class or bundle; otherwise, a list of lists of FLEXMethods. -+ (NSArray *)dataForKeyPath:(FLEXRuntimeKeyPath *)keyPath; - -/// Useful when you need to specify which classes to search in. -/// \c dataForKeyPath: will only search classes matching the class key. -/// We use this elsewhere when we need to search a class hierarchy. -+ (NSArray *> *)methodsForToken:(FLEXSearchToken *)token - instance:(NSNumber *)onlyInstanceMethods - inClasses:(NSArray *)classes; - -/// Useful when you need the classes that are associated with the -/// double list of methods returned from \c dataForKeyPath -+ (NSMutableArray *)classesForKeyPath:(FLEXRuntimeKeyPath *)keyPath; - -+ (NSString *)shortBundleNameForClass:(NSString *)name; - -+ (NSString *)imagePathWithShortName:(NSString *)suffix; - -/// Gives back short names. For example, "Foundation.framework" -+ (NSArray *)allBundleNames; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.m deleted file mode 100644 index 64dda728..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeController.m +++ /dev/null @@ -1,192 +0,0 @@ -// -// FLEXRuntimeController.m -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeController.h" -#import "FLEXRuntimeClient.h" -#import "FLEXMethod.h" - -@interface FLEXRuntimeController () -@property (nonatomic, readonly) NSCache *bundlePathsCache; -@property (nonatomic, readonly) NSCache *bundleNamesCache; -@property (nonatomic, readonly) NSCache *classNamesCache; -@property (nonatomic, readonly) NSCache *methodsCache; -@end - -@implementation FLEXRuntimeController - -#pragma mark Initialization - -static FLEXRuntimeController *controller = nil; -+ (instancetype)shared { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - controller = [self new]; - }); - - return controller; -} - -- (id)init { - self = [super init]; - if (self) { - _bundlePathsCache = [NSCache new]; - _bundleNamesCache = [NSCache new]; - _classNamesCache = [NSCache new]; - _methodsCache = [NSCache new]; - } - - return self; -} - -#pragma mark Public - -+ (NSArray *)dataForKeyPath:(FLEXRuntimeKeyPath *)keyPath { - if (keyPath.bundleKey) { - if (keyPath.classKey) { - if (keyPath.methodKey) { - return [[self shared] methodsForKeyPath:keyPath]; - } else { - return [[self shared] classesForKeyPath:keyPath]; - } - } else { - return [[self shared] bundleNamesForToken:keyPath.bundleKey]; - } - } else { - return @[]; - } -} - -+ (NSArray *> *)methodsForToken:(FLEXSearchToken *)token - instance:(NSNumber *)inst - inClasses:(NSArray *)classes { - return [FLEXRuntimeClient.runtime - methodsForToken:token - instance:inst - inClasses:classes - ]; -} - -+ (NSMutableArray *)classesForKeyPath:(FLEXRuntimeKeyPath *)keyPath { - return [[self shared] classesForKeyPath:keyPath]; -} - -+ (NSString *)shortBundleNameForClass:(NSString *)name { - const char *imageName = class_getImageName(NSClassFromString(name)); - if (!imageName) { - return @"(unspecified)"; - } - - return [FLEXRuntimeClient.runtime shortNameForImageName:@(imageName)]; -} - -+ (NSString *)imagePathWithShortName:(NSString *)suffix { - return [FLEXRuntimeClient.runtime imageNameForShortName:suffix]; -} - -+ (NSArray *)allBundleNames { - return FLEXRuntimeClient.runtime.imageDisplayNames; -} - -#pragma mark Private - -- (NSMutableArray *)bundlePathsForToken:(FLEXSearchToken *)token { - // Only cache if no wildcard - BOOL shouldCache = token == TBWildcardOptionsNone; - - if (shouldCache) { - NSMutableArray *cached = [self.bundlePathsCache objectForKey:token]; - if (cached) { - return cached; - } - - NSMutableArray *bundles = [FLEXRuntimeClient.runtime bundlePathsForToken:token]; - [self.bundlePathsCache setObject:bundles forKey:token]; - return bundles; - } - else { - return [FLEXRuntimeClient.runtime bundlePathsForToken:token]; - } -} - -- (NSMutableArray *)bundleNamesForToken:(FLEXSearchToken *)token { - // Only cache if no wildcard - BOOL shouldCache = token == TBWildcardOptionsNone; - - if (shouldCache) { - NSMutableArray *cached = [self.bundleNamesCache objectForKey:token]; - if (cached) { - return cached; - } - - NSMutableArray *bundles = [FLEXRuntimeClient.runtime bundleNamesForToken:token]; - [self.bundleNamesCache setObject:bundles forKey:token]; - return bundles; - } - else { - return [FLEXRuntimeClient.runtime bundleNamesForToken:token]; - } -} - -- (NSMutableArray *)classesForKeyPath:(FLEXRuntimeKeyPath *)keyPath { - FLEXSearchToken *classToken = keyPath.classKey; - FLEXSearchToken *bundleToken = keyPath.bundleKey; - - // Only cache if no wildcard - BOOL shouldCache = bundleToken.options == 0 && classToken.options == 0; - NSString *key = nil; - - if (shouldCache) { - key = [@[bundleToken.description, classToken.description] componentsJoinedByString:@"+"]; - NSMutableArray *cached = [self.classNamesCache objectForKey:key]; - if (cached) { - return cached; - } - } - - NSMutableArray *bundles = [self bundlePathsForToken:bundleToken]; - NSMutableArray *classes = [FLEXRuntimeClient.runtime - classesForToken:classToken inBundles:bundles - ]; - - if (shouldCache) { - [self.classNamesCache setObject:classes forKey:key]; - } - - return classes; -} - -- (NSArray *> *)methodsForKeyPath:(FLEXRuntimeKeyPath *)keyPath { - // Only cache if no wildcard, but check cache anyway bc I'm lazy - NSArray *cached = [self.methodsCache objectForKey:keyPath]; - if (cached) { - return cached; - } - - NSArray *classes = [self classesForKeyPath:keyPath]; - NSArray *> *methodLists = [FLEXRuntimeClient.runtime - methodsForToken:keyPath.methodKey - instance:keyPath.instanceMethods - inClasses:classes - ]; - - for (NSMutableArray *methods in methodLists) { - [methods sortUsingComparator:^NSComparisonResult(FLEXMethod *m1, FLEXMethod *m2) { - return [m1.description caseInsensitiveCompare:m2.description]; - }]; - } - - // Only cache if no wildcard, otherwise the cache could grow very large - if (keyPath.bundleKey.isAbsolute && - keyPath.classKey.isAbsolute) { - [self.methodsCache setObject:methodLists forKey:keyPath]; - } - - return methodLists; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.h deleted file mode 100644 index 69ce1cf8..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXRuntimeExporter.h -// FLEX -// -// Created by Tanner Bennett on 3/26/20. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -/// A class for exporting all runtime metadata to an SQLite database. -//API_AVAILABLE(ios(10.0)) -@interface FLEXRuntimeExporter : NSObject - -+ (void)createRuntimeDatabaseAtPath:(NSString *)path - progressHandler:(void(^)(NSString *status))progress - completion:(void(^)(NSString *_Nullable error))completion; - -+ (void)createRuntimeDatabaseAtPath:(NSString *)path - forImages:(nullable NSArray *)images - progressHandler:(void(^)(NSString *status))progress - completion:(void(^)(NSString *_Nullable error))completion; - - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.m deleted file mode 100644 index 0b89a6c1..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/DataSources/FLEXRuntimeExporter.m +++ /dev/null @@ -1,875 +0,0 @@ -// -// FLEXRuntimeExporter.m -// FLEX -// -// Created by Tanner Bennett on 3/26/20. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeExporter.h" -#import "FLEXSQLiteDatabaseManager.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXRuntimeController.h" -#import "FLEXRuntimeClient.h" -#import "NSArray+FLEX.h" -#import "FLEXTypeEncodingParser.h" -#import - -#import "FLEXProtocol.h" -#import "FLEXProperty.h" -#import "FLEXIvar.h" -#import "FLEXMethodBase.h" -#import "FLEXMethod.h" -#import "FLEXPropertyAttributes.h" - -NSString * const kFREEnableForeignKeys = @"PRAGMA foreign_keys = ON;"; - -/// Loaded images -NSString * const kFRECreateTableMachOCommand = @"CREATE TABLE MachO( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "shortName TEXT, " - "imagePath TEXT, " - "bundleID TEXT " -");"; - -NSString * const kFREInsertImage = @"INSERT INTO MachO ( " - "shortName, imagePath, bundleID " -") VALUES ( " - "$shortName, $imagePath, $bundleID " -");"; - -/// Objc classes -NSString * const kFRECreateTableClassCommand = @"CREATE TABLE Class( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "className TEXT, " - "superclass INTEGER, " - "instanceSize INTEGER, " - "version INTEGER, " - "image INTEGER, " - - "FOREIGN KEY(superclass) REFERENCES Class(id), " - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertClass = @"INSERT INTO Class ( " - "className, instanceSize, version, image " -") VALUES ( " - "$className, $instanceSize, $version, $image " -");"; - -NSString * const kFREUpdateClassSetSuper = @"UPDATE Class SET superclass = $super WHERE id = $id;"; - -/// Unique objc selectors -NSString * const kFRECreateTableSelectorCommand = @"CREATE TABLE Selector( " - "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - "name text NOT NULL UNIQUE " -");"; - -NSString * const kFREInsertSelector = @"INSERT OR IGNORE INTO Selector (name) VALUES ($name);"; - -/// Unique objc type encodings -NSString * const kFRECreateTableTypeEncodingCommand = @"CREATE TABLE TypeEncoding( " - "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - "string text NOT NULL UNIQUE, " - "size integer " -");"; - -NSString * const kFREInsertTypeEncoding = @"INSERT OR IGNORE INTO TypeEncoding " - "(string, size) VALUES ($type, $size);"; - -/// Unique objc type signatures -NSString * const kFRECreateTableTypeSignatureCommand = @"CREATE TABLE TypeSignature( " - "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - "string text NOT NULL UNIQUE " -");"; - -NSString * const kFREInsertTypeSignature = @"INSERT OR IGNORE INTO TypeSignature " - "(string) VALUES ($type);"; - -NSString * const kFRECreateTableMethodSignatureCommand = @"CREATE TABLE MethodSignature( " - "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " - "typeEncoding TEXT, " - "argc INTEGER, " - "returnType INTEGER, " - "frameLength INTEGER, " - - "FOREIGN KEY(returnType) REFERENCES TypeEncoding(id) " -");"; - -NSString * const kFREInsertMethodSignature = @"INSERT INTO MethodSignature ( " - "typeEncoding, argc, returnType, frameLength " -") VALUES ( " - "$typeEncoding, $argc, $returnType, $frameLength " -");"; - -NSString * const kFRECreateTableMethodCommand = @"CREATE TABLE Method( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "sel INTEGER, " - "class INTEGER, " - "instance INTEGER, " // 0 if class method, 1 if instance method - "signature INTEGER, " - "image INTEGER, " - - "FOREIGN KEY(sel) REFERENCES Selector(id), " - "FOREIGN KEY(class) REFERENCES Class(id), " - "FOREIGN KEY(signature) REFERENCES MethodSignature(id), " - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertMethod = @"INSERT INTO Method ( " - "sel, class, instance, signature, image " -") VALUES ( " - "$sel, $class, $instance, $signature, $image " -");"; - -NSString * const kFRECreateTablePropertyCommand = @"CREATE TABLE Property( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "name TEXT, " - "class INTEGER, " - "instance INTEGER, " // 0 if class prop, 1 if instance prop - "image INTEGER, " - "attributes TEXT, " - - "customGetter INTEGER, " - "customSetter INTEGER, " - - "type INTEGER, " - "ivar TEXT, " - "readonly INTEGER, " - "copy INTEGER, " - "retained INTEGER, " - "nonatomic INTEGER, " - "dynamic INTEGER, " - "weak INTEGER, " - "canGC INTEGER, " - - "FOREIGN KEY(class) REFERENCES Class(id), " - "FOREIGN KEY(customGetter) REFERENCES Selector(id), " - "FOREIGN KEY(customSetter) REFERENCES Selector(id), " - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertProperty = @"INSERT INTO Property ( " - "name, class, instance, attributes, image, " - "customGetter, customSetter, type, ivar, readonly, " - "copy, retained, nonatomic, dynamic, weak, canGC " -") VALUES ( " - "$name, $class, $instance, $attributes, $image, " - "$customGetter, $customSetter, $type, $ivar, $readonly, " - "$copy, $retained, $nonatomic, $dynamic, $weak, $canGC " -");"; - -NSString * const kFRECreateTableIvarCommand = @"CREATE TABLE Ivar( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "name TEXT, " - "offset INTEGER, " - "type INTEGER, " - "class INTEGER, " - "image INTEGER, " - - "FOREIGN KEY(type) REFERENCES TypeEncoding(id), " - "FOREIGN KEY(class) REFERENCES Class(id), " - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertIvar = @"INSERT INTO Ivar ( " - "name, offset, type, class, image " -") VALUES ( " - "$name, $offset, $type, $class, $image " -");"; - -NSString * const kFRECreateTableProtocolCommand = @"CREATE TABLE Protocol( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "name TEXT, " - "image INTEGER, " - - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertProtocol = @"INSERT INTO Protocol " - "(name, image) VALUES ($name, $image);"; - -NSString * const kFRECreateTableProtocolPropertyCommand = @"CREATE TABLE ProtocolMember( " - "id INTEGER PRIMARY KEY AUTOINCREMENT, " - "protocol INTEGER, " - "required INTEGER, " - "instance INTEGER, " // 0 if class member, 1 if instance member - - // Only of the two below is used - "property TEXT, " - "method TEXT, " - - "image INTEGER, " - - "FOREIGN KEY(protocol) REFERENCES Protocol(id), " - "FOREIGN KEY(image) REFERENCES MachO(id) " -");"; - -NSString * const kFREInsertProtocolMember = @"INSERT INTO ProtocolMember ( " - "protocol, required, instance, property, method, image " -") VALUES ( " - "$protocol, $required, $instance, $property, $method, $image " -");"; - -/// For protocols conforming to other protocols -NSString * const kFRECreateTableProtocolConformanceCommand = @"CREATE TABLE ProtocolConformance( " - "protocol INTEGER, " - "conformance INTEGER, " - - "FOREIGN KEY(protocol) REFERENCES Protocol(id), " - "FOREIGN KEY(conformance) REFERENCES Protocol(id) " -");"; - -NSString * const kFREInsertProtocolConformance = @"INSERT INTO ProtocolConformance " -"(protocol, conformance) VALUES ($protocol, $conformance);"; - -/// For classes conforming to protocols -NSString * const kFRECreateTableClassConformanceCommand = @"CREATE TABLE ClassConformance( " - "class INTEGER, " - "conformance INTEGER, " - - "FOREIGN KEY(class) REFERENCES Class(id), " - "FOREIGN KEY(conformance) REFERENCES Protocol(id) " -");"; - -NSString * const kFREInsertClassConformance = @"INSERT INTO ClassConformance " -"(class, conformance) VALUES ($class, $conformance);"; - -@interface FLEXRuntimeExporter () -@property (nonatomic, readonly) FLEXSQLiteDatabaseManager *db; -@property (nonatomic, copy) NSArray *loadedShortBundleNames; -@property (nonatomic, copy) NSArray *loadedBundlePaths; -@property (nonatomic, copy) NSArray *protocols; -@property (nonatomic, copy) NSArray *classes; - -@property (nonatomic) NSMutableDictionary *bundlePathsToIDs; -@property (nonatomic) NSMutableDictionary *protocolsToIDs; -@property (nonatomic) NSMutableDictionary *classesToIDs; -@property (nonatomic) NSMutableDictionary *typeEncodingsToIDs; -@property (nonatomic) NSMutableDictionary *methodSignaturesToIDs; -@property (nonatomic) NSMutableDictionary *selectorsToIDs; -@end - -@implementation FLEXRuntimeExporter - -+ (NSString *)tempFilename { - NSString *temp = NSTemporaryDirectory(); - NSString *uuid = [NSUUID.UUID.UUIDString substringToIndex:8]; - NSString *filename = [NSString stringWithFormat:@"FLEXRuntimeDatabase-%@.db", uuid]; - return [temp stringByAppendingPathComponent:filename]; -} - -+ (void)createRuntimeDatabaseAtPath:(NSString *)path - progressHandler:(void(^)(NSString *status))progress - completion:(void (^)(NSString *))completion { - [self createRuntimeDatabaseAtPath:path forImages:nil progressHandler:progress completion:completion]; -} - -+ (void)createRuntimeDatabaseAtPath:(NSString *)path - forImages:(NSArray *)images - progressHandler:(void(^)(NSString *status))progress - completion:(void(^)(NSString *_Nullable error))completion { - __typeof(completion) callback = ^(NSString *error) { - dispatch_async(dispatch_get_main_queue(), ^{ - completion(error); - }); - }; - - // This must be called on the main thread first - if (NSThread.isMainThread) { - [FLEXRuntimeClient initializeWebKitLegacy]; - } else { - dispatch_sync(dispatch_get_main_queue(), ^{ - [FLEXRuntimeClient initializeWebKitLegacy]; - }); - } - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - NSError *error = nil; - NSString *errorMessage = nil; - - // Get unused temp filename, remove existing database if any - NSString *tempPath = [self tempFilename]; - if ([NSFileManager.defaultManager fileExistsAtPath:tempPath]) { - [NSFileManager.defaultManager removeItemAtPath:tempPath error:&error]; - if (error) { - callback(error.localizedDescription); - return; - } - } - - // Attempt to create and populate the database, abort if we fail - FLEXRuntimeExporter *exporter = [self new]; - exporter.loadedBundlePaths = images; - if (![exporter createAndPopulateDatabaseAtPath:tempPath - progressHandler:progress - error:&errorMessage]) { - // Remove temp database if it was not moved - if ([NSFileManager.defaultManager fileExistsAtPath:tempPath]) { - [NSFileManager.defaultManager removeItemAtPath:tempPath error:nil]; - } - - callback(errorMessage); - return; - } - - // Remove old database at given path - if ([NSFileManager.defaultManager fileExistsAtPath:path]) { - [NSFileManager.defaultManager removeItemAtPath:path error:&error]; - if (error) { - callback(error.localizedDescription); - return; - } - } - - // Move new database to desired path - [NSFileManager.defaultManager moveItemAtPath:tempPath toPath:path error:&error]; - if (error) { - callback(error.localizedDescription); - } - - // Remove temp database if it was not moved - if ([NSFileManager.defaultManager fileExistsAtPath:tempPath]) { - [NSFileManager.defaultManager removeItemAtPath:tempPath error:nil]; - } - - callback(nil); - }); -} - -- (id)init { - self = [super init]; - if (self) { - _bundlePathsToIDs = [NSMutableDictionary new]; - _protocolsToIDs = [NSMutableDictionary new]; - _classesToIDs = [NSMutableDictionary new]; - _typeEncodingsToIDs = [NSMutableDictionary new]; - _methodSignaturesToIDs = [NSMutableDictionary new]; - _selectorsToIDs = [NSMutableDictionary new]; - - _bundlePathsToIDs[NSNull.null] = (id)NSNull.null; - } - - return self; -} - -- (BOOL)createAndPopulateDatabaseAtPath:(NSString *)path - progressHandler:(void(^)(NSString *status))step - error:(NSString **)error { - _db = [FLEXSQLiteDatabaseManager managerForDatabase:path]; - - [self loadMetadata:step]; - - if ([self createTables] && [self addImages:step] && [self addProtocols:step] && - [self addClasses:step] && [self setSuperclasses:step] && - [self addProtocolConformances:step] && [self addClassConformances:step] && - [self addIvars:step] && [self addMethods:step] && [self addProperties:step]) { - _db = nil; // Close the database - return YES; - } - - *error = self.db.lastResult.message; - return NO; -} - -- (void)loadMetadata:(void(^)(NSString *status))progress { - progress(@"Loading metadata…"); - - FLEXRuntimeClient *runtime = FLEXRuntimeClient.runtime; - - // Only load metadata for the existing paths if any - if (self.loadedBundlePaths) { - // Images - self.loadedShortBundleNames = [self.loadedBundlePaths flex_mapped:^id(NSString *path, NSUInteger idx) { - return [runtime shortNameForImageName:path]; - }]; - - // Classes - self.classes = [[runtime classesForToken:FLEXSearchToken.any - inBundles:self.loadedBundlePaths.mutableCopy - ] flex_mapped:^id(NSString *cls, NSUInteger idx) { - return NSClassFromString(cls); - }]; - } else { - // Images - self.loadedShortBundleNames = runtime.imageDisplayNames; - self.loadedBundlePaths = [self.loadedShortBundleNames flex_mapped:^id(NSString *name, NSUInteger idx) { - return [runtime imageNameForShortName:name]; - }]; - - // Classes - self.classes = [runtime copySafeClassList]; - } - - // ...except protocols, because there's not a lot of them - // and there's no way load the protocols for a given image - self.protocols = [[runtime copyProtocolList] flex_mapped:^id(Protocol *proto, NSUInteger idx) { - return [FLEXProtocol protocol:proto]; - }]; -} - -- (BOOL)createTables { - NSArray *commands = @[ - kFREEnableForeignKeys, - kFRECreateTableMachOCommand, - kFRECreateTableClassCommand, - kFRECreateTableSelectorCommand, - kFRECreateTableTypeEncodingCommand, - kFRECreateTableTypeSignatureCommand, - kFRECreateTableMethodSignatureCommand, - kFRECreateTableMethodCommand, - kFRECreateTablePropertyCommand, - kFRECreateTableIvarCommand, - kFRECreateTableProtocolCommand, - kFRECreateTableProtocolPropertyCommand, - kFRECreateTableProtocolConformanceCommand, - kFRECreateTableClassConformanceCommand - ]; - - for (NSString *command in commands) { - if (![self.db executeStatement:command]) { - return NO; - } - } - - return YES; -} - -- (BOOL)addImages:(void(^)(NSString *status))progress { - progress(@"Adding loaded images…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSArray *shortNames = self.loadedShortBundleNames; - NSArray *fullPaths = self.loadedBundlePaths; - NSParameterAssert(shortNames.count == fullPaths.count); - - NSInteger count = shortNames.count; - for (NSInteger i = 0; i < count; i++) { - // Grab bundle ID - NSString *bundleID = [NSBundle - bundleWithPath:fullPaths[i] - ].bundleIdentifier; - - [database executeStatement:kFREInsertImage arguments:@{ - @"$shortName": shortNames[i], - @"$imagePath": fullPaths[i], - @"$bundleID": bundleID ?: NSNull.null - }]; - - if (database.lastResult.isError) { - return NO; - } else { - self.bundlePathsToIDs[fullPaths[i]] = @(database.lastRowID); - } - } - - return YES; -} - -NS_INLINE BOOL FREInsertProtocolMember(FLEXSQLiteDatabaseManager *db, - id proto, id required, id instance, - id prop, id methSel, id image) { - return ![db executeStatement:kFREInsertProtocolMember arguments:@{ - @"$protocol": proto, - @"$required": required, - @"$instance": instance ?: NSNull.null, - @"$property": prop ?: NSNull.null, - @"$method": methSel ?: NSNull.null, - @"$image": image - }].isError; -} - -- (BOOL)addProtocols:(void(^)(NSString *status))progress { - progress([NSString stringWithFormat:@"Adding %@ protocols…", @(self.protocols.count)]); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *imageIDs = self.bundlePathsToIDs; - - for (FLEXProtocol *proto in self.protocols) { - id imagePath = proto.imagePath ?: NSNull.null; - NSNumber *image = imageIDs[imagePath] ?: NSNull.null; - NSNumber *pid = nil; - - // Insert protocol - BOOL failed = [database executeStatement:kFREInsertProtocol arguments:@{ - @"$name": proto.name, @"$image": image - }].isError; - - // Cache rowid - if (failed) { - return NO; - } else { - self.protocolsToIDs[proto.name] = pid = @(database.lastRowID); - } - - // Insert its members // - - // Required methods - for (FLEXMethodDescription *method in proto.requiredMethods) { - NSString *selector = NSStringFromSelector(method.selector); - if (!FREInsertProtocolMember(database, pid, @YES, method.instance, nil, selector, image)) { - return NO; - } - } - // Optional methods - for (FLEXMethodDescription *method in proto.optionalMethods) { - NSString *selector = NSStringFromSelector(method.selector); - if (!FREInsertProtocolMember(database, pid, @NO, method.instance, nil, selector, image)) { - return NO; - } - } - - if (@available(iOS 10, *)) { - // Required properties - for (FLEXProperty *property in proto.requiredProperties) { - BOOL success = FREInsertProtocolMember( - database, pid, @YES, @(property.isClassProperty), property.name, NSNull.null, image - ); - - if (!success) return NO; - } - // Optional properties - for (FLEXProperty *property in proto.optionalProperties) { - BOOL success = FREInsertProtocolMember( - database, pid, @NO, @(property.isClassProperty), property.name, NSNull.null, image - ); - - if (!success) return NO; - } - } else { - // Just... properties. - for (FLEXProperty *property in proto.properties) { - BOOL success = FREInsertProtocolMember( - database, pid, nil, @(property.isClassProperty), property.name, NSNull.null, image - ); - - if (!success) return NO; - } - } - } - - return YES; -} - -- (BOOL)addProtocolConformances:(void(^)(NSString *status))progress { - progress(@"Adding protocol-to-protocol conformances…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *protocolIDs = self.protocolsToIDs; - - for (FLEXProtocol *proto in self.protocols) { - id protoID = protocolIDs[proto.name]; - - for (FLEXProtocol *conform in proto.protocols) { - BOOL failed = [database executeStatement:kFREInsertProtocolConformance arguments:@{ - @"$protocol": protoID, - @"$conformance": protocolIDs[conform.name] - }].isError; - - if (failed) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addClasses:(void(^)(NSString *status))progress { - progress([NSString stringWithFormat:@"Adding %@ classes…", @(self.classes.count)]); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *imageIDs = self.bundlePathsToIDs; - - for (Class cls in self.classes) { - const char *imageName = class_getImageName(cls); - id image = imageName ? imageIDs[@(imageName)] : NSNull.null; - image = image ?: NSNull.null; - - BOOL failed = [database executeStatement:kFREInsertClass arguments:@{ - @"$className": NSStringFromClass(cls), - @"$instanceSize": @(class_getInstanceSize(cls)), - @"$version": @(class_getVersion(cls)), - @"$image": image - }].isError; - - if (failed) { - return NO; - } else { - self.classesToIDs[(id)cls] = @(database.lastRowID); - } - } - - return YES; -} - -- (BOOL)setSuperclasses:(void(^)(NSString *status))progress { - progress(@"Setting superclasses…"); - - FLEXSQLiteDatabaseManager *database = self.db; - - for (Class cls in self.classes) { - // Grab superclass ID - Class superclass = class_getSuperclass(cls); - NSNumber *superclassID = _classesToIDs[class_getSuperclass(cls)]; - - // ... or add the superclass and cache its ID if the - // superclass does not reside in the target image(s) - if (!superclassID) { - NSDictionary *args = @{ @"$className": NSStringFromClass(superclass) }; - BOOL failed = [database executeStatement:kFREInsertClass arguments:args].isError; - if (failed) { return NO; } - - _classesToIDs[(id)superclass] = superclassID = @(database.lastRowID); - } - - if (superclass) { - BOOL failed = [database executeStatement:kFREUpdateClassSetSuper arguments:@{ - @"$super": superclassID, @"$id": _classesToIDs[cls] - }].isError; - - if (failed) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addClassConformances:(void(^)(NSString *status))progress { - progress(@"Adding class-to-protocol conformances…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *protocolIDs = self.protocolsToIDs; - NSDictionary *classIDs = self.classesToIDs; - - for (Class cls in self.classes) { - id classID = classIDs[(id)cls]; - - for (FLEXProtocol *conform in FLEXGetConformedProtocols(cls)) { - BOOL failed = [database executeStatement:kFREInsertClassConformance arguments:@{ - @"$class": classID, - @"$conformance": protocolIDs[conform.name] - }].isError; - - if (failed) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addIvars:(void(^)(NSString *status))progress { - progress(@"Adding ivars…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *imageIDs = self.bundlePathsToIDs; - - for (Class cls in self.classes) { - for (FLEXIvar *ivar in FLEXGetAllIvars(cls)) { - // Insert type first - if (![self addTypeEncoding:ivar.typeEncoding size:ivar.size]) { - return NO; - } - - id imagePath = ivar.imagePath ?: NSNull.null; - NSNumber *image = imageIDs[imagePath] ?: NSNull.null; - - BOOL failed = [database executeStatement:kFREInsertIvar arguments:@{ - @"$name": ivar.name, - @"$offset": @(ivar.offset), - @"$type": _typeEncodingsToIDs[ivar.typeEncoding], - @"$class": _classesToIDs[cls], - @"$image": image - }].isError; - - if (failed) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addMethods:(void(^)(NSString *status))progress { - progress(@"Adding methods…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *imageIDs = self.bundlePathsToIDs; - - // Loop over all classes - for (Class cls in self.classes) { - NSNumber *classID = _classesToIDs[(id)cls]; - const char *imageName = class_getImageName(cls); - id image = imageName ? imageIDs[@(imageName)] : NSNull.null; - image = image ?: NSNull.null; - - // Block used to process each message - BOOL (^insert)(FLEXMethod *, NSNumber *) = ^BOOL(FLEXMethod *method, NSNumber *instance) { - // Insert selector and signature first - if (![self addSelector:method.selectorString]) { - return NO; - } - if (![self addMethodSignature:method]) { - return NO; - } - - return ![database executeStatement:kFREInsertMethod arguments:@{ - @"$sel": self->_selectorsToIDs[method.selectorString], - @"$class": classID, - @"$instance": instance, - @"$signature": self->_methodSignaturesToIDs[method.signatureString], - @"$image": image - }].isError; - }; - - // Loop over all instance and class methods of that class // - - for (FLEXMethod *method in FLEXGetAllMethods(cls, YES)) { - if (!insert(method, @YES)) { - return NO; - } - } - for (FLEXMethod *method in FLEXGetAllMethods(object_getClass(cls), NO)) { - if (!insert(method, @NO)) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addProperties:(void(^)(NSString *status))progress { - progress(@"Adding properties…"); - - FLEXSQLiteDatabaseManager *database = self.db; - NSDictionary *imageIDs = self.bundlePathsToIDs; - - // Loop over all classes - for (Class cls in self.classes) { - NSNumber *classID = _classesToIDs[(id)cls]; - - // Block used to process each message - BOOL (^insert)(FLEXProperty *, NSNumber *) = ^BOOL(FLEXProperty *property, NSNumber *instance) { - FLEXPropertyAttributes *attrs = property.attributes; - NSString *customGetter = attrs.customGetterString; - NSString *customSetter = attrs.customSetterString; - - // Insert selectors first - if (customGetter) { - if (![self addSelector:customGetter]) { - return NO; - } - } - if (customSetter) { - if (![self addSelector:customSetter]) { - return NO; - } - } - - // Insert type encoding first - NSInteger size = [FLEXTypeEncodingParser - sizeForTypeEncoding:attrs.typeEncoding alignment:nil - ]; - if (![self addTypeEncoding:attrs.typeEncoding size:size]) { - return NO; - } - - id imagePath = property.imagePath ?: NSNull.null; - id image = imageIDs[imagePath] ?: NSNull.null; - return ![database executeStatement:kFREInsertProperty arguments:@{ - @"$name": property.name, - @"$class": classID, - @"$instance": instance, - @"$image": image, - @"$attributes": attrs.string, - - @"$customGetter": self->_selectorsToIDs[customGetter] ?: NSNull.null, - @"$customSetter": self->_selectorsToIDs[customSetter] ?: NSNull.null, - - @"$type": self->_typeEncodingsToIDs[attrs.typeEncoding] ?: NSNull.null, - @"$ivar": attrs.backingIvar ?: NSNull.null, - @"$readonly": @(attrs.isReadOnly), - @"$copy": @(attrs.isCopy), - @"$retained": @(attrs.isRetained), - @"$nonatomic": @(attrs.isNonatomic), - @"$dynamic": @(attrs.isDynamic), - @"$weak": @(attrs.isWeak), - @"$canGC": @(attrs.isGarbageCollectable), - }].isError; - }; - - // Loop over all instance and class methods of that class // - - for (FLEXProperty *property in FLEXGetAllProperties(cls)) { - if (!insert(property, @YES)) { - return NO; - } - } - for (FLEXProperty *property in FLEXGetAllProperties(object_getClass(cls))) { - if (!insert(property, @NO)) { - return NO; - } - } - } - - return YES; -} - -- (BOOL)addSelector:(NSString *)sel { - return [self executeInsert:kFREInsertSelector args:@{ - @"$name": sel - } key:sel cacheResult:_selectorsToIDs]; -} - -- (BOOL)addTypeEncoding:(NSString *)type size:(NSInteger)size { - return [self executeInsert:kFREInsertTypeEncoding args:@{ - @"$type": type, @"$size": @(size) - } key:type cacheResult:_typeEncodingsToIDs]; -} - -- (BOOL)addMethodSignature:(FLEXMethod *)method { - NSString *signature = method.signatureString; - NSString *returnType = @((char *)method.returnType); - - // Insert return type first - if (![self addTypeEncoding:returnType size:method.returnSize]) { - return NO; - } - - return [self executeInsert:kFREInsertMethodSignature args:@{ - @"$typeEncoding": signature, - @"$returnType": _typeEncodingsToIDs[returnType], - @"$argc": @(method.numberOfArguments), - @"$frameLength": @(method.signature.frameLength) - } key:signature cacheResult:_methodSignaturesToIDs]; -} - -- (BOOL)executeInsert:(NSString *)statement - args:(NSDictionary *)args - key:(NSString *)cacheKey - cacheResult:(NSMutableDictionary *)rowids { - // Check if already inserted - if (rowids[cacheKey]) { - return YES; - } - - // Insert - FLEXSQLiteDatabaseManager *database = _db; - [database executeStatement:statement arguments:args]; - - if (database.lastResult.isError) { - return NO; - } - - // Cache rowid - rowids[cacheKey] = @(database.lastRowID); - return YES; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.h deleted file mode 100644 index f2ab468d..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.h +++ /dev/null @@ -1,31 +0,0 @@ -// -// FLEXKBToolbarButton.h -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import - -typedef void (^FLEXKBToolbarAction)(NSString *buttonTitle, BOOL isSuggestion); - - -@interface FLEXKBToolbarButton : UIButton - -/// Set to `default` to use the system appearance on iOS 13+ -@property (nonatomic) UIKeyboardAppearance appearance; - -+ (instancetype)buttonWithTitle:(NSString *)title; -+ (instancetype)buttonWithTitle:(NSString *)title action:(FLEXKBToolbarAction)eventHandler; -+ (instancetype)buttonWithTitle:(NSString *)title action:(FLEXKBToolbarAction)action forControlEvents:(UIControlEvents)controlEvents; - -/// Adds the event handler for the button. -/// -/// @param eventHandler The event handler block. -/// @param controlEvents The type of event. -- (void)addEventHandler:(FLEXKBToolbarAction)eventHandler forControlEvents:(UIControlEvents)controlEvents; - -@end - -@interface FLEXKBToolbarSuggestedButton : FLEXKBToolbarButton @end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.m deleted file mode 100644 index 15db7fc1..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKBToolbarButton.m +++ /dev/null @@ -1,160 +0,0 @@ -// -// FLEXKBToolbarButton.m -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXKBToolbarButton.h" -#import "UIFont+FLEX.h" -#import "FLEXUtility.h" -#import "CALayer+FLEX.h" - -@interface FLEXKBToolbarButton () -@property (nonatomic ) NSString *title; -@property (nonatomic, copy) FLEXKBToolbarAction buttonPressBlock; -/// YES if appearance is set to `default` -@property (nonatomic, readonly) BOOL useSystemAppearance; -/// YES if the current trait collection is set to dark mode and \c useSystemAppearance is YES -@property (nonatomic, readonly) BOOL usingDarkMode; -@end - -@implementation FLEXKBToolbarButton - -+ (instancetype)buttonWithTitle:(NSString *)title { - return [[self alloc] initWithTitle:title]; -} - -+ (instancetype)buttonWithTitle:(NSString *)title action:(FLEXKBToolbarAction)eventHandler forControlEvents:(UIControlEvents)controlEvent { - FLEXKBToolbarButton *newButton = [self buttonWithTitle:title]; - [newButton addEventHandler:eventHandler forControlEvents:controlEvent]; - return newButton; -} - -+ (instancetype)buttonWithTitle:(NSString *)title action:(FLEXKBToolbarAction)eventHandler { - return [self buttonWithTitle:title action:eventHandler forControlEvents:UIControlEventTouchUpInside]; -} - -- (id)initWithTitle:(NSString *)title { - self = [super init]; - if (self) { - _title = title; - self.layer.shadowOffset = CGSizeMake(0, 1); - self.layer.shadowOpacity = 0.35; - self.layer.shadowRadius = 0; - self.layer.cornerRadius = 5; - self.clipsToBounds = NO; - self.titleLabel.font = [UIFont systemFontOfSize:18.0]; - self.layer.flex_continuousCorners = YES; - [self setTitle:self.title forState:UIControlStateNormal]; - [self sizeToFit]; - - if (@available(iOS 13, *)) { - self.appearance = UIKeyboardAppearanceDefault; - } else { - self.appearance = UIKeyboardAppearanceLight; - } - - CGRect frame = self.frame; - frame.size.width += title.length < 3 ? 30 : 15; - frame.size.height += 10; - self.frame = frame; - } - - return self; -} - -- (void)addEventHandler:(FLEXKBToolbarAction)eventHandler forControlEvents:(UIControlEvents)controlEvent { - self.buttonPressBlock = eventHandler; - [self addTarget:self action:@selector(buttonPressed) forControlEvents:controlEvent]; -} - -- (void)buttonPressed { - self.buttonPressBlock(self.title, NO); -} - -- (void)setAppearance:(UIKeyboardAppearance)appearance { - _appearance = appearance; - - UIColor *titleColor = nil, *backgroundColor = nil; - UIColor *lightColor = [UIColor colorWithRed:253.0/255.0 green:253.0/255.0 blue:254.0/255.0 alpha:1]; - UIColor *darkColor = [UIColor colorWithRed:101.0/255.0 green:102.0/255.0 blue:104.0/255.0 alpha:1]; - - switch (_appearance) { - default: - case UIKeyboardAppearanceDefault: - if (@available(iOS 13, *)) { - titleColor = UIColor.labelColor; - - if (self.usingDarkMode) { - // style = UIBlurEffectStyleSystemUltraThinMaterialLight; - backgroundColor = darkColor; - } else { - // style = UIBlurEffectStyleSystemMaterialLight; - backgroundColor = lightColor; - } - break; - } - case UIKeyboardAppearanceLight: - titleColor = UIColor.blackColor; - backgroundColor = lightColor; - // style = UIBlurEffectStyleExtraLight; - break; - case UIKeyboardAppearanceDark: - titleColor = UIColor.whiteColor; - backgroundColor = darkColor; - // style = UIBlurEffectStyleDark; - break; - } - - self.backgroundColor = backgroundColor; - [self setTitleColor:titleColor forState:UIControlStateNormal]; -} - -- (BOOL)isEqual:(id)object { - if ([object isKindOfClass:[FLEXKBToolbarButton class]]) { - return [self.title isEqualToString:[object title]]; - } - - return NO; -} - -- (NSUInteger)hash { - return self.title.hash; -} - -- (BOOL)useSystemAppearance { - return self.appearance == UIKeyboardAppearanceDefault; -} - -- (BOOL)usingDarkMode { - if (@available(iOS 12, *)) { - return self.useSystemAppearance && self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark; - } - - return self.appearance == UIKeyboardAppearanceDark; -} - -- (void)traitCollectionDidChange:(UITraitCollection *)previous { - if (@available(iOS 12, *)) { - // Was darkmode toggled? - if (previous.userInterfaceStyle != self.traitCollection.userInterfaceStyle) { - if (self.useSystemAppearance) { - // Recreate the background view with the proper colors - self.appearance = self.appearance; - } - } - } -} - -@end - - -@implementation FLEXKBToolbarSuggestedButton - -- (void)buttonPressed { - self.buttonPressBlock(self.title, YES); -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.h deleted file mode 100644 index 98c2960b..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// FLEXKeyPathSearchController.h -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import -#import "FLEXRuntimeBrowserToolbar.h" -#import "FLEXMethod.h" - -@protocol FLEXKeyPathSearchControllerDelegate - -@property (nonatomic, readonly) UITableView *tableView; -@property (nonatomic, readonly) UISearchController *searchController; - -/// For loaded images which don't have an NSBundle -- (void)didSelectImagePath:(NSString *)message shortName:(NSString *)shortName; -- (void)didSelectBundle:(NSBundle *)bundle; -- (void)didSelectClass:(Class)cls; - -@end - - -@interface FLEXKeyPathSearchController : NSObject - -+ (instancetype)delegate:(id)delegate; - -@property (nonatomic) FLEXRuntimeBrowserToolbar *toolbar; - -/// Suggestions for the toolbar -@property (nonatomic, readonly) NSArray *suggestions; - -- (void)didSelectKeyPathOption:(NSString *)text; -- (void)didPressButton:(NSString *)text insertInto:(UISearchBar *)searchBar; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.m deleted file mode 100644 index e33cf7ce..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyPathSearchController.m +++ /dev/null @@ -1,417 +0,0 @@ -// -// FLEXKeyPathSearchController.m -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXKeyPathSearchController.h" -#import "FLEXRuntimeKeyPathTokenizer.h" -#import "FLEXRuntimeController.h" -#import "NSString+FLEX.h" -#import "NSArray+FLEX.h" -#import "UITextField+Range.h" -#import "NSTimer+FLEX.h" -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "FLEXObjectExplorerFactory.h" - -@interface FLEXKeyPathSearchController () -@property (nonatomic, readonly, weak) id delegate; -@property (nonatomic) NSTimer *timer; -/// If \c keyPath is \c nil or if it only has a \c bundleKey, this is -/// a list of bundle key path components like \c UICatalog or \c UIKit\.framework -/// If \c keyPath has more than a \c bundleKey then it is a list of class names. -@property (nonatomic) NSArray *bundlesOrClasses; -/// nil when search bar is empty -@property (nonatomic) FLEXRuntimeKeyPath *keyPath; - -@property (nonatomic, readonly) NSString *emptySuggestion; - -/// Used to track which methods go with which classes. This is used in -/// two scenarios: (1) when the target class is absolute and has classes, -/// (this list will include the "leaf" class as well as parent classes in this case) -/// or (2) when the class key is a wildcard and we're searching methods in many -/// classes at once. Each list in \c classesToMethods correspnds to a class here. -@property (nonatomic) NSArray *classes; -/// A filtered version of \c classes used when searching for a specific attribute. -/// Classes with no matching ivars/properties/methods are not shown. -@property (nonatomic) NSArray *filteredClasses; -// We use this regardless of whether the target class is absolute, just as above -@property (nonatomic) NSArray *> *classesToMethods; -@end - -@implementation FLEXKeyPathSearchController - -+ (instancetype)delegate:(id)delegate { - FLEXKeyPathSearchController *controller = [self new]; - controller->_bundlesOrClasses = [FLEXRuntimeController allBundleNames]; - controller->_delegate = delegate; - controller->_emptySuggestion = NSBundle.mainBundle.executablePath.lastPathComponent; - - NSParameterAssert(delegate.tableView); - NSParameterAssert(delegate.searchController); - - delegate.tableView.delegate = controller; - delegate.tableView.dataSource = controller; - - UISearchBar *searchBar = delegate.searchController.searchBar; - searchBar.delegate = controller; - searchBar.keyboardType = UIKeyboardTypeWebSearch; - searchBar.autocorrectionType = UITextAutocorrectionTypeNo; - if (@available(iOS 11, *)) { - searchBar.smartQuotesType = UITextSmartQuotesTypeNo; - searchBar.smartInsertDeleteType = UITextSmartInsertDeleteTypeNo; - } - - return controller; -} - -- (void)scrollViewDidScroll:(UIScrollView *)scrollView { - if (scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) { - [self.delegate.searchController.searchBar resignFirstResponder]; - } -} - -- (void)setToolbar:(FLEXRuntimeBrowserToolbar *)toolbar { - _toolbar = toolbar; - self.delegate.searchController.searchBar.inputAccessoryView = toolbar; -} - -- (NSArray *)classesOf:(NSString *)className { - Class baseClass = NSClassFromString(className); - if (!baseClass) { - return @[]; - } - - // Find classes - NSMutableArray *classes = [NSMutableArray arrayWithObject:className]; - while ([baseClass superclass]) { - [classes addObject:NSStringFromClass([baseClass superclass])]; - baseClass = [baseClass superclass]; - } - - return classes; -} - -#pragma mark Key path stuff - -- (void)didSelectKeyPathOption:(NSString *)text { - [_timer invalidate]; // Still might be waiting to refresh when method is selected - - // Change "Bundle.fooba" to "Bundle.foobar." - NSString *orig = self.delegate.searchController.searchBar.text; - NSString *keyPath = [orig flex_stringByReplacingLastKeyPathComponent:text]; - self.delegate.searchController.searchBar.text = keyPath; - - self.keyPath = [FLEXRuntimeKeyPathTokenizer tokenizeString:keyPath]; - - // Get classes if class was selected - if (self.keyPath.classKey.isAbsolute && self.keyPath.methodKey.isAny) { - [self didSelectAbsoluteClass:text]; - } else { - self.classes = nil; - self.filteredClasses = nil; - } - - [self updateTable]; -} - -- (void)didSelectAbsoluteClass:(NSString *)name { - self.classes = [self classesOf:name]; - self.filteredClasses = self.classes; - self.bundlesOrClasses = nil; - self.classesToMethods = nil; -} - -- (void)didPressButton:(NSString *)text insertInto:(UISearchBar *)searchBar { - [self.toolbar setKeyPath:self.keyPath suggestions:nil]; - - // Available since at least iOS 9, still present in iOS 13 - UITextField *field = [searchBar valueForKey:@"_searchBarTextField"]; - - if ([self searchBar:searchBar shouldChangeTextInRange:field.flex_selectedRange replacementText:text]) { - [field replaceRange:field.selectedTextRange withText:text]; - } -} - -- (NSArray *)suggestions { - if (self.bundlesOrClasses) { - if (self.classes) { - if (self.classesToMethods) { - // We have selected a class and are searching metadata - return nil; - } - - // We are currently searching classes - return [self.filteredClasses flex_subArrayUpto:10]; - } - - if (!self.keyPath) { - // Search bar is empty - return @[self.emptySuggestion]; - } - - // We are currently searching bundles - return [self.bundlesOrClasses flex_subArrayUpto:10]; - } - - // We have nothing at all to even search - return nil; -} - -#pragma mark - Filtering + UISearchBarDelegate - -- (void)updateTable { - // Compute the method, class, or bundle lists on a background thread - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - if (self.classes) { - // Here, our class key is 'absolute'; .classes is a list of superclasses - // and we want to show the methods for those classes specifically - // TODO: add caching to this somehow - NSMutableArray *methods = [FLEXRuntimeController - methodsForToken:self.keyPath.methodKey - instance:self.keyPath.instanceMethods - inClasses:self.classes - ].mutableCopy; - - // Remove classes without results if we're searching for a method - // - // Note: this will remove classes without any methods or overrides - // even if the query doesn't specify a method, like `*.*.` - if (self.keyPath.methodKey) { - [self setNonEmptyMethodLists:methods withClasses:self.classes.mutableCopy]; - } else { - self.filteredClasses = self.classes; - } - } - else { - FLEXRuntimeKeyPath *keyPath = self.keyPath; - NSArray *models = [FLEXRuntimeController dataForKeyPath:keyPath]; - if (keyPath.methodKey) { // We're looking at methods - self.bundlesOrClasses = nil; - - NSMutableArray *methods = models.mutableCopy; - NSMutableArray *classes = [ - FLEXRuntimeController classesForKeyPath:keyPath - ]; - self.classes = classes; - [self setNonEmptyMethodLists:methods withClasses:classes]; - } else { // We're looking at bundles or classes - self.bundlesOrClasses = models; - self.classesToMethods = nil; - } - } - - // Finally, reload the table on the main thread - dispatch_async(dispatch_get_main_queue(), ^{ - [self updateToolbarButtons]; - [self.delegate.tableView reloadData]; - }); - }); -} - -- (void)updateToolbarButtons { - // Update toolbar buttons - [self.toolbar setKeyPath:self.keyPath suggestions:self.suggestions]; -} - -/// Assign assign .filteredClasses and .classesToMethods after removing empty sections -- (void)setNonEmptyMethodLists:(NSMutableArray *> *)methods - withClasses:(NSMutableArray *)classes { - // Remove sections with no methods - NSIndexSet *allEmpty = [methods indexesOfObjectsPassingTest:^BOOL(NSArray *list, NSUInteger idx, BOOL *stop) { - return list.count == 0; - }]; - [methods removeObjectsAtIndexes:allEmpty]; - [classes removeObjectsAtIndexes:allEmpty]; - - self.filteredClasses = classes; - self.classesToMethods = methods; -} - -- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text { - // Check if character is even legal - if (![FLEXRuntimeKeyPathTokenizer allowedInKeyPath:text]) { - return NO; - } - - BOOL terminatedToken = NO; - BOOL isAppending = range.length == 0 && range.location == searchBar.text.length; - if (isAppending && [text isEqualToString:@"."]) { - terminatedToken = YES; - } - - // Actually parse input - @try { - text = [searchBar.text stringByReplacingCharactersInRange:range withString:text] ?: text; - self.keyPath = [FLEXRuntimeKeyPathTokenizer tokenizeString:text]; - if (self.keyPath.classKey.isAbsolute && terminatedToken) { - [self didSelectAbsoluteClass:self.keyPath.classKey.string]; - } - } @catch (id e) { - return NO; - } - - return YES; -} - -- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { - [_timer invalidate]; - - // Schedule update timer - if (searchText.length) { - if (!self.keyPath.methodKey) { - self.classes = nil; - self.filteredClasses = nil; - } - - self.timer = [NSTimer flex_fireSecondsFromNow:0.15 block:^{ - [self updateTable]; - }]; - } - // ... or remove all rows - else { - _bundlesOrClasses = [FLEXRuntimeController allBundleNames]; - _classesToMethods = nil; - _classes = nil; - _keyPath = nil; - [self updateToolbarButtons]; - [self.delegate.tableView reloadData]; - } -} - -- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { - self.keyPath = FLEXRuntimeKeyPath.empty; - [self updateTable]; -} - -/// Restore key path when going "back" and activating search bar again -- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { - searchBar.text = self.keyPath.description; -} - -- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { - [_timer invalidate]; - [searchBar resignFirstResponder]; - [self updateTable]; -} - -#pragma mark UITableViewDataSource - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.filteredClasses.count ?: self.bundlesOrClasses.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [tableView - dequeueReusableCellWithIdentifier:kFLEXMultilineDetailCell - forIndexPath:indexPath - ]; - - if (self.bundlesOrClasses.count) { - cell.accessoryType = UITableViewCellAccessoryDetailButton; - cell.textLabel.text = self.bundlesOrClasses[indexPath.row]; - cell.detailTextLabel.text = nil; - if (self.keyPath.classKey) { - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } - } - // One row per section - else if (self.filteredClasses.count) { - NSArray *methods = self.classesToMethods[indexPath.row]; - NSMutableString *summary = [NSMutableString new]; - [methods enumerateObjectsUsingBlock:^(FLEXMethod *method, NSUInteger idx, BOOL *stop) { - NSString *format = nil; - if (idx == methods.count-1) { - format = @"%@%@"; - *stop = YES; - } else if (idx < 3) { - format = @"%@%@\n"; - } else { - format = @"%@%@\n…"; - *stop = YES; - } - - [summary appendFormat:format, method.isInstanceMethod ? @"-" : @"+", method.selectorString]; - }]; - - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - cell.textLabel.text = self.filteredClasses[indexPath.row]; - if (@available(iOS 10, *)) { - cell.detailTextLabel.text = summary.length ? summary : nil; - } - - } - else { - @throw NSInternalInconsistencyException; - } - - return cell; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - if (self.filteredClasses || self.keyPath.methodKey) { - return @" "; - } else if (self.bundlesOrClasses) { - NSInteger count = self.bundlesOrClasses.count; - if (self.keyPath.classKey) { - return FLEXPluralString(count, @"classes", @"class"); - } else { - return FLEXPluralString(count, @"bundles", @"bundle"); - } - } - - return [self.delegate tableView:tableView titleForHeaderInSection:section]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { - if (self.filteredClasses || self.keyPath.methodKey) { - if (section == 0) { - return 55; - } - - return 0; - } - - return 55; -} - -#pragma mark UITableViewDelegate - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (self.bundlesOrClasses) { - NSString *bundleSuffixOrClass = self.bundlesOrClasses[indexPath.row]; - if (self.keyPath.classKey) { - NSParameterAssert(NSClassFromString(bundleSuffixOrClass)); - [self.delegate didSelectClass:NSClassFromString(bundleSuffixOrClass)]; - } else { - // Selected a bundle - [self didSelectKeyPathOption:bundleSuffixOrClass]; - } - } else { - if (self.filteredClasses.count) { - Class cls = NSClassFromString(self.filteredClasses[indexPath.row]); - NSParameterAssert(cls); - [self.delegate didSelectClass:cls]; - } else { - @throw NSInternalInconsistencyException; - } - } -} - -- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - NSString *bundleSuffixOrClass = self.bundlesOrClasses[indexPath.row]; - NSString *imagePath = [FLEXRuntimeController imagePathWithShortName:bundleSuffixOrClass]; - NSBundle *bundle = [NSBundle bundleWithPath:imagePath.stringByDeletingLastPathComponent]; - - if (bundle) { - [self.delegate didSelectBundle:bundle]; - } else { - [self.delegate didSelectImagePath:imagePath shortName:bundleSuffixOrClass]; - } -} - -@end - diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.h deleted file mode 100644 index e44fdb6b..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXKeyboardToolbar.h -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXKBToolbarButton.h" - -@interface FLEXKeyboardToolbar : UIView - -+ (instancetype)toolbarWithButtons:(NSArray *)buttons; - -@property (nonatomic) NSArray *buttons; -@property (nonatomic) UIKeyboardAppearance appearance; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.m deleted file mode 100644 index 2640a4c8..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXKeyboardToolbar.m +++ /dev/null @@ -1,225 +0,0 @@ -// -// FLEXKeyboardToolbar.m -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXKeyboardToolbar.h" -#import "FLEXUtility.h" - -#define kToolbarHeight 44 -#define kButtonSpacing 6 -#define kScrollViewHorizontalMargins 3 - -@interface FLEXKeyboardToolbar () - -/// The fake top border to replicate the toolbar. -@property (nonatomic) CALayer *topBorder; -@property (nonatomic) UIView *toolbarView; -@property (nonatomic) UIScrollView *scrollView; -@property (nonatomic) UIVisualEffectView *blurView; -/// YES if appearance is set to `default` -@property (nonatomic, readonly) BOOL useSystemAppearance; -/// YES if the current trait collection is set to dark mode and \c useSystemAppearance is YES -@property (nonatomic, readonly) BOOL usingDarkMode; -@end - -@implementation FLEXKeyboardToolbar - -+ (instancetype)toolbarWithButtons:(NSArray *)buttons { - return [[self alloc] initWithButtons:buttons]; -} - -- (id)initWithButtons:(NSArray *)buttons { - self = [super initWithFrame:CGRectMake(0, 0, self.window.rootViewController.view.bounds.size.width, kToolbarHeight)]; - if (self) { - _buttons = [buttons copy]; - - self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - if (@available(iOS 13, *)) { - self.appearance = UIKeyboardAppearanceDefault; - } else { - self.appearance = UIKeyboardAppearanceLight; - } - } - - return self; -} - -- (void)setAppearance:(UIKeyboardAppearance)appearance { - _appearance = appearance; - - // Remove toolbar if it exits because it will be recreated below - if (self.toolbarView) { - [self.toolbarView removeFromSuperview]; - } - - [self addSubview:self.inputAccessoryView]; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - // Layout top border - CGRect frame = _toolbarView.bounds; - frame.size.height = 0.5; - _topBorder.frame = frame; - - // Scroll view // - - frame = CGRectMake(0, 0, self.bounds.size.width, kToolbarHeight); - CGSize contentSize = self.scrollView.contentSize; - CGFloat scrollViewWidth = frame.size.width; - - // If our content size is smaller than the scroll view, - // we want to right-align all the content - if (contentSize.width < scrollViewWidth) { - // Compute the content size to scroll view size difference - UIEdgeInsets insets = self.scrollView.contentInset; - CGFloat margin = insets.left + insets.right; - CGFloat difference = scrollViewWidth - contentSize.width - margin; - // Update the content size to be the full width of the scroll view - contentSize.width += difference; - self.scrollView.contentSize = contentSize; - - // Offset every button by the difference above - // so that every button appears right-aligned - for (UIView *button in self.scrollView.subviews) { - CGRect f = button.frame; - f.origin.x += difference; - button.frame = f; - } - } -} - -- (UIView *)inputAccessoryView { - _topBorder = [CALayer new]; - _topBorder.frame = CGRectMake(0.0, 0.0, self.bounds.size.width, 0.5); - [self makeScrollView]; - - UIColor *borderColor = nil, *backgroundColor = nil; - UIColor *lightColor = [UIColor colorWithHue:216.0/360.0 saturation:0.05 brightness:0.85 alpha:1]; - UIColor *darkColor = [UIColor colorWithHue:220.0/360.0 saturation:0.07 brightness:0.16 alpha:1]; - - switch (_appearance) { - case UIKeyboardAppearanceDefault: - if (@available(iOS 13, *)) { - borderColor = UIColor.systemBackgroundColor; - - if (self.usingDarkMode) { - // style = UIBlurEffectStyleSystemThickMaterial; - backgroundColor = darkColor; - } else { - // style = UIBlurEffectStyleSystemUltraThinMaterialLight; - backgroundColor = lightColor; - } - break; - } - case UIKeyboardAppearanceLight: { - borderColor = UIColor.clearColor; - backgroundColor = lightColor; - break; - } - case UIKeyboardAppearanceDark: { - borderColor = [UIColor colorWithWhite:0.100 alpha:1.000]; - backgroundColor = darkColor; - break; - } - } - - self.toolbarView = [UIView new]; - [self.toolbarView addSubview:self.scrollView]; - [self.toolbarView.layer addSublayer:self.topBorder]; - self.toolbarView.frame = CGRectMake(0, 0, self.bounds.size.width, kToolbarHeight); - self.toolbarView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - self.backgroundColor = backgroundColor; - self.topBorder.backgroundColor = borderColor.CGColor; - - return self.toolbarView; -} - -- (UIScrollView *)makeScrollView { - UIScrollView *scrollView = [UIScrollView new]; - scrollView.backgroundColor = UIColor.clearColor; - scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - scrollView.contentInset = UIEdgeInsetsMake( - 8.f, kScrollViewHorizontalMargins, 4.f, kScrollViewHorizontalMargins - ); - scrollView.showsHorizontalScrollIndicator = NO; - - self.scrollView = scrollView; - [self addButtons]; - - return scrollView; -} - -- (void)addButtons { - NSUInteger originX = 0.f; - - CGRect originFrame; - CGFloat top = self.scrollView.contentInset.top; - CGFloat bottom = self.scrollView.contentInset.bottom; - - for (FLEXKBToolbarButton *button in self.buttons) { - button.appearance = self.appearance; - - originFrame = button.frame; - originFrame.origin.x = originX; - originFrame.origin.y = 0.f; - originFrame.size.height = kToolbarHeight - (top + bottom); - button.frame = originFrame; - - [self.scrollView addSubview:button]; - - // originX tracks the origin of the next button to be added, - // so at the end of each iteration of this loop we increment - // it by the size of the last button with some padding - originX += button.bounds.size.width + kButtonSpacing; - } - - // Update contentSize, - // set to the max x value of the last button added - CGSize contentSize = self.scrollView.contentSize; - contentSize.width = originX - kButtonSpacing; - self.scrollView.contentSize = contentSize; - - // Needed to potentially right-align buttons - [self setNeedsLayout]; -} - -- (void)setButtons:(NSArray *)buttons { - [_buttons makeObjectsPerformSelector:@selector(removeFromSuperview)]; - _buttons = buttons.copy; - - [self addButtons]; -} - -- (BOOL)useSystemAppearance { - return self.appearance == UIKeyboardAppearanceDefault; -} - -- (BOOL)usingDarkMode { - if (@available(iOS 12, *)) { - return self.useSystemAppearance && self.traitCollection.userInterfaceStyle == UIUserInterfaceStyleDark; - } - - return self.appearance == UIKeyboardAppearanceDark; -} - -- (void)traitCollectionDidChange:(UITraitCollection *)previous { - if (@available(iOS 12, *)) { - // Was darkmode toggled? - if (previous.userInterfaceStyle != self.traitCollection.userInterfaceStyle) { - if (self.useSystemAppearance) { - // Recreate the background view with the proper colors - self.appearance = self.appearance; - } - } - } -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.h deleted file mode 100644 index 93ac54a5..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXObjcRuntimeViewController.h -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXTableViewController.h" -#import "FLEXGlobalsEntry.h" - -@interface FLEXObjcRuntimeViewController : FLEXTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.m deleted file mode 100644 index f729535e..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXObjcRuntimeViewController.m +++ /dev/null @@ -1,178 +0,0 @@ -// -// FLEXObjcRuntimeViewController.m -// FLEX -// -// Created by Tanner on 3/23/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXObjcRuntimeViewController.h" -#import "FLEXKeyPathSearchController.h" -#import "FLEXRuntimeBrowserToolbar.h" -#import "UIGestureRecognizer+Blocks.h" -#import "UIBarButtonItem+FLEX.h" -#import "FLEXTableView.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXAlert.h" -#import "FLEXRuntimeClient.h" -#import - -@interface FLEXObjcRuntimeViewController () - -@property (nonatomic, readonly ) FLEXKeyPathSearchController *keyPathController; -@property (nonatomic, readonly ) UIView *promptView; - -@end - -@implementation FLEXObjcRuntimeViewController - -#pragma mark - Setup, view events - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Long press on navigation bar to initialize webkit legacy - // - // We call initializeWebKitLegacy automatically before you search - // all bundles just to be safe (since touching some classes before - // WebKit is initialized will initialize it on a thread other than - // the main thread), but sometimes you can encounter this crash - // without searching through all bundles, of course. - [self.navigationController.navigationBar addGestureRecognizer:[ - [UILongPressGestureRecognizer alloc] - initWithTarget:[FLEXRuntimeClient class] - action:@selector(initializeWebKitLegacy) - ] - ]; - - [self addToolbarItems:@[FLEXBarButtonItem(@"dlopen()", self, @selector(dlopenPressed:))]]; - - // Search bar stuff, must be first because this creates self.searchController - self.showsSearchBar = YES; - self.showSearchBarInitially = YES; - self.activatesSearchBarAutomatically = YES; - // Using pinSearchBar on this screen causes a weird visual - // thing on the next view controller that gets pushed. - // - // self.pinSearchBar = YES; - self.searchController.searchBar.placeholder = @"UIKit*.UIView.-setFrame:"; - - // Search controller stuff - // key path controller automatically assigns itself as the delegate of the search bar - // To avoid a retain cycle below, use local variables - UISearchBar *searchBar = self.searchController.searchBar; - FLEXKeyPathSearchController *keyPathController = [FLEXKeyPathSearchController delegate:self]; - _keyPathController = keyPathController; - _keyPathController.toolbar = [FLEXRuntimeBrowserToolbar toolbarWithHandler:^(NSString *text, BOOL suggestion) { - if (suggestion) { - [keyPathController didSelectKeyPathOption:text]; - } else { - [keyPathController didPressButton:text insertInto:searchBar]; - } - } suggestions:keyPathController.suggestions]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - [self.tableView deselectRowAtIndexPath:self.tableView.indexPathForSelectedRow animated:YES]; -} - - -#pragma mark dlopen - -/// Prompt user for dlopen shortcuts to choose from -- (void)dlopenPressed:(id)sender { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Dynamically Open Library"); - make.message(@"Invoke dlopen() with the given path. Choose an option below."); - - make.button(@"System Framework").handler(^(NSArray *_) { - [self dlopenWithFormat:@"/System/Library/Frameworks/%@.framework/%@"]; - }); - make.button(@"System Private Framework").handler(^(NSArray *_) { - [self dlopenWithFormat:@"/System/Library/PrivateFrameworks/%@.framework/%@"]; - }); - make.button(@"Arbitrary Binary").handler(^(NSArray *_) { - [self dlopenWithFormat:nil]; - }); - - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; -} - -/// Prompt user for input and dlopen -- (void)dlopenWithFormat:(NSString *)format { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Dynamically Open Library"); - if (format) { - make.message(@"Pass in a framework name, such as CarKit or FrontBoard."); - } else { - make.message(@"Pass in an absolute path to a binary."); - } - - make.textField(format ? @"ARKit" : @"/System/Library/Frameworks/ARKit.framework/ARKit"); - - make.button(@"Cancel").cancelStyle(); - make.button(@"Open").destructiveStyle().handler(^(NSArray *strings) { - NSString *path = strings[0]; - - if (path.length < 2) { - [self dlopenInvalidPath]; - } else if (format) { - path = [NSString stringWithFormat:format, path, path]; - } - - dlopen(path.UTF8String, RTLD_NOW); - }); - } showFrom:self]; -} - -- (void)dlopenInvalidPath { - [FLEXAlert makeAlert:^(FLEXAlert * _Nonnull make) { - make.title(@"Path or Name Too Short"); - make.button(@"Dismiss").cancelStyle(); - } showFrom:self]; -} - - -#pragma mark Delegate stuff - -- (void)didSelectImagePath:(NSString *)path shortName:(NSString *)shortName { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(shortName); - make.message(@"No NSBundle associated with this path:\n\n"); - make.message(path); - - make.button(@"Copy Path").handler(^(NSArray *strings) { - UIPasteboard.generalPasteboard.string = path; - }); - make.button(@"Dismiss").cancelStyle(); - } showFrom:self]; -} - -- (void)didSelectBundle:(NSBundle *)bundle { - NSParameterAssert(bundle); - FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:bundle]; - [self.navigationController pushViewController:explorer animated:YES]; -} - -- (void)didSelectClass:(Class)cls { - NSParameterAssert(cls); - FLEXObjectExplorerViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:cls]; - [self.navigationController pushViewController:explorer animated:YES]; -} - - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"📚 Runtime Browser"; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - UIViewController *controller = [self new]; - controller.title = [self globalsEntryTitle:row]; - return controller; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.h deleted file mode 100644 index ca917e85..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXRuntimeBrowserToolbar.h -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXKeyboardToolbar.h" -#import "FLEXRuntimeKeyPath.h" - -@interface FLEXRuntimeBrowserToolbar : FLEXKeyboardToolbar - -+ (instancetype)toolbarWithHandler:(FLEXKBToolbarAction)tapHandler suggestions:(NSArray *)suggestions; - -- (void)setKeyPath:(FLEXRuntimeKeyPath *)keyPath suggestions:(NSArray *)suggestions; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.m deleted file mode 100644 index c34cc020..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeBrowserToolbar.m +++ /dev/null @@ -1,92 +0,0 @@ -// -// FLEXRuntimeBrowserToolbar.m -// FLEX -// -// Created by Tanner on 6/11/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeBrowserToolbar.h" -#import "FLEXRuntimeKeyPathTokenizer.h" - -@interface FLEXRuntimeBrowserToolbar () -@property (nonatomic, copy) FLEXKBToolbarAction tapHandler; -@end - -@implementation FLEXRuntimeBrowserToolbar - -+ (instancetype)toolbarWithHandler:(FLEXKBToolbarAction)tapHandler suggestions:(NSArray *)suggestions { - NSArray *buttons = [self - buttonsForKeyPath:FLEXRuntimeKeyPath.empty suggestions:suggestions handler:tapHandler - ]; - - FLEXRuntimeBrowserToolbar *me = [self toolbarWithButtons:buttons]; - me.tapHandler = tapHandler; - return me; -} - -+ (NSArray *)buttonsForKeyPath:(FLEXRuntimeKeyPath *)keyPath - suggestions:(NSArray *)suggestions - handler:(FLEXKBToolbarAction)handler { - NSMutableArray *buttons = [NSMutableArray new]; - FLEXSearchToken *lastKey = nil; - BOOL lastKeyIsMethod = NO; - - if (keyPath.methodKey) { - lastKey = keyPath.methodKey; - lastKeyIsMethod = YES; - } else { - lastKey = keyPath.classKey ?: keyPath.bundleKey; - } - - switch (lastKey.options) { - case TBWildcardOptionsNone: - case TBWildcardOptionsAny: - if (lastKeyIsMethod) { - if (!keyPath.instanceMethods) { - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"-" action:handler]]; - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"+" action:handler]]; - } - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*" action:handler]]; - } else { - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*" action:handler]]; - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*." action:handler]]; - } - break; - - default: { - if (lastKey.options & TBWildcardOptionsPrefix) { - if (lastKeyIsMethod) { - if (lastKey.string.length) { - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*" action:handler]]; - } - } else { - if (lastKey.string.length) { - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*." action:handler]]; - } - } - } - - else if (lastKey.options & TBWildcardOptionsSuffix) { - if (!lastKeyIsMethod) { - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*" action:handler]]; - [buttons addObject:[FLEXKBToolbarButton buttonWithTitle:@"*." action:handler]]; - } - } - } - } - - for (NSString *suggestion in suggestions) { - [buttons addObject:[FLEXKBToolbarSuggestedButton buttonWithTitle:suggestion action:handler]]; - } - - return buttons; -} - -- (void)setKeyPath:(FLEXRuntimeKeyPath *)keyPath suggestions:(NSArray *)suggestions { - self.buttons = [self.class - buttonsForKeyPath:keyPath suggestions:suggestions handler:self.tapHandler - ]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.h deleted file mode 100644 index 7babe801..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// FLEXRuntimeKeyPath.h -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXSearchToken.h" -@class FLEXMethod; - -NS_ASSUME_NONNULL_BEGIN - -/// A key path represents a query into a set of bundles or classes -/// for a set of one or more methods. It is composed of three tokens: -/// bundle, class, and method. A key path may be incomplete if it -/// is missing any of the tokens. A key path is considered "absolute" -/// if all tokens have no options and if methodKey.string begins -/// with a + or a -. -/// -/// The @code TBKeyPathTokenizer @endcode class is used to create -/// a key path from a string. -@interface FLEXRuntimeKeyPath : NSObject - -+ (instancetype)empty; - -/// @param method must start with either a wildcard or a + or -. -+ (instancetype)bundle:(FLEXSearchToken *)bundle - class:(FLEXSearchToken *)cls - method:(FLEXSearchToken *)method - isInstance:(NSNumber *)instance - string:(NSString *)keyPathString; - -@property (nonatomic, nullable, readonly) FLEXSearchToken *bundleKey; -@property (nonatomic, nullable, readonly) FLEXSearchToken *classKey; -@property (nonatomic, nullable, readonly) FLEXSearchToken *methodKey; - -/// Indicates whether the method token specifies instance methods. -/// Nil if not specified. -@property (nonatomic, nullable, readonly) NSNumber *instanceMethods; - -@end -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.m deleted file mode 100644 index 09d2099e..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPath.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// FLEXRuntimeKeyPath.m -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeKeyPath.h" -#import "FLEXRuntimeClient.h" - -@interface FLEXRuntimeKeyPath () { - NSString *flex_description; -} -@end - -@implementation FLEXRuntimeKeyPath - -+ (instancetype)empty { - static FLEXRuntimeKeyPath *empty = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - FLEXSearchToken *any = FLEXSearchToken.any; - - empty = [self new]; - empty->_bundleKey = any; - empty->flex_description = @""; - }); - - return empty; -} - -+ (instancetype)bundle:(FLEXSearchToken *)bundle - class:(FLEXSearchToken *)cls - method:(FLEXSearchToken *)method - isInstance:(NSNumber *)instance - string:(NSString *)keyPathString { - FLEXRuntimeKeyPath *keyPath = [self new]; - keyPath->_bundleKey = bundle; - keyPath->_classKey = cls; - keyPath->_methodKey = method; - - keyPath->_instanceMethods = instance; - - // Remove irrelevant trailing '*' for equality purposes - if ([keyPathString hasSuffix:@"*"]) { - keyPathString = [keyPathString substringToIndex:keyPathString.length]; - } - keyPath->flex_description = keyPathString; - - if (bundle.isAny && cls.isAny && method.isAny) { - [FLEXRuntimeClient initializeWebKitLegacy]; - } - - return keyPath; -} - -- (NSString *)description { - return flex_description; -} - -- (NSUInteger)hash { - return flex_description.hash; -} - -- (BOOL)isEqual:(id)object { - if ([object isKindOfClass:[FLEXRuntimeKeyPath class]]) { - FLEXRuntimeKeyPath *kp = object; - return [flex_description isEqualToString:kp->flex_description]; - } - - return NO; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.h deleted file mode 100644 index 1e8f6872..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXRuntimeKeyPathTokenizer.h -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeKeyPath.h" - -@interface FLEXRuntimeKeyPathTokenizer : NSObject - -+ (NSUInteger)tokenCountOfString:(NSString *)userInput; -+ (FLEXRuntimeKeyPath *)tokenizeString:(NSString *)userInput; - -+ (BOOL)allowedInKeyPath:(NSString *)text; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.m deleted file mode 100644 index e2cd6ff1..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXRuntimeKeyPathTokenizer.m +++ /dev/null @@ -1,218 +0,0 @@ -// -// FLEXRuntimeKeyPathTokenizer.m -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeKeyPathTokenizer.h" - -#define TBCountOfStringOccurence(target, str) ([target componentsSeparatedByString:str].count - 1) - -@implementation FLEXRuntimeKeyPathTokenizer - -#pragma mark Initialization - -static NSCharacterSet *firstAllowed = nil; -static NSCharacterSet *identifierAllowed = nil; -static NSCharacterSet *filenameAllowed = nil; -static NSCharacterSet *keyPathDisallowed = nil; -static NSCharacterSet *methodAllowed = nil; -+ (void)initialize { - if (self == [self class]) { - NSString *_methodFirstAllowed = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"; - NSString *_identifierAllowed = [_methodFirstAllowed stringByAppendingString:@"1234567890"]; - NSString *_methodAllowedSansType = [_identifierAllowed stringByAppendingString:@":"]; - NSString *_filenameNameAllowed = [_identifierAllowed stringByAppendingString:@"-+?!"]; - firstAllowed = [NSCharacterSet characterSetWithCharactersInString:_methodFirstAllowed]; - identifierAllowed = [NSCharacterSet characterSetWithCharactersInString:_identifierAllowed]; - filenameAllowed = [NSCharacterSet characterSetWithCharactersInString:_filenameNameAllowed]; - methodAllowed = [NSCharacterSet characterSetWithCharactersInString:_methodAllowedSansType]; - - NSString *_kpDisallowed = [_identifierAllowed stringByAppendingString:@"-+:\\.*"]; - keyPathDisallowed = [NSCharacterSet characterSetWithCharactersInString:_kpDisallowed].invertedSet; - } -} - -#pragma mark Public - -+ (FLEXRuntimeKeyPath *)tokenizeString:(NSString *)userInput { - if (!userInput.length) { - return nil; - } - - NSUInteger tokens = [self tokenCountOfString:userInput]; - if (tokens == 0) { - return nil; - } - - if ([userInput containsString:@"**"]) { - @throw NSInternalInconsistencyException; - } - - NSNumber *instance = nil; - NSScanner *scanner = [NSScanner scannerWithString:userInput]; - FLEXSearchToken *bundle = [self scanToken:scanner allowed:filenameAllowed first:filenameAllowed]; - FLEXSearchToken *cls = [self scanToken:scanner allowed:identifierAllowed first:firstAllowed]; - FLEXSearchToken *method = tokens > 2 ? [self scanMethodToken:scanner instance:&instance] : nil; - - return [FLEXRuntimeKeyPath bundle:bundle - class:cls - method:method - isInstance:instance - string:userInput]; -} - -+ (BOOL)allowedInKeyPath:(NSString *)text { - if (!text.length) { - return YES; - } - - return [text rangeOfCharacterFromSet:keyPathDisallowed].location == NSNotFound; -} - -#pragma mark Private - -+ (NSUInteger)tokenCountOfString:(NSString *)userInput { - NSUInteger escapedCount = TBCountOfStringOccurence(userInput, @"\\."); - NSUInteger tokenCount = TBCountOfStringOccurence(userInput, @".") - escapedCount + 1; - - return tokenCount; -} - -+ (FLEXSearchToken *)scanToken:(NSScanner *)scanner allowed:(NSCharacterSet *)allowedChars first:(NSCharacterSet *)first { - if (scanner.isAtEnd) { - if ([scanner.string hasSuffix:@"."] && ![scanner.string hasSuffix:@"\\."]) { - return [FLEXSearchToken string:nil options:TBWildcardOptionsAny]; - } - return nil; - } - - TBWildcardOptions options = TBWildcardOptionsNone; - NSMutableString *token = [NSMutableString new]; - - // Token cannot start with '.' - if ([scanner scanString:@"." intoString:nil]) { - @throw NSInternalInconsistencyException; - } - - if ([scanner scanString:@"*." intoString:nil]) { - return [FLEXSearchToken string:nil options:TBWildcardOptionsAny]; - } else if ([scanner scanString:@"*" intoString:nil]) { - if (scanner.isAtEnd) { - return FLEXSearchToken.any; - } - - options |= TBWildcardOptionsPrefix; - } - - NSString *tmp = nil; - BOOL stop = NO, didScanDelimiter = NO, didScanFirstAllowed = NO; - NSCharacterSet *disallowed = allowedChars.invertedSet; - while (!stop && ![scanner scanString:@"." intoString:&tmp] && !scanner.isAtEnd) { - // Scan word chars - // In this block, we have not scanned anything yet, except maybe leading '\' or '\.' - if (!didScanFirstAllowed) { - if ([scanner scanCharactersFromSet:first intoString:&tmp]) { - [token appendString:tmp]; - didScanFirstAllowed = YES; - } else if ([scanner scanString:@"\\" intoString:nil]) { - if (options == TBWildcardOptionsPrefix && [scanner scanString:@"." intoString:nil]) { - [token appendString:@"."]; - } else if (scanner.isAtEnd && options == TBWildcardOptionsPrefix) { - // Only allow standalone '\' if prefixed by '*' - return FLEXSearchToken.any; - } else { - // Token starts with a number, period, or something else not allowed, - // or token is a standalone '\' with no '*' prefix - @throw NSInternalInconsistencyException; - } - } else { - // Token starts with a number, period, or something else not allowed - @throw NSInternalInconsistencyException; - } - } else if ([scanner scanCharactersFromSet:allowedChars intoString:&tmp]) { - [token appendString:tmp]; - } - // Scan '\.' or trailing '\' - else if ([scanner scanString:@"\\" intoString:nil]) { - if ([scanner scanString:@"." intoString:nil]) { - [token appendString:@"."]; - } else if (scanner.isAtEnd) { - // Ignore forward slash not followed by period if at end - return [FLEXSearchToken string:token options:options | TBWildcardOptionsSuffix]; - } else { - // Only periods can follow a forward slash - @throw NSInternalInconsistencyException; - } - } - // Scan '*.' - else if ([scanner scanString:@"*." intoString:nil]) { - options |= TBWildcardOptionsSuffix; - stop = YES; - didScanDelimiter = YES; - } - // Scan '*' not followed by . - else if ([scanner scanString:@"*" intoString:nil]) { - if (!scanner.isAtEnd) { - // Invalid token, wildcard in middle of token - @throw NSInternalInconsistencyException; - } - } else if ([scanner scanCharactersFromSet:disallowed intoString:nil]) { - // Invalid token, invalid characters - @throw NSInternalInconsistencyException; - } - } - - // Did we scan a trailing, un-escsaped '.'? - if ([tmp isEqualToString:@"."]) { - didScanDelimiter = YES; - } - - if (!didScanDelimiter) { - options |= TBWildcardOptionsSuffix; - } - - return [FLEXSearchToken string:token options:options]; -} - -+ (FLEXSearchToken *)scanMethodToken:(NSScanner *)scanner instance:(NSNumber **)instance { - if (scanner.isAtEnd) { - if ([scanner.string hasSuffix:@"."]) { - return [FLEXSearchToken string:nil options:TBWildcardOptionsAny]; - } - return nil; - } - - if ([scanner.string hasSuffix:@"."] && ![scanner.string hasSuffix:@"\\."]) { - // Methods cannot end with '.' except for '\.' - @throw NSInternalInconsistencyException; - } - - if ([scanner scanString:@"-" intoString:nil]) { - *instance = @YES; - } else if ([scanner scanString:@"+" intoString:nil]) { - *instance = @NO; - } else { - if ([scanner scanString:@"*" intoString:nil]) { - // Just checking... It has to start with one of these three! - scanner.scanLocation--; - } else { - @throw NSInternalInconsistencyException; - } - } - - // -*foo not allowed - if (*instance && [scanner scanString:@"*" intoString:nil]) { - @throw NSInternalInconsistencyException; - } - - if (scanner.isAtEnd) { - return [FLEXSearchToken string:@"" options:TBWildcardOptionsSuffix]; - } - - return [self scanToken:scanner allowed:methodAllowed first:firstAllowed]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.h deleted file mode 100644 index 07c627d5..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// FLEXSearchToken.h -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import - -typedef NS_OPTIONS(NSUInteger, TBWildcardOptions) { - TBWildcardOptionsNone = 0, - TBWildcardOptionsAny = 1, - TBWildcardOptionsPrefix = 1 << 1, - TBWildcardOptionsSuffix = 1 << 2, -}; - -/// A token may contain wildcards at one or either end, -/// but not in the middle of the token (as of now). -@interface FLEXSearchToken : NSObject - -+ (instancetype)any; -+ (instancetype)string:(NSString *)string options:(TBWildcardOptions)options; - -/// Will not contain the wildcard (*) symbol -@property (nonatomic, readonly) NSString *string; -@property (nonatomic, readonly) TBWildcardOptions options; - -/// Opposite of "is ambiguous" -@property (nonatomic, readonly) BOOL isAbsolute; -@property (nonatomic, readonly) BOOL isAny; -/// Still \c isAny, but checks that the string is empty -@property (nonatomic, readonly) BOOL isEmpty; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.m deleted file mode 100644 index 975becf2..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeBrowser/FLEXSearchToken.m +++ /dev/null @@ -1,88 +0,0 @@ -// -// FLEXSearchToken.m -// FLEX -// -// Created by Tanner on 3/22/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXSearchToken.h" - -@interface FLEXSearchToken () { - NSString *flex_description; -} -@end - -@implementation FLEXSearchToken - -+ (instancetype)any { - static FLEXSearchToken *any = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - any = [self string:nil options:TBWildcardOptionsAny]; - }); - - return any; -} - -+ (instancetype)string:(NSString *)string options:(TBWildcardOptions)options { - FLEXSearchToken *token = [self new]; - token->_string = string; - token->_options = options; - return token; -} - -- (BOOL)isAbsolute { - return _options == TBWildcardOptionsNone; -} - -- (BOOL)isAny { - return _options == TBWildcardOptionsAny; -} - -- (BOOL)isEmpty { - return self.isAny && self.string.length == 0; -} - -- (NSString *)description { - if (flex_description) { - return flex_description; - } - - switch (_options) { - case TBWildcardOptionsNone: - flex_description = _string; - break; - case TBWildcardOptionsAny: - flex_description = @"*"; - break; - default: { - NSMutableString *desc = [NSMutableString new]; - if (_options & TBWildcardOptionsPrefix) { - [desc appendString:@"*"]; - } - [desc appendString:_string]; - if (_options & TBWildcardOptionsSuffix) { - [desc appendString:@"*"]; - } - flex_description = desc; - } - } - - return flex_description; -} - -- (NSUInteger)hash { - return self.description.hash; -} - -- (BOOL)isEqual:(id)object { - if ([object isKindOfClass:[FLEXSearchToken class]]) { - FLEXSearchToken *token = object; - return [_string isEqualToString:token->_string] && _options == token->_options; - } - - return NO; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.h b/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.h deleted file mode 100644 index 3f4408d9..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.h +++ /dev/null @@ -1,12 +0,0 @@ -#import -#import "FLEXRuntimeUtility.h" -#import "FLEXUtility.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface RuntimeExplore : NSObject -+ (id)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely; -+ (NSString *)getAddressFromDescription:(NSString *)description; -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.m b/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.m deleted file mode 100644 index 64ca0c7d..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/RuntimeExplore.m +++ /dev/null @@ -1,32 +0,0 @@ -#import "RuntimeExplore.h" - -@implementation RuntimeExplore -+ (id)tryExploreAddress:(NSString *)addressString safely:(BOOL)safely { - NSScanner *scanner = [NSScanner scannerWithString:addressString]; - unsigned long long hexValue = 0; - BOOL didParseAddress = [scanner scanHexLongLong:&hexValue]; - const void *pointerValue = (void *)hexValue; - - NSString *error = nil; - - if (didParseAddress) { - if (safely && ![FLEXRuntimeUtility pointerIsValidObjcObject:pointerValue]) { - error = @"The given address is unlikely to be a valid object."; - } - } else { - error = @"Malformed address. Make sure it's not too long and starts with '0x'."; - } - - if (!error) { - id object = (__bridge id)pointerValue; - return object; - } else { - return nil; - } -} -+ (NSString *)getAddressFromDescription:(NSString *)description { - NSMutableArray *split = [[NSMutableArray alloc] initWithArray:[description componentsSeparatedByString:@":"]]; - NSString *address = split.lastObject; - return [[address stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]; -} -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/ActivityStreamAPI.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/ActivityStreamAPI.h deleted file mode 100644 index 0702db59..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/ActivityStreamAPI.h +++ /dev/null @@ -1,209 +0,0 @@ -// -// Taken from https://github.com/llvm-mirror/lldb/blob/master/tools/debugserver/source/MacOSX/DarwinLog/ActivityStreamSPI.h -// by Tanner Bennett on 03/03/2019 with minimal modifications. -// - -//===-- ActivityStreamAPI.h -------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef ActivityStreamSPI_h -#define ActivityStreamSPI_h - -#include - -#include -// #include - -/* By default, XPC objects are declared as Objective-C types when building with - * an Objective-C compiler. This allows them to participate in ARC, in RR - * management by the Blocks runtime and in leaks checking by the static - * analyzer, and enables them to be added to Cocoa collections. - * - * See for details. - */ -#if !TARGET_OS_MACCATALYST -#if OS_OBJECT_USE_OBJC -OS_OBJECT_DECL(xpc_object); -#else -typedef void * xpc_object_t; -#endif -#endif - -#define OS_ACTIVITY_MAX_CALLSTACK 32 - -// Enums - -typedef NS_ENUM(uint32_t, os_activity_stream_flag_t) { - OS_ACTIVITY_STREAM_PROCESS_ONLY = 0x00000001, - OS_ACTIVITY_STREAM_SKIP_DECODE = 0x00000002, - OS_ACTIVITY_STREAM_PAYLOAD = 0x00000004, - OS_ACTIVITY_STREAM_HISTORICAL = 0x00000008, - OS_ACTIVITY_STREAM_CALLSTACK = 0x00000010, - OS_ACTIVITY_STREAM_DEBUG = 0x00000020, - OS_ACTIVITY_STREAM_BUFFERED = 0x00000040, - OS_ACTIVITY_STREAM_NO_SENSITIVE = 0x00000080, - OS_ACTIVITY_STREAM_INFO = 0x00000100, - OS_ACTIVITY_STREAM_PROMISCUOUS = 0x00000200, - OS_ACTIVITY_STREAM_PRECISE_TIMESTAMPS = 0x00000200 -}; - -typedef NS_ENUM(uint32_t, os_activity_stream_type_t) { - OS_ACTIVITY_STREAM_TYPE_ACTIVITY_CREATE = 0x0201, - OS_ACTIVITY_STREAM_TYPE_ACTIVITY_TRANSITION = 0x0202, - OS_ACTIVITY_STREAM_TYPE_ACTIVITY_USERACTION = 0x0203, - - OS_ACTIVITY_STREAM_TYPE_TRACE_MESSAGE = 0x0300, - - OS_ACTIVITY_STREAM_TYPE_LOG_MESSAGE = 0x0400, - OS_ACTIVITY_STREAM_TYPE_LEGACY_LOG_MESSAGE = 0x0480, - - OS_ACTIVITY_STREAM_TYPE_SIGNPOST_BEGIN = 0x0601, - OS_ACTIVITY_STREAM_TYPE_SIGNPOST_END = 0x0602, - OS_ACTIVITY_STREAM_TYPE_SIGNPOST_EVENT = 0x0603, - - OS_ACTIVITY_STREAM_TYPE_STATEDUMP_EVENT = 0x0A00, -}; - -typedef NS_ENUM(uint32_t, os_activity_stream_event_t) { - OS_ACTIVITY_STREAM_EVENT_STARTED = 1, - OS_ACTIVITY_STREAM_EVENT_STOPPED = 2, - OS_ACTIVITY_STREAM_EVENT_FAILED = 3, - OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED = 4, - OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED = 5, -}; - -// Types - -typedef uint64_t os_activity_id_t; -typedef struct os_activity_stream_s *os_activity_stream_t; -typedef struct os_activity_stream_entry_s *os_activity_stream_entry_t; - -#define OS_ACTIVITY_STREAM_COMMON() \ -uint64_t trace_id; \ -uint64_t timestamp; \ -uint64_t thread; \ -const uint8_t *image_uuid; \ -const char *image_path; \ -struct timeval tv_gmt; \ -struct timezone tz; \ -uint32_t offset - -typedef struct os_activity_stream_common_s { - OS_ACTIVITY_STREAM_COMMON(); -} * os_activity_stream_common_t; - -struct os_activity_create_s { - OS_ACTIVITY_STREAM_COMMON(); - const char *name; - os_activity_id_t creator_aid; - uint64_t unique_pid; -}; - -struct os_activity_transition_s { - OS_ACTIVITY_STREAM_COMMON(); - os_activity_id_t transition_id; -}; - -typedef struct os_log_message_s { - OS_ACTIVITY_STREAM_COMMON(); - const char *format; - const uint8_t *buffer; - size_t buffer_sz; - const uint8_t *privdata; - size_t privdata_sz; - const char *subsystem; - const char *category; - uint32_t oversize_id; - uint8_t ttl; - bool persisted; -} * os_log_message_t; - -typedef struct os_trace_message_v2_s { - OS_ACTIVITY_STREAM_COMMON(); - const char *format; - const void *buffer; - size_t bufferLen; - xpc_object_t __unsafe_unretained payload; -} * os_trace_message_v2_t; - -typedef struct os_activity_useraction_s { - OS_ACTIVITY_STREAM_COMMON(); - const char *action; - bool persisted; -} * os_activity_useraction_t; - -typedef struct os_signpost_s { - OS_ACTIVITY_STREAM_COMMON(); - const char *format; - const uint8_t *buffer; - size_t buffer_sz; - const uint8_t *privdata; - size_t privdata_sz; - const char *subsystem; - const char *category; - uint64_t duration_nsec; - uint32_t callstack_depth; - uint64_t callstack[OS_ACTIVITY_MAX_CALLSTACK]; -} * os_signpost_t; - -typedef struct os_activity_statedump_s { - OS_ACTIVITY_STREAM_COMMON(); - char *message; - size_t message_size; - char image_path_buffer[PATH_MAX]; -} * os_activity_statedump_t; - -struct os_activity_stream_entry_s { - os_activity_stream_type_t type; - - // information about the process streaming the data - pid_t pid; - uint64_t proc_id; - const uint8_t *proc_imageuuid; - const char *proc_imagepath; - - // the activity associated with this streamed event - os_activity_id_t activity_id; - os_activity_id_t parent_id; - - union { - struct os_activity_stream_common_s common; - struct os_activity_create_s activity_create; - struct os_activity_transition_s activity_transition; - struct os_log_message_s log_message; - struct os_trace_message_v2_s trace_message; - struct os_activity_useraction_s useraction; - struct os_signpost_s signpost; - struct os_activity_statedump_s statedump; - }; -}; - -// Blocks - -typedef bool (^os_activity_stream_block_t)(os_activity_stream_entry_t entry, - int error); - -typedef void (^os_activity_stream_event_block_t)( - os_activity_stream_t stream, os_activity_stream_event_t event); - -// SPI entry point prototypes - -typedef os_activity_stream_t (*os_activity_stream_for_pid_t)( - pid_t pid, os_activity_stream_flag_t flags, - os_activity_stream_block_t stream_block); - -typedef void (*os_activity_stream_resume_t)(os_activity_stream_t stream); - -typedef void (*os_activity_stream_cancel_t)(os_activity_stream_t stream); - -typedef char *(*os_log_copy_formatted_message_t)(os_log_message_t log_message); - -typedef void (*os_activity_stream_set_event_handler_t)( - os_activity_stream_t stream, os_activity_stream_event_block_t block); - -#endif /* ActivityStreamSPI_h */ diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.h deleted file mode 100644 index eeae7613..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXASLLogController.h -// FLEX -// -// Created by Tanner on 3/14/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXLogController.h" - -@interface FLEXASLLogController : NSObject - -/// Guaranteed to call back on the main thread. -+ (instancetype)withUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler; - -- (BOOL)startMonitoring; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.m b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.m deleted file mode 100644 index 328a1d01..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXASLLogController.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// FLEXASLLogController.m -// FLEX -// -// Created by Tanner on 3/14/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXASLLogController.h" -#import - -// Querying the ASL is much slower in the simulator. We need a longer polling interval to keep things responsive. -#if TARGET_IPHONE_SIMULATOR - #define updateInterval 5.0 -#else - #define updateInterval 0.5 -#endif - -@interface FLEXASLLogController () - -@property (nonatomic, readonly) void (^updateHandler)(NSArray *); - -@property (nonatomic) NSTimer *logUpdateTimer; -@property (nonatomic, readonly) NSMutableIndexSet *logMessageIdentifiers; - -// ASL stuff - -@property (nonatomic) NSUInteger heapSize; -@property (nonatomic) dispatch_queue_t logQueue; -@property (nonatomic) dispatch_io_t io; -@property (nonatomic) NSString *remaining; -@property (nonatomic) int stderror; -@property (nonatomic) NSString *lastTimestamp; - -@end - -@implementation FLEXASLLogController - -+ (instancetype)withUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler { - return [[self alloc] initWithUpdateHandler:newMessagesHandler]; -} - -- (id)initWithUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler { - NSParameterAssert(newMessagesHandler); - - self = [super init]; - if (self) { - _updateHandler = newMessagesHandler; - _logMessageIdentifiers = [NSMutableIndexSet new]; - self.logUpdateTimer = [NSTimer scheduledTimerWithTimeInterval:updateInterval - target:self - selector:@selector(updateLogMessages) - userInfo:nil - repeats:YES]; - } - - return self; -} - -- (void)dealloc { - [self.logUpdateTimer invalidate]; -} - -- (BOOL)startMonitoring { - [self.logUpdateTimer fire]; - return YES; -} - -- (void)updateLogMessages { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSArray *newMessages; - @synchronized (self) { - newMessages = [self newLogMessagesForCurrentProcess]; - if (!newMessages.count) { - return; - } - - for (FLEXSystemLogMessage *message in newMessages) { - [self.logMessageIdentifiers addIndex:(NSUInteger)message.messageID]; - } - - self.lastTimestamp = @(asl_get(newMessages.lastObject.aslMessage, ASL_KEY_TIME) ?: "null"); - } - - dispatch_async(dispatch_get_main_queue(), ^{ - self.updateHandler(newMessages); - }); - }); -} - -#pragma mark - Log Message Fetching - -- (NSArray *)newLogMessagesForCurrentProcess { - if (!self.logMessageIdentifiers.count) { - return [self allLogMessagesForCurrentProcess]; - } - - aslresponse response = [self ASLMessageListForCurrentProcess]; - aslmsg aslMessage = NULL; - - NSMutableArray *newMessages = [NSMutableArray new]; - - while ((aslMessage = asl_next(response))) { - NSUInteger messageID = (NSUInteger)atoll(asl_get(aslMessage, ASL_KEY_MSG_ID)); - if (![self.logMessageIdentifiers containsIndex:messageID]) { - [newMessages addObject:[FLEXSystemLogMessage logMessageFromASLMessage:aslMessage]]; - } - } - - asl_release(response); - return newMessages; -} - -- (aslresponse)ASLMessageListForCurrentProcess { - static NSString *pidString = nil; - if (!pidString) { - pidString = @([NSProcessInfo.processInfo processIdentifier]).stringValue; - } - - // Create system log query object. - asl_object_t query = asl_new(ASL_TYPE_QUERY); - - // Filter for messages from the current process. - // Note that this appears to happen by default on device, but is required in the simulator. - asl_set_query(query, ASL_KEY_PID, pidString.UTF8String, ASL_QUERY_OP_EQUAL); - // Filter for messages after the last retrieved message. - if (self.lastTimestamp) { - asl_set_query(query, ASL_KEY_TIME, self.lastTimestamp.UTF8String, ASL_QUERY_OP_GREATER); - } - - return asl_search(NULL, query); -} - -- (NSArray *)allLogMessagesForCurrentProcess { - aslresponse response = [self ASLMessageListForCurrentProcess]; - aslmsg aslMessage = NULL; - - NSMutableArray *logMessages = [NSMutableArray new]; - while ((aslMessage = asl_next(response))) { - [logMessages addObject:[FLEXSystemLogMessage logMessageFromASLMessage:aslMessage]]; - } - asl_release(response); - - return logMessages; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXLogController.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXLogController.h deleted file mode 100644 index cb35088f..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXLogController.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXLogController.h -// FLEX -// -// Created by Tanner on 3/17/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import "FLEXSystemLogMessage.h" - -@protocol FLEXLogController - -/// Guaranteed to call back on the main thread. -+ (instancetype)withUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler; - -- (BOOL)startMonitoring; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.h deleted file mode 100644 index 154813cf..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// FLEXOSLogController.h -// FLEX -// -// Created by Tanner on 12/19/18. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXLogController.h" - -#define FLEXOSLogAvailable() (NSProcessInfo.processInfo.operatingSystemVersion.majorVersion >= 10) - -/// The log controller used for iOS 10 and up. -@interface FLEXOSLogController : NSObject - -+ (instancetype)withUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler; - -- (BOOL)startMonitoring; - -/// Whether log messages are to be recorded and kept in-memory in the background. -/// You do not need to initialize this value, only change it. -@property (nonatomic) BOOL persistent; -/// Used mostly internally, but also used by the log VC to persist messages -/// that were created prior to enabling persistence. -@property (nonatomic) NSMutableArray *messages; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.m b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.m deleted file mode 100644 index 08e4f498..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXOSLogController.m +++ /dev/null @@ -1,214 +0,0 @@ -// -// FLEXOSLogController.m -// FLEX -// -// Created by Tanner on 12/19/18. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXOSLogController.h" -#import "NSUserDefaults+FLEX.h" -#include -#include "ActivityStreamAPI.h" - -static os_activity_stream_for_pid_t OSActivityStreamForPID; -static os_activity_stream_resume_t OSActivityStreamResume; -static os_activity_stream_cancel_t OSActivityStreamCancel; -static os_log_copy_formatted_message_t OSLogCopyFormattedMessage; -static os_activity_stream_set_event_handler_t OSActivityStreamSetEventHandler; -static int (*proc_name)(int, char *, unsigned int); -static int (*proc_listpids)(uint32_t, uint32_t, void*, int); -static uint8_t (*OSLogGetType)(void *); - -@interface FLEXOSLogController () - -+ (FLEXOSLogController *)sharedLogController; - -@property (nonatomic) void (^updateHandler)(NSArray *); - -@property (nonatomic) BOOL canPrint; -@property (nonatomic) int filterPid; -@property (nonatomic) BOOL levelInfo; -@property (nonatomic) BOOL subsystemInfo; - -@property (nonatomic) os_activity_stream_t stream; - -@end - -@implementation FLEXOSLogController - -+ (void)load { - // Persist logs when the app launches on iOS 10 if we have persistent logs turned on - if (FLEXOSLogAvailable()) { - if (NSUserDefaults.standardUserDefaults.flex_cacheOSLogMessages) { - [self sharedLogController].persistent = YES; - [[self sharedLogController] startMonitoring]; - } - } -} - -+ (instancetype)sharedLogController { - static FLEXOSLogController *shared = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - shared = [self new]; - }); - - return shared; -} - -+ (instancetype)withUpdateHandler:(void(^)(NSArray *newMessages))newMessagesHandler { - FLEXOSLogController *shared = [self sharedLogController]; - shared.updateHandler = newMessagesHandler; - return shared; -} - -- (id)init { - NSAssert(FLEXOSLogAvailable(), @"os_log is only available on iOS 10 and up"); - - self = [super init]; - if (self) { - _filterPid = NSProcessInfo.processInfo.processIdentifier; - _levelInfo = NO; - _subsystemInfo = NO; - } - - return self; -} - -- (void)dealloc { - OSActivityStreamCancel(self.stream); - _stream = nil; -} - -- (void)setPersistent:(BOOL)persistent { - if (_persistent == persistent) return; - - _persistent = persistent; - self.messages = persistent ? [NSMutableArray new] : nil; -} - -- (BOOL)startMonitoring { - if (![self lookupSPICalls]) { - // >= iOS 10 is required - return NO; - } - - // Are we already monitoring? - if (self.stream) { - // Should we send out the "persisted" messages? - if (self.updateHandler && self.messages.count) { - dispatch_async(dispatch_get_main_queue(), ^{ - self.updateHandler(self.messages); - }); - } - - return YES; - } - - // Stream entry handler - os_activity_stream_block_t block = ^bool(os_activity_stream_entry_t entry, int error) { - return [self handleStreamEntry:entry error:error]; - }; - - // Controls which types of messages we see - // 'Historical' appears to just show NSLog stuff - uint32_t activity_stream_flags = OS_ACTIVITY_STREAM_HISTORICAL; - activity_stream_flags |= OS_ACTIVITY_STREAM_PROCESS_ONLY; -// activity_stream_flags |= OS_ACTIVITY_STREAM_PROCESS_ONLY; - - self.stream = OSActivityStreamForPID(self.filterPid, activity_stream_flags, block); - - // Specify the stream-related event handler - OSActivityStreamSetEventHandler(self.stream, [self streamEventHandlerBlock]); - // Start the stream - OSActivityStreamResume(self.stream); - - return YES; -} - -- (BOOL)lookupSPICalls { - static BOOL hasSPI = NO; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - void *handle = dlopen("/System/Library/PrivateFrameworks/LoggingSupport.framework/LoggingSupport", RTLD_NOW); - - OSActivityStreamForPID = (os_activity_stream_for_pid_t)dlsym(handle, "os_activity_stream_for_pid"); - OSActivityStreamResume = (os_activity_stream_resume_t)dlsym(handle, "os_activity_stream_resume"); - OSActivityStreamCancel = (os_activity_stream_cancel_t)dlsym(handle, "os_activity_stream_cancel"); - OSLogCopyFormattedMessage = (os_log_copy_formatted_message_t)dlsym(handle, "os_log_copy_formatted_message"); - OSActivityStreamSetEventHandler = (os_activity_stream_set_event_handler_t)dlsym(handle, "os_activity_stream_set_event_handler"); - proc_name = (int(*)(int, char *, unsigned int))dlsym(handle, "proc_name"); - proc_listpids = (int(*)(uint32_t, uint32_t, void*, int))dlsym(handle, "proc_listpids"); - OSLogGetType = (uint8_t(*)(void *))dlsym(handle, "os_log_get_type"); - - hasSPI = (OSActivityStreamForPID != NULL) && - (OSActivityStreamResume != NULL) && - (OSActivityStreamCancel != NULL) && - (OSLogCopyFormattedMessage != NULL) && - (OSActivityStreamSetEventHandler != NULL) && - (OSLogGetType != NULL) && - (proc_name != NULL); - }); - - return hasSPI; -} - -- (BOOL)handleStreamEntry:(os_activity_stream_entry_t)entry error:(int)error { - if (!self.canPrint || (self.filterPid != -1 && entry->pid != self.filterPid)) { - return YES; - } - - if (!error && entry) { - if (entry->type == OS_ACTIVITY_STREAM_TYPE_LOG_MESSAGE || - entry->type == OS_ACTIVITY_STREAM_TYPE_LEGACY_LOG_MESSAGE) { - os_log_message_t log_message = &entry->log_message; - - // Get date - NSDate *date = [NSDate dateWithTimeIntervalSince1970:log_message->tv_gmt.tv_sec]; - - // Get log message text - // https://github.com/limneos/oslog/issues/1 - // https://github.com/FLEXTool/FLEX/issues/564 - const char *messageText = OSLogCopyFormattedMessage(log_message) ?: ""; - - // move messageText from stack to heap - NSString *msg = [NSString stringWithUTF8String:messageText]; - - dispatch_async(dispatch_get_main_queue(), ^{ - FLEXSystemLogMessage *message = [FLEXSystemLogMessage logMessageFromDate:date text:msg]; - if (self.persistent) { - [self.messages addObject:message]; - } - if (self.updateHandler) { - self.updateHandler(@[message]); - } - }); - } - } - - return YES; -} - -- (os_activity_stream_event_block_t)streamEventHandlerBlock { - return [^void(os_activity_stream_t stream, os_activity_stream_event_t event) { - switch (event) { - case OS_ACTIVITY_STREAM_EVENT_STARTED: - self.canPrint = YES; - break; - case OS_ACTIVITY_STREAM_EVENT_STOPPED: - break; - case OS_ACTIVITY_STREAM_EVENT_FAILED: - break; - case OS_ACTIVITY_STREAM_EVENT_CHUNK_STARTED: - break; - case OS_ACTIVITY_STREAM_EVENT_CHUNK_FINISHED: - break; - default: - printf("=== Unhandled case ===\n"); - break; - } - } copy]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.h deleted file mode 100644 index 4fdc629e..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// FLEXSystemLogCell.h -// FLEX -// -// Created by Ryan Olson on 1/25/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewCell.h" - -@class FLEXSystemLogMessage; - -extern NSString *const kFLEXSystemLogCellIdentifier; - -@interface FLEXSystemLogCell : FLEXTableViewCell - -@property (nonatomic) FLEXSystemLogMessage *logMessage; -@property (nonatomic, copy) NSString *highlightedText; - -+ (NSString *)displayedTextForLogMessage:(FLEXSystemLogMessage *)logMessage; -+ (CGFloat)preferredHeightForLogMessage:(FLEXSystemLogMessage *)logMessage inWidth:(CGFloat)width; - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.m b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.m deleted file mode 100644 index 95cfbcde..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogCell.m +++ /dev/null @@ -1,119 +0,0 @@ -// -// FLEXSystemLogCell.m -// FLEX -// -// Created by Ryan Olson on 1/25/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSystemLogCell.h" -#import "FLEXSystemLogMessage.h" -#import "UIFont+FLEX.h" - -NSString *const kFLEXSystemLogCellIdentifier = @"FLEXSystemLogCellIdentifier"; - -@interface FLEXSystemLogCell () - -@property (nonatomic) UILabel *logMessageLabel; -@property (nonatomic) NSAttributedString *logMessageAttributedText; - -@end - -@implementation FLEXSystemLogCell - -- (void)postInit { - [super postInit]; - - self.logMessageLabel = [UILabel new]; - self.logMessageLabel.numberOfLines = 0; - self.separatorInset = UIEdgeInsetsZero; - self.selectionStyle = UITableViewCellSelectionStyleNone; - [self.contentView addSubview:self.logMessageLabel]; -} - -- (void)setLogMessage:(FLEXSystemLogMessage *)logMessage { - if (![_logMessage isEqual:logMessage]) { - _logMessage = logMessage; - self.logMessageAttributedText = nil; - [self setNeedsLayout]; - } -} - -- (void)setHighlightedText:(NSString *)highlightedText { - if (![_highlightedText isEqual:highlightedText]) { - _highlightedText = highlightedText; - self.logMessageAttributedText = nil; - [self setNeedsLayout]; - } -} - -- (NSAttributedString *)logMessageAttributedText { - if (!_logMessageAttributedText) { - _logMessageAttributedText = [[self class] attributedTextForLogMessage:self.logMessage highlightedText:self.highlightedText]; - } - return _logMessageAttributedText; -} - -static const UIEdgeInsets kFLEXLogMessageCellInsets = {10.0, 10.0, 10.0, 10.0}; - -- (void)layoutSubviews { - [super layoutSubviews]; - - self.logMessageLabel.attributedText = self.logMessageAttributedText; - self.logMessageLabel.frame = UIEdgeInsetsInsetRect(self.contentView.bounds, kFLEXLogMessageCellInsets); -} - - -#pragma mark - Stateless helpers - -+ (NSAttributedString *)attributedTextForLogMessage:(FLEXSystemLogMessage *)logMessage highlightedText:(NSString *)highlightedText { - NSString *text = [self displayedTextForLogMessage:logMessage]; - NSDictionary *attributes = @{ NSFontAttributeName : UIFont.flex_codeFont }; - NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:attributes]; - - if (highlightedText.length > 0) { - NSMutableAttributedString *mutableAttributedText = attributedText.mutableCopy; - NSMutableDictionary *highlightAttributes = attributes.mutableCopy; - highlightAttributes[NSBackgroundColorAttributeName] = UIColor.yellowColor; - - NSRange remainingSearchRange = NSMakeRange(0, text.length); - while (remainingSearchRange.location < text.length) { - remainingSearchRange.length = text.length - remainingSearchRange.location; - NSRange foundRange = [text rangeOfString:highlightedText options:NSCaseInsensitiveSearch range:remainingSearchRange]; - if (foundRange.location != NSNotFound) { - remainingSearchRange.location = foundRange.location + foundRange.length; - [mutableAttributedText setAttributes:highlightAttributes range:foundRange]; - } else { - break; - } - } - attributedText = mutableAttributedText; - } - - return attributedText; -} - -+ (NSString *)displayedTextForLogMessage:(FLEXSystemLogMessage *)logMessage { - return [NSString stringWithFormat:@"%@: %@", [self logTimeStringFromDate:logMessage.date], logMessage.messageText]; -} - -+ (CGFloat)preferredHeightForLogMessage:(FLEXSystemLogMessage *)logMessage inWidth:(CGFloat)width { - UIEdgeInsets insets = kFLEXLogMessageCellInsets; - CGFloat availableWidth = width - insets.left - insets.right; - NSAttributedString *attributedLogText = [self attributedTextForLogMessage:logMessage highlightedText:nil]; - CGSize labelSize = [attributedLogText boundingRectWithSize:CGSizeMake(availableWidth, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading context:nil].size; - return labelSize.height + insets.top + insets.bottom; -} - -+ (NSString *)logTimeStringFromDate:(NSDate *)date { - static NSDateFormatter *formatter = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - formatter = [NSDateFormatter new]; - formatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; - }); - - return [formatter stringFromDate:date]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h deleted file mode 100644 index 4976eacd..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// FLEXSystemLogMessage.h -// FLEX -// -// Created by Ryan Olson on 1/25/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import -#import "ActivityStreamAPI.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXSystemLogMessage : NSObject - -+ (instancetype)logMessageFromASLMessage:(aslmsg)aslMessage; -+ (instancetype)logMessageFromDate:(NSDate *)date text:(NSString *)text; - -// ASL specific properties -@property (nonatomic, readonly, nullable) NSString *sender; -@property (nonatomic, readonly, nullable) aslmsg aslMessage; - -@property (nonatomic, readonly) NSDate *date; -@property (nonatomic, readonly) NSString *messageText; -@property (nonatomic, readonly) long long messageID; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m deleted file mode 100644 index 98f9e05f..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogMessage.m +++ /dev/null @@ -1,88 +0,0 @@ -// -// FLEXSystemLogMessage.m -// FLEX -// -// Created by Ryan Olson on 1/25/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSystemLogMessage.h" - -@implementation FLEXSystemLogMessage - -+ (instancetype)logMessageFromASLMessage:(aslmsg)aslMessage { - NSDate *date = nil; - NSString *sender = nil, *text = nil; - long long identifier = 0; - - const char *timestamp = asl_get(aslMessage, ASL_KEY_TIME); - if (timestamp) { - NSTimeInterval timeInterval = [@(timestamp) integerValue]; - const char *nanoseconds = asl_get(aslMessage, ASL_KEY_TIME_NSEC); - if (nanoseconds) { - timeInterval += [@(nanoseconds) doubleValue] / NSEC_PER_SEC; - } - date = [NSDate dateWithTimeIntervalSince1970:timeInterval]; - } - - const char *s = asl_get(aslMessage, ASL_KEY_SENDER); - if (s) { - sender = @(s); - } - - const char *messageText = asl_get(aslMessage, ASL_KEY_MSG); - if (messageText) { - text = @(messageText); - } - - const char *messageID = asl_get(aslMessage, ASL_KEY_MSG_ID); - if (messageID) { - identifier = [@(messageID) longLongValue]; - } - - FLEXSystemLogMessage *message = [[self alloc] initWithDate:date sender:sender text:text messageID:identifier]; - message->_aslMessage = aslMessage; - return message; -} - -+ (instancetype)logMessageFromDate:(NSDate *)date text:(NSString *)text { - return [[self alloc] initWithDate:date sender:nil text:text messageID:0]; -} - -- (id)initWithDate:(NSDate *)date sender:(NSString *)sender text:(NSString *)text messageID:(long long)identifier { - self = [super init]; - if (self) { - _date = date; - _sender = sender; - _messageText = text; - _messageID = identifier; - } - - return self; -} - -- (BOOL)isEqual:(id)object { - if ([object isKindOfClass:[self class]]) { - if (self.messageID) { - // Only ASL uses messageID, otherwise it is 0 - return self.messageID == [object messageID]; - } else { - // Test message texts and dates for OS Log - return [self.messageText isEqual:[object messageText]] && - [self.date isEqualToDate:[object date]]; - } - } - - return NO; -} - -- (NSUInteger)hash { - return (NSUInteger)self.messageID; -} - -- (NSString *)description { - NSString *escaped = [self.messageText stringByReplacingOccurrencesOfString:@"\n" withString:@"\\n"]; - return [NSString stringWithFormat:@"(%@) %@", @(self.messageText.length), escaped]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.h b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.h deleted file mode 100644 index 59ce054e..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXSystemLogViewController.h -// FLEX -// -// Created by Ryan Olson on 1/19/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXFilteringTableViewController.h" -#import "FLEXGlobalsEntry.h" - -@interface FLEXSystemLogViewController : FLEXFilteringTableViewController - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.m b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.m deleted file mode 100644 index c727a14b..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/FLEXSystemLogViewController.m +++ /dev/null @@ -1,287 +0,0 @@ -// -// FLEXSystemLogViewController.m -// FLEX -// -// Created by Ryan Olson on 1/19/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSystemLogViewController.h" -#import "FLEXASLLogController.h" -#import "FLEXOSLogController.h" -#import "FLEXSystemLogCell.h" -#import "FLEXMutableListSection.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" -#import "FLEXResources.h" -#import "UIBarButtonItem+FLEX.h" -#import "NSUserDefaults+FLEX.h" -#import "flex_fishhook.h" -#import - -@interface FLEXSystemLogViewController () - -@property (nonatomic, readonly) FLEXMutableListSection *logMessages; -@property (nonatomic, readonly) id logController; - -@end - -static void (*MSHookFunction)(void *symbol, void *replace, void **result); - -static BOOL FLEXDidHookNSLog = NO; -static BOOL FLEXNSLogHookWorks = NO; - -BOOL (*os_log_shim_enabled)(void *addr) = nil; -BOOL (*orig_os_log_shim_enabled)(void *addr) = nil; -static BOOL my_os_log_shim_enabled(void *addr) { - return NO; -} - -@implementation FLEXSystemLogViewController - -#pragma mark - Initialization - -+ (void)load { - // User must opt-into disabling os_log - if (!NSUserDefaults.standardUserDefaults.flex_disableOSLog) { - return; - } - - // Thanks to @Ram4096 on GitHub for telling me that - // os_log is conditionally enabled by the SDK version - void *addr = __builtin_return_address(0); - void *libsystem_trace = dlopen("/usr/lib/system/libsystem_trace.dylib", RTLD_LAZY); - os_log_shim_enabled = dlsym(libsystem_trace, "os_log_shim_enabled"); - if (!os_log_shim_enabled) { - return; - } - - FLEXDidHookNSLog = flex_rebind_symbols((struct rebinding[1]) {{ - "os_log_shim_enabled", - (void *)my_os_log_shim_enabled, - (void **)&orig_os_log_shim_enabled - }}, 1) == 0; - - if (FLEXDidHookNSLog && orig_os_log_shim_enabled != nil) { - // Check if our rebinding worked - FLEXNSLogHookWorks = my_os_log_shim_enabled(addr) == NO; - } - - // So, just because we rebind the lazily loaded symbol for - // this function doesn't mean it's even going to be used. - // While it seems to be sufficient for the simulator, for - // whatever reason it is not sufficient on-device. We need - // to actually hook the function with something like Substrate. - - // Check if we have substrate, and if so use that instead - void *handle = dlopen("/usr/lib/libsubstrate.dylib", RTLD_LAZY); - if (handle) { - MSHookFunction = dlsym(handle, "MSHookFunction"); - - if (MSHookFunction) { - // Set the hook and check if it worked - void *unused; - MSHookFunction(os_log_shim_enabled, my_os_log_shim_enabled, &unused); - FLEXNSLogHookWorks = os_log_shim_enabled(addr) == NO; - } - } -} - -- (id)init { - return [super initWithStyle:UITableViewStylePlain]; -} - - -#pragma mark - Overrides - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; - self.showSearchBarInitially = NO; - - weakify(self) - id logHandler = ^(NSArray *newMessages) { strongify(self) - [self handleUpdateWithNewMessages:newMessages]; - }; - - if (FLEXOSLogAvailable() && !FLEXNSLogHookWorks) { - _logController = [FLEXOSLogController withUpdateHandler:logHandler]; - } else { - _logController = [FLEXASLLogController withUpdateHandler:logHandler]; - } - - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - self.title = @"Waiting for Logs..."; - - // Toolbar buttons // - - UIBarButtonItem *scrollDown = [UIBarButtonItem - flex_itemWithImage:FLEXResources.scrollToBottomIcon - target:self - action:@selector(scrollToLastRow) - ]; - UIBarButtonItem *settings = [UIBarButtonItem - flex_itemWithImage:FLEXResources.gearIcon - target:self - action:@selector(showLogSettings) - ]; - - [self addToolbarItems:@[scrollDown, settings]]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [self.logController startMonitoring]; -} - -- (NSArray *)makeSections { weakify(self) - _logMessages = [FLEXMutableListSection list:@[] - cellConfiguration:^(FLEXSystemLogCell *cell, FLEXSystemLogMessage *message, NSInteger row) { - strongify(self) - - cell.logMessage = message; - cell.highlightedText = self.filterText; - - if (row % 2 == 0) { - cell.backgroundColor = FLEXColor.primaryBackgroundColor; - } else { - cell.backgroundColor = FLEXColor.secondaryBackgroundColor; - } - } filterMatcher:^BOOL(NSString *filterText, FLEXSystemLogMessage *message) { - NSString *displayedText = [FLEXSystemLogCell displayedTextForLogMessage:message]; - return [displayedText localizedCaseInsensitiveContainsString:filterText]; - } - ]; - - self.logMessages.cellRegistrationMapping = @{ - kFLEXSystemLogCellIdentifier : [FLEXSystemLogCell class] - }; - - return @[self.logMessages]; -} - -- (NSArray *)nonemptySections { - return @[self.logMessages]; -} - - -#pragma mark - Private - -- (void)handleUpdateWithNewMessages:(NSArray *)newMessages { - self.title = [self.class globalsEntryTitle:FLEXGlobalsRowSystemLog]; - - [self.logMessages mutate:^(NSMutableArray *list) { - [list addObjectsFromArray:newMessages]; - }]; - - // "Follow" the log as new messages stream in if we were previously near the bottom. - BOOL wasNearBottom = self.tableView.contentOffset.y >= self.tableView.contentSize.height - self.tableView.frame.size.height - 100.0; - [self reloadData]; - if (wasNearBottom) { - [self scrollToLastRow]; - } -} - -- (void)scrollToLastRow { - NSInteger numberOfRows = [self.tableView numberOfRowsInSection:0]; - if (numberOfRows > 0) { - NSIndexPath *lastIndexPath = [NSIndexPath indexPathForRow:numberOfRows - 1 inSection:0]; - [self.tableView scrollToRowAtIndexPath:lastIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; - } -} - -- (void)showLogSettings { - NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; - BOOL disableOSLog = defaults.flex_disableOSLog; - BOOL persistent = defaults.flex_cacheOSLogMessages; - - NSString *aslToggle = disableOSLog ? @"Enable os_log (default)" : @"Disable os_log"; - NSString *persistence = persistent ? @"Disable persistent logging" : @"Enable persistent logging"; - - NSString *title = @"System Log Settings"; - NSString *body = @"In iOS 10 and up, ASL has been replaced by os_log. " - "The os_log API is much more limited. Below, you can opt-into the old behavior " - "if you want cleaner, more reliable logs within FLEX, but this will break " - "anything that expects os_log to be working, such as Console.app. " - "This setting requires the app to restart to take effect. \n\n" - - "To get as close to the old behavior as possible with os_log enabled, logs must " - "be collected manually at launch and stored. This setting has no effect " - "on iOS 9 and below, or if os_log is disabled. " - "You should only enable persistent logging when you need it."; - - FLEXOSLogController *logController = (FLEXOSLogController *)self.logController; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(title).message(body); - make.button(aslToggle).destructiveStyle().handler(^(NSArray *strings) { - [defaults flex_toggleBoolForKey:kFLEXDefaultsDisableOSLogForceASLKey]; - }); - - make.button(persistence).handler(^(NSArray *strings) { - [defaults flex_toggleBoolForKey:kFLEXDefaultsiOSPersistentOSLogKey]; - logController.persistent = !persistent; - [logController.messages addObjectsFromArray:self.logMessages.list]; - }); - make.button(@"Dismiss").cancelStyle(); - } showFrom:self]; -} - - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"⚠️ System Log"; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - return [self new]; -} - - -#pragma mark - Table view data source - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXSystemLogMessage *logMessage = self.logMessages.filteredList[indexPath.row]; - return [FLEXSystemLogCell preferredHeightForLogMessage:logMessage inWidth:self.tableView.bounds.size.width]; -} - - -#pragma mark - Copy on long press - -- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - return action == @selector(copy:); -} - -- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - if (action == @selector(copy:)) { - // We usually only want to copy the log message itself, not any metadata associated with it. - UIPasteboard.generalPasteboard.string = self.logMessages.filteredList[indexPath.row].messageText ?: @""; - } -} - -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView -contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath - point:(CGPoint)point __IOS_AVAILABLE(13.0) { - weakify(self) - return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil - actionProvider:^UIMenu *(NSArray *suggestedActions) { - UIAction *copy = [UIAction actionWithTitle:@"Copy" - image:nil - identifier:@"Copy" - handler:^(UIAction *action) { strongify(self) - // We usually only want to copy the log message itself, not any metadata associated with it. - UIPasteboard.generalPasteboard.string = self.logMessages.filteredList[indexPath.row].messageText ?: @""; - }]; - return [UIMenu menuWithTitle:@"" image:nil identifier:nil options:UIMenuOptionsDisplayInline children:@[copy]]; - } - ]; -} - -@end diff --git a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/LLVM_LICENSE.TXT b/BHTwitter/Classes/GlobalStateExplorers/SystemLog/LLVM_LICENSE.TXT deleted file mode 100644 index 029b1d9a..00000000 --- a/BHTwitter/Classes/GlobalStateExplorers/SystemLog/LLVM_LICENSE.TXT +++ /dev/null @@ -1,276 +0,0 @@ -============================================================================== -The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: -============================================================================== - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ----- LLVM Exceptions to the Apache 2.0 License ---- - -As an exception, if, as a result of your compiling your source code, portions -of this Software are embedded into an Object form of such source code, you -may redistribute such embedded portions in such Object form without complying -with the conditions of Sections 4(a), 4(b) and 4(d) of the License. - -In addition, if you combine or link compiled forms of this Software with -software that is licensed under the GPLv2 ("Combined Software") and if a -court of competent jurisdiction determines that the patent provision (Section -3), the indemnity provision (Section 9) or other Section of the License -conflicts with the conditions of the GPLv2, you may retroactively and -prospectively choose to deem waived or otherwise exclude such Section(s) of -the License, but only in their entirety and only with respect to the Combined -Software. - -============================================================================== -Software from third parties included in the LLVM Project: -============================================================================== -The LLVM Project contains third party software which is under different license -terms. All such code will be identified clearly using at least one of two -mechanisms: -1) It will be in a separate directory tree with its own `LICENSE.txt` or - `LICENSE` file at the top containing the specific license and restrictions - which apply to that software, or -2) It will contain specific license and restriction terms at the top of every - file. - -============================================================================== -Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): -============================================================================== -University of Illinois/NCSA -Open Source License - -Copyright (c) 2010 Apple Inc. -All rights reserved. - -Developed by: - - LLDB Team - - http://lldb.llvm.org/ - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal with -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimers. - - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimers in the - documentation and/or other materials provided with the distribution. - - * Neither the names of the LLDB Team, copyright holders, nor the names of - its contributors may be used to endorse or promote products derived from - this Software without specific prior written permission. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE -SOFTWARE. - diff --git a/BHTwitter/Classes/Headers/CALayer+FLEX.h b/BHTwitter/Classes/Headers/CALayer+FLEX.h deleted file mode 120000 index fbfd906e..00000000 --- a/BHTwitter/Classes/Headers/CALayer+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/CALayer+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEX-Categories.h b/BHTwitter/Classes/Headers/FLEX-Categories.h deleted file mode 120000 index 11e18d16..00000000 --- a/BHTwitter/Classes/Headers/FLEX-Categories.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/FLEX-Categories.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEX-Core.h b/BHTwitter/Classes/Headers/FLEX-Core.h deleted file mode 120000 index 0cad9351..00000000 --- a/BHTwitter/Classes/Headers/FLEX-Core.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/FLEX-Core.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEX-ObjectExploring.h b/BHTwitter/Classes/Headers/FLEX-ObjectExploring.h deleted file mode 120000 index 5736d397..00000000 --- a/BHTwitter/Classes/Headers/FLEX-ObjectExploring.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/FLEX-ObjectExploring.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEX-Runtime.h b/BHTwitter/Classes/Headers/FLEX-Runtime.h deleted file mode 120000 index 62855bb8..00000000 --- a/BHTwitter/Classes/Headers/FLEX-Runtime.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/FLEX-Runtime.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEX.h b/BHTwitter/Classes/Headers/FLEX.h deleted file mode 120000 index 738206d1..00000000 --- a/BHTwitter/Classes/Headers/FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXAlert.h b/BHTwitter/Classes/Headers/FLEXAlert.h deleted file mode 120000 index 547ff864..00000000 --- a/BHTwitter/Classes/Headers/FLEXAlert.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/FLEXAlert.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXBlockDescription.h b/BHTwitter/Classes/Headers/FLEXBlockDescription.h deleted file mode 120000 index fd4faaea..00000000 --- a/BHTwitter/Classes/Headers/FLEXBlockDescription.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXClassBuilder.h b/BHTwitter/Classes/Headers/FLEXClassBuilder.h deleted file mode 120000 index ea432a0f..00000000 --- a/BHTwitter/Classes/Headers/FLEXClassBuilder.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXCodeFontCell.h b/BHTwitter/Classes/Headers/FLEXCodeFontCell.h deleted file mode 120000 index 00e66cdc..00000000 --- a/BHTwitter/Classes/Headers/FLEXCodeFontCell.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/Cells/FLEXCodeFontCell.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXCollectionContentSection.h b/BHTwitter/Classes/Headers/FLEXCollectionContentSection.h deleted file mode 120000 index aced8cdb..00000000 --- a/BHTwitter/Classes/Headers/FLEXCollectionContentSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXColorPreviewSection.h b/BHTwitter/Classes/Headers/FLEXColorPreviewSection.h deleted file mode 120000 index e55ab3ab..00000000 --- a/BHTwitter/Classes/Headers/FLEXColorPreviewSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXDefaultsContentSection.h b/BHTwitter/Classes/Headers/FLEXDefaultsContentSection.h deleted file mode 120000 index 4932c598..00000000 --- a/BHTwitter/Classes/Headers/FLEXDefaultsContentSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXExplorerToolbar.h b/BHTwitter/Classes/Headers/FLEXExplorerToolbar.h deleted file mode 120000 index 80c18679..00000000 --- a/BHTwitter/Classes/Headers/FLEXExplorerToolbar.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Toolbar/FLEXExplorerToolbar.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXExplorerToolbarItem.h b/BHTwitter/Classes/Headers/FLEXExplorerToolbarItem.h deleted file mode 120000 index bdc71550..00000000 --- a/BHTwitter/Classes/Headers/FLEXExplorerToolbarItem.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Toolbar/FLEXExplorerToolbarItem.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXFilteringTableViewController.h b/BHTwitter/Classes/Headers/FLEXFilteringTableViewController.h deleted file mode 120000 index fbb2e5db..00000000 --- a/BHTwitter/Classes/Headers/FLEXFilteringTableViewController.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Controllers/FLEXFilteringTableViewController.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXGlobalsEntry.h b/BHTwitter/Classes/Headers/FLEXGlobalsEntry.h deleted file mode 120000 index f3c80b09..00000000 --- a/BHTwitter/Classes/Headers/FLEXGlobalsEntry.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/GlobalStateExplorers/Globals/FLEXGlobalsEntry.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXIvar.h b/BHTwitter/Classes/Headers/FLEXIvar.h deleted file mode 120000 index 6c61cd32..00000000 --- a/BHTwitter/Classes/Headers/FLEXIvar.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXKeyValueTableViewCell.h b/BHTwitter/Classes/Headers/FLEXKeyValueTableViewCell.h deleted file mode 120000 index 4a887f7b..00000000 --- a/BHTwitter/Classes/Headers/FLEXKeyValueTableViewCell.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/Cells/FLEXKeyValueTableViewCell.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMacros.h b/BHTwitter/Classes/Headers/FLEXMacros.h deleted file mode 120000 index fff2f7a9..00000000 --- a/BHTwitter/Classes/Headers/FLEXMacros.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/FLEXMacros.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXManager+Extensibility.h b/BHTwitter/Classes/Headers/FLEXManager+Extensibility.h deleted file mode 120000 index d4ce0e78..00000000 --- a/BHTwitter/Classes/Headers/FLEXManager+Extensibility.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Manager/FLEXManager+Extensibility.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXManager+Networking.h b/BHTwitter/Classes/Headers/FLEXManager+Networking.h deleted file mode 120000 index eee45aee..00000000 --- a/BHTwitter/Classes/Headers/FLEXManager+Networking.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Manager/FLEXManager+Networking.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXManager.h b/BHTwitter/Classes/Headers/FLEXManager.h deleted file mode 120000 index f041bb6c..00000000 --- a/BHTwitter/Classes/Headers/FLEXManager.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Manager/FLEXManager.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMetadataSection.h b/BHTwitter/Classes/Headers/FLEXMetadataSection.h deleted file mode 120000 index bc6f4ed8..00000000 --- a/BHTwitter/Classes/Headers/FLEXMetadataSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXMetadataSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMethod.h b/BHTwitter/Classes/Headers/FLEXMethod.h deleted file mode 120000 index 9c817b80..00000000 --- a/BHTwitter/Classes/Headers/FLEXMethod.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMethodBase.h b/BHTwitter/Classes/Headers/FLEXMethodBase.h deleted file mode 120000 index 5031eed3..00000000 --- a/BHTwitter/Classes/Headers/FLEXMethodBase.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMirror.h b/BHTwitter/Classes/Headers/FLEXMirror.h deleted file mode 120000 index c3a34f17..00000000 --- a/BHTwitter/Classes/Headers/FLEXMirror.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMultilineTableViewCell.h b/BHTwitter/Classes/Headers/FLEXMultilineTableViewCell.h deleted file mode 120000 index 46c14ced..00000000 --- a/BHTwitter/Classes/Headers/FLEXMultilineTableViewCell.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/Cells/FLEXMultilineTableViewCell.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXMutableListSection.h b/BHTwitter/Classes/Headers/FLEXMutableListSection.h deleted file mode 120000 index bab3c7d6..00000000 --- a/BHTwitter/Classes/Headers/FLEXMutableListSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXMutableListSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXNavigationController.h b/BHTwitter/Classes/Headers/FLEXNavigationController.h deleted file mode 120000 index 650cdc4f..00000000 --- a/BHTwitter/Classes/Headers/FLEXNavigationController.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Controllers/FLEXNavigationController.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXObjcInternal.h b/BHTwitter/Classes/Headers/FLEXObjcInternal.h deleted file mode 120000 index 448469d3..00000000 --- a/BHTwitter/Classes/Headers/FLEXObjcInternal.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/FLEXObjcInternal.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXObjectExplorer.h b/BHTwitter/Classes/Headers/FLEXObjectExplorer.h deleted file mode 120000 index b22a3e12..00000000 --- a/BHTwitter/Classes/Headers/FLEXObjectExplorer.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/FLEXObjectExplorer.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXObjectExplorerFactory.h b/BHTwitter/Classes/Headers/FLEXObjectExplorerFactory.h deleted file mode 120000 index d14e8306..00000000 --- a/BHTwitter/Classes/Headers/FLEXObjectExplorerFactory.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/FLEXObjectExplorerFactory.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXObjectExplorerViewController.h b/BHTwitter/Classes/Headers/FLEXObjectExplorerViewController.h deleted file mode 120000 index 21539ef5..00000000 --- a/BHTwitter/Classes/Headers/FLEXObjectExplorerViewController.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/FLEXObjectExplorerViewController.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXObjectInfoSection.h b/BHTwitter/Classes/Headers/FLEXObjectInfoSection.h deleted file mode 120000 index cdd9f596..00000000 --- a/BHTwitter/Classes/Headers/FLEXObjectInfoSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/FLEXObjectInfoSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXProperty.h b/BHTwitter/Classes/Headers/FLEXProperty.h deleted file mode 120000 index e3167abc..00000000 --- a/BHTwitter/Classes/Headers/FLEXProperty.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXPropertyAttributes.h b/BHTwitter/Classes/Headers/FLEXPropertyAttributes.h deleted file mode 120000 index 539e138e..00000000 --- a/BHTwitter/Classes/Headers/FLEXPropertyAttributes.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXProtocol.h b/BHTwitter/Classes/Headers/FLEXProtocol.h deleted file mode 120000 index a6d227c0..00000000 --- a/BHTwitter/Classes/Headers/FLEXProtocol.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXProtocolBuilder.h b/BHTwitter/Classes/Headers/FLEXProtocolBuilder.h deleted file mode 120000 index 962f66a8..00000000 --- a/BHTwitter/Classes/Headers/FLEXProtocolBuilder.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXResources.h b/BHTwitter/Classes/Headers/FLEXResources.h deleted file mode 120000 index 12a95c40..00000000 --- a/BHTwitter/Classes/Headers/FLEXResources.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/FLEXResources.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXRuntime+Compare.h b/BHTwitter/Classes/Headers/FLEXRuntime+Compare.h deleted file mode 120000 index 9ddeefdb..00000000 --- a/BHTwitter/Classes/Headers/FLEXRuntime+Compare.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/FLEXRuntime+Compare.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXRuntime+UIKitHelpers.h b/BHTwitter/Classes/Headers/FLEXRuntime+UIKitHelpers.h deleted file mode 120000 index 82208fb3..00000000 --- a/BHTwitter/Classes/Headers/FLEXRuntime+UIKitHelpers.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXRuntimeConstants.h b/BHTwitter/Classes/Headers/FLEXRuntimeConstants.h deleted file mode 120000 index aad5f99d..00000000 --- a/BHTwitter/Classes/Headers/FLEXRuntimeConstants.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXRuntimeSafety.h b/BHTwitter/Classes/Headers/FLEXRuntimeSafety.h deleted file mode 120000 index 704ed2c5..00000000 --- a/BHTwitter/Classes/Headers/FLEXRuntimeSafety.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXShortcut.h b/BHTwitter/Classes/Headers/FLEXShortcut.h deleted file mode 120000 index d9750566..00000000 --- a/BHTwitter/Classes/Headers/FLEXShortcut.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXShortcutsSection.h b/BHTwitter/Classes/Headers/FLEXShortcutsSection.h deleted file mode 120000 index 790d7d57..00000000 --- a/BHTwitter/Classes/Headers/FLEXShortcutsSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXSingleRowSection.h b/BHTwitter/Classes/Headers/FLEXSingleRowSection.h deleted file mode 120000 index 9cb1dca5..00000000 --- a/BHTwitter/Classes/Headers/FLEXSingleRowSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/FLEXSingleRowSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXSubtitleTableViewCell.h b/BHTwitter/Classes/Headers/FLEXSubtitleTableViewCell.h deleted file mode 120000 index c74e04d1..00000000 --- a/BHTwitter/Classes/Headers/FLEXSubtitleTableViewCell.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/Cells/FLEXSubtitleTableViewCell.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXTableView.h b/BHTwitter/Classes/Headers/FLEXTableView.h deleted file mode 120000 index 8fa2fb45..00000000 --- a/BHTwitter/Classes/Headers/FLEXTableView.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/FLEXTableView.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXTableViewCell.h b/BHTwitter/Classes/Headers/FLEXTableViewCell.h deleted file mode 120000 index 3c5fdea9..00000000 --- a/BHTwitter/Classes/Headers/FLEXTableViewCell.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Views/Cells/FLEXTableViewCell.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXTableViewController.h b/BHTwitter/Classes/Headers/FLEXTableViewController.h deleted file mode 120000 index 7072001e..00000000 --- a/BHTwitter/Classes/Headers/FLEXTableViewController.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/Controllers/FLEXTableViewController.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXTableViewSection.h b/BHTwitter/Classes/Headers/FLEXTableViewSection.h deleted file mode 120000 index 66415a82..00000000 --- a/BHTwitter/Classes/Headers/FLEXTableViewSection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Core/FLEXTableViewSection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/FLEXTypeEncodingParser.h b/BHTwitter/Classes/Headers/FLEXTypeEncodingParser.h deleted file mode 120000 index e4b250ac..00000000 --- a/BHTwitter/Classes/Headers/FLEXTypeEncodingParser.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/NSArray+FLEX.h b/BHTwitter/Classes/Headers/NSArray+FLEX.h deleted file mode 120000 index 4144ec56..00000000 --- a/BHTwitter/Classes/Headers/NSArray+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/NSArray+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/NSObject+FLEX_Reflection.h b/BHTwitter/Classes/Headers/NSObject+FLEX_Reflection.h deleted file mode 120000 index c42b7306..00000000 --- a/BHTwitter/Classes/Headers/NSObject+FLEX_Reflection.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/NSObject+FLEX_Reflection.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/NSTimer+FLEX.h b/BHTwitter/Classes/Headers/NSTimer+FLEX.h deleted file mode 120000 index e67c534e..00000000 --- a/BHTwitter/Classes/Headers/NSTimer+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/NSTimer+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/NSUserDefaults+FLEX.h b/BHTwitter/Classes/Headers/NSUserDefaults+FLEX.h deleted file mode 120000 index a6ceabf3..00000000 --- a/BHTwitter/Classes/Headers/NSUserDefaults+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/NSUserDefaults+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UIBarButtonItem+FLEX.h b/BHTwitter/Classes/Headers/UIBarButtonItem+FLEX.h deleted file mode 120000 index db0238e0..00000000 --- a/BHTwitter/Classes/Headers/UIBarButtonItem+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UIBarButtonItem+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UIFont+FLEX.h b/BHTwitter/Classes/Headers/UIFont+FLEX.h deleted file mode 120000 index 5f16d848..00000000 --- a/BHTwitter/Classes/Headers/UIFont+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UIFont+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UIGestureRecognizer+Blocks.h b/BHTwitter/Classes/Headers/UIGestureRecognizer+Blocks.h deleted file mode 120000 index c8cc1a87..00000000 --- a/BHTwitter/Classes/Headers/UIGestureRecognizer+Blocks.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UIGestureRecognizer+Blocks.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UIMenu+FLEX.h b/BHTwitter/Classes/Headers/UIMenu+FLEX.h deleted file mode 120000 index a7b0c1ff..00000000 --- a/BHTwitter/Classes/Headers/UIMenu+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UIMenu+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UIPasteboard+FLEX.h b/BHTwitter/Classes/Headers/UIPasteboard+FLEX.h deleted file mode 120000 index 0c840bbf..00000000 --- a/BHTwitter/Classes/Headers/UIPasteboard+FLEX.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UIPasteboard+FLEX.h \ No newline at end of file diff --git a/BHTwitter/Classes/Headers/UITextField+Range.h b/BHTwitter/Classes/Headers/UITextField+Range.h deleted file mode 120000 index 52e8beaa..00000000 --- a/BHTwitter/Classes/Headers/UITextField+Range.h +++ /dev/null @@ -1 +0,0 @@ -../../Classes/Utility/Categories/UITextField+Range.h \ No newline at end of file diff --git a/BHTwitter/Classes/Manager/FLEXManager+Extensibility.h b/BHTwitter/Classes/Manager/FLEXManager+Extensibility.h deleted file mode 100644 index 1a71a0e3..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager+Extensibility.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// FLEXManager+Extensibility.h -// FLEX -// -// Created by Tanner on 2/2/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager.h" -#import "FLEXGlobalsEntry.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXManager (Extensibility) - -#pragma mark - Globals Screen Entries - -/// Adds an entry at the top of the list of Global State items. -/// Call this method before this view controller is displayed. -/// @param entryName The string to be displayed in the cell. -/// @param objectFutureBlock When you tap on the row, information about the object returned -/// by this block will be displayed. Passing a block that returns an object allows you to display -/// information about an object whose actual pointer may change at runtime (e.g. +currentUser) -/// @note This method must be called from the main thread. -/// The objectFutureBlock will be invoked from the main thread and may return nil. -/// @note The passed block will be copied and retain for the duration of the application, -/// you may want to use __weak references. -- (void)registerGlobalEntryWithName:(NSString *)entryName objectFutureBlock:(id (^)(void))objectFutureBlock; - -/// Adds an entry at the top of the list of Global State items. -/// Call this method before this view controller is displayed. -/// @param entryName The string to be displayed in the cell. -/// @param viewControllerFutureBlock When you tap on the row, view controller returned -/// by this block will be pushed on the navigation controller stack. -/// @note This method must be called from the main thread. -/// The viewControllerFutureBlock will be invoked from the main thread and may not return nil. -/// @note The passed block will be copied and retain for the duration of the application, -/// you may want to use __weak references as needed. -- (void)registerGlobalEntryWithName:(NSString *)entryName - viewControllerFutureBlock:(UIViewController * (^)(void))viewControllerFutureBlock; - -/// Adds an entry at the top of the list of Global State items. -/// @param entryName The string to be displayed in the cell. -/// @param rowSelectedAction When you tap on the row, this block will be invoked -/// with the host table view view controller. Use it to deselect the row or present an alert. -/// @note This method must be called from the main thread. -/// The rowSelectedAction will be invoked from the main thread. -/// @note The passed block will be copied and retain for the duration of the application, -/// you may want to use __weak references as needed. -- (void)registerGlobalEntryWithName:(NSString *)entryName action:(FLEXGlobalsEntryRowAction)rowSelectedAction; - -/// Removes all registered global entries. -- (void)clearGlobalEntries; - -#pragma mark - Simulator Shortcuts - -/// Simulator keyboard shortcuts are enabled by default. -/// The shortcuts will not fire when there is an active text field, text view, or other responder -/// accepting key input. You can disable keyboard shortcuts if you have existing keyboard shortcuts -/// that conflict with FLEX, or if you like doing things the hard way ;) -/// Keyboard shortcuts are always disabled (and support is #if'd out) in non-simulator builds -@property (nonatomic) BOOL simulatorShortcutsEnabled; - -/// Adds an action to run when the specified key & modifier combination is pressed -/// @param key A single character string matching a key on the keyboard -/// @param modifiers Modifier keys such as shift, command, or alt/option -/// @param action The block to run on the main thread when the key & modifier combination is recognized. -/// @param description Shown the the keyboard shortcut help menu, which is accessed via the '?' key. -/// @note The action block will be retained for the duration of the application. You may want to use weak references. -/// @note FLEX registers several default keyboard shortcuts. Use the '?' key to see a list of shortcuts. -- (void)registerSimulatorShortcutWithKey:(NSString *)key - modifiers:(UIKeyModifierFlags)modifiers - action:(dispatch_block_t)action - description:(NSString *)description; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Manager/FLEXManager+Extensibility.m b/BHTwitter/Classes/Manager/FLEXManager+Extensibility.m deleted file mode 100644 index ce79b6a9..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager+Extensibility.m +++ /dev/null @@ -1,272 +0,0 @@ -// -// FLEXManager+Extensibility.m -// FLEX -// -// Created by Tanner on 2/2/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager+Extensibility.h" -#import "FLEXManager+Private.h" -#import "FLEXNavigationController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXKeyboardShortcutManager.h" -#import "FLEXExplorerViewController.h" -#import "FLEXNetworkMITMViewController.h" -#import "FLEXKeyboardHelpViewController.h" -#import "FLEXFileBrowserController.h" -#import "FLEXUtility.h" - -@interface FLEXManager (ExtensibilityPrivate) -@property (nonatomic, readonly) UIViewController *topViewController; -@end - -@implementation FLEXManager (Extensibility) - -#pragma mark - Globals Screen Entries - -- (void)registerGlobalEntryWithName:(NSString *)entryName objectFutureBlock:(id (^)(void))objectFutureBlock { - NSParameterAssert(entryName); - NSParameterAssert(objectFutureBlock); - NSAssert(NSThread.isMainThread, @"This method must be called from the main thread."); - - entryName = entryName.copy; - FLEXGlobalsEntry *entry = [FLEXGlobalsEntry entryWithNameFuture:^NSString *{ - return entryName; - } viewControllerFuture:^UIViewController *{ - return [FLEXObjectExplorerFactory explorerViewControllerForObject:objectFutureBlock()]; - }]; - - [self.userGlobalEntries addObject:entry]; -} - -- (void)registerGlobalEntryWithName:(NSString *)entryName viewControllerFutureBlock:(UIViewController * (^)(void))viewControllerFutureBlock { - NSParameterAssert(entryName); - NSParameterAssert(viewControllerFutureBlock); - NSAssert(NSThread.isMainThread, @"This method must be called from the main thread."); - - entryName = entryName.copy; - FLEXGlobalsEntry *entry = [FLEXGlobalsEntry entryWithNameFuture:^NSString *{ - return entryName; - } viewControllerFuture:^UIViewController *{ - UIViewController *viewController = viewControllerFutureBlock(); - NSCAssert(viewController, @"'%@' entry returned nil viewController. viewControllerFutureBlock should never return nil.", entryName); - return viewController; - }]; - - [self.userGlobalEntries addObject:entry]; -} - -- (void)registerGlobalEntryWithName:(NSString *)entryName action:(FLEXGlobalsEntryRowAction)rowSelectedAction { - NSParameterAssert(entryName); - NSParameterAssert(rowSelectedAction); - NSAssert(NSThread.isMainThread, @"This method must be called from the main thread."); - - entryName = entryName.copy; - FLEXGlobalsEntry *entry = [FLEXGlobalsEntry entryWithNameFuture:^NSString * _Nonnull{ - return entryName; - } action:rowSelectedAction]; - - [self.userGlobalEntries addObject:entry]; -} - -- (void)clearGlobalEntries { - [self.userGlobalEntries removeAllObjects]; -} - - -#pragma mark - Simulator Shortcuts - -- (void)registerSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR - [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:YES]; -#endif -} - -- (void)setSimulatorShortcutsEnabled:(BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR - [FLEXKeyboardShortcutManager.sharedManager setEnabled:simulatorShortcutsEnabled]; -#endif -} - -- (BOOL)simulatorShortcutsEnabled { -#if TARGET_OS_SIMULATOR - return FLEXKeyboardShortcutManager.sharedManager.isEnabled; -#else - return NO; -#endif -} - - -#pragma mark - Shortcuts Defaults - -- (void)registerDefaultSimulatorShortcutWithKey:(NSString *)key modifiers:(UIKeyModifierFlags)modifiers action:(dispatch_block_t)action description:(NSString *)description { -#if TARGET_OS_SIMULATOR - // Don't allow override to avoid changing keys registered by the app - [FLEXKeyboardShortcutManager.sharedManager registerSimulatorShortcutWithKey:key modifiers:modifiers action:action description:description allowOverride:NO]; -#endif -} - -- (void)registerDefaultSimulatorShortcuts { - [self registerDefaultSimulatorShortcutWithKey:@"f" modifiers:0 action:^{ - [self toggleExplorer]; - } description:@"Toggle FLEX toolbar"]; - - [self registerDefaultSimulatorShortcutWithKey:@"g" modifiers:0 action:^{ - [self showExplorerIfNeeded]; - [self.explorerViewController toggleMenuTool]; - } description:@"Toggle FLEX globals menu"]; - - [self registerDefaultSimulatorShortcutWithKey:@"v" modifiers:0 action:^{ - [self showExplorerIfNeeded]; - [self.explorerViewController toggleViewsTool]; - } description:@"Toggle view hierarchy menu"]; - - [self registerDefaultSimulatorShortcutWithKey:@"s" modifiers:0 action:^{ - [self showExplorerIfNeeded]; - [self.explorerViewController toggleSelectTool]; - } description:@"Toggle select tool"]; - - [self registerDefaultSimulatorShortcutWithKey:@"m" modifiers:0 action:^{ - [self showExplorerIfNeeded]; - [self.explorerViewController toggleMoveTool]; - } description:@"Toggle move tool"]; - - [self registerDefaultSimulatorShortcutWithKey:@"n" modifiers:0 action:^{ - [self toggleTopViewControllerOfClass:[FLEXNetworkMITMViewController class]]; - } description:@"Toggle network history view"]; - - [self registerDefaultSimulatorShortcutWithKey:UIKeyInputDownArrow modifiers:0 action:^{ - if (self.isHidden || ![self.explorerViewController handleDownArrowKeyPressed]) { - [self tryScrollDown]; - } - } description:@"Cycle view selection\n\t\tMove view down\n\t\tScroll down"]; - - [self registerDefaultSimulatorShortcutWithKey:UIKeyInputUpArrow modifiers:0 action:^{ - if (self.isHidden || ![self.explorerViewController handleUpArrowKeyPressed]) { - [self tryScrollUp]; - } - } description:@"Cycle view selection\n\t\tMove view up\n\t\tScroll up"]; - - [self registerDefaultSimulatorShortcutWithKey:UIKeyInputRightArrow modifiers:0 action:^{ - if (!self.isHidden) { - [self.explorerViewController handleRightArrowKeyPressed]; - } - } description:@"Move selected view right"]; - - [self registerDefaultSimulatorShortcutWithKey:UIKeyInputLeftArrow modifiers:0 action:^{ - if (self.isHidden) { - [self tryGoBack]; - } else { - [self.explorerViewController handleLeftArrowKeyPressed]; - } - } description:@"Move selected view left"]; - - [self registerDefaultSimulatorShortcutWithKey:@"?" modifiers:0 action:^{ - [self toggleTopViewControllerOfClass:[FLEXKeyboardHelpViewController class]]; - } description:@"Toggle (this) help menu"]; - - [self registerDefaultSimulatorShortcutWithKey:UIKeyInputEscape modifiers:0 action:^{ - [[self.topViewController presentingViewController] dismissViewControllerAnimated:YES completion:nil]; - } description:@"End editing text\n\t\tDismiss top view controller"]; - - [self registerDefaultSimulatorShortcutWithKey:@"o" modifiers:UIKeyModifierCommand|UIKeyModifierShift action:^{ - [self toggleTopViewControllerOfClass:[FLEXFileBrowserController class]]; - } description:@"Toggle file browser menu"]; -} - -+ (void)load { - dispatch_async(dispatch_get_main_queue(), ^{ - [self.sharedManager registerDefaultSimulatorShortcuts]; - }); -} - - -#pragma mark - Private - -- (UIEdgeInsets)contentInsetsOfScrollView:(UIScrollView *)scrollView { - if (@available(iOS 11, *)) { - return scrollView.adjustedContentInset; - } - - return scrollView.contentInset; -} - -- (void)tryScrollDown { - UIScrollView *scrollview = [self firstScrollView]; - UIEdgeInsets insets = [self contentInsetsOfScrollView:scrollview]; - CGPoint contentOffset = scrollview.contentOffset; - CGFloat maxYOffset = scrollview.contentSize.height - scrollview.bounds.size.height + insets.bottom; - contentOffset.y = MIN(contentOffset.y + 200, maxYOffset); - [scrollview setContentOffset:contentOffset animated:YES]; -} - -- (void)tryScrollUp { - UIScrollView *scrollview = [self firstScrollView]; - UIEdgeInsets insets = [self contentInsetsOfScrollView:scrollview]; - CGPoint contentOffset = scrollview.contentOffset; - contentOffset.y = MAX(contentOffset.y - 200, -insets.top); - [scrollview setContentOffset:contentOffset animated:YES]; -} - -- (UIScrollView *)firstScrollView { - NSMutableArray *views = FLEXUtility.appKeyWindow.subviews.mutableCopy; - UIScrollView *scrollView = nil; - while (views.count > 0) { - UIView *view = views.firstObject; - [views removeObjectAtIndex:0]; - if ([view isKindOfClass:[UIScrollView class]]) { - scrollView = (UIScrollView *)view; - break; - } else { - [views addObjectsFromArray:view.subviews]; - } - } - return scrollView; -} - -- (void)tryGoBack { - UINavigationController *navigationController = nil; - UIViewController *topViewController = self.topViewController; - if ([topViewController isKindOfClass:[UINavigationController class]]) { - navigationController = (UINavigationController *)topViewController; - } else { - navigationController = topViewController.navigationController; - } - [navigationController popViewControllerAnimated:YES]; -} - -- (UIViewController *)topViewController { - return [FLEXUtility topViewControllerInWindow:UIApplication.sharedApplication.keyWindow]; -} - -- (void)toggleTopViewControllerOfClass:(Class)class { - UINavigationController *topViewController = (id)self.topViewController; - if ([topViewController isKindOfClass:[FLEXNavigationController class]]) { - if ([topViewController.topViewController isKindOfClass:[class class]]) { - if (topViewController.viewControllers.count == 1) { - // Dismiss since we are already presenting it - [topViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil]; - } else { - // Pop since we are viewing it but it's not the only thing on the stack - [topViewController popViewControllerAnimated:YES]; - } - } else { - // Push it on the existing navigation stack - [topViewController pushViewController:[class new] animated:YES]; - } - } else { - // Present it in an entirely new navigation controller - [self.explorerViewController presentViewController: - [FLEXNavigationController withRootViewController:[class new]] - animated:YES completion:nil]; - } -} - -- (void)showExplorerIfNeeded { - if (self.isHidden) { - [self showExplorer]; - } -} - -@end diff --git a/BHTwitter/Classes/Manager/FLEXManager+Networking.h b/BHTwitter/Classes/Manager/FLEXManager+Networking.h deleted file mode 100644 index 827d7f96..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager+Networking.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// FLEXManager+Networking.h -// FLEX -// -// Created by Tanner on 2/1/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXManager (Networking) - -/// If this property is set to YES, FLEX will swizzle NSURLConnection*Delegate and NSURLSession*Delegate methods -/// on classes that conform to the protocols. This allows you to view network activity history from the main FLEX menu. -/// Full responses are kept temporarily in a size-limited cache and may be pruned under memory pressure. -@property (nonatomic, getter=isNetworkDebuggingEnabled) BOOL networkDebuggingEnabled; - -/// Defaults to 25 MB if never set. Values set here are persisted across launches of the app. -/// The response cache uses an NSCache, so it may purge prior to hitting the limit when the app is under memory pressure. -@property (nonatomic) NSUInteger networkResponseCacheByteLimit; - -/// Requests whose host ends with one of the excluded entries in this array will be not be recorded (eg. google.com). -/// Wildcard or subdomain entries are not required (eg. google.com will match any subdomain under google.com). -/// Useful to remove requests that are typically noisy, such as analytics requests that you aren't interested in tracking. -@property (nonatomic) NSMutableArray *networkRequestHostDenylist; - -/// Sets custom viewer for specific content type. -/// @param contentType Mime type like application/json -/// @param viewControllerFutureBlock Viewer (view controller) creation block -/// @note This method must be called from the main thread. -/// The viewControllerFutureBlock will be invoked from the main thread and may not return nil. -/// @note The passed block will be copied and retain for the duration of the application, you may want to use __weak references. -- (void)setCustomViewerForContentType:(NSString *)contentType - viewControllerFutureBlock:(FLEXCustomContentViewerFuture)viewControllerFutureBlock; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Manager/FLEXManager+Networking.m b/BHTwitter/Classes/Manager/FLEXManager+Networking.m deleted file mode 100644 index a8cd15f4..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager+Networking.m +++ /dev/null @@ -1,68 +0,0 @@ -// -// FLEXManager+Networking.m -// FLEX -// -// Created by Tanner on 2/1/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager+Networking.h" -#import "FLEXManager+Private.h" -#import "FLEXNetworkObserver.h" -#import "FLEXNetworkRecorder.h" -#import "FLEXObjectExplorerFactory.h" -#import "NSUserDefaults+FLEX.h" - -@implementation FLEXManager (Networking) - -+ (void)load { - if (NSUserDefaults.standardUserDefaults.flex_registerDictionaryJSONViewerOnLaunch) { - dispatch_async(dispatch_get_main_queue(), ^{ - // Register array/dictionary viewer for JSON responses - [self.sharedManager setCustomViewerForContentType:@"application/json" - viewControllerFutureBlock:^UIViewController *(NSData *data) { - id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; - if (jsonObject) { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:jsonObject]; - } - return nil; - } - ]; - }); - } -} - -- (BOOL)isNetworkDebuggingEnabled { - return FLEXNetworkObserver.isEnabled; -} - -- (void)setNetworkDebuggingEnabled:(BOOL)networkDebuggingEnabled { - FLEXNetworkObserver.enabled = networkDebuggingEnabled; -} - -- (NSUInteger)networkResponseCacheByteLimit { - return FLEXNetworkRecorder.defaultRecorder.responseCacheByteLimit; -} - -- (void)setNetworkResponseCacheByteLimit:(NSUInteger)networkResponseCacheByteLimit { - FLEXNetworkRecorder.defaultRecorder.responseCacheByteLimit = networkResponseCacheByteLimit; -} - -- (NSMutableArray *)networkRequestHostDenylist { - return FLEXNetworkRecorder.defaultRecorder.hostDenylist; -} - -- (void)setNetworkRequestHostDenylist:(NSMutableArray *)networkRequestHostDenylist { - FLEXNetworkRecorder.defaultRecorder.hostDenylist = networkRequestHostDenylist; -} - -- (void)setCustomViewerForContentType:(NSString *)contentType - viewControllerFutureBlock:(FLEXCustomContentViewerFuture)viewControllerFutureBlock { - NSParameterAssert(contentType.length); - NSParameterAssert(viewControllerFutureBlock); - NSAssert(NSThread.isMainThread, @"This method must be called from the main thread."); - - self.customContentTypeViewers[contentType.lowercaseString] = viewControllerFutureBlock; -} - -@end diff --git a/BHTwitter/Classes/Manager/FLEXManager.h b/BHTwitter/Classes/Manager/FLEXManager.h deleted file mode 100644 index a413acc0..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// FLEXManager.h -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXExplorerToolbar.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXManager : NSObject - -@property (nonatomic, readonly, class) FLEXManager *sharedManager; - -@property (nonatomic, readonly) BOOL isHidden; -@property (nonatomic, readonly) FLEXExplorerToolbar *toolbar; - -- (void)showExplorer; -- (void)hideExplorer; -- (void)toggleExplorer; - -/// Programmatically dismiss anything presented by FLEX, leaving only the toolbar visible. -- (void)dismissAnyPresentedTools:(void (^_Nullable)(void))completion; -/// Programmatically present something on top of the FLEX toolbar. -/// This method will automatically dismiss any currently presented tool, -/// so you do not need to call \c dismissAnyPresentedTools: yourself. -- (void)presentTool:(UINavigationController *(^)(void))viewControllerFuture - completion:(void (^_Nullable)(void))completion; - -/// Use this to present the explorer in a specific scene when the one -/// it chooses by default is not the one you wish to display it in. -- (void)showExplorerFromScene:(UIWindowScene *)scene API_AVAILABLE(ios(13.0)); - -#pragma mark - Misc - -/// Default database password is @c nil by default. -/// Set this to the password you want the databases to open with. -@property (copy, nonatomic) NSString *defaultSqliteDatabasePassword; - -@end - - -typedef UIViewController * _Nullable(^FLEXCustomContentViewerFuture)(NSData *data); - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Manager/FLEXManager.m b/BHTwitter/Classes/Manager/FLEXManager.m deleted file mode 100644 index f0113568..00000000 --- a/BHTwitter/Classes/Manager/FLEXManager.m +++ /dev/null @@ -1,145 +0,0 @@ -// -// FLEXManager.m -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager.h" -#import "FLEXUtility.h" -#import "FLEXExplorerViewController.h" -#import "FLEXWindow.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXFileBrowserController.h" - -@interface FLEXManager () - -@property (nonatomic, readonly, getter=isHidden) BOOL hidden; - -@property (nonatomic) FLEXWindow *explorerWindow; -@property (nonatomic) FLEXExplorerViewController *explorerViewController; - -@property (nonatomic, readonly) NSMutableArray *userGlobalEntries; -@property (nonatomic, readonly) NSMutableDictionary *customContentTypeViewers; - -@end - -@implementation FLEXManager - -+ (instancetype)sharedManager { - static FLEXManager *sharedManager = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedManager = [self new]; - }); - return sharedManager; -} - -- (instancetype)init { - self = [super init]; - if (self) { - _userGlobalEntries = [NSMutableArray new]; - _customContentTypeViewers = [NSMutableDictionary new]; - } - return self; -} - -- (FLEXWindow *)explorerWindow { - NSAssert(NSThread.isMainThread, @"You must use %@ from the main thread only.", NSStringFromClass([self class])); - - if (!_explorerWindow) { - _explorerWindow = [[FLEXWindow alloc] initWithFrame:FLEXUtility.appKeyWindow.bounds]; - _explorerWindow.eventDelegate = self; - _explorerWindow.rootViewController = self.explorerViewController; - } - - return _explorerWindow; -} - -- (FLEXExplorerViewController *)explorerViewController { - if (!_explorerViewController) { - _explorerViewController = [FLEXExplorerViewController new]; - _explorerViewController.delegate = self; - } - - return _explorerViewController; -} - -- (void)showExplorer { - UIWindow *flex = self.explorerWindow; - flex.hidden = NO; - if (@available(iOS 13.0, *)) { - // Only look for a new scene if we don't have one - if (!flex.windowScene) { - flex.windowScene = FLEXUtility.appKeyWindow.windowScene; - } - } -} - -- (void)hideExplorer { - self.explorerWindow.hidden = YES; -} - -- (void)toggleExplorer { - if (self.explorerWindow.isHidden) { - if (@available(iOS 13.0, *)) { - [self showExplorerFromScene:FLEXUtility.appKeyWindow.windowScene]; - } else { - [self showExplorer]; - } - } else { - [self hideExplorer]; - } -} - -- (void)dismissAnyPresentedTools:(void (^)(void))completion { - if (self.explorerViewController.presentedViewController) { - [self.explorerViewController dismissViewControllerAnimated:YES completion:completion]; - } else if (completion) { - completion(); - } -} - -- (void)presentTool:(UINavigationController * _Nonnull (^)(void))future completion:(void (^)(void))completion { - [self showExplorer]; - [self.explorerViewController presentTool:future completion:completion]; -} - -- (void)showExplorerFromScene:(UIWindowScene *)scene { - if (@available(iOS 13.0, *)) { - self.explorerWindow.windowScene = scene; - } - self.explorerWindow.hidden = NO; -} - -- (BOOL)isHidden { - return self.explorerWindow.isHidden; -} - -- (FLEXExplorerToolbar *)toolbar { - return self.explorerViewController.explorerToolbar; -} - - -#pragma mark - FLEXWindowEventDelegate - -- (BOOL)shouldHandleTouchAtPoint:(CGPoint)pointInWindow { - // Ask the explorer view controller - return [self.explorerViewController shouldReceiveTouchAtWindowPoint:pointInWindow]; -} - -- (BOOL)canBecomeKeyWindow { - // Only when the explorer view controller wants it because - // it needs to accept key input & affect the status bar. - return self.explorerViewController.wantsWindowToBecomeKey; -} - - -#pragma mark - FLEXExplorerViewControllerDelegate - -- (void)explorerViewControllerDidFinish:(FLEXExplorerViewController *)explorerViewController { - [self hideExplorer]; -} - -@end diff --git a/BHTwitter/Classes/Manager/Private/FLEXManager+Private.h b/BHTwitter/Classes/Manager/Private/FLEXManager+Private.h deleted file mode 100644 index a4f5a913..00000000 --- a/BHTwitter/Classes/Manager/Private/FLEXManager+Private.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// FLEXManager+Private.h -// PebbleApp -// -// Created by Javier Soto on 7/26/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXManager.h" -#import "FLEXWindow.h" - -@class FLEXGlobalsEntry, FLEXExplorerViewController; - -@interface FLEXManager (Private) - -@property (nonatomic, readonly) FLEXWindow *explorerWindow; -@property (nonatomic, readonly) FLEXExplorerViewController *explorerViewController; - -/// An array of FLEXGlobalsEntry objects that have been registered by the user. -@property (nonatomic, readonly) NSMutableArray *userGlobalEntries; -@property (nonatomic, readonly) NSMutableDictionary *customContentTypeViewers; - -@end diff --git a/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.h b/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.h deleted file mode 100644 index 36390529..00000000 --- a/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXHTTPTransactionDetailController.h -// Flipboard -// -// Created by Ryan Olson on 2/10/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@class FLEXHTTPTransaction; - -@interface FLEXHTTPTransactionDetailController : UITableViewController - -+ (instancetype)withTransaction:(FLEXHTTPTransaction *)transaction; - -@end diff --git a/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.m b/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.m deleted file mode 100644 index 3e5684f7..00000000 --- a/BHTwitter/Classes/Network/FLEXHTTPTransactionDetailController.m +++ /dev/null @@ -1,535 +0,0 @@ -// -// FLEXNetworkTransactionDetailController.m -// Flipboard -// -// Created by Ryan Olson on 2/10/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXHTTPTransactionDetailController.h" -#import "FLEXNetworkCurlLogger.h" -#import "FLEXNetworkRecorder.h" -#import "FLEXNetworkTransaction.h" -#import "FLEXWebViewController.h" -#import "FLEXImagePreviewViewController.h" -#import "FLEXMultilineTableViewCell.h" -#import "FLEXUtility.h" -#import "FLEXManager+Private.h" -#import "FLEXTableView.h" -#import "UIBarButtonItem+FLEX.h" - -typedef UIViewController *(^FLEXNetworkDetailRowSelectionFuture)(void); - -@interface FLEXNetworkDetailRow : NSObject -@property (nonatomic, copy) NSString *title; -@property (nonatomic, copy) NSString *detailText; -@property (nonatomic, copy) FLEXNetworkDetailRowSelectionFuture selectionFuture; -@end - -@implementation FLEXNetworkDetailRow -@end - -@interface FLEXNetworkDetailSection : NSObject -@property (nonatomic, copy) NSString *title; -@property (nonatomic, copy) NSArray *rows; -@end - -@implementation FLEXNetworkDetailSection -@end - -@interface FLEXHTTPTransactionDetailController () - -@property (nonatomic, readonly) FLEXHTTPTransaction *transaction; -@property (nonatomic, copy) NSArray *sections; - -@end - -@implementation FLEXHTTPTransactionDetailController - -+ (instancetype)withTransaction:(FLEXHTTPTransaction *)transaction { - FLEXHTTPTransactionDetailController *controller = [self new]; - controller.transaction = transaction; - return controller; -} - -- (instancetype)initWithStyle:(UITableViewStyle)style { - // Force grouped style - return [super initWithStyle:UITableViewStyleGrouped]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - [NSNotificationCenter.defaultCenter addObserver:self - selector:@selector(handleTransactionUpdatedNotification:) - name:kFLEXNetworkRecorderTransactionUpdatedNotification - object:nil - ]; - self.toolbarItems = @[ - UIBarButtonItem.flex_flexibleSpace, - [UIBarButtonItem - flex_itemWithTitle:@"Copy curl" - target:self - action:@selector(copyButtonPressed:) - ] - ]; - - [self.tableView registerClass:[FLEXMultilineTableViewCell class] forCellReuseIdentifier:kFLEXMultilineCell]; -} - -- (void)setTransaction:(FLEXHTTPTransaction *)transaction { - if (![_transaction isEqual:transaction]) { - _transaction = transaction; - self.title = [transaction.request.URL lastPathComponent]; - [self rebuildTableSections]; - } -} - -- (void)setSections:(NSArray *)sections { - if (![_sections isEqual:sections]) { - _sections = [sections copy]; - [self.tableView reloadData]; - } -} - -- (void)rebuildTableSections { - NSMutableArray *sections = [NSMutableArray new]; - - FLEXNetworkDetailSection *generalSection = [[self class] generalSectionForTransaction:self.transaction]; - if (generalSection.rows.count > 0) { - [sections addObject:generalSection]; - } - FLEXNetworkDetailSection *requestHeadersSection = [[self class] requestHeadersSectionForTransaction:self.transaction]; - if (requestHeadersSection.rows.count > 0) { - [sections addObject:requestHeadersSection]; - } - FLEXNetworkDetailSection *queryParametersSection = [[self class] queryParametersSectionForTransaction:self.transaction]; - if (queryParametersSection.rows.count > 0) { - [sections addObject:queryParametersSection]; - } - FLEXNetworkDetailSection *postBodySection = [[self class] postBodySectionForTransaction:self.transaction]; - if (postBodySection.rows.count > 0) { - [sections addObject:postBodySection]; - } - FLEXNetworkDetailSection *responseHeadersSection = [[self class] responseHeadersSectionForTransaction:self.transaction]; - if (responseHeadersSection.rows.count > 0) { - [sections addObject:responseHeadersSection]; - } - - self.sections = sections; -} - -- (void)handleTransactionUpdatedNotification:(NSNotification *)notification { - FLEXNetworkTransaction *transaction = [[notification userInfo] objectForKey:kFLEXNetworkRecorderUserInfoTransactionKey]; - if (transaction == self.transaction) { - [self rebuildTableSections]; - } -} - -- (void)copyButtonPressed:(id)sender { - [UIPasteboard.generalPasteboard setString:[FLEXNetworkCurlLogger curlCommandString:_transaction.request]]; -} - -#pragma mark - Table view data source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return self.sections.count; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - FLEXNetworkDetailSection *sectionModel = self.sections[section]; - return sectionModel.rows.count; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - FLEXNetworkDetailSection *sectionModel = self.sections[section]; - return sectionModel.title; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXMultilineTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kFLEXMultilineCell forIndexPath:indexPath]; - - FLEXNetworkDetailRow *rowModel = [self rowModelAtIndexPath:indexPath]; - - cell.textLabel.attributedText = [[self class] attributedTextForRow:rowModel]; - cell.accessoryType = rowModel.selectionFuture ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - cell.selectionStyle = rowModel.selectionFuture ? UITableViewCellSelectionStyleDefault : UITableViewCellSelectionStyleNone; - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXNetworkDetailRow *rowModel = [self rowModelAtIndexPath:indexPath]; - - UIViewController *viewController = nil; - if (rowModel.selectionFuture) { - viewController = rowModel.selectionFuture(); - } - - if ([viewController isKindOfClass:UIAlertController.class]) { - [self presentViewController:viewController animated:YES completion:nil]; - } else if (viewController) { - [self.navigationController pushViewController:viewController animated:YES]; - } - - [tableView deselectRowAtIndexPath:indexPath animated:YES]; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXNetworkDetailRow *row = [self rowModelAtIndexPath:indexPath]; - NSAttributedString *attributedText = [[self class] attributedTextForRow:row]; - BOOL showsAccessory = row.selectionFuture != nil; - return [FLEXMultilineTableViewCell - preferredHeightWithAttributedText:attributedText - maxWidth:tableView.bounds.size.width - style:tableView.style - showsAccessory:showsAccessory - ]; -} - -- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { - return [NSArray flex_forEachUpTo:self.sections.count map:^id(NSUInteger i) { - return @"⦁"; - }]; -} - -- (FLEXNetworkDetailRow *)rowModelAtIndexPath:(NSIndexPath *)indexPath { - FLEXNetworkDetailSection *sectionModel = self.sections[indexPath.section]; - return sectionModel.rows[indexPath.row]; -} - -#pragma mark - Cell Copying - -- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - return action == @selector(copy:); -} - -- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - if (action == @selector(copy:)) { - FLEXNetworkDetailRow *row = [self rowModelAtIndexPath:indexPath]; - UIPasteboard.generalPasteboard.string = row.detailText; - } -} - -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point __IOS_AVAILABLE(13.0) { - return [UIContextMenuConfiguration - configurationWithIdentifier:nil - previewProvider:nil - actionProvider:^UIMenu *(NSArray *suggestedActions) { - UIAction *copy = [UIAction - actionWithTitle:@"Copy" - image:nil - identifier:nil - handler:^(__kindof UIAction *action) { - FLEXNetworkDetailRow *row = [self rowModelAtIndexPath:indexPath]; - UIPasteboard.generalPasteboard.string = row.detailText; - } - ]; - return [UIMenu - menuWithTitle:@"" image:nil identifier:nil - options:UIMenuOptionsDisplayInline - children:@[copy] - ]; - } - ]; -} - -#pragma mark - View Configuration - -+ (NSAttributedString *)attributedTextForRow:(FLEXNetworkDetailRow *)row { - NSDictionary *titleAttributes = @{ NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-Medium" size:12.0], - NSForegroundColorAttributeName : [UIColor colorWithWhite:0.5 alpha:1.0] }; - NSDictionary *detailAttributes = @{ NSFontAttributeName : UIFont.flex_defaultTableCellFont, - NSForegroundColorAttributeName : FLEXColor.primaryTextColor }; - - NSString *title = [NSString stringWithFormat:@"%@: ", row.title]; - NSString *detailText = row.detailText ?: @""; - NSMutableAttributedString *attributedText = [NSMutableAttributedString new]; - [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:title attributes:titleAttributes]]; - [attributedText appendAttributedString:[[NSAttributedString alloc] initWithString:detailText attributes:detailAttributes]]; - - return attributedText; -} - -#pragma mark - Table Data Generation - -+ (FLEXNetworkDetailSection *)generalSectionForTransaction:(FLEXHTTPTransaction *)transaction { - NSMutableArray *rows = [NSMutableArray new]; - - FLEXNetworkDetailRow *requestURLRow = [FLEXNetworkDetailRow new]; - requestURLRow.title = @"Request URL"; - NSURL *url = transaction.request.URL; - requestURLRow.detailText = url.absoluteString; - requestURLRow.selectionFuture = ^{ - UIViewController *urlWebViewController = [[FLEXWebViewController alloc] initWithURL:url]; - urlWebViewController.title = url.absoluteString; - return urlWebViewController; - }; - [rows addObject:requestURLRow]; - - FLEXNetworkDetailRow *requestMethodRow = [FLEXNetworkDetailRow new]; - requestMethodRow.title = @"Request Method"; - requestMethodRow.detailText = transaction.request.HTTPMethod; - [rows addObject:requestMethodRow]; - - if (transaction.cachedRequestBody.length > 0) { - FLEXNetworkDetailRow *postBodySizeRow = [FLEXNetworkDetailRow new]; - postBodySizeRow.title = @"Request Body Size"; - postBodySizeRow.detailText = [NSByteCountFormatter stringFromByteCount:transaction.cachedRequestBody.length countStyle:NSByteCountFormatterCountStyleBinary]; - [rows addObject:postBodySizeRow]; - - FLEXNetworkDetailRow *postBodyRow = [FLEXNetworkDetailRow new]; - postBodyRow.title = @"Request Body"; - postBodyRow.detailText = @"tap to view"; - postBodyRow.selectionFuture = ^UIViewController * () { - // Show the body if we can - NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"]; - UIViewController *detailViewController = [self detailViewControllerForMIMEType:contentType data:[self postBodyDataForTransaction:transaction]]; - if (detailViewController) { - detailViewController.title = @"Request Body"; - return detailViewController; - } - - // We can't show the body, alert user - return [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Can't View HTTP Body Data"); - make.message(@"FLEX does not have a viewer for request body data with MIME type: "); - make.message(contentType); - make.button(@"Dismiss").cancelStyle(); - }]; - }; - - [rows addObject:postBodyRow]; - } - - NSString *statusCodeString = [FLEXUtility statusCodeStringFromURLResponse:transaction.response]; - if (statusCodeString.length > 0) { - FLEXNetworkDetailRow *statusCodeRow = [FLEXNetworkDetailRow new]; - statusCodeRow.title = @"Status Code"; - statusCodeRow.detailText = statusCodeString; - [rows addObject:statusCodeRow]; - } - - if (transaction.error) { - FLEXNetworkDetailRow *errorRow = [FLEXNetworkDetailRow new]; - errorRow.title = @"Error"; - errorRow.detailText = transaction.error.localizedDescription; - [rows addObject:errorRow]; - } - - FLEXNetworkDetailRow *responseBodyRow = [FLEXNetworkDetailRow new]; - responseBodyRow.title = @"Response Body"; - NSData *responseData = [FLEXNetworkRecorder.defaultRecorder cachedResponseBodyForTransaction:transaction]; - if (responseData.length > 0) { - responseBodyRow.detailText = @"tap to view"; - - // Avoid a long lived strong reference to the response data in case we need to purge it from the cache. - weakify(responseData) - responseBodyRow.selectionFuture = ^UIViewController *() { strongify(responseData) - - // Show the response if we can - NSString *contentType = transaction.response.MIMEType; - if (responseData) { - UIViewController *bodyDetails = [self detailViewControllerForMIMEType:contentType data:responseData]; - if (bodyDetails) { - bodyDetails.title = @"Response"; - return bodyDetails; - } - } - - // We can't show the response, alert user - return [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Unable to View Response"); - if (responseData) { - make.message(@"No viewer content type: ").message(contentType); - } else { - make.message(@"The response has been purged from the cache"); - } - make.button(@"OK").cancelStyle(); - }]; - }; - } else { - BOOL emptyResponse = transaction.receivedDataLength == 0; - responseBodyRow.detailText = emptyResponse ? @"empty" : @"not in cache"; - } - - [rows addObject:responseBodyRow]; - - FLEXNetworkDetailRow *responseSizeRow = [FLEXNetworkDetailRow new]; - responseSizeRow.title = @"Response Size"; - responseSizeRow.detailText = [NSByteCountFormatter stringFromByteCount:transaction.receivedDataLength countStyle:NSByteCountFormatterCountStyleBinary]; - [rows addObject:responseSizeRow]; - - FLEXNetworkDetailRow *mimeTypeRow = [FLEXNetworkDetailRow new]; - mimeTypeRow.title = @"MIME Type"; - mimeTypeRow.detailText = transaction.response.MIMEType; - [rows addObject:mimeTypeRow]; - - FLEXNetworkDetailRow *mechanismRow = [FLEXNetworkDetailRow new]; - mechanismRow.title = @"Mechanism"; - mechanismRow.detailText = transaction.requestMechanism; - [rows addObject:mechanismRow]; - - NSDateFormatter *startTimeFormatter = [NSDateFormatter new]; - startTimeFormatter.dateFormat = @"yyyy-MM-dd HH:mm:ss.SSS"; - - FLEXNetworkDetailRow *localStartTimeRow = [FLEXNetworkDetailRow new]; - localStartTimeRow.title = [NSString stringWithFormat:@"Start Time (%@)", [NSTimeZone.localTimeZone abbreviationForDate:transaction.startTime]]; - localStartTimeRow.detailText = [startTimeFormatter stringFromDate:transaction.startTime]; - [rows addObject:localStartTimeRow]; - - startTimeFormatter.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"]; - - FLEXNetworkDetailRow *utcStartTimeRow = [FLEXNetworkDetailRow new]; - utcStartTimeRow.title = @"Start Time (UTC)"; - utcStartTimeRow.detailText = [startTimeFormatter stringFromDate:transaction.startTime]; - [rows addObject:utcStartTimeRow]; - - FLEXNetworkDetailRow *unixStartTime = [FLEXNetworkDetailRow new]; - unixStartTime.title = @"Unix Start Time"; - unixStartTime.detailText = [NSString stringWithFormat:@"%f", [transaction.startTime timeIntervalSince1970]]; - [rows addObject:unixStartTime]; - - FLEXNetworkDetailRow *durationRow = [FLEXNetworkDetailRow new]; - durationRow.title = @"Total Duration"; - durationRow.detailText = [FLEXUtility stringFromRequestDuration:transaction.duration]; - [rows addObject:durationRow]; - - FLEXNetworkDetailRow *latencyRow = [FLEXNetworkDetailRow new]; - latencyRow.title = @"Latency"; - latencyRow.detailText = [FLEXUtility stringFromRequestDuration:transaction.latency]; - [rows addObject:latencyRow]; - - FLEXNetworkDetailSection *generalSection = [FLEXNetworkDetailSection new]; - generalSection.title = @"General"; - generalSection.rows = rows; - - return generalSection; -} - -+ (FLEXNetworkDetailSection *)requestHeadersSectionForTransaction:(FLEXHTTPTransaction *)transaction { - FLEXNetworkDetailSection *requestHeadersSection = [FLEXNetworkDetailSection new]; - requestHeadersSection.title = @"Request Headers"; - requestHeadersSection.rows = [self networkDetailRowsFromDictionary:transaction.request.allHTTPHeaderFields]; - - return requestHeadersSection; -} - -+ (FLEXNetworkDetailSection *)postBodySectionForTransaction:(FLEXHTTPTransaction *)transaction { - FLEXNetworkDetailSection *postBodySection = [FLEXNetworkDetailSection new]; - postBodySection.title = @"Request Body Parameters"; - if (transaction.cachedRequestBody.length > 0) { - NSString *contentType = [transaction.request valueForHTTPHeaderField:@"Content-Type"]; - if ([contentType hasPrefix:@"application/x-www-form-urlencoded"]) { - NSData *body = [self postBodyDataForTransaction:transaction]; - NSString *bodyString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding]; - postBodySection.rows = [self networkDetailRowsFromQueryItems:[FLEXUtility itemsFromQueryString:bodyString]]; - } - } - return postBodySection; -} - -+ (FLEXNetworkDetailSection *)queryParametersSectionForTransaction:(FLEXHTTPTransaction *)transaction { - NSArray *queries = [FLEXUtility itemsFromQueryString:transaction.request.URL.query]; - FLEXNetworkDetailSection *querySection = [FLEXNetworkDetailSection new]; - querySection.title = @"Query Parameters"; - querySection.rows = [self networkDetailRowsFromQueryItems:queries]; - - return querySection; -} - -+ (FLEXNetworkDetailSection *)responseHeadersSectionForTransaction:(FLEXHTTPTransaction *)transaction { - FLEXNetworkDetailSection *responseHeadersSection = [FLEXNetworkDetailSection new]; - responseHeadersSection.title = @"Response Headers"; - if ([transaction.response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)transaction.response; - responseHeadersSection.rows = [self networkDetailRowsFromDictionary:httpResponse.allHeaderFields]; - } - return responseHeadersSection; -} - -+ (NSArray *)networkDetailRowsFromDictionary:(NSDictionary *)dictionary { - NSMutableArray *rows = [NSMutableArray new]; - NSArray *sortedKeys = [dictionary.allKeys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; - - for (NSString *key in sortedKeys) { - id value = dictionary[key]; - FLEXNetworkDetailRow *row = [FLEXNetworkDetailRow new]; - row.title = key; - row.detailText = [value description]; - [rows addObject:row]; - } - - return rows.copy; -} - -+ (NSArray *)networkDetailRowsFromQueryItems:(NSArray *)items { - // Sort the items by name - items = [items sortedArrayUsingComparator:^NSComparisonResult(NSURLQueryItem *item1, NSURLQueryItem *item2) { - return [item1.name caseInsensitiveCompare:item2.name]; - }]; - - NSMutableArray *rows = [NSMutableArray new]; - for (NSURLQueryItem *item in items) { - FLEXNetworkDetailRow *row = [FLEXNetworkDetailRow new]; - row.title = item.name; - row.detailText = item.value; - [rows addObject:row]; - } - - return [rows copy]; -} - -+ (UIViewController *)detailViewControllerForMIMEType:(NSString *)mimeType data:(NSData *)data { - FLEXCustomContentViewerFuture makeCustomViewer = FLEXManager.sharedManager.customContentTypeViewers[mimeType.lowercaseString]; - - if (makeCustomViewer) { - UIViewController *viewer = makeCustomViewer(data); - - if (viewer) { - return viewer; - } - } - - // FIXME (RKO): Don't rely on UTF8 string encoding - UIViewController *detailViewController = nil; - if ([FLEXUtility isValidJSONData:data]) { - NSString *prettyJSON = [FLEXUtility prettyJSONStringFromData:data]; - if (prettyJSON.length > 0) { - detailViewController = [[FLEXWebViewController alloc] initWithText:prettyJSON]; - } - } else if ([mimeType hasPrefix:@"image/"]) { - UIImage *image = [UIImage imageWithData:data]; - detailViewController = [FLEXImagePreviewViewController forImage:image]; - } else if ([mimeType isEqual:@"application/x-plist"]) { - id propertyList = [NSPropertyListSerialization propertyListWithData:data options:0 format:NULL error:NULL]; - detailViewController = [[FLEXWebViewController alloc] initWithText:[propertyList description]]; - } - - // Fall back to trying to show the response as text - if (!detailViewController) { - NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - if (text.length > 0) { - detailViewController = [[FLEXWebViewController alloc] initWithText:text]; - } - } - return detailViewController; -} - -+ (NSData *)postBodyDataForTransaction:(FLEXHTTPTransaction *)transaction { - NSData *bodyData = transaction.cachedRequestBody; - if (bodyData.length > 0) { - NSString *contentEncoding = [transaction.request valueForHTTPHeaderField:@"Content-Encoding"]; - if ([contentEncoding rangeOfString:@"deflate" options:NSCaseInsensitiveSearch].length > 0 || [contentEncoding rangeOfString:@"gzip" options:NSCaseInsensitiveSearch].length > 0) { - bodyData = [FLEXUtility inflatedDataFromCompressedData:bodyData]; - } - } - return bodyData; -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXMITMDataSource.h b/BHTwitter/Classes/Network/FLEXMITMDataSource.h deleted file mode 100644 index 440f4498..00000000 --- a/BHTwitter/Classes/Network/FLEXMITMDataSource.h +++ /dev/null @@ -1,34 +0,0 @@ -// -// FLEXMITMDataSource.h -// FLEX -// -// Created by Tanner Bennett on 8/22/21. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXMITMDataSource<__covariant TransactionType> : NSObject - -+ (instancetype)dataSourceWithProvider:(NSArray *(^)(void))future; - -@property (nonatomic, readonly) NSArray *transactions; -@property (nonatomic, readonly) NSArray *allTransactions; -/// Equal to \c allTransactions if not filtered -@property (nonatomic, readonly) NSArray *filteredTransactions; - -/// Use this instead of either of the other two as it updates based on whether we have a filter or not -@property (nonatomic) NSInteger bytesReceived; -@property (nonatomic) NSInteger totalBytesReceived; -/// Equal to \c totalBytesReceived if not filtered -@property (nonatomic) NSInteger filteredBytesReceived; - -- (void)reloadByteCounts; -- (void)reloadData:(void (^_Nullable)(FLEXMITMDataSource *dataSource))completion; -- (void)filter:(NSString *)searchString completion:(void(^_Nullable)(FLEXMITMDataSource *dataSource))completion; - - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Network/FLEXMITMDataSource.m b/BHTwitter/Classes/Network/FLEXMITMDataSource.m deleted file mode 100644 index 412cd8ac..00000000 --- a/BHTwitter/Classes/Network/FLEXMITMDataSource.m +++ /dev/null @@ -1,102 +0,0 @@ -// -// FLEXMITMDataSource.m -// FLEX -// -// Created by Tanner Bennett on 8/22/21. -// - -#import "FLEXMITMDataSource.h" -#import "FLEXNetworkTransaction.h" -#import "FLEXUtility.h" - -@interface FLEXMITMDataSource () -@property (nonatomic, readonly) NSArray *(^dataProvider)(void); -@property (nonatomic) NSString *filterString; -@end - -@implementation FLEXMITMDataSource - -+ (instancetype)dataSourceWithProvider:(NSArray *(^)(void))future { - FLEXMITMDataSource *ds = [self new]; - ds->_dataProvider = future; - [ds reloadData:nil]; - - return ds; -} - -- (NSArray *)transactions { - return _filteredTransactions; -} - -- (NSInteger)bytesReceived { - return _filteredBytesReceived; -} - -- (void)reloadByteCounts { - [self updateBytesReceived]; - [self updateFilteredBytesReceived]; -} - -- (void)reloadData:(void (^)(FLEXMITMDataSource *dataSource))completion { - self.allTransactions = self.dataProvider(); - [self filter:self.filterString completion:completion]; -} - -- (void)filter:(NSString *)searchString completion:(void (^)(FLEXMITMDataSource *dataSource))completion { - self.filterString = searchString; - - if (!searchString.length) { - self.filteredTransactions = self.allTransactions; - if (completion) completion(self); - } else { - [self onBackgroundQueue:^NSArray *{ - return [self.allTransactions flex_filtered:^BOOL(FLEXNetworkTransaction *entry, NSUInteger idx) { - return [entry matchesQuery:searchString]; - }]; - } thenOnMainQueue:^(NSArray *filteredNetworkTransactions) { - if ([self.filterString isEqual:searchString]) { - self.filteredTransactions = filteredNetworkTransactions; - if (completion) completion(self); - } - }]; - } -} - -- (void)setAllTransactions:(NSArray *)transactions { - _allTransactions = transactions; - [self updateBytesReceived]; -} - -- (void)setFilteredTransactions:(NSArray *)filteredTransactions { - _filteredTransactions = filteredTransactions; - [self updateFilteredBytesReceived]; -} - -- (void)updateBytesReceived { - NSInteger bytesReceived = 0; - for (FLEXNetworkTransaction *transaction in self.transactions) { - bytesReceived += transaction.receivedDataLength; - } - - self.bytesReceived = bytesReceived; -} - -- (void)updateFilteredBytesReceived { - NSInteger filteredBytesReceived = 0; - for (FLEXNetworkTransaction *transaction in self.filteredTransactions) { - filteredBytesReceived += transaction.receivedDataLength; - } - - self.filteredBytesReceived = filteredBytesReceived; -} - -- (void)onBackgroundQueue:(NSArray *(^)(void))backgroundBlock thenOnMainQueue:(void(^)(NSArray *))mainBlock { - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSArray *items = backgroundBlock(); - dispatch_async(dispatch_get_main_queue(), ^{ - mainBlock(items); - }); - }); -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.h b/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.h deleted file mode 100644 index 6fb7eb63..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXCurlLogger.h -// -// -// Created by Ji Pei on 07/27/16 -// - -#import - -@interface FLEXNetworkCurlLogger : NSObject - -/** - * Generates a cURL command equivalent to the given request. - * - * @param request The request to be translated - */ -+ (NSString *)curlCommandString:(NSURLRequest *)request; - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.m b/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.m deleted file mode 100644 index dff385d1..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkCurlLogger.m +++ /dev/null @@ -1,38 +0,0 @@ -// -// FLEXCurlLogger.m -// -// -// Created by Ji Pei on 07/27/16 -// - -#import "FLEXNetworkCurlLogger.h" - -@implementation FLEXNetworkCurlLogger - -+ (NSString *)curlCommandString:(NSURLRequest *)request { - __block NSMutableString *curlCommandString = [NSMutableString stringWithFormat:@"curl -v -X %@ ", request.HTTPMethod]; - - [curlCommandString appendFormat:@"\'%@\' ", request.URL.absoluteString]; - - [request.allHTTPHeaderFields enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *val, BOOL *stop) { - [curlCommandString appendFormat:@"-H \'%@: %@\' ", key, val]; - }]; - - NSArray *cookies = [NSHTTPCookieStorage.sharedHTTPCookieStorage cookiesForURL:request.URL]; - if (cookies) { - [curlCommandString appendFormat:@"-H \'Cookie:"]; - for (NSHTTPCookie *cookie in cookies) { - [curlCommandString appendFormat:@" %@=%@;", cookie.name, cookie.value]; - } - [curlCommandString appendFormat:@"\' "]; - } - - if (request.HTTPBody) { - NSString *body = [[NSString alloc] initWithData:request.HTTPBody encoding:NSUTF8StringEncoding]; - [curlCommandString appendFormat:@"-d \'%@\'", body]; - } - - return curlCommandString; -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.h b/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.h deleted file mode 100644 index 3db00895..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// FLEXNetworkMITMViewController.h -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" -#import "FLEXGlobalsEntry.h" - -/// The main screen for the network observer, which displays a list of network transactions. -@interface FLEXNetworkMITMViewController : FLEXTableViewController - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.m b/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.m deleted file mode 100644 index ea4f5f7f..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkMITMViewController.m +++ /dev/null @@ -1,526 +0,0 @@ -// -// FLEXNetworkMITMViewController.m -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXUtility.h" -#import "FLEXMITMDataSource.h" -#import "FLEXNetworkMITMViewController.h" -#import "FLEXNetworkTransaction.h" -#import "FLEXNetworkRecorder.h" -#import "FLEXNetworkObserver.h" -#import "FLEXNetworkTransactionCell.h" -#import "FLEXHTTPTransactionDetailController.h" -#import "FLEXNetworkSettingsController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXGlobalsViewController.h" -#import "FLEXWebViewController.h" -#import "UIBarButtonItem+FLEX.h" -#import "FLEXResources.h" - -typedef NS_ENUM(NSUInteger, FLEXNetworkObserverMode) { - FLEXNetworkObserverModeREST = 0, - FLEXNetworkObserverModeWebsockets, -}; - -@interface FLEXNetworkMITMViewController () - -@property (nonatomic) BOOL updateInProgress; -@property (nonatomic) BOOL pendingReload; - -@property (nonatomic, readonly) FLEXNetworkObserverMode mode; - -@property (nonatomic, readonly) FLEXMITMDataSource *dataSource; -@property (nonatomic, readonly) FLEXMITMDataSource *HTTPDataSource; -@property (nonatomic, readonly) FLEXMITMDataSource *websocketDataSource; - -@end - -@implementation FLEXNetworkMITMViewController - -#pragma mark - Lifecycle - -- (id)init { - return [self initWithStyle:UITableViewStylePlain]; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsSearchBar = YES; - self.showSearchBarInitially = NO; - - _HTTPDataSource = [FLEXMITMDataSource dataSourceWithProvider:^NSArray * { - return FLEXNetworkRecorder.defaultRecorder.HTTPTransactions; - }]; - - if (@available(iOS 13.0, *)) { - self.searchController.searchBar.showsScopeBar = YES; - self.searchController.searchBar.scopeButtonTitles = @[@"REST", @"Websockets"]; - _websocketDataSource = [FLEXMITMDataSource dataSourceWithProvider:^NSArray * { - return FLEXNetworkRecorder.defaultRecorder.websocketTransactions; - }]; - } - - [self addToolbarItems:@[ - [UIBarButtonItem - flex_itemWithImage:FLEXResources.gearIcon - target:self - action:@selector(settingsButtonTapped:) - ], - [[UIBarButtonItem - flex_systemItem:UIBarButtonSystemItemTrash - target:self - action:@selector(trashButtonTapped:) - ] flex_withTintColor:UIColor.redColor] - ]]; - - [self.tableView - registerClass:FLEXNetworkTransactionCell.class - forCellReuseIdentifier:FLEXNetworkTransactionCell.reuseID - ]; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - self.tableView.rowHeight = FLEXNetworkTransactionCell.preferredCellHeight; - - [self registerForNotifications]; - [self updateTransactions:nil]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - // Reload the table if we received updates while not on-screen - if (self.pendingReload) { - [self.tableView reloadData]; - self.pendingReload = NO; - } -} - -- (void)dealloc { - [NSNotificationCenter.defaultCenter removeObserver:self]; -} - -- (void)registerForNotifications { - NSDictionary *notifications = @{ - kFLEXNetworkRecorderNewTransactionNotification: - NSStringFromSelector(@selector(handleNewTransactionRecordedNotification:)), - kFLEXNetworkRecorderTransactionUpdatedNotification: - NSStringFromSelector(@selector(handleTransactionUpdatedNotification:)), - kFLEXNetworkRecorderTransactionsClearedNotification: - NSStringFromSelector(@selector(handleTransactionsClearedNotification:)), - kFLEXNetworkObserverEnabledStateChangedNotification: - NSStringFromSelector(@selector(handleNetworkObserverEnabledStateChangedNotification:)), - }; - - for (NSString *name in notifications.allKeys) { - [NSNotificationCenter.defaultCenter addObserver:self - selector:NSSelectorFromString(notifications[name]) name:name object:nil - ]; - } -} - - -#pragma mark - Private - -#pragma mark Button Actions - -- (void)settingsButtonTapped:(UIBarButtonItem *)sender { - UIViewController *settings = [FLEXNetworkSettingsController new]; - settings.navigationItem.rightBarButtonItem = FLEXBarButtonItemSystem( - Done, self, @selector(settingsViewControllerDoneTapped:) - ); - settings.title = @"Network Debugging Settings"; - - // This is not a FLEXNavigationController because it is not intended as a new tab - UIViewController *nav = [[UINavigationController alloc] initWithRootViewController:settings]; - [self presentViewController:nav animated:YES completion:nil]; -} - -- (void)trashButtonTapped:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - make.title(@"Clear All Recorded Requests?"); - make.message(@"This cannot be undone."); - - make.button(@"Cancel").cancelStyle(); - make.button(@"Clear All").destructiveStyle().handler(^(NSArray *strings) { - [FLEXNetworkRecorder.defaultRecorder clearRecordedActivity]; - }); - } showFrom:self source:sender]; -} - -- (void)settingsViewControllerDoneTapped:(id)sender { - [self dismissViewControllerAnimated:YES completion:nil]; -} - - -#pragma mark Transactions - -- (FLEXNetworkObserverMode)mode { - return self.searchController.searchBar.selectedScopeButtonIndex; -} - -- (FLEXMITMDataSource *)dataSource { - switch (self.mode) { - case FLEXNetworkObserverModeREST: - return self.HTTPDataSource; - case FLEXNetworkObserverModeWebsockets: - return self.websocketDataSource; - - default: - @throw NSInternalInconsistencyException; - } -} - -- (void)updateTransactions:(void(^)(void))callback { - id completion = ^(FLEXMITMDataSource *dataSource) { - // Update byte count - [self updateFirstSectionHeader]; - if (callback && dataSource == self.dataSource) callback(); - }; - - [self.HTTPDataSource reloadData:completion]; - [self.websocketDataSource reloadData:completion]; -} - - -#pragma mark Header - -- (void)updateFirstSectionHeader { - UIView *view = [self.tableView headerViewForSection:0]; - if ([view isKindOfClass:[UITableViewHeaderFooterView class]]) { - UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view; - headerView.textLabel.text = [self headerText]; - [headerView setNeedsLayout]; - } -} - -- (NSString *)headerText { - long long bytesReceived = 0; - NSInteger totalRequests = 0; - if (self.searchController.isActive) { - bytesReceived = self.dataSource.filteredBytesReceived; - totalRequests = self.dataSource.transactions.count; - } else { - bytesReceived = self.dataSource.bytesReceived; - totalRequests = self.dataSource.transactions.count; - } - - NSString *byteCountText = [NSByteCountFormatter - stringFromByteCount:bytesReceived countStyle:NSByteCountFormatterCountStyleBinary - ]; - NSString *requestsText = totalRequests == 1 ? @"Request" : @"Requests"; - return [NSString stringWithFormat:@"%@ %@ (%@ received)", - @(totalRequests), requestsText, byteCountText - ]; -} - - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - return @"📡 Network History"; -} - -+ (FLEXGlobalsEntryRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row { - return ^(UITableViewController *host) { - if (FLEXNetworkObserver.isEnabled) { - [host.navigationController pushViewController:[ - self globalsEntryViewController:row - ] animated:YES]; - } else { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Network Monitor Disabled"); - make.message(@"You must enable network monitoring to proceed."); - - make.button(@"Turn On").handler(^(NSArray *strings) { - FLEXNetworkObserver.enabled = YES; - [host.navigationController pushViewController:[ - self globalsEntryViewController:row - ] animated:YES]; - }).cancelStyle(); - make.button(@"Dismiss"); - } showFrom:host]; - } - }; -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - UIViewController *controller = [self new]; - controller.title = [self globalsEntryTitle:row]; - return controller; -} - - -#pragma mark - Notification Handlers - -- (void)handleNewTransactionRecordedNotification:(NSNotification *)notification { - [self tryUpdateTransactions]; -} - -- (void)tryUpdateTransactions { - // Don't do any view updating if we aren't in the view hierarchy - if (!self.viewIfLoaded.window) { - [self updateTransactions:nil]; - self.pendingReload = YES; - return; - } - - // Let the previous row insert animation finish before starting a new one to avoid stomping. - // We'll try calling the method again when the insertion completes, - // and we properly no-op if there haven't been changes. - if (self.updateInProgress) { - return; - } - - self.updateInProgress = YES; - - // Get state before update - NSString *currentFilter = self.searchText; - FLEXNetworkObserverMode currentMode = self.mode; - NSInteger existingRowCount = self.dataSource.transactions.count; - - [self updateTransactions:^{ - // Compare to state after update - NSString *newFilter = self.searchText; - FLEXNetworkObserverMode newMode = self.mode; - NSInteger newRowCount = self.dataSource.transactions.count; - NSInteger rowCountDiff = newRowCount - existingRowCount; - - // Abort if the observation mode changed, or if the search field text changed - if (newMode != currentMode || ![currentFilter isEqualToString:newFilter]) { - self.updateInProgress = NO; - return; - } - - if (rowCountDiff) { - // Insert animation if we're at the top. - if (self.tableView.contentOffset.y <= 0.0 && rowCountDiff > 0) { - [CATransaction begin]; - - [CATransaction setCompletionBlock:^{ - self.updateInProgress = NO; - // This isn't an infinite loop, it won't run a third time - // if there were no new transactions the second time - [self tryUpdateTransactions]; - }]; - - NSMutableArray *indexPathsToReload = [NSMutableArray new]; - for (NSInteger row = 0; row < rowCountDiff; row++) { - [indexPathsToReload addObject:[NSIndexPath indexPathForRow:row inSection:0]]; - } - - [self.tableView insertRowsAtIndexPaths:indexPathsToReload withRowAnimation:UITableViewRowAnimationAutomatic]; - [CATransaction commit]; - } else { - // Maintain the user's position if they've scrolled down. - CGSize existingContentSize = self.tableView.contentSize; - [self.tableView reloadData]; - CGFloat contentHeightChange = self.tableView.contentSize.height - existingContentSize.height; - self.tableView.contentOffset = CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y + contentHeightChange); - self.updateInProgress = NO; - } - } else { - self.updateInProgress = NO; - } - }]; -} - -- (void)handleTransactionUpdatedNotification:(NSNotification *)notification { - [self.HTTPDataSource reloadByteCounts]; - [self.websocketDataSource reloadByteCounts]; - - FLEXNetworkTransaction *transaction = notification.userInfo[kFLEXNetworkRecorderUserInfoTransactionKey]; - - // Update both the main table view and search table view if needed. - for (FLEXNetworkTransactionCell *cell in self.tableView.visibleCells) { - if ([cell.transaction isEqual:transaction]) { - // Using -[UITableView reloadRowsAtIndexPaths:withRowAnimation:] is overkill here and kicks off a lot of - // work that can make the table view somewhat unresponsive when lots of updates are streaming in. - // We just need to tell the cell that it needs to re-layout. - [cell setNeedsLayout]; - break; - } - } - - [self updateFirstSectionHeader]; -} - -- (void)handleTransactionsClearedNotification:(NSNotification *)notification { - [self updateTransactions:^{ - [self.tableView reloadData]; - }]; -} - -- (void)handleNetworkObserverEnabledStateChangedNotification:(NSNotification *)notification { - // Update the header, which displays a warning when network debugging is disabled - [self updateFirstSectionHeader]; -} - - -#pragma mark - Table view data source - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.dataSource.transactions.count; -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - return [self headerText]; -} - -- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section { - if ([view isKindOfClass:[UITableViewHeaderFooterView class]]) { - UITableViewHeaderFooterView *headerView = (UITableViewHeaderFooterView *)view; - headerView.textLabel.font = [UIFont systemFontOfSize:14.0 weight:UIFontWeightSemibold]; - } -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - FLEXNetworkTransactionCell *cell = [tableView - dequeueReusableCellWithIdentifier:FLEXNetworkTransactionCell.reuseID - forIndexPath:indexPath - ]; - - cell.transaction = [self transactionAtIndexPath:indexPath]; - - // Since we insert from the top, assign background colors bottom up to keep them consistent for each transaction. - NSInteger totalRows = [tableView numberOfRowsInSection:indexPath.section]; - if ((totalRows - indexPath.row) % 2 == 0) { - cell.backgroundColor = FLEXColor.secondaryBackgroundColor; - } else { - cell.backgroundColor = FLEXColor.primaryBackgroundColor; - } - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - switch (self.mode) { - case FLEXNetworkObserverModeREST: { - FLEXHTTPTransaction *transaction = [self HTTPTransactionAtIndexPath:indexPath]; - UIViewController *details = [FLEXHTTPTransactionDetailController withTransaction:transaction]; - [self.navigationController pushViewController:details animated:YES]; - break; - } - - case FLEXNetworkObserverModeWebsockets: { - if (@available(iOS 13.0, *)) { // This check will never fail - FLEXWebsocketTransaction *transaction = [self websocketTransactionAtIndexPath:indexPath]; - - UIViewController *details = nil; - if (transaction.message.type == NSURLSessionWebSocketMessageTypeData) { - details = [FLEXObjectExplorerFactory explorerViewControllerForObject:transaction.message.data]; - } else { - details = [[FLEXWebViewController alloc] initWithText:transaction.message.string]; - } - - [self.navigationController pushViewController:details animated:YES]; - } - break; - } - - default: - @throw NSInternalInconsistencyException; - } -} - - -#pragma mark - Menu Actions - -- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { - return YES; -} - -- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - return action == @selector(copy:); -} - -- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - if (action == @selector(copy:)) { - UIPasteboard.generalPasteboard.string = [self transactionAtIndexPath:indexPath].copyString; - } -} - -- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point __IOS_AVAILABLE(13.0) { - - FLEXNetworkTransaction *transaction = [self transactionAtIndexPath:indexPath]; - - return [UIContextMenuConfiguration - configurationWithIdentifier:nil - previewProvider:nil - actionProvider:^UIMenu *(NSArray *suggestedActions) { - UIAction *copy = [UIAction - actionWithTitle:@"Copy URL" - image:nil - identifier:nil - handler:^(__kindof UIAction *action) { - UIPasteboard.generalPasteboard.string = transaction.copyString; - } - ]; - - NSArray *children = @[copy]; - if (self.mode == FLEXNetworkObserverModeREST) { - NSURLRequest *request = [self HTTPTransactionAtIndexPath:indexPath].request; - UIAction *denylist = [UIAction - actionWithTitle:[NSString stringWithFormat:@"Exclude '%@'", request.URL.host] - image:nil - identifier:nil - handler:^(__kindof UIAction *action) { - NSMutableArray *denylist = FLEXNetworkRecorder.defaultRecorder.hostDenylist; - [denylist addObject:request.URL.host]; - [FLEXNetworkRecorder.defaultRecorder clearExcludedTransactions]; - [FLEXNetworkRecorder.defaultRecorder synchronizeDenylist]; - [self tryUpdateTransactions]; - } - ]; - - children = [children arrayByAddingObject:denylist]; - } - return [UIMenu - menuWithTitle:@"" image:nil identifier:nil - options:UIMenuOptionsDisplayInline - children:children - ]; - } - ]; -} - -- (FLEXNetworkTransaction *)transactionAtIndexPath:(NSIndexPath *)indexPath { - return self.dataSource.transactions[indexPath.row]; -} - -- (FLEXHTTPTransaction *)HTTPTransactionAtIndexPath:(NSIndexPath *)indexPath { - return self.HTTPDataSource.transactions[indexPath.row]; -} - -- (FLEXWebsocketTransaction *)websocketTransactionAtIndexPath:(NSIndexPath *)indexPath { - return self.websocketDataSource.transactions[indexPath.row]; -} - - -#pragma mark - Search Bar - -- (void)updateSearchResults:(NSString *)searchString { - id callback = ^(FLEXMITMDataSource *dataSource) { - if (self.dataSource == dataSource) { - [self.tableView reloadData]; - } - }; - - [self.HTTPDataSource filter:searchString completion:callback]; - [self.websocketDataSource filter:searchString completion:callback]; -} - -- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope { - [self updateFirstSectionHeader]; - [self.tableView reloadData]; -} - -- (void)willDismissSearchController:(UISearchController *)searchController { - [self.tableView reloadData]; -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkRecorder.h b/BHTwitter/Classes/Network/FLEXNetworkRecorder.h deleted file mode 100644 index 704e1c6b..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkRecorder.h +++ /dev/null @@ -1,85 +0,0 @@ -// -// FLEXNetworkRecorder.h -// Flipboard -// -// Created by Ryan Olson on 2/4/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -// Notifications posted when the record is updated -extern NSString *const kFLEXNetworkRecorderNewTransactionNotification; -extern NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification; -extern NSString *const kFLEXNetworkRecorderUserInfoTransactionKey; -extern NSString *const kFLEXNetworkRecorderTransactionsClearedNotification; - -@class FLEXNetworkTransaction, FLEXHTTPTransaction, FLEXWebsocketTransaction; - -@interface FLEXNetworkRecorder : NSObject - -/// In general, it only makes sense to have one recorder for the entire application. -@property (nonatomic, readonly, class) FLEXNetworkRecorder *defaultRecorder; - -/// Defaults to 25 MB if never set. Values set here are persisted across launches of the app. -@property (nonatomic) NSUInteger responseCacheByteLimit; - -/// If NO, the recorder not cache will not cache response for content types -/// with an "image", "video", or "audio" prefix. -@property (nonatomic) BOOL shouldCacheMediaResponses; - -@property (nonatomic) NSMutableArray *hostDenylist; - -/// Call this after adding to or setting the \c hostDenylist to remove excluded transactions -- (void)clearExcludedTransactions; - -/// Call this to save the denylist to the disk to be loaded next time -- (void)synchronizeDenylist; - - -#pragma mark Accessing recorded network activity - -/// Array of FLEXHTTPTransaction objects ordered by start time with the newest first. -@property (nonatomic, readonly) NSArray *HTTPTransactions; -/// Array of FLEXWebsocketTransaction objects ordered by start time with the newest first. -@property (nonatomic, readonly) NSArray *websocketTransactions API_AVAILABLE(ios(13.0)); - -/// The full response data IFF it hasn't been purged due to memory pressure. -- (NSData *)cachedResponseBodyForTransaction:(FLEXHTTPTransaction *)transaction; - -/// Dumps all network transactions and cached response bodies. -- (void)clearRecordedActivity; - - -#pragma mark Recording network activity - -/// Call when app is about to send HTTP request. -- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID - request:(NSURLRequest *)request - redirectResponse:(NSURLResponse *)redirectResponse; - -/// Call when HTTP response is available. -- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response; - -/// Call when data chunk is received over the network. -- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength; - -/// Call when HTTP request has finished loading. -- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody; - -/// Call when HTTP request has failed to load. -- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error; - -/// Call to set the request mechanism anytime after recordRequestWillBeSent... has been called. -/// This string can be set to anything useful about the API used to make the request. -- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID; - -- (void)recordWebsocketMessageSend:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task API_AVAILABLE(ios(13.0)); -- (void)recordWebsocketMessageSendCompletion:(NSURLSessionWebSocketMessage *)message - error:(NSError *)error API_AVAILABLE(ios(13.0)); - -- (void)recordWebsocketMessageReceived:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task API_AVAILABLE(ios(13.0)); - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkRecorder.m b/BHTwitter/Classes/Network/FLEXNetworkRecorder.m deleted file mode 100644 index 79bd5885..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkRecorder.m +++ /dev/null @@ -1,331 +0,0 @@ -// -// FLEXNetworkRecorder.m -// Flipboard -// -// Created by Ryan Olson on 2/4/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXNetworkRecorder.h" -#import "FLEXNetworkCurlLogger.h" -#import "FLEXNetworkTransaction.h" -#import "FLEXUtility.h" -#import "FLEXResources.h" -#import "NSUserDefaults+FLEX.h" -#import "OSCache.h" - -NSString *const kFLEXNetworkRecorderNewTransactionNotification = @"kFLEXNetworkRecorderNewTransactionNotification"; -NSString *const kFLEXNetworkRecorderTransactionUpdatedNotification = @"kFLEXNetworkRecorderTransactionUpdatedNotification"; -NSString *const kFLEXNetworkRecorderUserInfoTransactionKey = @"transaction"; -NSString *const kFLEXNetworkRecorderTransactionsClearedNotification = @"kFLEXNetworkRecorderTransactionsClearedNotification"; - -NSString *const kFLEXNetworkRecorderResponseCacheLimitDefaultsKey = @"com.flex.responseCacheLimit"; - -@interface FLEXNetworkRecorder () - -@property (nonatomic) OSCache *restCache; -@property (nonatomic) NSMutableArray *orderedHTTPTransactions; -@property (nonatomic) NSMutableArray *orderedWSTransactions; -@property (nonatomic) NSMutableDictionary *requestIDsToHTTPTransactions; -@property (nonatomic) dispatch_queue_t queue; - -@end - -@implementation FLEXNetworkRecorder - -- (instancetype)init { - self = [super init]; - if (self) { - self.restCache = [OSCache new]; - NSUInteger responseCacheLimit = [[NSUserDefaults.standardUserDefaults - objectForKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey] unsignedIntegerValue - ]; - - // Default to 25 MB max. The cache will purge earlier if there is memory pressure. - self.restCache.totalCostLimit = responseCacheLimit ?: 25 * 1024 * 1024; - [self.restCache setTotalCostLimit:responseCacheLimit]; - - self.orderedWSTransactions = [NSMutableArray new]; - self.orderedHTTPTransactions = [NSMutableArray new]; - self.requestIDsToHTTPTransactions = [NSMutableDictionary new]; - self.hostDenylist = NSUserDefaults.standardUserDefaults.flex_networkHostDenylist.mutableCopy; - - // Serial queue used because we use mutable objects that are not thread safe - self.queue = dispatch_queue_create("com.flex.FLEXNetworkRecorder", DISPATCH_QUEUE_SERIAL); - } - - return self; -} - -+ (instancetype)defaultRecorder { - static FLEXNetworkRecorder *defaultRecorder = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - defaultRecorder = [self new]; - }); - - return defaultRecorder; -} - -#pragma mark - Public Data Access - -- (NSUInteger)responseCacheByteLimit { - return self.restCache.totalCostLimit; -} - -- (void)setResponseCacheByteLimit:(NSUInteger)responseCacheByteLimit { - self.restCache.totalCostLimit = responseCacheByteLimit; - [NSUserDefaults.standardUserDefaults - setObject:@(responseCacheByteLimit) - forKey:kFLEXNetworkRecorderResponseCacheLimitDefaultsKey - ]; -} - -- (NSArray *)HTTPTransactions { - return self.orderedHTTPTransactions.copy; -} - -- (NSArray *)websocketTransactions { - return self.orderedWSTransactions.copy; -} - -- (NSData *)cachedResponseBodyForTransaction:(FLEXHTTPTransaction *)transaction { - return [self.restCache objectForKey:transaction.requestID]; -} - -- (void)clearRecordedActivity { - dispatch_async(self.queue, ^{ - [self.restCache removeAllObjects]; - [self.orderedWSTransactions removeAllObjects]; - [self.orderedHTTPTransactions removeAllObjects]; - [self.requestIDsToHTTPTransactions removeAllObjects]; - - [self notify:kFLEXNetworkRecorderTransactionsClearedNotification transaction:nil]; - }); -} - -- (void)clearExcludedTransactions { - dispatch_sync(self.queue, ^{ - self.orderedHTTPTransactions = ({ - [self.orderedHTTPTransactions flex_filtered:^BOOL(FLEXHTTPTransaction *ta, NSUInteger idx) { - NSString *host = ta.request.URL.host; - for (NSString *excluded in self.hostDenylist) { - if ([host hasSuffix:excluded]) { - return NO; - } - } - - return YES; - }]; - }); - }); -} - -- (void)synchronizeDenylist { - NSUserDefaults.standardUserDefaults.flex_networkHostDenylist = self.hostDenylist; -} - -#pragma mark - Network Events - -- (void)recordRequestWillBeSentWithRequestID:(NSString *)requestID - request:(NSURLRequest *)request - redirectResponse:(NSURLResponse *)redirectResponse { - for (NSString *host in self.hostDenylist) { - if ([request.URL.host hasSuffix:host]) { - return; - } - } - - FLEXHTTPTransaction *transaction = [FLEXHTTPTransaction request:request identifier:requestID]; - - // Before async block to keep times accurate - if (redirectResponse) { - [self recordResponseReceivedWithRequestID:requestID response:redirectResponse]; - [self recordLoadingFinishedWithRequestID:requestID responseBody:nil]; - } - - dispatch_async(self.queue, ^{ - [self.orderedHTTPTransactions insertObject:transaction atIndex:0]; - [self.requestIDsToHTTPTransactions setObject:transaction forKey:requestID]; - transaction.transactionState = FLEXNetworkTransactionStateAwaitingResponse; - - [self postNewTransactionNotificationWithTransaction:transaction]; - }); -} - -- (void)recordResponseReceivedWithRequestID:(NSString *)requestID response:(NSURLResponse *)response { - // Before async block to stay accurate - NSDate *responseDate = [NSDate date]; - - dispatch_async(self.queue, ^{ - FLEXHTTPTransaction *transaction = self.requestIDsToHTTPTransactions[requestID]; - if (!transaction) { - return; - } - - transaction.response = response; - transaction.transactionState = FLEXNetworkTransactionStateReceivingData; - transaction.latency = -[transaction.startTime timeIntervalSinceDate:responseDate]; - - [self postUpdateNotificationForTransaction:transaction]; - }); -} - -- (void)recordDataReceivedWithRequestID:(NSString *)requestID dataLength:(int64_t)dataLength { - dispatch_async(self.queue, ^{ - FLEXHTTPTransaction *transaction = self.requestIDsToHTTPTransactions[requestID]; - if (!transaction) { - return; - } - - transaction.receivedDataLength += dataLength; - [self postUpdateNotificationForTransaction:transaction]; - }); -} - -- (void)recordLoadingFinishedWithRequestID:(NSString *)requestID responseBody:(NSData *)responseBody { - NSDate *finishedDate = [NSDate date]; - - dispatch_async(self.queue, ^{ - FLEXHTTPTransaction *transaction = self.requestIDsToHTTPTransactions[requestID]; - if (!transaction) { - return; - } - - transaction.transactionState = FLEXNetworkTransactionStateFinished; - transaction.duration = -[transaction.startTime timeIntervalSinceDate:finishedDate]; - - BOOL shouldCache = responseBody.length > 0; - if (!self.shouldCacheMediaResponses) { - NSArray *ignoredMIMETypePrefixes = @[ @"audio", @"image", @"video" ]; - for (NSString *ignoredPrefix in ignoredMIMETypePrefixes) { - shouldCache = shouldCache && ![transaction.response.MIMEType hasPrefix:ignoredPrefix]; - } - } - - if (shouldCache) { - [self.restCache setObject:responseBody forKey:requestID cost:responseBody.length]; - } - - NSString *mimeType = transaction.response.MIMEType; - if ([mimeType hasPrefix:@"image/"] && responseBody.length > 0) { - // Thumbnail image previews on a separate background queue - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - NSInteger maxPixelDimension = UIScreen.mainScreen.scale * 32.0; - transaction.thumbnail = [FLEXUtility - thumbnailedImageWithMaxPixelDimension:maxPixelDimension - fromImageData:responseBody - ]; - [self postUpdateNotificationForTransaction:transaction]; - }); - } else if ([mimeType isEqual:@"application/json"]) { - transaction.thumbnail = FLEXResources.jsonIcon; - } else if ([mimeType isEqual:@"text/plain"]){ - transaction.thumbnail = FLEXResources.textPlainIcon; - } else if ([mimeType isEqual:@"text/html"]) { - transaction.thumbnail = FLEXResources.htmlIcon; - } else if ([mimeType isEqual:@"application/x-plist"]) { - transaction.thumbnail = FLEXResources.plistIcon; - } else if ([mimeType isEqual:@"application/octet-stream"] || [mimeType isEqual:@"application/binary"]) { - transaction.thumbnail = FLEXResources.binaryIcon; - } else if ([mimeType containsString:@"javascript"]) { - transaction.thumbnail = FLEXResources.jsIcon; - } else if ([mimeType containsString:@"xml"]) { - transaction.thumbnail = FLEXResources.xmlIcon; - } else if ([mimeType hasPrefix:@"audio"]) { - transaction.thumbnail = FLEXResources.audioIcon; - } else if ([mimeType hasPrefix:@"video"]) { - transaction.thumbnail = FLEXResources.videoIcon; - } else if ([mimeType hasPrefix:@"text"]) { - transaction.thumbnail = FLEXResources.textIcon; - } - - [self postUpdateNotificationForTransaction:transaction]; - }); -} - -- (void)recordLoadingFailedWithRequestID:(NSString *)requestID error:(NSError *)error { - dispatch_async(self.queue, ^{ - FLEXHTTPTransaction *transaction = self.requestIDsToHTTPTransactions[requestID]; - if (!transaction) { - return; - } - - transaction.transactionState = FLEXNetworkTransactionStateFailed; - transaction.duration = -[transaction.startTime timeIntervalSinceNow]; - transaction.error = error; - - [self postUpdateNotificationForTransaction:transaction]; - }); -} - -- (void)recordMechanism:(NSString *)mechanism forRequestID:(NSString *)requestID { - dispatch_async(self.queue, ^{ - FLEXHTTPTransaction *transaction = self.requestIDsToHTTPTransactions[requestID]; - if (!transaction) { - return; - } - - transaction.requestMechanism = mechanism; - [self postUpdateNotificationForTransaction:transaction]; - }); -} - -#pragma mark - Websocket Events - -- (void)recordWebsocketMessageSend:(NSURLSessionWebSocketMessage *)message task:(NSURLSessionWebSocketTask *)task { - dispatch_async(self.queue, ^{ - FLEXWebsocketTransaction *send = [FLEXWebsocketTransaction - withMessage:message task:task direction:FLEXWebsocketOutgoing - ]; - - [self.orderedWSTransactions addObject:send]; - [self postNewTransactionNotificationWithTransaction:send]; - }); -} - -- (void)recordWebsocketMessageSendCompletion:(NSURLSessionWebSocketMessage *)message error:(NSError *)error { - dispatch_async(self.queue, ^{ - FLEXWebsocketTransaction *send = [self.orderedWSTransactions flex_firstWhere:^BOOL(FLEXWebsocketTransaction *t) { - return t.message == message; - }]; - send.error = error; - send.transactionState = error ? FLEXNetworkTransactionStateFailed : FLEXNetworkTransactionStateFinished; - - [self postUpdateNotificationForTransaction:send]; - }); -} - -- (void)recordWebsocketMessageReceived:(NSURLSessionWebSocketMessage *)message task:(NSURLSessionWebSocketTask *)task { - dispatch_async(self.queue, ^{ - FLEXWebsocketTransaction *receive = [FLEXWebsocketTransaction - withMessage:message task:task direction:FLEXWebsocketIncoming - ]; - - [self.orderedWSTransactions addObject:receive]; - [self postNewTransactionNotificationWithTransaction:receive]; - }); -} - -#pragma mark Notification Posting - -- (void)postNewTransactionNotificationWithTransaction:(FLEXNetworkTransaction *)transaction { - [self notify:kFLEXNetworkRecorderNewTransactionNotification transaction:transaction]; -} - -- (void)postUpdateNotificationForTransaction:(FLEXNetworkTransaction *)transaction { - [self notify:kFLEXNetworkRecorderTransactionUpdatedNotification transaction:transaction]; -} - -- (void)notify:(NSString *)name transaction:(FLEXNetworkTransaction *)transaction { - NSDictionary *userInfo = nil; - if (transaction) { - userInfo = @{ kFLEXNetworkRecorderUserInfoTransactionKey : transaction }; - } - - dispatch_async(dispatch_get_main_queue(), ^{ - [NSNotificationCenter.defaultCenter postNotificationName:name object:self userInfo:userInfo]; - }); -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkSettingsController.h b/BHTwitter/Classes/Network/FLEXNetworkSettingsController.h deleted file mode 100644 index 1094fb50..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkSettingsController.h +++ /dev/null @@ -1,12 +0,0 @@ -// -// FLEXNetworkSettingsController.h -// FLEXInjected -// -// Created by Ryan Olson on 2/20/15. -// - -#import "FLEXTableViewController.h" - -@interface FLEXNetworkSettingsController : FLEXTableViewController - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkSettingsController.m b/BHTwitter/Classes/Network/FLEXNetworkSettingsController.m deleted file mode 100644 index 7490f52e..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkSettingsController.m +++ /dev/null @@ -1,253 +0,0 @@ -// -// FLEXNetworkSettingsController.m -// FLEXInjected -// -// Created by Ryan Olson on 2/20/15. -// - -#import "FLEXNetworkSettingsController.h" -#import "FLEXNetworkObserver.h" -#import "FLEXNetworkRecorder.h" -#import "FLEXUtility.h" -#import "FLEXTableView.h" -#import "FLEXColor.h" -#import "NSUserDefaults+FLEX.h" - -@interface FLEXNetworkSettingsController () -@property (nonatomic) float cacheLimitValue; -@property (nonatomic, readonly) NSString *cacheLimitCellTitle; - -@property (nonatomic, readonly) UISwitch *observerSwitch; -@property (nonatomic, readonly) UISwitch *cacheMediaSwitch; -@property (nonatomic, readonly) UISwitch *jsonViewerSwitch; -@property (nonatomic, readonly) UISlider *cacheLimitSlider; -@property (nonatomic) UILabel *cacheLimitLabel; - -@property (nonatomic) NSMutableArray *hostDenylist; -@end - -@implementation FLEXNetworkSettingsController - -- (void)viewDidLoad { - [super viewDidLoad]; - - [self disableToolbar]; - self.hostDenylist = FLEXNetworkRecorder.defaultRecorder.hostDenylist.mutableCopy; - - NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; - - _observerSwitch = [UISwitch new]; - _cacheMediaSwitch = [UISwitch new]; - _jsonViewerSwitch = [UISwitch new]; - _cacheLimitSlider = [UISlider new]; - - self.observerSwitch.on = FLEXNetworkObserver.enabled; - [self.observerSwitch addTarget:self - action:@selector(networkDebuggingToggled:) - forControlEvents:UIControlEventValueChanged - ]; - - self.cacheMediaSwitch.on = FLEXNetworkRecorder.defaultRecorder.shouldCacheMediaResponses; - [self.cacheMediaSwitch addTarget:self - action:@selector(cacheMediaResponsesToggled:) - forControlEvents:UIControlEventValueChanged - ]; - - self.jsonViewerSwitch.on = defaults.flex_registerDictionaryJSONViewerOnLaunch; - [self.jsonViewerSwitch addTarget:self - action:@selector(jsonViewerSettingToggled:) - forControlEvents:UIControlEventValueChanged - ]; - - [self.cacheLimitSlider addTarget:self - action:@selector(cacheLimitAdjusted:) - forControlEvents:UIControlEventValueChanged - ]; - - UISlider *slider = self.cacheLimitSlider; - self.cacheLimitValue = FLEXNetworkRecorder.defaultRecorder.responseCacheByteLimit; - const NSUInteger fiftyMega = 50 * 1024 * 1024; - slider.minimumValue = 0; - slider.maximumValue = fiftyMega; - slider.value = self.cacheLimitValue; -} - -- (void)setCacheLimitValue:(float)cacheLimitValue { - _cacheLimitValue = cacheLimitValue; - self.cacheLimitLabel.text = self.cacheLimitCellTitle; - [FLEXNetworkRecorder.defaultRecorder setResponseCacheByteLimit:cacheLimitValue]; -} - -- (NSString *)cacheLimitCellTitle { - NSInteger cacheLimit = self.cacheLimitValue; - NSInteger limitInMB = round(cacheLimit / (1024 * 1024)); - return [NSString stringWithFormat:@"Cache Limit (%@ MB)", @(limitInMB)]; -} - - -#pragma mark - Settings Actions - -- (void)networkDebuggingToggled:(UISwitch *)sender { - FLEXNetworkObserver.enabled = sender.isOn; -} - -- (void)cacheMediaResponsesToggled:(UISwitch *)sender { - FLEXNetworkRecorder.defaultRecorder.shouldCacheMediaResponses = sender.isOn; -} - -- (void)jsonViewerSettingToggled:(UISwitch *)sender { - [NSUserDefaults.standardUserDefaults flex_toggleBoolForKey:kFLEXDefaultsRegisterJSONExplorerKey]; -} - -- (void)cacheLimitAdjusted:(UISlider *)sender { - self.cacheLimitValue = sender.value; -} - - -#pragma mark - Table View Data Source - -- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - return self.hostDenylist.count ? 2 : 1; -} - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - switch (section) { - case 0: return 5; - case 1: return self.hostDenylist.count; - default: return 0; - } -} - -- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { - switch (section) { - case 0: return @"General"; - case 1: return @"Host Denylist"; - default: return nil; - } -} - -- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { - if (section == 0) { - return @"By default, JSON is rendered in a webview. Turn on " - "\"View JSON as a dictionary/array\" to convert JSON payloads " - "to objects and view them in an object explorer. " - "This setting requires a restart of the app."; - } - - return nil; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - UITableViewCell *cell = [self.tableView - dequeueReusableCellWithIdentifier:kFLEXDefaultCell forIndexPath:indexPath - ]; - - cell.accessoryView = nil; - cell.textLabel.textColor = FLEXColor.primaryTextColor; - - switch (indexPath.section) { - // Settings - case 0: { - switch (indexPath.row) { - case 0: - cell.textLabel.text = @"Network Debugging"; - cell.accessoryView = self.observerSwitch; - break; - case 1: - cell.textLabel.text = @"Cache Media Responses"; - cell.accessoryView = self.cacheMediaSwitch; - break; - case 2: - cell.textLabel.text = @"View JSON as a dictionary/array"; - cell.accessoryView = self.jsonViewerSwitch; - break; - case 3: - cell.textLabel.text = @"Reset Host Denylist"; - cell.textLabel.textColor = tableView.tintColor; - break; - case 4: - cell.textLabel.text = self.cacheLimitCellTitle; - self.cacheLimitLabel = cell.textLabel; - [self.cacheLimitSlider removeFromSuperview]; - [cell.contentView addSubview:self.cacheLimitSlider]; - - CGRect container = cell.contentView.frame; - UISlider *slider = self.cacheLimitSlider; - [slider sizeToFit]; - - CGFloat sliderWidth = 150.f; - CGFloat sliderOriginY = FLEXFloor((container.size.height - slider.frame.size.height) / 2.0); - CGFloat sliderOriginX = CGRectGetMaxX(container) - sliderWidth - tableView.separatorInset.left; - self.cacheLimitSlider.frame = CGRectMake( - sliderOriginX, sliderOriginY, sliderWidth, slider.frame.size.height - ); - - // Make wider, keep in middle of cell, keep to trailing edge of cell - self.cacheLimitSlider.autoresizingMask = ({ - UIViewAutoresizingFlexibleWidth | - UIViewAutoresizingFlexibleLeftMargin | - UIViewAutoresizingFlexibleTopMargin | - UIViewAutoresizingFlexibleBottomMargin; - }); - break; - } - - break; - } - - // Denylist entries - case 1: { - cell.textLabel.text = self.hostDenylist[indexPath.row]; - break; - } - - default: - @throw NSInternalInconsistencyException; - break; - } - - return cell; -} - -#pragma mark - Table View Delegate - -- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)ip { - // Can only select the "Reset Host Denylist" row - return ip.section == 0 && ip.row == 2; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - [tableView deselectRowAtIndexPath:indexPath animated:YES]; - - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Reset Host Denylist"); - make.message(@"You cannot undo this action. Are you sure?"); - make.button(@"Reset").destructiveStyle().handler(^(NSArray *strings) { - self.hostDenylist = nil; - [FLEXNetworkRecorder.defaultRecorder.hostDenylist removeAllObjects]; - [FLEXNetworkRecorder.defaultRecorder synchronizeDenylist]; - [self.tableView deleteSections: - [NSIndexSet indexSetWithIndex:1] - withRowAnimation:UITableViewRowAnimationAutomatic]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self]; -} - -- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { - return indexPath.section == 1; -} - -- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)style -forRowAtIndexPath:(NSIndexPath *)indexPath { - NSParameterAssert(style == UITableViewCellEditingStyleDelete); - - NSString *host = self.hostDenylist[indexPath.row]; - [self.hostDenylist removeObjectAtIndex:indexPath.row]; - [FLEXNetworkRecorder.defaultRecorder.hostDenylist removeObject:host]; - [FLEXNetworkRecorder.defaultRecorder synchronizeDenylist]; - - [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkTransaction.h b/BHTwitter/Classes/Network/FLEXNetworkTransaction.h deleted file mode 100644 index 12407b58..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkTransaction.h +++ /dev/null @@ -1,107 +0,0 @@ -// -// FLEXNetworkTransaction.h -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import "UIKit/UIKit.h" - -typedef NS_ENUM(NSInteger, FLEXNetworkTransactionState) { - FLEXNetworkTransactionStateUnstarted, - FLEXNetworkTransactionStateAwaitingResponse, - FLEXNetworkTransactionStateReceivingData, - FLEXNetworkTransactionStateFinished, - FLEXNetworkTransactionStateFailed -}; - -typedef NS_ENUM(NSUInteger, FLEXWebsocketMessageDirection) { - FLEXWebsocketIncoming = 1, - FLEXWebsocketOutgoing, -}; - -/// The shared base class for all types of network transactions. -/// Subclasses should implement the descriptions and details properties, and assign a thumbnail. -@interface FLEXNetworkTransaction : NSObject - -+ (instancetype)withStartTime:(NSDate *)startTime; - -+ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state; - -@property (nonatomic) NSError *error; -/// Subclasses can override to provide error state based on response data as well -@property (nonatomic, readonly) BOOL displayAsError; -@property (nonatomic, readonly) NSDate *startTime; - -@property (nonatomic) FLEXNetworkTransactionState transactionState; -@property (nonatomic) int64_t receivedDataLength; -/// A small thumbnail to preview the type of/the response -@property (nonatomic) UIImage *thumbnail; - -/// The most prominent line of the cell. Typically a URL endpoint or other distinguishing attribute. -/// This line turns red when the transaction indicates an error. -@property (nonatomic, readonly) NSString *primaryDescription; -/// Something less important, such as a blob of data or the URL's domain. -@property (nonatomic, readonly) NSString *secondaryDescription; -/// Minor details to display at the bottom of the cell, such as a timestamp, HTTP method, or status. -@property (nonatomic, readonly) NSString *tertiaryDescription; - -/// Subclasses should implement for when the transaction is complete -@property (nonatomic, readonly) NSArray *details; - -/// The string to copy when the user selects the "copy" action -@property (nonatomic, readonly) NSString *copyString; - -/// Whether or not this request should show up when the user searches for a given string -- (BOOL)matchesQuery:(NSString *)filterString; - -@end - -/// The shared base class for all NSURL-API-related transactions. -/// Descriptions are generated by this class using the URL provided by subclasses. -@interface FLEXURLTransaction : FLEXNetworkTransaction - -+ (instancetype)withRequest:(NSURLRequest *)request startTime:(NSDate *)startTime; - -@property (nonatomic, readonly) NSURLRequest *request; - -@end - - -@interface FLEXHTTPTransaction : FLEXURLTransaction - -+ (instancetype)request:(NSURLRequest *)request identifier:(NSString *)requestID; - -@property (nonatomic, readonly) NSString *requestID; -@property (nonatomic) NSURLResponse *response; -@property (nonatomic, copy) NSString *requestMechanism; - -@property (nonatomic) NSTimeInterval latency; -@property (nonatomic) NSTimeInterval duration; - -/// Populated lazily. Handles both normal HTTPBody data and HTTPBodyStreams. -@property (nonatomic, readonly) NSData *cachedRequestBody; - -@end - - -@interface FLEXWebsocketTransaction : FLEXURLTransaction - -+ (instancetype)withMessage:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task - direction:(FLEXWebsocketMessageDirection)direction API_AVAILABLE(ios(13.0)); - -+ (instancetype)withMessage:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task - direction:(FLEXWebsocketMessageDirection)direction - startTime:(NSDate *)started API_AVAILABLE(ios(13.0)); - -//@property (nonatomic, readonly) NSURLSessionWebSocketTask *task; -@property (nonatomic, readonly) NSURLSessionWebSocketMessage *message API_AVAILABLE(ios(13.0)); -@property (nonatomic, readonly) FLEXWebsocketMessageDirection direction API_AVAILABLE(ios(13.0)); - -@property (nonatomic, readonly) int64_t dataLength API_AVAILABLE(ios(13.0)); - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkTransaction.m b/BHTwitter/Classes/Network/FLEXNetworkTransaction.m deleted file mode 100644 index 7a9d2e15..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkTransaction.m +++ /dev/null @@ -1,305 +0,0 @@ -// -// FLEXNetworkTransaction.m -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXNetworkTransaction.h" -#import "FLEXResources.h" -#import "FLEXUtility.h" - -@interface FLEXNetworkTransaction () { - @protected - - NSString *_primaryDescription; - NSString *_secondaryDescription; - NSString *_tertiaryDescription; -} - -@end - -@implementation FLEXNetworkTransaction - -+ (NSString *)readableStringFromTransactionState:(FLEXNetworkTransactionState)state { - NSString *readableString = nil; - switch (state) { - case FLEXNetworkTransactionStateUnstarted: - readableString = @"Unstarted"; - break; - - case FLEXNetworkTransactionStateAwaitingResponse: - readableString = @"Awaiting Response"; - break; - - case FLEXNetworkTransactionStateReceivingData: - readableString = @"Receiving Data"; - break; - - case FLEXNetworkTransactionStateFinished: - readableString = @"Finished"; - break; - - case FLEXNetworkTransactionStateFailed: - readableString = @"Failed"; - break; - } - return readableString; -} - -+ (instancetype)withStartTime:(NSDate *)startTime { - FLEXNetworkTransaction *transaction = [self new]; - transaction->_startTime = startTime; - return transaction; -} - -- (BOOL)displayAsError { - return _error != nil; -} - -- (NSString *)copyString { - return nil; -} - -- (BOOL)matchesQuery:(NSString *)filterString { - return NO; -} - -@end - - -@interface FLEXURLTransaction () - -@end - -@implementation FLEXURLTransaction - -+ (instancetype)withRequest:(NSURLRequest *)request startTime:(NSDate *)startTime { - FLEXURLTransaction *transaction = [self withStartTime:startTime]; - transaction->_request = request; - return transaction; -} - -- (NSString *)timestampStringFromRequestDate:(NSDate *)date { - static NSDateFormatter *dateFormatter = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - dateFormatter = [NSDateFormatter new]; - dateFormatter.dateFormat = @"HH:mm:ss"; - }); - - return [dateFormatter stringFromDate:date]; -} - -- (NSString *)primaryDescription { - if (!_primaryDescription) { - NSString *name = self.request.URL.lastPathComponent; - if (!name.length) { - name = @"/"; - } - - if (_request.URL.query) { - name = [name stringByAppendingFormat:@"?%@", self.request.URL.query]; - } - - _primaryDescription = name; - } - - return _primaryDescription; -} - -- (NSString *)secondaryDescription { - if (!_secondaryDescription) { - NSMutableArray *mutablePathComponents = self.request.URL.pathComponents.mutableCopy; - if (mutablePathComponents.count > 0) { - [mutablePathComponents removeLastObject]; - } - - NSString *path = self.request.URL.host; - for (NSString *pathComponent in mutablePathComponents) { - path = [path stringByAppendingPathComponent:pathComponent]; - } - - _secondaryDescription = path; - } - - return _secondaryDescription; -} - -- (NSString *)tertiaryDescription { - if (!_tertiaryDescription) { - NSMutableArray *detailComponents = [NSMutableArray new]; - - NSString *timestamp = [self timestampStringFromRequestDate:self.startTime]; - if (timestamp.length > 0) { - [detailComponents addObject:timestamp]; - } - - // Omit method for GET (assumed as default) - NSString *httpMethod = self.request.HTTPMethod; - if (httpMethod.length > 0) { - [detailComponents addObject:httpMethod]; - } - - if (self.transactionState == FLEXNetworkTransactionStateFinished || self.transactionState == FLEXNetworkTransactionStateFailed) { - [detailComponents addObjectsFromArray:self.details]; - } else { - // Unstarted, Awaiting Response, Receiving Data, etc. - NSString *state = [self.class readableStringFromTransactionState:self.transactionState]; - [detailComponents addObject:state]; - } - - _tertiaryDescription = [detailComponents componentsJoinedByString:@" ・ "]; - } - - return _tertiaryDescription; -} - -- (void)setTransactionState:(FLEXNetworkTransactionState)transactionState { - super.transactionState = transactionState; - // Reset bottom description - _tertiaryDescription = nil; -} - -- (NSString *)copyString { - return self.request.URL.absoluteString; -} - -- (BOOL)matchesQuery:(NSString *)filterString { - return [self.request.URL.absoluteString localizedCaseInsensitiveContainsString:filterString]; -} - -@end - -@interface FLEXHTTPTransaction () -@property (nonatomic, readwrite) NSData *cachedRequestBody; -@end - -@implementation FLEXHTTPTransaction - -+ (instancetype)request:(NSURLRequest *)request identifier:(NSString *)requestID { - FLEXHTTPTransaction *httpt = [self withRequest:request startTime:NSDate.date]; - httpt->_requestID = requestID; - return httpt; -} - -- (NSString *)description { - NSString *description = [super description]; - - description = [description stringByAppendingFormat:@" id = %@;", self.requestID]; - description = [description stringByAppendingFormat:@" url = %@;", self.request.URL]; - description = [description stringByAppendingFormat:@" duration = %f;", self.duration]; - description = [description stringByAppendingFormat:@" receivedDataLength = %lld", self.receivedDataLength]; - - return description; -} - -- (NSData *)cachedRequestBody { - if (!_cachedRequestBody) { - if (self.request.HTTPBody != nil) { - _cachedRequestBody = self.request.HTTPBody; - } else if ([self.request.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { - NSInputStream *bodyStream = [self.request.HTTPBodyStream copy]; - const NSUInteger bufferSize = 1024; - uint8_t buffer[bufferSize]; - NSMutableData *data = [NSMutableData new]; - [bodyStream open]; - NSInteger readBytes = 0; - do { - readBytes = [bodyStream read:buffer maxLength:bufferSize]; - [data appendBytes:buffer length:readBytes]; - } while (readBytes > 0); - [bodyStream close]; - _cachedRequestBody = data; - } - } - return _cachedRequestBody; -} - -- (NSArray *)detailString { - NSMutableArray *detailComponents = [NSMutableArray new]; - - NSString *statusCodeString = [FLEXUtility statusCodeStringFromURLResponse:self.response]; - if (statusCodeString.length > 0) { - [detailComponents addObject:statusCodeString]; - } - - if (self.receivedDataLength > 0) { - NSString *responseSize = [NSByteCountFormatter - stringFromByteCount:self.receivedDataLength - countStyle:NSByteCountFormatterCountStyleBinary - ]; - [detailComponents addObject:responseSize]; - } - - NSString *totalDuration = [FLEXUtility stringFromRequestDuration:self.duration]; - NSString *latency = [FLEXUtility stringFromRequestDuration:self.latency]; - NSString *duration = [NSString stringWithFormat:@"%@ (%@)", totalDuration, latency]; - [detailComponents addObject:duration]; - - return detailComponents; -} - -- (BOOL)displayAsError { - return [FLEXUtility isErrorStatusCodeFromURLResponse:self.response] || super.displayAsError; -} - -@end - - -@implementation FLEXWebsocketTransaction - -+ (instancetype)withMessage:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task - direction:(FLEXWebsocketMessageDirection)direction - startTime:(NSDate *)started { - FLEXWebsocketTransaction *wst = [self withRequest:task.originalRequest startTime:started]; - wst->_message = message; - wst->_direction = direction; - - // Populate receivedDataLength - if (direction == FLEXWebsocketIncoming) { - wst.receivedDataLength = wst.dataLength; - wst.transactionState = FLEXNetworkTransactionStateFinished; - } - - // Populate thumbnail image - if (message.type == NSURLSessionWebSocketMessageTypeData) { - wst.thumbnail = FLEXResources.binaryIcon; - } else { - wst.thumbnail = FLEXResources.textIcon; - } - - return wst; -} - -+ (instancetype)withMessage:(NSURLSessionWebSocketMessage *)message - task:(NSURLSessionWebSocketTask *)task - direction:(FLEXWebsocketMessageDirection)direction { - return [self withMessage:message task:task direction:direction startTime:NSDate.date]; -} - -- (NSArray *)details API_AVAILABLE(ios(13.0)) { - return @[ - self.direction == FLEXWebsocketOutgoing ? @"SENT →" : @"→ RECEIVED", - [NSByteCountFormatter - stringFromByteCount:self.dataLength - countStyle:NSByteCountFormatterCountStyleBinary - ] - ]; -} - -- (int64_t)dataLength { - if (self.message) { - if (self.message.type == NSURLSessionWebSocketMessageTypeString) { - return self.message.string.length; - } - - return self.message.data.length; - } - - return 0; -} - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.h b/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.h deleted file mode 100644 index dc462376..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// FLEXNetworkTransactionCell.h -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@class FLEXNetworkTransaction; - -@interface FLEXNetworkTransactionCell : UITableViewCell - -@property (nonatomic) FLEXNetworkTransaction *transaction; - -@property (nonatomic, readonly, class) NSString *reuseID; -@property (nonatomic, readonly, class) CGFloat preferredCellHeight; - -@end diff --git a/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.m b/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.m deleted file mode 100644 index 32bea502..00000000 --- a/BHTwitter/Classes/Network/FLEXNetworkTransactionCell.m +++ /dev/null @@ -1,115 +0,0 @@ -// -// FLEXNetworkTransactionCell.m -// Flipboard -// -// Created by Ryan Olson on 2/8/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXNetworkTransactionCell.h" -#import "FLEXNetworkTransaction.h" -#import "FLEXUtility.h" -#import "FLEXResources.h" - -NSString * const kFLEXNetworkTransactionCellIdentifier = @"kFLEXNetworkTransactionCellIdentifier"; - -@interface FLEXNetworkTransactionCell () - -@property (nonatomic) UIImageView *thumbnailImageView; -@property (nonatomic) UILabel *nameLabel; -@property (nonatomic) UILabel *pathLabel; -@property (nonatomic) UILabel *transactionDetailsLabel; - -@end - -@implementation FLEXNetworkTransactionCell - -- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - - self.nameLabel = [UILabel new]; - self.nameLabel.font = UIFont.flex_defaultTableCellFont; - [self.contentView addSubview:self.nameLabel]; - - self.pathLabel = [UILabel new]; - self.pathLabel.font = UIFont.flex_defaultTableCellFont; - self.pathLabel.textColor = [UIColor colorWithWhite:0.4 alpha:1.0]; - [self.contentView addSubview:self.pathLabel]; - - self.thumbnailImageView = [UIImageView new]; - self.thumbnailImageView.layer.borderColor = UIColor.blackColor.CGColor; - self.thumbnailImageView.layer.borderWidth = 1.0; - self.thumbnailImageView.contentMode = UIViewContentModeScaleAspectFit; - [self.contentView addSubview:self.thumbnailImageView]; - - self.transactionDetailsLabel = [UILabel new]; - self.transactionDetailsLabel.font = [UIFont systemFontOfSize:10.0]; - self.transactionDetailsLabel.textColor = [UIColor colorWithWhite:0.65 alpha:1.0]; - [self.contentView addSubview:self.transactionDetailsLabel]; - } - return self; -} - -- (void)setTransaction:(FLEXNetworkTransaction *)transaction { - if (_transaction != transaction) { - _transaction = transaction; - [self setNeedsLayout]; - } -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - const CGFloat kVerticalPadding = 8.0; - const CGFloat kLeftPadding = 10.0; - const CGFloat kImageDimension = 32.0; - - CGFloat thumbnailOriginY = round((self.contentView.bounds.size.height - kImageDimension) / 2.0); - self.thumbnailImageView.frame = CGRectMake(kLeftPadding, thumbnailOriginY, kImageDimension, kImageDimension); - self.thumbnailImageView.image = self.transaction.thumbnail; - - CGFloat textOriginX = CGRectGetMaxX(self.thumbnailImageView.frame) + kLeftPadding; - CGFloat availableTextWidth = self.contentView.bounds.size.width - textOriginX; - - self.nameLabel.text = [self nameLabelText]; - CGSize nameLabelPreferredSize = [self.nameLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; - self.nameLabel.frame = CGRectMake(textOriginX, kVerticalPadding, availableTextWidth, nameLabelPreferredSize.height); - self.nameLabel.textColor = self.transaction.displayAsError ? UIColor.redColor : FLEXColor.primaryTextColor; - - self.pathLabel.text = [self pathLabelText]; - CGSize pathLabelPreferredSize = [self.pathLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; - CGFloat pathLabelOriginY = ceil((self.contentView.bounds.size.height - pathLabelPreferredSize.height) / 2.0); - self.pathLabel.frame = CGRectMake(textOriginX, pathLabelOriginY, availableTextWidth, pathLabelPreferredSize.height); - - self.transactionDetailsLabel.text = [self transactionDetailsLabelText]; - CGSize transactionLabelPreferredSize = [self.transactionDetailsLabel sizeThatFits:CGSizeMake(availableTextWidth, CGFLOAT_MAX)]; - CGFloat transactionDetailsOriginX = textOriginX; - CGFloat transactionDetailsLabelOriginY = CGRectGetMaxY(self.contentView.bounds) - kVerticalPadding - transactionLabelPreferredSize.height; - CGFloat transactionDetailsLabelWidth = self.contentView.bounds.size.width - transactionDetailsOriginX; - self.transactionDetailsLabel.frame = CGRectMake(transactionDetailsOriginX, transactionDetailsLabelOriginY, transactionDetailsLabelWidth, transactionLabelPreferredSize.height); -} - -- (NSString *)nameLabelText { - return self.transaction.primaryDescription; -} - -- (NSString *)pathLabelText { - return self.transaction.secondaryDescription; -} - -- (NSString *)transactionDetailsLabelText { - return self.transaction.tertiaryDescription; -} - -+ (CGFloat)preferredCellHeight { - return 65.0; -} - -+ (NSString *)reuseID { - return kFLEXNetworkTransactionCellIdentifier; -} - -@end diff --git a/BHTwitter/Classes/Network/OSCache/LICENSE.md b/BHTwitter/Classes/Network/OSCache/LICENSE.md deleted file mode 100644 index f1b63c7d..00000000 --- a/BHTwitter/Classes/Network/OSCache/LICENSE.md +++ /dev/null @@ -1,20 +0,0 @@ -OSCache -version 1.2.1, Decembet 18th, 2015 - -Copyright (C) 2014 Charcoal Design - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/BHTwitter/Classes/Network/OSCache/OSCache.h b/BHTwitter/Classes/Network/OSCache/OSCache.h deleted file mode 100644 index bdb277da..00000000 --- a/BHTwitter/Classes/Network/OSCache/OSCache.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// OSCache.h -// -// Version 1.2.1 -// -// Created by Nick Lockwood on 01/01/2014. -// Copyright (C) 2014 Charcoal Design -// -// Distributed under the permissive zlib License -// Get the latest version from here: -// -// https://github.com/nicklockwood/OSCache -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface OSCache : NSCache - -@property (nonatomic, readonly) NSUInteger count; -@property (nonatomic, readonly) NSUInteger totalCost; - -- (id)objectForKeyedSubscript:(KeyType )key; -- (void)setObject:(ObjectType)obj forKeyedSubscript:(KeyType )key; -- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ObjectType obj, BOOL *stop))block; - -@end - - -@protocol OSCacheDelegate -@optional - -- (BOOL)cache:(OSCache *)cache shouldEvictObject:(id)entry; -- (void)cache:(OSCache *)cache willEvictObject:(id)entry; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Network/OSCache/OSCache.m b/BHTwitter/Classes/Network/OSCache/OSCache.m deleted file mode 100644 index 28e76ceb..00000000 --- a/BHTwitter/Classes/Network/OSCache/OSCache.m +++ /dev/null @@ -1,409 +0,0 @@ -// -// OSCache.m -// -// Version 1.2.1 -// -// Created by Nick Lockwood on 01/01/2014. -// Copyright (C) 2014 Charcoal Design -// -// Distributed under the permissive zlib License -// Get the latest version from here: -// -// https://github.com/nicklockwood/OSCache -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would be -// appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not be -// misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source distribution. -// - -#import "OSCache.h" -#import -#if TARGET_OS_IPHONE -#import -#endif - - -#import -#if !__has_feature(objc_arc) -#error This class requires automatic reference counting -#endif - - -#pragma GCC diagnostic ignored "-Wobjc-missing-property-synthesis" -#pragma GCC diagnostic ignored "-Wdirect-ivar-access" -#pragma GCC diagnostic ignored "-Wgnu" - - -@interface OSCacheEntry : NSObject - -@property (nonatomic, strong) NSObject *object; -@property (nonatomic, assign) NSUInteger cost; -@property (nonatomic, assign) NSInteger sequenceNumber; - -@end - - -@implementation OSCacheEntry - -@end - - -@interface OSCache_Private : NSObject - -@property (nonatomic, unsafe_unretained) id delegate; -@property (nonatomic, assign) NSUInteger countLimit; -@property (nonatomic, assign) NSUInteger totalCostLimit; -@property (nonatomic, copy) NSString *name; - -@property (nonatomic, strong) NSMutableDictionary *cache; -@property (nonatomic, assign) NSUInteger totalCost; -@property (nonatomic, assign) NSInteger sequenceNumber; - -@end - - -@implementation OSCache_Private -{ - BOOL _delegateRespondsToWillEvictObject; - BOOL _delegateRespondsToShouldEvictObject; - BOOL _currentlyCleaning; - NSMutableArray *_entryPool; - NSLock *_lock; -} - -- (instancetype)init -{ - if ((self = [super init])) - { - //create storage - _cache = [[NSMutableDictionary alloc] init]; - _entryPool = [[NSMutableArray alloc] init]; - _lock = [[NSLock alloc] init]; - _totalCost = 0; - -#if TARGET_OS_IPHONE - - //clean up in the event of a memory warning - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cleanUpAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; - -#endif - - } - return self; -} - -- (void)dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; -} - -- (void)setDelegate:(id)delegate -{ - _delegate = delegate; - _delegateRespondsToShouldEvictObject = [delegate respondsToSelector:@selector(cache:shouldEvictObject:)]; - _delegateRespondsToWillEvictObject = [delegate respondsToSelector:@selector(cache:willEvictObject:)]; -} - -- (void)setCountLimit:(NSUInteger)countLimit -{ - [_lock lock]; - _countLimit = countLimit; - [_lock unlock]; - [self cleanUp:NO]; -} - -- (void)setTotalCostLimit:(NSUInteger)totalCostLimit -{ - [_lock lock]; - _totalCostLimit = totalCostLimit; - [_lock unlock]; - [self cleanUp:NO]; -} - -- (NSUInteger)count -{ - return [_cache count]; -} - -- (void)cleanUp:(BOOL)keepEntries -{ - [_lock lock]; - NSUInteger maxCount = _countLimit ?: INT_MAX; - NSUInteger maxCost = _totalCostLimit ?: INT_MAX; - NSUInteger totalCount = _cache.count; - NSMutableArray *keys = [_cache.allKeys mutableCopy]; - while (totalCount > maxCount || _totalCost > maxCost) - { - NSInteger lowestSequenceNumber = INT_MAX; - OSCacheEntry *lowestEntry = nil; - id lowestKey = nil; - - //remove oldest items until within limit - for (id key in keys) - { - OSCacheEntry *entry = _cache[key]; - if (entry.sequenceNumber < lowestSequenceNumber) - { - lowestSequenceNumber = entry.sequenceNumber; - lowestEntry = entry; - lowestKey = key; - } - } - - if (lowestKey) - { - [keys removeObject:lowestKey]; - if (!_delegateRespondsToShouldEvictObject || - [_delegate cache:(OSCache *)self shouldEvictObject:lowestEntry.object]) - { - if (_delegateRespondsToWillEvictObject) - { - _currentlyCleaning = YES; - [self.delegate cache:(OSCache *)self willEvictObject:lowestEntry.object]; - _currentlyCleaning = NO; - } - [_cache removeObjectForKey:lowestKey]; - _totalCost -= lowestEntry.cost; - totalCount --; - if (keepEntries) - { - [_entryPool addObject:lowestEntry]; - lowestEntry.object = nil; - } - } - } - } - [_lock unlock]; -} - -- (void)cleanUpAllObjects -{ - [_lock lock]; - if (_delegateRespondsToShouldEvictObject || _delegateRespondsToWillEvictObject) - { - NSArray *keys = [_cache allKeys]; - if (_delegateRespondsToShouldEvictObject) - { - //sort, oldest first (in case we want to use that information in our eviction test) - keys = [keys sortedArrayUsingComparator:^NSComparisonResult(id key1, id key2) { - OSCacheEntry *entry1 = self->_cache[key1]; - OSCacheEntry *entry2 = self->_cache[key2]; - return (NSComparisonResult)MIN(1, MAX(-1, entry1.sequenceNumber - entry2.sequenceNumber)); - }]; - } - - //remove all items individually - for (id key in keys) - { - OSCacheEntry *entry = _cache[key]; - if (!_delegateRespondsToShouldEvictObject || [_delegate cache:(OSCache *)self shouldEvictObject:entry.object]) - { - if (_delegateRespondsToWillEvictObject) - { - _currentlyCleaning = YES; - [_delegate cache:(OSCache *)self willEvictObject:entry.object]; - _currentlyCleaning = NO; - } - [_cache removeObjectForKey:key]; - _totalCost -= entry.cost; - } - } - } - else - { - _totalCost = 0; - [_cache removeAllObjects]; - _sequenceNumber = 0; - } - [_lock unlock]; -} - -- (void)resequence -{ - //sort, oldest first - NSArray *entries = [[_cache allValues] sortedArrayUsingComparator:^NSComparisonResult(OSCacheEntry *entry1, OSCacheEntry *entry2) { - return (NSComparisonResult)MIN(1, MAX(-1, entry1.sequenceNumber - entry2.sequenceNumber)); - }]; - - //renumber items - NSInteger index = 0; - for (OSCacheEntry *entry in entries) - { - entry.sequenceNumber = index++; - } -} - -- (id)objectForKey:(id)key -{ - [_lock lock]; - OSCacheEntry *entry = _cache[key]; - entry.sequenceNumber = _sequenceNumber++; - if (_sequenceNumber < 0) - { - [self resequence]; - } - id object = entry.object; - [_lock unlock]; - return object; -} - -- (id)objectForKeyedSubscript:(id)key -{ - return [self objectForKey:key]; -} - -- (void)setObject:(id)obj forKey:(id)key -{ - [self setObject:obj forKey:key cost:0]; -} - -- (void)setObject:(id)obj forKeyedSubscript:(id)key -{ - [self setObject:obj forKey:key cost:0]; -} - -- (void)setObject:(id)obj forKey:(id)key cost:(NSUInteger)g -{ - if (!obj) - { - [self removeObjectForKey:key]; - return; - } - NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method."); - [_lock lock]; - _totalCost -= [_cache[key] cost]; - _totalCost += g; - OSCacheEntry *entry = _cache[key]; - if (!entry) { - entry = [[OSCacheEntry alloc] init]; - _cache[key] = entry; - } - entry.object = obj; - entry.cost = g; - entry.sequenceNumber = _sequenceNumber++; - if (_sequenceNumber < 0) - { - [self resequence]; - } - [_lock unlock]; - [self cleanUp:YES]; -} - -- (void)removeObjectForKey:(id)key -{ - NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method."); - [_lock lock]; - OSCacheEntry *entry = _cache[key]; - if (entry) { - _totalCost -= entry.cost; - entry.object = nil; - [_entryPool addObject:entry]; - [_cache removeObjectForKey:key]; - } - [_lock unlock]; -} - -- (void)removeAllObjects -{ - NSAssert(!_currentlyCleaning, @"It is not possible to modify cache from within the implementation of this delegate method."); - [_lock lock]; - _totalCost = 0; - _sequenceNumber = 0; - for (OSCacheEntry *entry in _cache.allValues) - { - entry.object = nil; - [_entryPool addObject:entry]; - } - [_cache removeAllObjects]; - [_lock unlock]; -} - -- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state - objects:(id __unsafe_unretained [])buffer - count:(NSUInteger)len -{ - [_lock lock]; - NSUInteger count = [_cache countByEnumeratingWithState:state objects:buffer count:len]; - [_lock unlock]; - return count; -} - -- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block -{ - if (block) - { - [_lock lock]; - [_cache enumerateKeysAndObjectsUsingBlock:^(id key, OSCacheEntry *entry, BOOL *stop) { - block(key, entry.object, stop); - }]; - [_lock unlock]; - } -} - -//handle unimplemented methods - -- (BOOL)isKindOfClass:(Class)aClass -{ - //pretend that we're an NSCache if anyone asks - if (aClass == [OSCache class] || aClass == [NSCache class]) - { - return YES; - } - return [super isKindOfClass:aClass]; -} - -- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector -{ - //protect against calls to unimplemented NSCache methods - NSMethodSignature *signature = [super methodSignatureForSelector:selector]; - if (!signature) - { - signature = [NSCache instanceMethodSignatureForSelector:selector]; - } - return signature; -} - -- (void)forwardInvocation:(NSInvocation *)invocation -{ - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wnonnull" - - [invocation invokeWithTarget:nil]; - -#pragma clang diagnostic pop - -} - -@end - - -@implementation OSCache - -+ (instancetype)allocWithZone:(struct _NSZone *)zone -{ - return (OSCache *)[OSCache_Private allocWithZone:zone]; -} - -- (id)objectForKeyedSubscript:(__unused id)key { return nil; } -- (void)setObject:(__unused id)obj forKeyedSubscript:(__unused id)key {} -- (void)enumerateKeysAndObjectsUsingBlock:(__unused void (^)(id, id, BOOL *))block { } -- (NSUInteger)countByEnumeratingWithState:(__unused NSFastEnumerationState *)state - objects:(__unused __unsafe_unretained id [])buffer - count:(__unused NSUInteger)len { return 0; } - -@end diff --git a/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.h b/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.h deleted file mode 100644 index 6169bd27..00000000 --- a/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// FLEXNetworkObserver.h -// Derived from: -// -// PDAFNetworkDomainController.h -// PonyDebugger -// -// Created by Mike Lewis on 2/27/12. -// -// Licensed to Square, Inc. under one or more contributor license agreements. -// See the LICENSE file distributed with this work for the terms under -// which Square, Inc. licenses this file to you. -// - -#import - -FOUNDATION_EXTERN NSString *const kFLEXNetworkObserverEnabledStateChangedNotification; - -/// This class swizzles NSURLConnection and NSURLSession delegate methods to observe events in the URL loading system. -/// High level network events are sent to the default FLEXNetworkRecorder instance which maintains the request history and caches response bodies. -@interface FLEXNetworkObserver : NSObject - -/// Swizzling occurs when the observer is enabled for the first time. -/// This reduces the impact of FLEX if network debugging is not desired. -/// NOTE: this setting persists between launches of the app. -@property (nonatomic, class, getter=isEnabled) BOOL enabled; - -@end diff --git a/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.m b/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.m deleted file mode 100644 index 20e495a0..00000000 --- a/BHTwitter/Classes/Network/PonyDebugger/FLEXNetworkObserver.m +++ /dev/null @@ -1,1715 +0,0 @@ -// -// FLEXNetworkObserver.m -// Derived from: -// -// PDAFNetworkDomainController.m -// PonyDebugger -// -// Created by Mike Lewis on 2/27/12. -// -// Licensed to Square, Inc. under one or more contributor license agreements. -// See the LICENSE file distributed with this work for the terms under -// which Square, Inc. licenses this file to you. -// -// Heavily modified and added to by Tanner Bennett and various other contributors. -// git blame details these modifications. -// - -#import "FLEXNetworkObserver.h" -#import "FLEXNetworkRecorder.h" -#import "FLEXUtility.h" -#import "NSUserDefaults+FLEX.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXMethod.h" - -#import -#import -#import -#include - -NSString *const kFLEXNetworkObserverEnabledStateChangedNotification = @"kFLEXNetworkObserverEnabledStateChangedNotification"; - -typedef void (^NSURLSessionAsyncCompletion)(id fileURLOrData, NSURLResponse *response, NSError *error); -typedef NSURLSessionTask * (^NSURLSessionNewTaskMethod)(NSURLSession *, id, NSURLSessionAsyncCompletion); - -@interface FLEXInternalRequestState : NSObject - -@property (nonatomic, copy) NSURLRequest *request; -@property (nonatomic) NSMutableData *dataAccumulator; - -@end - -@implementation FLEXInternalRequestState - -@end - -@interface FLEXNetworkObserver (NSURLConnectionHelpers) - -- (void)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response delegate:(id)delegate; -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response delegate:(id)delegate; - -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data delegate:(id)delegate; - -- (void)connectionDidFinishLoading:(NSURLConnection *)connection delegate:(id)delegate; -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error delegate:(id)delegate; - -- (void)connectionWillCancel:(NSURLConnection *)connection; - -@end - - -@interface FLEXNetworkObserver (NSURLSessionTaskHelpers) - -- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest *))completionHandler delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask -didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite delegate:(id)delegate; -- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data delegate:(id)delegate; - -- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task; - -- (void)websocketTask:(NSURLSessionWebSocketTask *)task - sendMessagage:(NSURLSessionWebSocketMessage *)message API_AVAILABLE(ios(13.0)); -- (void)websocketTaskMessageSendCompletion:(NSURLSessionWebSocketMessage *)message - error:(NSError *)error API_AVAILABLE(ios(13.0)); - -- (void)websocketTask:(NSURLSessionWebSocketTask *)task - receiveMessagage:(NSURLSessionWebSocketMessage *)message - error:(NSError *)error API_AVAILABLE(ios(13.0)); - -@end - -@interface FLEXNetworkObserver () - -@property (nonatomic) NSMutableDictionary *requestStatesForRequestIDs; -@property (nonatomic) dispatch_queue_t queue; - -@end - -@implementation FLEXNetworkObserver - -#pragma mark - Public Methods - -+ (void)setEnabled:(BOOL)enabled { - BOOL previouslyEnabled = [self isEnabled]; - - NSUserDefaults.standardUserDefaults.flex_networkObserverEnabled = enabled; - - if (enabled) { - // Inject if needed. This injection is protected with a dispatch_once, so we're ok calling it multiple times. - // By doing the injection lazily, we keep the impact of the tool lower when this feature isn't enabled. - [self injectIntoAllNSURLThings]; - } - - if (previouslyEnabled != enabled) { - [NSNotificationCenter.defaultCenter postNotificationName:kFLEXNetworkObserverEnabledStateChangedNotification object:self]; - } -} - -+ (BOOL)isEnabled { - return NSUserDefaults.standardUserDefaults.flex_networkObserverEnabled; -} - -+ (void)load { - // We don't want to do the swizzling from +load because not all the classes may be loaded at this point. - dispatch_async(dispatch_get_main_queue(), ^{ - if ([self isEnabled]) { - [self injectIntoAllNSURLThings]; - } - }); -} - -#pragma mark - Statics - -+ (instancetype)sharedObserver { - static FLEXNetworkObserver *sharedObserver = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedObserver = [self new]; - }); - return sharedObserver; -} - -+ (NSString *)nextRequestID { - return NSUUID.UUID.UUIDString; -} - -#pragma mark Delegate Injection Convenience Methods - -/// All swizzled delegate methods should make use of this guard. -/// This will prevent duplicated sniffing when the original implementation calls up to a superclass -/// implementation which we've also swizzled. The superclass implementation (and implementations in -/// classes above that) will be executed without interference if called from the original implementation. -+ (void)sniffWithoutDuplicationForObject:(NSObject *)object selector:(SEL)selector - sniffingBlock:(void (^)(void))sniffingBlock originalImplementationBlock:(void (^)(void))originalImplementationBlock { - // If we don't have an object to detect nested calls on, just run the original implementation and bail. - // This case can happen if someone besides the URL loading system calls the delegate methods directly. - // See https://github.com/Flipboard/FLEX/issues/61 for an example. - if (!object) { - originalImplementationBlock(); - return; - } - - const void *key = selector; - - // Don't run the sniffing block if we're inside a nested call - if (!objc_getAssociatedObject(object, key)) { - sniffingBlock(); - } - - // Mark that we're calling through to the original so we can detect nested calls - objc_setAssociatedObject(object, key, @YES, OBJC_ASSOCIATION_RETAIN_NONATOMIC); - originalImplementationBlock(); - objc_setAssociatedObject(object, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC); -} - -#pragma mark - Delegate Injection - -+ (void)injectIntoAllNSURLThings { - // Only allow swizzling once. - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // Swizzle any classes that implement one of these selectors. - const SEL selectors[] = { - @selector(connectionDidFinishLoading:), - @selector(connection:willSendRequest:redirectResponse:), - @selector(connection:didReceiveResponse:), - @selector(connection:didReceiveData:), - @selector(connection:didFailWithError:), - @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:), - @selector(URLSession:dataTask:didReceiveData:), - @selector(URLSession:dataTask:didReceiveResponse:completionHandler:), - @selector(URLSession:task:didCompleteWithError:), - @selector(URLSession:dataTask:didBecomeDownloadTask:), - @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:), - @selector(URLSession:downloadTask:didFinishDownloadingToURL:) - }; - - const int numSelectors = sizeof(selectors) / sizeof(SEL); - - Class *classes = NULL; - int numClasses = objc_getClassList(NULL, 0); - - if (numClasses > 0) { - classes = (__unsafe_unretained Class *)malloc(sizeof(Class) * numClasses); - numClasses = objc_getClassList(classes, numClasses); - for (NSInteger classIndex = 0; classIndex < numClasses; ++classIndex) { - Class class = classes[classIndex]; - - if (class == [FLEXNetworkObserver class]) { - continue; - } - - // Use the C API rather than NSObject methods to avoid sending messages - // to classes we're not interested in swizzling, which could result - // in us calling +initialize on potentially uninitialized classes. - // NOTE: calling class_getInstanceMethod() DOES send +initialize - // to the class. That's why we iterate through the method list. - unsigned int methodCount = 0; - Method *methods = class_copyMethodList(class, &methodCount); - BOOL matchingSelectorFound = NO; - for (unsigned int methodIndex = 0; methodIndex < methodCount; methodIndex++) { - for (int selectorIndex = 0; selectorIndex < numSelectors; ++selectorIndex) { - if (method_getName(methods[methodIndex]) == selectors[selectorIndex]) { - [self injectIntoDelegateClass:class]; - matchingSelectorFound = YES; - break; - } - } - if (matchingSelectorFound) { - break; - } - } - - free(methods); - } - - free(classes); - } - - [self injectIntoNSURLConnectionCancel]; - [self injectIntoNSURLSessionTaskResume]; - - [self injectIntoNSURLConnectionAsynchronousClassMethod]; - [self injectIntoNSURLConnectionSynchronousClassMethod]; - - [self injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods]; - [self injectIntoNSURLSessionAsyncUploadTaskMethods]; - - if (@available(iOS 13.0, *)) { - Class websocketTask = NSClassFromString(@"__NSURLSessionWebSocketTask"); - [self injectWebsocketSendMessage:websocketTask]; - [self injectWebsocketReceiveMessage:websocketTask]; - websocketTask = [NSURLSessionWebSocketTask class]; - [self injectWebsocketSendMessage:websocketTask]; - [self injectWebsocketReceiveMessage:websocketTask]; - } - }); -} - -+ (void)injectIntoDelegateClass:(Class)cls { - // Connections - [self injectWillSendRequestIntoDelegateClass:cls]; - [self injectDidReceiveDataIntoDelegateClass:cls]; - [self injectDidReceiveResponseIntoDelegateClass:cls]; - [self injectDidFinishLoadingIntoDelegateClass:cls]; - [self injectDidFailWithErrorIntoDelegateClass:cls]; - - // Sessions - [self injectTaskWillPerformHTTPRedirectionIntoDelegateClass:cls]; - [self injectTaskDidReceiveDataIntoDelegateClass:cls]; - [self injectTaskDidReceiveResponseIntoDelegateClass:cls]; - [self injectTaskDidCompleteWithErrorIntoDelegateClass:cls]; - [self injectRespondsToSelectorIntoDelegateClass:cls]; - - // Data tasks - [self injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:cls]; - - // Download tasks - [self injectDownloadTaskDidWriteDataIntoDelegateClass:cls]; - [self injectDownloadTaskDidFinishDownloadingIntoDelegateClass:cls]; -} - -+ (void)injectIntoNSURLConnectionCancel { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = [NSURLConnection class]; - SEL selector = @selector(cancel); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - Method originalCancel = class_getInstanceMethod(class, selector); - - void (^swizzleBlock)(NSURLConnection *) = ^(NSURLConnection *slf) { - [FLEXNetworkObserver.sharedObserver connectionWillCancel:slf]; - ((void(*)(id, SEL))objc_msgSend)( - slf, swizzledSelector - ); - }; - - IMP implementation = imp_implementationWithBlock(swizzleBlock); - class_addMethod(class, swizzledSelector, implementation, method_getTypeEncoding(originalCancel)); - Method newCancel = class_getInstanceMethod(class, swizzledSelector); - method_exchangeImplementations(originalCancel, newCancel); - }); -} - -+ (void)injectIntoNSURLSessionTaskResume { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - // In iOS 7 resume lives in __NSCFLocalSessionTask - // In iOS 8 resume lives in NSURLSessionTask - // In iOS 9 resume lives in __NSCFURLSessionTask - // In iOS 14 resume lives in NSURLSessionTask - Class baseResumeClass = Nil; - if (![NSProcessInfo.processInfo respondsToSelector:@selector(operatingSystemVersion)]) { - // iOS ... 7 - baseResumeClass = NSClassFromString(@"__NSCFLocalSessionTask"); - } else { - NSInteger majorVersion = NSProcessInfo.processInfo.operatingSystemVersion.majorVersion; - if (majorVersion < 9 || majorVersion >= 14) { - // iOS 8 or iOS 14+ - baseResumeClass = [NSURLSessionTask class]; - } else { - // iOS 9 ... 13 - baseResumeClass = NSClassFromString(@"__NSCFURLSessionTask"); - } - } - - // Hook the base implementation of -resume - IMP originalResume = [baseResumeClass instanceMethodForSelector:@selector(resume)]; - [self swizzleResumeSelector:@selector(resume) forClass:baseResumeClass]; - - // *Sigh* - // - // So, multiple versions of AFNetworking 2.5.X swizzle -resume in various and - // short-sighted ways. If you look through the version history from 2.5.0 upwards, - // you'll see a variety of techniques were tried, including taking a private - // subclass of NSURLSessionTask and calling class_addMethod with `originalResume` - // below, so that a duplicate implementation of -resume exists in that class. - // - // This technique in particular is troublesome, because the implementation in - // `baseResumeClass` is never called at all, which means our swizzle is never invoked. - // - // The only solution is a brute-force one: we must loop over the class tree - // below `baseResumeClass` and check for all classes that implement `af_resume`. - // if the IMP corresponding to that method is equal to `originalResume` then we - // swizzle that in addition to swizzling `resume` on `baseResumeClass` above. - // - // However, we only go to the trouble at all if NSSelectorFromString - // can even find an `"af_resume"` selector in the first place. - SEL sel_af_resume = NSSelectorFromString(@"af_resume"); - if (sel_af_resume) { - NSMutableArray *classTree = FLEXGetAllSubclasses(baseResumeClass, NO).mutableCopy; - for (NSInteger i = 0; i < classTree.count; i++) { - [classTree addObjectsFromArray:FLEXGetAllSubclasses(classTree[i], NO)]; - } - - for (Class current in classTree) { - IMP af_resume = [current instanceMethodForSelector:sel_af_resume]; - if (af_resume == originalResume) { - [self swizzleResumeSelector:sel_af_resume forClass:current]; - } - } - } - }); -} - -+ (void)swizzleResumeSelector:(SEL)selector forClass:(Class)class { - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - Method originalResume = class_getInstanceMethod(class, selector); - IMP implementation = imp_implementationWithBlock(^(NSURLSessionTask *slf) { - - // iOS's internal HTTP parser finalization code is mysteriously not thread safe, - // invoking it asynchronously has a chance to cause a `double free` crash. - // This line below will ask for HTTPBody synchronously, make the HTTPParser - // parse the request, and cache them in advance. After that the HTTPParser - // will be finalized. Make sure other threads inspecting the request - // won't trigger a race to finalize the parser. - [slf.currentRequest HTTPBody]; - - [FLEXNetworkObserver.sharedObserver URLSessionTaskWillResume:slf]; - ((void(*)(id, SEL))objc_msgSend)( - slf, swizzledSelector - ); - }); - - class_addMethod(class, swizzledSelector, implementation, method_getTypeEncoding(originalResume)); - Method newResume = class_getInstanceMethod(class, swizzledSelector); - method_exchangeImplementations(originalResume, newResume); -} - -+ (void)injectIntoNSURLConnectionAsynchronousClassMethod { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = objc_getMetaClass(class_getName([NSURLConnection class])); - SEL selector = @selector(sendAsynchronousRequest:queue:completionHandler:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - typedef void (^AsyncCompletion)( - NSURLResponse *response, NSData *data, NSError *error - ); - typedef void (^SendAsyncRequestBlock)( - Class, NSURLRequest *, NSOperationQueue *, AsyncCompletion - ); - SendAsyncRequestBlock swizzleBlock = ^(Class slf, - NSURLRequest *request, - NSOperationQueue *queue, - AsyncCompletion completion) { - if (FLEXNetworkObserver.isEnabled) { - NSString *requestID = [self nextRequestID]; - [FLEXNetworkRecorder.defaultRecorder - recordRequestWillBeSentWithRequestID:requestID - request:request - redirectResponse:nil - ]; - - NSString *mechanism = [self mechanismFromClassMethod:selector onClass:class]; - [FLEXNetworkRecorder.defaultRecorder recordMechanism:mechanism forRequestID:requestID]; - - AsyncCompletion wrapper = ^(NSURLResponse *response, NSData *data, NSError *error) { - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:response - ]; - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:data.length - ]; - if (error) { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFailedWithRequestID:requestID - error:error - ]; - } else { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFinishedWithRequestID:requestID - responseBody:data - ]; - } - - // Call through to the original completion handler - if (completion) { - completion(response, data, error); - } - }; - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, request, queue, wrapper - ); - } else { - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, request, queue, completion - ); - } - }; - - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:class withBlock:swizzleBlock swizzledSelector:swizzledSelector - ]; - }); -} - -+ (void)injectIntoNSURLConnectionSynchronousClassMethod { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = objc_getMetaClass(class_getName([NSURLConnection class])); - SEL selector = @selector(sendSynchronousRequest:returningResponse:error:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - typedef NSData * (^AsyncCompletion)(Class, NSURLRequest *, NSURLResponse **, NSError **); - AsyncCompletion swizzleBlock = ^NSData *(Class slf, - NSURLRequest *request, - NSURLResponse **response, - NSError **error) { - NSData *data = nil; - if (FLEXNetworkObserver.isEnabled) { - NSString *requestID = [self nextRequestID]; - [FLEXNetworkRecorder.defaultRecorder - recordRequestWillBeSentWithRequestID:requestID - request:request - redirectResponse:nil - ]; - - NSString *mechanism = [self mechanismFromClassMethod:selector onClass:class]; - [FLEXNetworkRecorder.defaultRecorder recordMechanism:mechanism forRequestID:requestID]; - NSError *temporaryError = nil; - NSURLResponse *temporaryResponse = nil; - data = ((id(*)(id, SEL, id, NSURLResponse **, NSError **))objc_msgSend)( - slf, swizzledSelector, request, &temporaryResponse, &temporaryError - ); - - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:temporaryResponse - ]; - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:data.length - ]; - - if (temporaryError) { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFailedWithRequestID:requestID - error:temporaryError - ]; - } else { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFinishedWithRequestID:requestID - responseBody:data - ]; - } - - if (error) { - *error = temporaryError; - } - if (response) { - *response = temporaryResponse; - } - } else { - data = ((id(*)(id, SEL, id, NSURLResponse **, NSError **))objc_msgSend)( - slf, swizzledSelector, request, response, error - ); - } - - return data; - }; - - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:class withBlock:swizzleBlock swizzledSelector:swizzledSelector - ]; - }); -} - -+ (void)injectIntoNSURLSessionAsyncDataAndDownloadTaskMethods { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = [NSURLSession class]; - - // The method signatures here are close enough that - // we can use the same logic to inject into all of them. - const SEL selectors[] = { - @selector(dataTaskWithRequest:completionHandler:), - @selector(dataTaskWithURL:completionHandler:), - @selector(downloadTaskWithRequest:completionHandler:), - @selector(downloadTaskWithResumeData:completionHandler:), - @selector(downloadTaskWithURL:completionHandler:) - }; - - const int numSelectors = sizeof(selectors) / sizeof(SEL); - - for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { - SEL selector = selectors[selectorIndex]; - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:class]) { - // iOS 7 does not implement these methods on NSURLSession. We actually want to - // swizzle __NSCFURLSession, which we can get from the class of the shared session - class = [NSURLSession.sharedSession class]; - } - - typedef NSURLSessionTask * (^NSURLSessionNewTaskMethod)( - NSURLSession *, id, NSURLSessionAsyncCompletion - ); - NSURLSessionNewTaskMethod swizzleBlock = ^NSURLSessionTask *(NSURLSession *slf, - id argument, - NSURLSessionAsyncCompletion completion) { - NSURLSessionTask *task = nil; - // Check if network observing is on and a callback was provided - if (FLEXNetworkObserver.isEnabled && completion) { - NSString *requestID = [self nextRequestID]; - NSString *mechanism = [self mechanismFromClassMethod:selector onClass:class]; - // "Hook" the completion block - NSURLSessionAsyncCompletion completionWrapper = [self - asyncCompletionWrapperForRequestID:requestID - mechanism:mechanism - completion:completion - ]; - - // Call the original method - task = ((id(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, argument, completionWrapper - ); - [self setRequestID:requestID forConnectionOrTask:task]; - } else { - // Network observer disabled or no callback provided, - // just pass through to the original method - task = ((id(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, argument, completion - ); - } - return task; - }; - - // Actually swizzle - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:class withBlock:swizzleBlock swizzledSelector:swizzledSelector - ]; - } - }); -} - -+ (void)injectIntoNSURLSessionAsyncUploadTaskMethods { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - Class class = [NSURLSession class]; - - // The method signatures here are close enough that we can use the same logic to inject into both of them. - // Note that they have 3 arguments, so we can't easily combine with the data and download method above. - typedef NSURLSessionUploadTask *(^UploadTaskMethod)( - NSURLSession *, NSURLRequest *, id, NSURLSessionAsyncCompletion - ); - const SEL selectors[] = { - @selector(uploadTaskWithRequest:fromData:completionHandler:), - @selector(uploadTaskWithRequest:fromFile:completionHandler:) - }; - - const int numSelectors = sizeof(selectors) / sizeof(SEL); - - for (int selectorIndex = 0; selectorIndex < numSelectors; selectorIndex++) { - SEL selector = selectors[selectorIndex]; - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - if ([FLEXUtility instanceRespondsButDoesNotImplementSelector:selector class:class]) { - // iOS 7 does not implement these methods on NSURLSession. We actually want to - // swizzle __NSCFURLSession, which we can get from the class of the shared session - class = [NSURLSession.sharedSession class]; - } - - - UploadTaskMethod swizzleBlock = ^NSURLSessionUploadTask *(NSURLSession * slf, - NSURLRequest *request, - id argument, - NSURLSessionAsyncCompletion completion) { - NSURLSessionUploadTask *task = nil; - if (FLEXNetworkObserver.isEnabled && completion) { - NSString *requestID = [self nextRequestID]; - NSString *mechanism = [self mechanismFromClassMethod:selector onClass:class]; - NSURLSessionAsyncCompletion completionWrapper = [self - asyncCompletionWrapperForRequestID:requestID - mechanism:mechanism - completion:completion - ]; - - task = ((id(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, request, argument, completionWrapper - ); - [self setRequestID:requestID forConnectionOrTask:task]; - } else { - task = ((id(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, request, argument, completion - ); - } - return task; - }; - - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:class withBlock:swizzleBlock swizzledSelector:swizzledSelector - ]; - } - }); -} - -+ (NSString *)mechanismFromClassMethod:(SEL)selector onClass:(Class)class { - return [NSString stringWithFormat:@"+[%@ %@]", NSStringFromClass(class), NSStringFromSelector(selector)]; -} - -+ (NSURLSessionAsyncCompletion)asyncCompletionWrapperForRequestID:(NSString *)requestID - mechanism:(NSString *)mechanism - completion:(NSURLSessionAsyncCompletion)completion { - NSURLSessionAsyncCompletion completionWrapper = ^(id fileURLOrData, NSURLResponse *response, NSError *error) { - [FLEXNetworkRecorder.defaultRecorder recordMechanism:mechanism forRequestID:requestID]; - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:response - ]; - - NSData *data = nil; - if ([fileURLOrData isKindOfClass:[NSURL class]]) { - data = [NSData dataWithContentsOfURL:fileURLOrData]; - } else if ([fileURLOrData isKindOfClass:[NSData class]]) { - data = fileURLOrData; - } - - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:data.length - ]; - - if (error) { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFailedWithRequestID:requestID - error:error - ]; - } else { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFinishedWithRequestID:requestID - responseBody:data - ]; - } - - // Call through to the original completion handler - if (completion) { - completion(fileURLOrData, response, error); - } - }; - return completionWrapper; -} - -+ (void)injectWillSendRequestIntoDelegateClass:(Class)cls { - SEL selector = @selector(connection:willSendRequest:redirectResponse:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - Protocol *protocol = @protocol(NSURLConnectionDataDelegate); - protocol = protocol ?: @protocol(NSURLConnectionDelegate); - struct objc_method_description methodDescription = protocol_getMethodDescription( - protocol, selector, NO, YES - ); - - typedef NSURLRequest *(^WillSendRequestBlock)( - id slf, NSURLConnection *connection, - NSURLRequest *request, NSURLResponse *response - ); - - WillSendRequestBlock undefinedBlock = ^NSURLRequest *(id slf, - NSURLConnection *connection, - NSURLRequest *request, - NSURLResponse *response) { - [FLEXNetworkObserver.sharedObserver - connection:connection - willSendRequest:request - redirectResponse:response - delegate:slf - ]; - return request; - }; - - WillSendRequestBlock implementationBlock = ^NSURLRequest *(id slf, - NSURLConnection *connection, - NSURLRequest *request, - NSURLResponse *response) { - __block NSURLRequest *returnValue = nil; - [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ - undefinedBlock(slf, connection, request, response); - } originalImplementationBlock:^{ - returnValue = ((id(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, connection, request, response - ); - }]; - return returnValue; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:methodDescription - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDidReceiveResponseIntoDelegateClass:(Class)cls { - SEL selector = @selector(connection:didReceiveResponse:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - Protocol *protocol = @protocol(NSURLConnectionDataDelegate); - protocol = protocol ?: @protocol(NSURLConnectionDelegate); - struct objc_method_description description = protocol_getMethodDescription( - protocol, selector, NO, YES - ); - - typedef void (^DidReceiveResponseBlock)( - id slf, NSURLConnection *connection, NSURLResponse *response - ); - - DidReceiveResponseBlock undefinedBlock = ^(id slf, - NSURLConnection *connection, - NSURLResponse *response) { - [FLEXNetworkObserver.sharedObserver connection:connection - didReceiveResponse:response delegate:slf - ]; - }; - - DidReceiveResponseBlock implementationBlock = ^(id slf, - NSURLConnection *connection, - NSURLResponse *response) { - [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ - undefinedBlock(slf, connection, response); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, connection, response - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDidReceiveDataIntoDelegateClass:(Class)cls { - SEL selector = @selector(connection:didReceiveData:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - Protocol *protocol = @protocol(NSURLConnectionDataDelegate); - protocol = protocol ?: @protocol(NSURLConnectionDelegate); - struct objc_method_description description = protocol_getMethodDescription( - protocol, selector, NO, YES - ); - - typedef void (^DidReceiveDataBlock)( - id slf, NSURLConnection *connection, NSData *data - ); - - DidReceiveDataBlock undefinedBlock = ^(id slf, - NSURLConnection *connection, - NSData *data) { - [FLEXNetworkObserver.sharedObserver connection:connection - didReceiveData:data delegate:slf - ]; - }; - - DidReceiveDataBlock implementationBlock = ^(id slf, - NSURLConnection *connection, - NSData *data) { - [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ - undefinedBlock(slf, connection, data); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, connection, data - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDidFinishLoadingIntoDelegateClass:(Class)cls { - SEL selector = @selector(connectionDidFinishLoading:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - Protocol *protocol = @protocol(NSURLConnectionDataDelegate); - protocol = protocol ?: @protocol(NSURLConnectionDelegate); - struct objc_method_description description = protocol_getMethodDescription( - protocol, selector, NO, YES - ); - - typedef void (^FinishLoadingBlock)(id slf, NSURLConnection *connection); - - FinishLoadingBlock undefinedBlock = ^(id slf, NSURLConnection *connection) { - [FLEXNetworkObserver.sharedObserver connectionDidFinishLoading:connection delegate:slf]; - }; - - FinishLoadingBlock implementationBlock = ^(id slf, NSURLConnection *connection) { - [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ - undefinedBlock(slf, connection); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id))objc_msgSend)( - slf, swizzledSelector, connection - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDidFailWithErrorIntoDelegateClass:(Class)cls { - SEL selector = @selector(connection:didFailWithError:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLConnectionDelegate), selector, NO, YES - ); - - typedef void (^DidFailWithErrorBlock)( - id slf, NSURLConnection *connection, NSError *error - ); - - DidFailWithErrorBlock undefinedBlock = ^(id slf, - NSURLConnection *connection, - NSError *error) { - [FLEXNetworkObserver.sharedObserver connection:connection - didFailWithError:error delegate:slf - ]; - }; - - DidFailWithErrorBlock implementationBlock = ^(id slf, - NSURLConnection *connection, - NSError *error) { - [self sniffWithoutDuplicationForObject:connection selector:selector sniffingBlock:^{ - undefinedBlock(slf, connection, error); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, connection, error - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectTaskWillPerformHTTPRedirectionIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionTaskDelegate), selector, NO, YES - ); - - typedef void (^HTTPRedirectionBlock)(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSHTTPURLResponse *response, - NSURLRequest *newRequest, - void(^completionHandler)(NSURLRequest *)); - - HTTPRedirectionBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSHTTPURLResponse *response, - NSURLRequest *newRequest, - void(^completionHandler)(NSURLRequest *)) { - [FLEXNetworkObserver.sharedObserver - URLSession:session task:task - willPerformHTTPRedirection:response - newRequest:newRequest - completionHandler:completionHandler - delegate:slf - ]; - completionHandler(newRequest); - }; - - HTTPRedirectionBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSHTTPURLResponse *response, - NSURLRequest *newRequest, - void(^completionHandler)(NSURLRequest *)) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - [FLEXNetworkObserver.sharedObserver - URLSession:session task:task - willPerformHTTPRedirection:response - newRequest:newRequest - completionHandler:completionHandler - delegate:slf - ]; - } originalImplementationBlock:^{ - ((id(*)(id, SEL, id, id, id, id, void(^)(NSURLRequest *)))objc_msgSend)( - slf, swizzledSelector, session, task, response, newRequest, completionHandler - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectTaskDidReceiveDataIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:dataTask:didReceiveData:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDataDelegate), selector, NO, YES - ); - - typedef void (^DidReceiveDataBlock)(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSData *data); - DidReceiveDataBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSData *data) { - [FLEXNetworkObserver.sharedObserver URLSession:session - dataTask:dataTask didReceiveData:data delegate:slf - ]; - }; - - DidReceiveDataBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSData *data) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - undefinedBlock(slf, session, dataTask, data); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, session, dataTask, data - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDataTaskDidBecomeDownloadTaskIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:dataTask:didBecomeDownloadTask:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDataDelegate), selector, NO, YES - ); - - typedef void (^DidBecomeDownloadTaskBlock)(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLSessionDownloadTask *downloadTask); - - DidBecomeDownloadTaskBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLSessionDownloadTask *downloadTask) { - [FLEXNetworkObserver.sharedObserver URLSession:session - dataTask:dataTask didBecomeDownloadTask:downloadTask delegate:slf - ]; - }; - - DidBecomeDownloadTaskBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLSessionDownloadTask *downloadTask) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - undefinedBlock(slf, session, dataTask, downloadTask); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, session, dataTask, downloadTask - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectTaskDidReceiveResponseIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:dataTask:didReceiveResponse:completionHandler:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDataDelegate), selector, NO, YES - ); - - typedef void (^DidReceiveResponseBlock)(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLResponse *response, - void(^completion)(NSURLSessionResponseDisposition)); - - DidReceiveResponseBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLResponse *response, - void(^completion)(NSURLSessionResponseDisposition)) { - [FLEXNetworkObserver.sharedObserver - URLSession:session - dataTask:dataTask - didReceiveResponse:response - completionHandler:completion - delegate:slf - ]; - completion(NSURLSessionResponseAllow); - }; - - DidReceiveResponseBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDataTask *dataTask, - NSURLResponse *response, - void(^completion)(NSURLSessionResponseDisposition )) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - [FLEXNetworkObserver.sharedObserver - URLSession:session - dataTask:dataTask - didReceiveResponse:response - completionHandler:completion - delegate:slf - ]; - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, id, void(^)(NSURLSessionResponseDisposition)))objc_msgSend)( - slf, swizzledSelector, session, dataTask, response, completion - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; - -} - -+ (void)injectTaskDidCompleteWithErrorIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:task:didCompleteWithError:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDataDelegate), selector, NO, YES - ); - - typedef void (^DidCompleteWithErrorBlock)(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSError *error); - - DidCompleteWithErrorBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSError *error) { - [FLEXNetworkObserver.sharedObserver URLSession:session - task:task didCompleteWithError:error delegate:slf - ]; - }; - - DidCompleteWithErrorBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionTask *task, - NSError *error) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - undefinedBlock(slf, session, task, error); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, session, task, error - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -// Used for overriding AFNetworking behavior -+ (void)injectRespondsToSelectorIntoDelegateClass:(Class)cls { - SEL selector = @selector(respondsToSelector:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - //Protocol *protocol = @protocol(NSURLSessionTaskDelegate); - Method method = class_getInstanceMethod(cls, selector); - struct objc_method_description methodDescription = *method_getDescription(method); - - typedef BOOL (^RespondsToSelectorImpl)(id self, SEL sel); - RespondsToSelectorImpl undefinedBlock = ^(id slf, SEL sel) { - return YES; - }; - - RespondsToSelectorImpl implementationBlock = ^(id slf, SEL sel) { - if (sel == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { - return undefinedBlock(slf, sel); - } - return ((BOOL(*)(id, SEL, SEL))objc_msgSend)(slf, swizzledSelector, sel); - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:methodDescription - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDownloadTaskDidFinishDownloadingIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:downloadTask:didFinishDownloadingToURL:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDownloadDelegate), selector, NO, YES - ); - - typedef void (^DidFinishDownloadingBlock)(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - NSURL *location); - - DidFinishDownloadingBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - NSURL *location) { - NSData *data = [NSData dataWithContentsOfFile:location.relativePath]; - [FLEXNetworkObserver.sharedObserver URLSession:session - task:task didFinishDownloadingToURL:location data:data delegate:slf - ]; - }; - - DidFinishDownloadingBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - NSURL *location) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - undefinedBlock(slf, session, task, location); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, id))objc_msgSend)( - slf, swizzledSelector, session, task, location - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectDownloadTaskDidWriteDataIntoDelegateClass:(Class)cls { - SEL selector = @selector(URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - struct objc_method_description description = protocol_getMethodDescription( - @protocol(NSURLSessionDownloadDelegate), selector, NO, YES - ); - - typedef void (^DidWriteDataBlock)(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - int64_t bytesWritten, - int64_t totalBytesWritten, - int64_t totalBytesExpectedToWrite); - - DidWriteDataBlock undefinedBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - int64_t bytesWritten, - int64_t totalBytesWritten, - int64_t totalBytesExpectedToWrite) { - [FLEXNetworkObserver.sharedObserver URLSession:session - downloadTask:task didWriteData:bytesWritten - totalBytesWritten:totalBytesWritten - totalBytesExpectedToWrite:totalBytesExpectedToWrite - delegate:slf - ]; - }; - - DidWriteDataBlock implementationBlock = ^(id slf, - NSURLSession *session, - NSURLSessionDownloadTask *task, - int64_t bytesWritten, - int64_t totalBytesWritten, - int64_t totalBytesExpectedToWrite) { - [self sniffWithoutDuplicationForObject:session selector:selector sniffingBlock:^{ - undefinedBlock( - slf, session, task, bytesWritten, - totalBytesWritten, totalBytesExpectedToWrite - ); - } originalImplementationBlock:^{ - ((void(*)(id, SEL, id, id, int64_t, int64_t, int64_t))objc_msgSend)( - slf, swizzledSelector, session, task, bytesWritten, - totalBytesWritten, totalBytesExpectedToWrite - ); - }]; - }; - - [FLEXUtility replaceImplementationOfSelector:selector - withSelector:swizzledSelector - forClass:cls - withMethodDescription:description - implementationBlock:implementationBlock - undefinedBlock:undefinedBlock - ]; -} - -+ (void)injectWebsocketSendMessage:(Class)cls API_AVAILABLE(ios(13.0)) { - SEL selector = @selector(sendMessage:completionHandler:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - typedef void (^SendMessageBlock)( - NSURLSessionWebSocketTask *slf, - NSURLSessionWebSocketMessage *message, - void (^completion)(NSError *error) - ); - - SendMessageBlock implementationBlock = ^( - NSURLSessionWebSocketTask *slf, - NSURLSessionWebSocketMessage *message, - void (^completion)(NSError *error) - ) { - [FLEXNetworkObserver.sharedObserver - websocketTask:slf sendMessagage:message - ]; - completion = ^(NSError *error) { - [FLEXNetworkObserver.sharedObserver - websocketTaskMessageSendCompletion:message - error:error - ]; - }; - - ((void(*)(id, SEL, id, id))objc_msgSend)( - slf, swizzledSelector, message, completion - ); - }; - - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:cls - withBlock:implementationBlock - swizzledSelector:swizzledSelector - ]; -} - -+ (void)injectWebsocketReceiveMessage:(Class)cls API_AVAILABLE(ios(13.0)) { - SEL selector = @selector(receiveMessageWithCompletionHandler:); - SEL swizzledSelector = [FLEXUtility swizzledSelectorForSelector:selector]; - - typedef void (^SendMessageBlock)( - NSURLSessionWebSocketTask *slf, - void (^completion)(NSURLSessionWebSocketMessage *message, NSError *error) - ); - - SendMessageBlock implementationBlock = ^( - NSURLSessionWebSocketTask *slf, - void (^completion)(NSURLSessionWebSocketMessage *message, NSError *error) - ) { - id completionHook = ^(NSURLSessionWebSocketMessage *message, NSError *error) { - [FLEXNetworkObserver.sharedObserver - websocketTask:slf receiveMessagage:message error:error - ]; - completion(message, error); - }; - - ((void(*)(id, SEL, id))objc_msgSend)( - slf, swizzledSelector, completionHook - ); - - }; - - [FLEXUtility replaceImplementationOfKnownSelector:selector - onClass:cls - withBlock:implementationBlock - swizzledSelector:swizzledSelector - ]; -} - -static char const * const kFLEXRequestIDKey = "kFLEXRequestIDKey"; - -+ (NSString *)requestIDForConnectionOrTask:(id)connectionOrTask { - NSString *requestID = objc_getAssociatedObject(connectionOrTask, kFLEXRequestIDKey); - if (!requestID) { - requestID = [self nextRequestID]; - [self setRequestID:requestID forConnectionOrTask:connectionOrTask]; - } - return requestID; -} - -+ (void)setRequestID:(NSString *)requestID forConnectionOrTask:(id)connectionOrTask { - objc_setAssociatedObject( - connectionOrTask, kFLEXRequestIDKey, requestID, OBJC_ASSOCIATION_RETAIN_NONATOMIC - ); -} - -#pragma mark - Initialization - -- (id)init { - self = [super init]; - if (self) { - self.requestStatesForRequestIDs = [NSMutableDictionary new]; - self.queue = dispatch_queue_create( - "com.flex.FLEXNetworkObserver", DISPATCH_QUEUE_SERIAL - ); - } - - return self; -} - -#pragma mark - Private Methods - -- (void)performBlock:(dispatch_block_t)block { - if ([[self class] isEnabled]) { - dispatch_async(_queue, block); - } -} - -- (FLEXInternalRequestState *)requestStateForRequestID:(NSString *)requestID { - FLEXInternalRequestState *requestState = self.requestStatesForRequestIDs[requestID]; - if (!requestState) { - requestState = [FLEXInternalRequestState new]; - [self.requestStatesForRequestIDs setObject:requestState forKey:requestID]; - } - - return requestState; -} - -- (void)removeRequestStateForRequestID:(NSString *)requestID { - [self.requestStatesForRequestIDs removeObjectForKey:requestID]; -} - -@end - - -@implementation FLEXNetworkObserver (NSURLConnectionHelpers) - -- (void)connection:(NSURLConnection *)connection - willSendRequest:(NSURLRequest *)request - redirectResponse:(NSURLResponse *)response - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - requestState.request = request; - - [FLEXNetworkRecorder.defaultRecorder - recordRequestWillBeSentWithRequestID:requestID - request:request - redirectResponse:response - ]; - - NSString *mechanism = [NSString stringWithFormat: - @"NSURLConnection (delegate: %@)", [delegate class] - ]; - [FLEXNetworkRecorder.defaultRecorder recordMechanism:mechanism forRequestID:requestID]; - }]; -} - -- (void)connection:(NSURLConnection *)connection -didReceiveResponse:(NSURLResponse *)response - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - requestState.dataAccumulator = [NSMutableData new]; - - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:response - ]; - }]; -} - -- (void)connection:(NSURLConnection *)connection - didReceiveData:(NSData *)data - delegate:(id)delegate { - // Just to be safe since we're doing this async - data = [data copy]; - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - [requestState.dataAccumulator appendData:data]; - - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:data.length - ]; - }]; -} - -- (void)connectionDidFinishLoading:(NSURLConnection *)connection - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFinishedWithRequestID:requestID - responseBody:requestState.dataAccumulator - ]; - [self removeRequestStateForRequestID:requestID]; - }]; -} - -- (void)connection:(NSURLConnection *)connection - didFailWithError:(NSError *)error - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:connection]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - - // Cancellations can occur prior to the willSendRequest:... - // NSURLConnection delegate call. These are pretty common - // and clutter up the logs. Only record the failure if the - // recorder already knows about the request through willSendRequest:... - if (requestState.request) { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFailedWithRequestID:requestID error:error - ]; - } - - [self removeRequestStateForRequestID:requestID]; - }]; -} - -- (void)connectionWillCancel:(NSURLConnection *)connection { - [self performBlock:^{ - // Mimic the behavior of NSURLSession which is to create an error on cancellation. - NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : @"cancelled" }; - NSError *error = [NSError errorWithDomain:NSURLErrorDomain - code:NSURLErrorCancelled userInfo:userInfo - ]; - [self connection:connection didFailWithError:error delegate:nil]; - }]; -} - -@end - - -@implementation FLEXNetworkObserver (NSURLSessionTaskHelpers) - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -willPerformHTTPRedirection:(NSHTTPURLResponse *)response - newRequest:(NSURLRequest *)request - completionHandler:(void (^)(NSURLRequest *))completionHandler - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; - [FLEXNetworkRecorder.defaultRecorder - recordRequestWillBeSentWithRequestID:requestID - request:request - redirectResponse:response - ]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didReceiveResponse:(NSURLResponse *)response - completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - requestState.dataAccumulator = [NSMutableData new]; - - NSString *requestMechanism = [NSString stringWithFormat: - @"NSURLSessionDataTask (delegate: %@)", [delegate class] - ]; - [FLEXNetworkRecorder.defaultRecorder - recordMechanism:requestMechanism - forRequestID:requestID - ]; - - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:response - ]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask -didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask - delegate:(id)delegate { - [self performBlock:^{ - // By setting the request ID of the download task to match the data task, - // it can pick up where the data task left off. - NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; - [[self class] setRequestID:requestID forConnectionOrTask:downloadTask]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - dataTask:(NSURLSessionDataTask *)dataTask - didReceiveData:(NSData *)data - delegate:(id)delegate { - // Just to be safe since we're doing this async - data = [data copy]; - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:dataTask]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - - [requestState.dataAccumulator appendData:data]; - - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:data.length - ]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didCompleteWithError:(NSError *)error - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - - if (error) { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFailedWithRequestID:requestID error:error - ]; - } else { - [FLEXNetworkRecorder.defaultRecorder - recordLoadingFinishedWithRequestID:requestID - responseBody:requestState.dataAccumulator - ]; - } - - [self removeRequestStateForRequestID:requestID]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - downloadTask:(NSURLSessionDownloadTask *)downloadTask - didWriteData:(int64_t)bytesWritten - totalBytesWritten:(int64_t)totalBytesWritten -totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite - delegate:(id)delegate { - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - - if (!requestState.dataAccumulator) { - requestState.dataAccumulator = [NSMutableData new]; - [FLEXNetworkRecorder.defaultRecorder - recordResponseReceivedWithRequestID:requestID - response:downloadTask.response - ]; - - NSString *requestMechanism = [NSString stringWithFormat: - @"NSURLSessionDownloadTask (delegate: %@)", [delegate class] - ]; - [FLEXNetworkRecorder.defaultRecorder - recordMechanism:requestMechanism - forRequestID:requestID - ]; - } - - [FLEXNetworkRecorder.defaultRecorder - recordDataReceivedWithRequestID:requestID - dataLength:bytesWritten - ]; - }]; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionDownloadTask *)downloadTask -didFinishDownloadingToURL:(NSURL *)location data:(NSData *)data - delegate:(id)delegate { - data = [data copy]; - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:downloadTask]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - [requestState.dataAccumulator appendData:data]; - }]; -} - -- (void)URLSessionTaskWillResume:(NSURLSessionTask *)task { - // Since resume can be called multiple times on the same task, only treat the first resume as - // the equivalent to connection:willSendRequest:... - [self performBlock:^{ - NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; - FLEXInternalRequestState *requestState = [self requestStateForRequestID:requestID]; - if (!requestState.request) { - requestState.request = task.currentRequest; - - [FLEXNetworkRecorder.defaultRecorder - recordRequestWillBeSentWithRequestID:requestID - request:task.currentRequest - redirectResponse:nil - ]; - } - }]; -} - -- (void)websocketTask:(NSURLSessionWebSocketTask *)task - sendMessagage:(NSURLSessionWebSocketMessage *)message { - [self performBlock:^{ -// NSString *requestID = [[self class] requestIDForConnectionOrTask:task]; - [FLEXNetworkRecorder.defaultRecorder recordWebsocketMessageSend:message task:task]; - }]; -} - -- (void)websocketTaskMessageSendCompletion:(NSURLSessionWebSocketMessage *)message - error:(NSError *)error { - [self performBlock:^{ - [FLEXNetworkRecorder.defaultRecorder - recordWebsocketMessageSendCompletion:message - error:error - ]; - }]; -} - -- (void)websocketTask:(NSURLSessionWebSocketTask *)task - receiveMessagage:(NSURLSessionWebSocketMessage *)message - error:(NSError *)error { - [self performBlock:^{ - if (!error && message) { - [FLEXNetworkRecorder.defaultRecorder - recordWebsocketMessageReceived:message - task:task - ]; - } - }]; -} - -@end diff --git a/BHTwitter/Classes/Network/PonyDebugger/LICENSE b/BHTwitter/Classes/Network/PonyDebugger/LICENSE deleted file mode 100644 index 23750c6e..00000000 --- a/BHTwitter/Classes/Network/PonyDebugger/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ - -PonyDebugger -Copyright 2012 Square Inc. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.h b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.h deleted file mode 100644 index 5b251f34..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// FLEXObjectExplorer.h -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntime+UIKitHelpers.h" - -/// Carries state about the current user defaults settings -@interface FLEXObjectExplorerDefaults : NSObject -+ (instancetype)canEdit:(BOOL)editable wantsPreviews:(BOOL)showPreviews; - -/// Only \c YES for properties and ivars -@property (nonatomic, readonly) BOOL isEditable; -/// Only affects properties and ivars -@property (nonatomic, readonly) BOOL wantsDynamicPreviews; -@end - -@interface FLEXObjectExplorer : NSObject - -+ (instancetype)forObject:(id)objectOrClass; - -+ (void)configureDefaultsForItems:(NSArray> *)items; - -@property (nonatomic, readonly) id object; -/// Subclasses can override to provide a more useful description -@property (nonatomic, readonly) NSString *objectDescription; - -/// @return \c YES if \c object is an instance of a class, -/// or \c NO if \c object is a class itself. -@property (nonatomic, readonly) BOOL objectIsInstance; - -/// An index into the `classHierarchy` array. -/// -/// This property determines which set of data comes out of the metadata arrays below -/// For example, \c properties contains the properties of the selected class scope, -/// while \c allProperties is an array of arrays where each array is a set of -/// properties for a class in the class hierarchy of the current object. -@property (nonatomic) NSInteger classScope; - -@property (nonatomic, readonly) NSArray *> *allProperties; -@property (nonatomic, readonly) NSArray *properties; - -@property (nonatomic, readonly) NSArray *> *allClassProperties; -@property (nonatomic, readonly) NSArray *classProperties; - -@property (nonatomic, readonly) NSArray *> *allIvars; -@property (nonatomic, readonly) NSArray *ivars; - -@property (nonatomic, readonly) NSArray *> *allMethods; -@property (nonatomic, readonly) NSArray *methods; - -@property (nonatomic, readonly) NSArray *> *allClassMethods; -@property (nonatomic, readonly) NSArray *classMethods; - -@property (nonatomic, readonly) NSArray *classHierarchyClasses; -@property (nonatomic, readonly) NSArray *classHierarchy; - -@property (nonatomic, readonly) NSArray *> *allConformedProtocols; -@property (nonatomic, readonly) NSArray *conformedProtocols; - -@property (nonatomic, readonly) NSArray *allInstanceSizes; -@property (nonatomic, readonly) FLEXStaticMetadata *instanceSize; - -@property (nonatomic, readonly) NSArray *allImageNames; -@property (nonatomic, readonly) FLEXStaticMetadata *imageName; - -- (void)reloadMetadata; -- (void)reloadClassHierarchy; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.m b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.m deleted file mode 100644 index 4413001e..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorer.m +++ /dev/null @@ -1,378 +0,0 @@ -// -// FLEXObjectExplorer.m -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectExplorer.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXRuntime+Compare.h" -#import "FLEXRuntime+UIKitHelpers.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXMetadataSection.h" -#import "NSUserDefaults+FLEX.h" - -@implementation FLEXObjectExplorerDefaults - -+ (instancetype)canEdit:(BOOL)editable wantsPreviews:(BOOL)showPreviews { - FLEXObjectExplorerDefaults *defaults = [self new]; - defaults->_isEditable = editable; - defaults->_wantsDynamicPreviews = showPreviews; - return defaults; -} - -@end - -@interface FLEXObjectExplorer () { - NSMutableArray *> *_allProperties; - NSMutableArray *> *_allClassProperties; - NSMutableArray *> *_allIvars; - NSMutableArray *> *_allMethods; - NSMutableArray *> *_allClassMethods; - NSMutableArray *> *_allConformedProtocols; - NSMutableArray *_allInstanceSizes; - NSMutableArray *_allImageNames; - NSString *_objectDescription; -} -@end - -@implementation FLEXObjectExplorer - -#pragma mark - Initialization - -+ (id)forObject:(id)objectOrClass { - return [[self alloc] initWithObject:objectOrClass]; -} - -- (id)initWithObject:(id)objectOrClass { - NSParameterAssert(objectOrClass); - - self = [super init]; - if (self) { - _object = objectOrClass; - _objectIsInstance = !object_isClass(objectOrClass); - - [self reloadMetadata]; - } - - return self; -} - - -#pragma mark - Public - -+ (void)configureDefaultsForItems:(NSArray> *)items { - BOOL hidePreviews = NSUserDefaults.standardUserDefaults.flex_explorerHidesVariablePreviews; - FLEXObjectExplorerDefaults *mutable = [FLEXObjectExplorerDefaults - canEdit:YES wantsPreviews:!hidePreviews - ]; - FLEXObjectExplorerDefaults *immutable = [FLEXObjectExplorerDefaults - canEdit:NO wantsPreviews:!hidePreviews - ]; - - // .tag is used to cache whether the value of .isEditable; - // This could change at runtime so it is important that - // it is cached every time shortcuts are requeted and not - // just once at as shortcuts are initially registered - for (id metadata in items) { - metadata.defaults = metadata.isEditable ? mutable : immutable; - } -} - -- (NSString *)objectDescription { - if (!_objectDescription) { - // Hard-code UIColor description - if ([FLEXRuntimeUtility safeObject:self.object isKindOfClass:[UIColor class]]) { - CGFloat h, s, l, r, g, b, a; - [self.object getRed:&r green:&g blue:&b alpha:&a]; - [self.object getHue:&h saturation:&s brightness:&l alpha:nil]; - - return [NSString stringWithFormat: - @"HSL: (%.3f, %.3f, %.3f)\nRGB: (%.3f, %.3f, %.3f)\nAlpha: %.3f", - h, s, l, r, g, b, a - ]; - } - - NSString *description = [FLEXRuntimeUtility safeDescriptionForObject:self.object]; - - if (!description.length) { - NSString *address = [FLEXUtility addressOfObject:self.object]; - return [NSString stringWithFormat:@"Object at %@ returned empty description", address]; - } - - if (description.length > 10000) { - description = [description substringToIndex:10000]; - } - - _objectDescription = description; - } - - return _objectDescription; -} - -- (void)setClassScope:(NSInteger)classScope { - _classScope = classScope; - - [self reloadScopedMetadata]; -} - -- (void)reloadMetadata { - _allProperties = [NSMutableArray new]; - _allClassProperties = [NSMutableArray new]; - _allIvars = [NSMutableArray new]; - _allMethods = [NSMutableArray new]; - _allClassMethods = [NSMutableArray new]; - _allConformedProtocols = [NSMutableArray new]; - _allInstanceSizes = [NSMutableArray new]; - _allImageNames = [NSMutableArray new]; - _objectDescription = nil; - - [self reloadClassHierarchy]; - - NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; - BOOL hideBackingIvars = defaults.flex_explorerHidesPropertyIvars; - BOOL hidePropertyMethods = defaults.flex_explorerHidesPropertyMethods; - BOOL hidePrivateMethods = defaults.flex_explorerHidesPrivateMethods; - BOOL showMethodOverrides = defaults.flex_explorerShowsMethodOverrides; - - NSMutableArray *> *allProperties = [NSMutableArray new]; - NSMutableArray *> *allClassProps = [NSMutableArray new]; - NSMutableArray *> *allMethods = [NSMutableArray new]; - NSMutableArray *> *allClassMethods = [NSMutableArray new]; - - // Loop over each class and each superclass, collect - // the fresh and unique metadata in each category - Class superclass = nil; - NSInteger count = self.classHierarchyClasses.count; - NSInteger rootIdx = count - 1; - for (NSInteger i = 0; i < count; i++) { - Class cls = self.classHierarchyClasses[i]; - superclass = (i < rootIdx) ? self.classHierarchyClasses[i+1] : nil; - - [allProperties addObject:[self - metadataUniquedByName:[cls flex_allInstanceProperties] - superclass:superclass - kind:FLEXMetadataKindProperties - skip:showMethodOverrides - ]]; - [allClassProps addObject:[self - metadataUniquedByName:[cls flex_allClassProperties] - superclass:superclass - kind:FLEXMetadataKindClassProperties - skip:showMethodOverrides - ]]; - [_allIvars addObject:[self - metadataUniquedByName:[cls flex_allIvars] - superclass:nil - kind:FLEXMetadataKindIvars - skip:NO - ]]; - [allMethods addObject:[self - metadataUniquedByName:[cls flex_allInstanceMethods] - superclass:superclass - kind:FLEXMetadataKindMethods - skip:showMethodOverrides - ]]; - [allClassMethods addObject:[self - metadataUniquedByName:[cls flex_allClassMethods] - superclass:superclass - kind:FLEXMetadataKindClassMethods - skip:showMethodOverrides - ]]; - [_allConformedProtocols addObject:[self - metadataUniquedByName:[cls flex_protocols] - superclass:superclass - kind:FLEXMetadataKindProtocols - skip:NO - ]]; - - // TODO: join instance size, image name, and class hierarchy into a single model object - // This would greatly reduce the laziness that has begun to manifest itself here - [_allInstanceSizes addObject:[FLEXStaticMetadata - style:FLEXStaticMetadataRowStyleKeyValue - title:@"Instance Size" number:@(class_getInstanceSize(cls)) - ]]; - [_allImageNames addObject:[FLEXStaticMetadata - style:FLEXStaticMetadataRowStyleDefault - title:@"Image Name" string:@(class_getImageName(cls) ?: "Created at Runtime") - ]]; - } - - _classHierarchy = [FLEXStaticMetadata classHierarchy:self.classHierarchyClasses]; - - NSArray *> *properties = allProperties; - - // Potentially filter property-backing ivars - if (hideBackingIvars) { - NSArray *> *ivars = _allIvars.copy; - _allIvars = [ivars flex_mapped:^id(NSArray *list, NSUInteger idx) { - // Get a set of all backing ivar names for the current class in the hierarchy - NSSet *ivarNames = [NSSet setWithArray:({ - [properties[idx] flex_mapped:^id(FLEXProperty *p, NSUInteger idx) { - // Nil if no ivar, and array is flatted - return p.likelyIvarName; - }]; - })]; - - // Remove ivars whose name is in the ivar names list - return [list flex_filtered:^BOOL(FLEXIvar *ivar, NSUInteger idx) { - return ![ivarNames containsObject:ivar.name]; - }]; - }]; - } - - // Potentially filter property-backing methods - if (hidePropertyMethods) { - allMethods = [allMethods flex_mapped:^id(NSArray *list, NSUInteger idx) { - // Get a set of all property method names for the current class in the hierarchy - NSSet *methodNames = [NSSet setWithArray:({ - [properties[idx] flex_flatmapped:^NSArray *(FLEXProperty *p, NSUInteger idx) { - if (p.likelyGetterExists) { - if (p.likelySetterExists) { - return @[p.likelyGetterString, p.likelySetterString]; - } - - return @[p.likelyGetterString]; - } else if (p.likelySetterExists) { - return @[p.likelySetterString]; - } - - return nil; - }]; - })]; - - // Remove methods whose name is in the property method names list - return [list flex_filtered:^BOOL(FLEXMethod *method, NSUInteger idx) { - return ![methodNames containsObject:method.selectorString]; - }]; - }]; - } - - if (hidePrivateMethods) { - id methodMapBlock = ^id(NSArray *list, NSUInteger idx) { - // Remove methods which contain an underscore - return [list flex_filtered:^BOOL(FLEXMethod *method, NSUInteger idx) { - return ![method.selectorString containsString:@"_"]; - }]; - }; - id propertyMapBlock = ^id(NSArray *list, NSUInteger idx) { - // Remove methods which contain an underscore - return [list flex_filtered:^BOOL(FLEXProperty *prop, NSUInteger idx) { - return ![prop.name containsString:@"_"]; - }]; - }; - - allMethods = [allMethods flex_mapped:methodMapBlock]; - allClassMethods = [allClassMethods flex_mapped:methodMapBlock]; - allProperties = [allProperties flex_mapped:propertyMapBlock]; - allClassProps = [allClassProps flex_mapped:propertyMapBlock]; - } - - _allProperties = allProperties; - _allClassProperties = allClassProps; - _allMethods = allMethods; - _allClassMethods = allClassMethods; - - // Set up UIKit helper data - // Really, we only need to call this on properties and ivars - // because no other metadata types support editing. - NSArray*metadatas = @[ - _allProperties, _allClassProperties, _allIvars, - /* _allMethods, _allClassMethods, _allConformedProtocols */ - ]; - for (NSArray *matrix in metadatas) { - for (NSArray *metadataByClass in matrix) { - [FLEXObjectExplorer configureDefaultsForItems:metadataByClass]; - } - } - - [self reloadScopedMetadata]; -} - - -#pragma mark - Private - -- (void)reloadScopedMetadata { - _properties = self.allProperties[self.classScope]; - _classProperties = self.allClassProperties[self.classScope]; - _ivars = self.allIvars[self.classScope]; - _methods = self.allMethods[self.classScope]; - _classMethods = self.allClassMethods[self.classScope]; - _conformedProtocols = self.allConformedProtocols[self.classScope]; - _instanceSize = self.allInstanceSizes[self.classScope]; - _imageName = self.allImageNames[self.classScope]; -} - -/// Accepts an array of flex metadata objects and discards objects -/// with duplicate names, as well as properties and methods which -/// aren't "new" (i.e. those which the superclass responds to) -- (NSArray *)metadataUniquedByName:(NSArray *)list - superclass:(Class)superclass - kind:(FLEXMetadataKind)kind - skip:(BOOL)skipUniquing { - if (skipUniquing) { - return list; - } - - // Remove items with same name and return filtered list - NSMutableSet *names = [NSMutableSet new]; - return [list flex_filtered:^BOOL(id obj, NSUInteger idx) { - NSString *name = [obj name]; - if ([names containsObject:name]) { - return NO; - } else { - [names addObject:name]; - - // Skip methods and properties which are just overrides, - // potentially skip ivars and methods associated with properties - switch (kind) { - case FLEXMetadataKindProperties: - if ([superclass instancesRespondToSelector:[obj likelyGetter]]) { - return NO; - } - break; - case FLEXMetadataKindClassProperties: - if ([superclass respondsToSelector:[obj likelyGetter]]) { - return NO; - } - break; - case FLEXMetadataKindMethods: - if ([superclass instancesRespondToSelector:NSSelectorFromString(name)]) { - return NO; - } - break; - case FLEXMetadataKindClassMethods: - if ([superclass respondsToSelector:NSSelectorFromString(name)]) { - return NO; - } - break; - - case FLEXMetadataKindProtocols: - case FLEXMetadataKindClassHierarchy: - case FLEXMetadataKindOther: - return YES; // These types are already uniqued - break; - - // Ivars cannot be overidden - case FLEXMetadataKindIvars: break; - } - - return YES; - } - }]; -} - - -#pragma mark - Superclasses - -- (void)reloadClassHierarchy { - // The class hierarchy will never contain metaclass objects by this logic; - // it is always the same for a given class and instances of it - _classHierarchyClasses = [[self.object class] flex_classHierarchy]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.h b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.h deleted file mode 100644 index 2d5e8400..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// FLEXObjectExplorerFactory.h -// Flipboard -// -// Created by Ryan Olson on 5/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXGlobalsEntry.h" - -#ifndef _FLEXObjectExplorerViewController_h -#import "FLEXObjectExplorerViewController.h" -#else -@class FLEXObjectExplorerViewController; -#endif - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXObjectExplorerFactory : NSObject - -+ (nullable FLEXObjectExplorerViewController *)explorerViewControllerForObject:(nullable id)object; - -/// Register a specific explorer view controller class to be used when exploring -/// an object of a specific class. Calls will overwrite existing registrations. -/// Sections must be initialized using \c forObject: like -+ (void)registerExplorerSection:(Class)sectionClass forClass:(Class)objectClass; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.m b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.m deleted file mode 100644 index e5bd7913..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerFactory.m +++ /dev/null @@ -1,243 +0,0 @@ -// -// FLEXObjectExplorerFactory.m -// Flipboard -// -// Created by Ryan Olson on 5/15/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectExplorerFactory.h" -#import "FLEXGlobalsViewController.h" -#import "FLEXClassShortcuts.h" -#import "FLEXViewShortcuts.h" -#import "FLEXViewControllerShortcuts.h" -#import "FLEXUIAppShortcuts.h" -#import "FLEXImageShortcuts.h" -#import "FLEXLayerShortcuts.h" -#import "FLEXColorPreviewSection.h" -#import "FLEXDefaultsContentSection.h" -#import "FLEXBundleShortcuts.h" -#import "FLEXNSStringShortcuts.h" -#import "FLEXNSDataShortcuts.h" -#import "FLEXBlockShortcuts.h" -#import "FLEXUtility.h" - -@implementation FLEXObjectExplorerFactory -static NSMutableDictionary, Class> *classesToRegisteredSections = nil; - -+ (void)initialize { - if (self == [FLEXObjectExplorerFactory class]) { - // DO NOT USE STRING KEYS HERE - // We NEED to use the class as a key, because we CANNOT - // differentiate a class's name from the metaclass's name. - // These mappings are per-class-object, not per-class-name. - // - // For example, if we used class names, this would result in - // the object explorer trying to render a color preview for - // the UIColor class object, which is not a color itself. - #define ClassKey(name) (id)[name class] - #define ClassKeyByName(str) (id)NSClassFromString(@ #str) - #define MetaclassKey(meta) (id)object_getClass([meta class]) - classesToRegisteredSections = [NSMutableDictionary dictionaryWithDictionary:@{ - MetaclassKey(NSObject) : [FLEXClassShortcuts class], - ClassKey(NSArray) : [FLEXCollectionContentSection class], - ClassKey(NSSet) : [FLEXCollectionContentSection class], - ClassKey(NSDictionary) : [FLEXCollectionContentSection class], - ClassKey(NSOrderedSet) : [FLEXCollectionContentSection class], - ClassKey(NSUserDefaults) : [FLEXDefaultsContentSection class], - ClassKey(UIViewController) : [FLEXViewControllerShortcuts class], - ClassKey(UIApplication) : [FLEXUIAppShortcuts class], - ClassKey(UIView) : [FLEXViewShortcuts class], - ClassKey(UIImage) : [FLEXImageShortcuts class], - ClassKey(CALayer) : [FLEXLayerShortcuts class], - ClassKey(UIColor) : [FLEXColorPreviewSection class], - ClassKey(NSBundle) : [FLEXBundleShortcuts class], - ClassKey(NSString) : [FLEXNSStringShortcuts class], - ClassKey(NSData) : [FLEXNSDataShortcuts class], - ClassKeyByName(NSBlock) : [FLEXBlockShortcuts class], - }]; - #undef ClassKey - #undef ClassKeyByName - #undef MetaclassKey - } -} - -+ (FLEXObjectExplorerViewController *)explorerViewControllerForObject:(id)object { - // Can't explore nil - if (!object) { - return nil; - } - - // If we're given an object, this will look up it's class hierarchy - // until it finds a registration. This will work for KVC classes, - // since they are children of the original class, and not siblings. - // If we are given an object, object_getClass will return a metaclass, - // and the same thing will happen. FLEXClassShortcuts is the default - // shortcut section for NSObject. - // - // TODO: rename it to FLEXNSObjectShortcuts or something? - FLEXShortcutsSection *shortcutsSection = [FLEXShortcutsSection forObject:object]; - NSArray *sections = @[shortcutsSection]; - - Class customSectionClass = nil; - Class cls = object_getClass(object); - do { - customSectionClass = classesToRegisteredSections[(id)cls]; - } while (!customSectionClass && (cls = [cls superclass])); - - if (customSectionClass) { - id customSection = [customSectionClass forObject:object]; - BOOL isFLEXShortcutSection = [customSection respondsToSelector:@selector(isNewSection)]; - - // If the section "replaces" the default shortcuts section, - // only return that section. Otherwise, return both this - // section and the default shortcuts section. - if (isFLEXShortcutSection && ![customSection isNewSection]) { - sections = @[customSection]; - } else { - // Custom section will go before shortcuts - sections = @[customSection, shortcutsSection]; - } - } - - return [FLEXObjectExplorerViewController - exploringObject:object - customSections:sections - ]; -} - -+ (void)registerExplorerSection:(Class)explorerClass forClass:(Class)objectClass { - classesToRegisteredSections[(id)objectClass] = explorerClass; -} - -#pragma mark - FLEXGlobalsEntry - -+ (NSString *)globalsEntryTitle:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowAppDelegate: - return @"🎟 App Delegate"; - case FLEXGlobalsRowKeyWindow: - return @"🔑 Key Window"; - case FLEXGlobalsRowRootViewController: - return @"🌴 Root View Controller"; - case FLEXGlobalsRowProcessInfo: - return @"🚦 NSProcessInfo.processInfo"; - case FLEXGlobalsRowUserDefaults: - return @"💾 Preferences"; - case FLEXGlobalsRowMainBundle: - return @"📦 NSBundle.mainBundle"; - case FLEXGlobalsRowApplication: - return @"🚀 UIApplication.sharedApplication"; - case FLEXGlobalsRowMainScreen: - return @"💻 UIScreen.mainScreen"; - case FLEXGlobalsRowCurrentDevice: - return @"📱 UIDevice.currentDevice"; - case FLEXGlobalsRowPasteboard: - return @"📋 UIPasteboard.generalPasteboard"; - case FLEXGlobalsRowURLSession: - return @"📡 NSURLSession.sharedSession"; - case FLEXGlobalsRowURLCache: - return @"⏳ NSURLCache.sharedURLCache"; - case FLEXGlobalsRowNotificationCenter: - return @"🔔 NSNotificationCenter.defaultCenter"; - case FLEXGlobalsRowMenuController: - return @"📎 UIMenuController.sharedMenuController"; - case FLEXGlobalsRowFileManager: - return @"🗄 NSFileManager.defaultManager"; - case FLEXGlobalsRowTimeZone: - return @"🌎 NSTimeZone.systemTimeZone"; - case FLEXGlobalsRowLocale: - return @"🗣 NSLocale.currentLocale"; - case FLEXGlobalsRowCalendar: - return @"📅 NSCalendar.currentCalendar"; - case FLEXGlobalsRowMainRunLoop: - return @"🏃🏻‍♂️ NSRunLoop.mainRunLoop"; - case FLEXGlobalsRowMainThread: - return @"🧵 NSThread.mainThread"; - case FLEXGlobalsRowOperationQueue: - return @"📚 NSOperationQueue.mainQueue"; - default: return nil; - } -} - -+ (UIViewController *)globalsEntryViewController:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowAppDelegate: { - id appDelegate = UIApplication.sharedApplication.delegate; - return [self explorerViewControllerForObject:appDelegate]; - } - case FLEXGlobalsRowProcessInfo: - return [self explorerViewControllerForObject:NSProcessInfo.processInfo]; - case FLEXGlobalsRowUserDefaults: - return [self explorerViewControllerForObject:NSUserDefaults.standardUserDefaults]; - case FLEXGlobalsRowMainBundle: - return [self explorerViewControllerForObject:NSBundle.mainBundle]; - case FLEXGlobalsRowApplication: - return [self explorerViewControllerForObject:UIApplication.sharedApplication]; - case FLEXGlobalsRowMainScreen: - return [self explorerViewControllerForObject:UIScreen.mainScreen]; - case FLEXGlobalsRowCurrentDevice: - return [self explorerViewControllerForObject:UIDevice.currentDevice]; - case FLEXGlobalsRowPasteboard: - return [self explorerViewControllerForObject:UIPasteboard.generalPasteboard]; - case FLEXGlobalsRowURLSession: - return [self explorerViewControllerForObject:NSURLSession.sharedSession]; - case FLEXGlobalsRowURLCache: - return [self explorerViewControllerForObject:NSURLCache.sharedURLCache]; - case FLEXGlobalsRowNotificationCenter: - return [self explorerViewControllerForObject:NSNotificationCenter.defaultCenter]; - case FLEXGlobalsRowMenuController: - return [self explorerViewControllerForObject:UIMenuController.sharedMenuController]; - case FLEXGlobalsRowFileManager: - return [self explorerViewControllerForObject:NSFileManager.defaultManager]; - case FLEXGlobalsRowTimeZone: - return [self explorerViewControllerForObject:NSTimeZone.systemTimeZone]; - case FLEXGlobalsRowLocale: - return [self explorerViewControllerForObject:NSLocale.currentLocale]; - case FLEXGlobalsRowCalendar: - return [self explorerViewControllerForObject:NSCalendar.currentCalendar]; - case FLEXGlobalsRowMainRunLoop: - return [self explorerViewControllerForObject:NSRunLoop.mainRunLoop]; - case FLEXGlobalsRowMainThread: - return [self explorerViewControllerForObject:NSThread.mainThread]; - case FLEXGlobalsRowOperationQueue: - return [self explorerViewControllerForObject:NSOperationQueue.mainQueue]; - - case FLEXGlobalsRowKeyWindow: - return [FLEXObjectExplorerFactory - explorerViewControllerForObject:FLEXUtility.appKeyWindow - ]; - case FLEXGlobalsRowRootViewController: { - id delegate = UIApplication.sharedApplication.delegate; - if ([delegate respondsToSelector:@selector(window)]) { - return [self explorerViewControllerForObject:delegate.window.rootViewController]; - } - - return nil; - } - default: return nil; - } -} - -+ (FLEXGlobalsEntryRowAction)globalsEntryRowAction:(FLEXGlobalsRow)row { - switch (row) { - case FLEXGlobalsRowRootViewController: { - // Check if the app delegate responds to -window. If not, present an alert - return ^(UITableViewController *host) { - id delegate = UIApplication.sharedApplication.delegate; - if ([delegate respondsToSelector:@selector(window)]) { - UIViewController *explorer = [self explorerViewControllerForObject: - delegate.window.rootViewController - ]; - [host.navigationController pushViewController:explorer animated:YES]; - } else { - NSString *msg = @"The app delegate doesn't respond to -window"; - [FLEXAlert showAlert:@":(" message:msg from:host]; - } - }; - } - default: return nil; - } -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.h b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.h deleted file mode 100644 index 849bea22..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// FLEXObjectExplorerViewController.h -// Flipboard -// -// Created by Ryan Olson on 2014-05-03. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#ifndef _FLEXObjectExplorerViewController_h -#define _FLEXObjectExplorerViewController_h -#endif - -#import "FLEXFilteringTableViewController.h" -#import "FLEXObjectExplorer.h" -@class FLEXTableViewSection; - -NS_ASSUME_NONNULL_BEGIN - -/// A class that displays information about an object or class. -/// -/// The explorer view controller uses \c FLEXObjectExplorer to provide a description -/// of the object and list it's properties, ivars, methods, and it's superclasses. -/// Below the description and before properties, some shortcuts will be displayed -/// for certain classes like UIViews. At very bottom, there is an option to view -/// a list of other objects found to be referencing the object being explored. -@interface FLEXObjectExplorerViewController : FLEXFilteringTableViewController - -/// Uses the default \c FLEXShortcutsSection for this object as a custom section. -+ (instancetype)exploringObject:(id)objectOrClass; -/// No custom section unless you provide one. -+ (instancetype)exploringObject:(id)objectOrClass customSection:(nullable FLEXTableViewSection *)customSection; -/// No custom sections unless you provide some. -+ (instancetype)exploringObject:(id)objectOrClass - customSections:(nullable NSArray *)customSections; - -/// The object being explored, which may be an instance of a class or a class itself. -@property (nonatomic, readonly) id object; -/// This object provides the object's metadata for the explorer view controller. -@property (nonatomic, readonly) FLEXObjectExplorer *explorer; - -/// Called once to initialize the list of section objects. -/// -/// Subclasses can override this to add, remove, or rearrange sections of the explorer. -- (NSArray *)makeSections; - -/// Whether to allow showing/drilling in to current values for ivars and properties. Default is YES. -@property (nonatomic, readonly) BOOL canHaveInstanceState; - -/// Whether to allow drilling in to method calling interfaces for instance methods. Default is YES. -@property (nonatomic, readonly) BOOL canCallInstanceMethods; - -/// If the custom section data makes the description redundant, subclasses can choose to hide it. Default is YES. -@property (nonatomic, readonly) BOOL shouldShowDescription; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.m b/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.m deleted file mode 100644 index d94ada06..00000000 --- a/BHTwitter/Classes/ObjectExplorers/FLEXObjectExplorerViewController.m +++ /dev/null @@ -1,393 +0,0 @@ -// -// FLEXObjectExplorerViewController.m -// Flipboard -// -// Created by Ryan Olson on 2014-05-03. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectExplorerViewController.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" -#import "UIBarButtonItem+FLEX.h" -#import "FLEXMultilineTableViewCell.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXFieldEditorViewController.h" -#import "FLEXMethodCallingViewController.h" -#import "FLEXObjectListViewController.h" -#import "FLEXTabsViewController.h" -#import "FLEXBookmarkManager.h" -#import "FLEXTableView.h" -#import "FLEXResources.h" -#import "FLEXTableViewCell.h" -#import "FLEXScopeCarousel.h" -#import "FLEXMetadataSection.h" -#import "FLEXSingleRowSection.h" -#import "FLEXShortcutsSection.h" -#import "NSUserDefaults+FLEX.h" -#import - -#pragma mark - Private properties -@interface FLEXObjectExplorerViewController () -@property (nonatomic, readonly) FLEXSingleRowSection *descriptionSection; -@property (nonatomic, readonly) NSArray *customSections; -@property (nonatomic) NSIndexSet *customSectionVisibleIndexes; - -@property (nonatomic, readonly) NSArray *observedNotifications; - -@end - -@implementation FLEXObjectExplorerViewController - -#pragma mark - Initialization - -+ (instancetype)exploringObject:(id)target { - return [self exploringObject:target customSection:[FLEXShortcutsSection forObject:target]]; -} - -+ (instancetype)exploringObject:(id)target customSection:(FLEXTableViewSection *)section { - return [self exploringObject:target customSections:@[section]]; -} - -+ (instancetype)exploringObject:(id)target customSections:(NSArray *)customSections { - return [[self alloc] - initWithObject:target - explorer:[FLEXObjectExplorer forObject:target] - customSections:customSections - ]; -} - -- (id)initWithObject:(id)target - explorer:(__kindof FLEXObjectExplorer *)explorer - customSections:(NSArray *)customSections { - NSParameterAssert(target); - - self = [super initWithStyle:UITableViewStyleGrouped]; - if (self) { - _object = target; - _explorer = explorer; - _customSections = customSections; - } - - return self; -} - -- (NSArray *)observedNotifications { - return @[ - kFLEXDefaultsHidePropertyIvarsKey, - kFLEXDefaultsHidePropertyMethodsKey, - kFLEXDefaultsHidePrivateMethodsKey, - kFLEXDefaultsShowMethodOverridesKey, - kFLEXDefaultsHideVariablePreviewsKey, - ]; -} - -#pragma mark - View controller lifecycle - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.showsShareToolbarItem = YES; - self.wantsSectionIndexTitles = YES; - - // Use [object class] here rather than object_getClass - // to avoid the KVO prefix for observed objects - self.title = [FLEXRuntimeUtility safeClassNameForObject:self.object]; - - // Search - self.showsSearchBar = YES; - self.searchBarDebounceInterval = kFLEXDebounceInstant; - self.showsCarousel = YES; - - // Carousel scope bar - [self.explorer reloadClassHierarchy]; - self.carousel.items = [self.explorer.classHierarchyClasses flex_mapped:^id(Class cls, NSUInteger idx) { - return NSStringFromClass(cls); - }]; - - // ... button for extra options - [self addToolbarItems:@[[UIBarButtonItem - flex_itemWithImage:FLEXResources.moreIcon target:self action:@selector(moreButtonPressed:) - ]]]; - - // Swipe gestures to swipe between classes in the hierarchy - UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] - initWithTarget:self action:@selector(handleSwipeGesture:) - ]; - UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] - initWithTarget:self action:@selector(handleSwipeGesture:) - ]; - leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft; - rightSwipe.direction = UISwipeGestureRecognizerDirectionRight; - leftSwipe.delegate = self; - rightSwipe.delegate = self; - [self.tableView addGestureRecognizer:leftSwipe]; - [self.tableView addGestureRecognizer:rightSwipe]; - - // Observe preferences which may change on other screens - // - // "If your app targets iOS 9.0 and later or macOS 10.11 and later, - // you don't need to unregister an observer in its dealloc method." - for (NSString *pref in self.observedNotifications) { - [NSNotificationCenter.defaultCenter - addObserver:self - selector:@selector(fullyReloadData) - name:pref - object:nil - ]; - } -} - -- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { - [self.navigationController setToolbarHidden:NO animated:YES]; - return YES; -} - - -#pragma mark - Overrides - -/// Override to hide the description section when searching -- (NSArray *)nonemptySections { - if (self.shouldShowDescription) { - return super.nonemptySections; - } - - return [super.nonemptySections flex_filtered:^BOOL(FLEXTableViewSection *section, NSUInteger idx) { - return section != self.descriptionSection; - }]; -} - -- (NSArray *)makeSections { - FLEXObjectExplorer *explorer = self.explorer; - - // Description section is only for instances - if (self.explorer.objectIsInstance) { - _descriptionSection = [FLEXSingleRowSection - title:@"Description" reuse:kFLEXMultilineCell cell:^(FLEXTableViewCell *cell) { - cell.titleLabel.font = UIFont.flex_defaultTableCellFont; - cell.titleLabel.text = explorer.objectDescription; - } - ]; - self.descriptionSection.filterMatcher = ^BOOL(NSString *filterText) { - return [explorer.objectDescription localizedCaseInsensitiveContainsString:filterText]; - }; - } - - // Object graph section - FLEXSingleRowSection *referencesSection = [FLEXSingleRowSection - title:@"Object Graph" reuse:kFLEXDefaultCell cell:^(FLEXTableViewCell *cell) { - cell.titleLabel.text = @"See Objects with References to This Object"; - cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; - } - ]; - referencesSection.selectionAction = ^(UIViewController *host) { - UIViewController *references = [FLEXObjectListViewController - objectsWithReferencesToObject:explorer.object - retained:NO - ]; - [host.navigationController pushViewController:references animated:YES]; - }; - - NSMutableArray *sections = [NSMutableArray arrayWithArray:@[ - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindProperties], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindClassProperties], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindIvars], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindMethods], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindClassMethods], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindClassHierarchy], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindProtocols], - [FLEXMetadataSection explorer:self.explorer kind:FLEXMetadataKindOther], - referencesSection - ]]; - - if (self.customSections) { - [sections insertObjects:self.customSections atIndexes:[NSIndexSet - indexSetWithIndexesInRange:NSMakeRange(0, self.customSections.count) - ]]; - } - if (self.descriptionSection) { - [sections insertObject:self.descriptionSection atIndex:0]; - } - - return sections.copy; -} - -/// In our case, all this does is reload the table view, -/// or reload the sections' data if we changed places -/// in the class hierarchy. Doesn't refresh \c self.explorer -- (void)reloadData { - // Check to see if class scope changed, update accordingly - if (self.explorer.classScope != self.selectedScope) { - self.explorer.classScope = self.selectedScope; - [self reloadSections]; - } - - [super reloadData]; -} - -- (void)shareButtonPressed:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - make.button(@"Add to Bookmarks").handler(^(NSArray *strings) { - [FLEXBookmarkManager.bookmarks addObject:self.object]; - }); - make.button(@"Copy Description").handler(^(NSArray *strings) { - UIPasteboard.generalPasteboard.string = self.explorer.objectDescription; - }); - make.button(@"Copy Address").handler(^(NSArray *strings) { - UIPasteboard.generalPasteboard.string = [FLEXUtility addressOfObject:self.object]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - - -#pragma mark - Private - -/// Unlike \c -reloadData, this refreshes everything, including the explorer. -- (void)fullyReloadData { - [self.explorer reloadMetadata]; - [self reloadSections]; - [self reloadData]; -} - -- (void)handleSwipeGesture:(UISwipeGestureRecognizer *)gesture { - if (gesture.state == UIGestureRecognizerStateEnded) { - switch (gesture.direction) { - case UISwipeGestureRecognizerDirectionRight: - if (self.selectedScope > 0) { - self.selectedScope -= 1; - } - break; - case UISwipeGestureRecognizerDirectionLeft: - if (self.selectedScope != self.explorer.classHierarchy.count - 1) { - self.selectedScope += 1; - } - break; - - default: - break; - } - } -} - -- (BOOL)gestureRecognizer:(UIGestureRecognizer *)g1 shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)g2 { - // Prioritize important pan gestures over our swipe gesture - if ([g2 isKindOfClass:[UIPanGestureRecognizer class]]) { - if (g2 == self.navigationController.interactivePopGestureRecognizer) { - return NO; - } - - if (g2 == self.tableView.panGestureRecognizer) { - return NO; - } - } - - return YES; -} - -- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gesture { - // Don't allow swiping from the carousel - CGPoint location = [gesture locationInView:self.tableView]; - if ([self.carousel hitTest:location withEvent:nil]) { - return NO; - } - - return YES; -} - -- (void)moreButtonPressed:(UIBarButtonItem *)sender { - NSUserDefaults *defaults = NSUserDefaults.standardUserDefaults; - // Maps preference keys to a description of what they affect - NSDictionary *explorerToggles = @{ - kFLEXDefaultsHidePropertyIvarsKey: @"Property-Backing Ivars", - kFLEXDefaultsHidePropertyMethodsKey: @"Property-Backing Methods", - kFLEXDefaultsHidePrivateMethodsKey: @"Likely Private Methods", - kFLEXDefaultsShowMethodOverridesKey: @"Method Overrides", - kFLEXDefaultsHideVariablePreviewsKey: @"Variable Previews" - }; - - // Maps the key of the action itself to a map of a description - // of the action ("hide X") mapped to the current state. - // - // So keys that are hidden by default have NO mapped to "Show" - NSDictionary *nextStateDescriptions = @{ - kFLEXDefaultsHidePropertyIvarsKey: @{ @NO: @"Hide ", @YES: @"Show " }, - kFLEXDefaultsHidePropertyMethodsKey: @{ @NO: @"Hide ", @YES: @"Show " }, - kFLEXDefaultsHidePrivateMethodsKey: @{ @NO: @"Hide ", @YES: @"Show " }, - kFLEXDefaultsShowMethodOverridesKey: @{ @NO: @"Show ", @YES: @"Hide " }, - kFLEXDefaultsHideVariablePreviewsKey: @{ @NO: @"Hide ", @YES: @"Show " }, - }; - - [FLEXAlert makeSheet:^(FLEXAlert *make) { - make.title(@"Options"); - - for (NSString *option in explorerToggles.allKeys) { - BOOL current = [defaults boolForKey:option]; - NSString *title = [nextStateDescriptions[option][@(current)] - stringByAppendingString:explorerToggles[option] - ]; - make.button(title).handler(^(NSArray *strings) { - [NSUserDefaults.standardUserDefaults flex_toggleBoolForKey:option]; - [self fullyReloadData]; - }); - } - - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - -#pragma mark - Description - -- (BOOL)shouldShowDescription { - // Hide if we have filter text; it is rarely - // useful to see the description when searching - // since it's already at the top of the screen - if (self.filterText.length) { - return NO; - } - - return YES; -} - -- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - // For the description section, we want that nice slim/snug looking row. - // Other rows use the automatic size. - FLEXTableViewSection *section = self.filterDelegate.sections[indexPath.section]; - - if (section == self.descriptionSection) { - NSAttributedString *attributedText = [[NSAttributedString alloc] - initWithString:self.explorer.objectDescription - attributes:@{ NSFontAttributeName : UIFont.flex_defaultTableCellFont } - ]; - - return [FLEXMultilineTableViewCell - preferredHeightWithAttributedText:attributedText - maxWidth:tableView.frame.size.width - tableView.separatorInset.right - style:tableView.style - showsAccessory:NO - ]; - } - - return UITableViewAutomaticDimension; -} - -- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(NSIndexPath *)indexPath { - return self.filterDelegate.sections[indexPath.section] == self.descriptionSection; -} - -- (BOOL)tableView:(UITableView *)tableView canPerformAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - // Only the description section has "actions" - if (self.filterDelegate.sections[indexPath.section] == self.descriptionSection) { - return action == @selector(copy:); - } - - return NO; -} - -- (void)tableView:(UITableView *)tableView performAction:(SEL)action forRowAtIndexPath:(NSIndexPath *)indexPath withSender:(id)sender { - if (action == @selector(copy:)) { - UIPasteboard.generalPasteboard.string = self.explorer.objectDescription; - } -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.h deleted file mode 100644 index 8ca05f2b..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.h +++ /dev/null @@ -1,93 +0,0 @@ -// -// FLEXCollectionContentSection.h -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" -#import "FLEXObjectInfoSection.h" -@class FLEXCollectionContentSection, FLEXTableViewCell; -@protocol FLEXCollection, FLEXMutableCollection; - -/// Any foundation collection implicitly conforms to FLEXCollection. -/// This future should return one. We don't explicitly put FLEXCollection -/// here because making generic collections conform to FLEXCollection breaks -/// compile-time features of generic arrays, such as \c someArray[0].property -typedef id(^FLEXCollectionContentFuture)(__kindof FLEXCollectionContentSection *section); - -#pragma mark Collection -/// A protocol that enables \c FLEXCollectionContentSection to operate on any arbitrary collection. -/// \c NSArray, \c NSDictionary, \c NSSet, and \c NSOrderedSet all conform to this protocol. -@protocol FLEXCollection - -@property (nonatomic, readonly) NSUInteger count; - -- (id)copy; -- (id)mutableCopy; - -@optional - -/// Unordered, unkeyed collections must implement this -@property (nonatomic, readonly) NSArray *allObjects; -/// Keyed collections must implement this and \c objectForKeyedSubscript: -@property (nonatomic, readonly) NSArray *allKeys; - -/// Ordered, indexed collections must implement this. -- (id)objectAtIndexedSubscript:(NSUInteger)idx; -/// Keyed, unordered collections must implement this and \c allKeys -- (id)objectForKeyedSubscript:(id)idx; - -@end - -@protocol FLEXMutableCollection -- (void)filterUsingPredicate:(NSPredicate *)predicate; -@end - - -#pragma mark - FLEXCollectionContentSection -/// A custom section for viewing collection elements. -/// -/// Tapping on a row pushes an object explorer for that element. -@interface FLEXCollectionContentSection<__covariant ObjectType> : FLEXTableViewSection { - @protected - /// Unused if initialized with a future - id _collection; - /// Unused if initialized with a collection - FLEXCollectionContentFuture _collectionFuture; - /// The filtered collection from \c _collection or \c _collectionFuture - id _cachedCollection; -} - -+ (instancetype)forCollection:(id)collection; -/// The future given should be safe to call more than once. -/// The result of calling this future multiple times may yield -/// different results each time if the data is changing by nature. -+ (instancetype)forReusableFuture:(FLEXCollectionContentFuture)collectionFuture; - -/// Defaults to \c NO -@property (nonatomic) BOOL hideSectionTitle; -/// Defaults to \c nil -@property (nonatomic, copy) NSString *customTitle; -/// Defaults to \c NO -/// -/// Settings this to \c NO will not display the element index for ordered collections. -/// This property only applies to \c NSArray or \c NSOrderedSet and their subclasses. -@property (nonatomic) BOOL hideOrderIndexes; - -/// Set this property to provide a custom filter matcher. -/// -/// By default, the collection will filter on the title and subtitle of the row. -/// So if you don't ever call \c configureCell: for example, you will need to set -/// this property so that your filter logic will match how you're setting up the cell. -@property (nonatomic) BOOL (^customFilter)(NSString *filterText, ObjectType element); - -/// Get the object in the collection associated with the given row. -/// For dictionaries, this returns the value, not the key. -- (ObjectType)objectForRow:(NSInteger)row; - -/// Subclasses may override. -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.m deleted file mode 100644 index 82862323..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXCollectionContentSection.m +++ /dev/null @@ -1,246 +0,0 @@ -// -// FLEXCollectionContentSection.m -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCollectionContentSection.h" -#import "FLEXUtility.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXSubtitleTableViewCell.h" -#import "FLEXTableView.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXDefaultEditorViewController.h" - -typedef NS_ENUM(NSUInteger, FLEXCollectionType) { - FLEXUnsupportedCollection, - FLEXOrderedCollection, - FLEXUnorderedCollection, - FLEXKeyedCollection -}; - -@interface NSArray (FLEXCollection) @end -@interface NSSet (FLEXCollection) @end -@interface NSOrderedSet (FLEXCollection) @end -@interface NSDictionary (FLEXCollection) @end - -@interface NSMutableArray (FLEXMutableCollection) @end -@interface NSMutableSet (FLEXMutableCollection) @end -@interface NSMutableOrderedSet (FLEXMutableCollection) @end -@interface NSMutableDictionary (FLEXMutableCollection) -- (void)filterUsingPredicate:(NSPredicate *)predicate; -@end - -@interface FLEXCollectionContentSection () -/// Generated from \c collectionFuture or \c collection -@property (nonatomic, copy) id cachedCollection; -/// A static collection to display -@property (nonatomic, readonly) id collection; -/// A collection that may change over time and can be called upon for new data -@property (nonatomic, readonly) FLEXCollectionContentFuture collectionFuture; -@property (nonatomic, readonly) FLEXCollectionType collectionType; -@property (nonatomic, readonly) BOOL isMutable; -@end - -@implementation FLEXCollectionContentSection -@synthesize filterText = _filterText; - -#pragma mark Initialization - -+ (instancetype)forObject:(id)object { - return [self forCollection:object]; -} - -+ (id)forCollection:(id)collection { - FLEXCollectionContentSection *section = [self new]; - section->_collectionType = [self typeForCollection:collection]; - section->_collection = collection; - section.cachedCollection = collection; - section->_isMutable = [collection respondsToSelector:@selector(filterUsingPredicate:)]; - return section; -} - -+ (id)forReusableFuture:(FLEXCollectionContentFuture)collectionFuture { - FLEXCollectionContentSection *section = [self new]; - section->_collectionFuture = collectionFuture; - section.cachedCollection = (id)collectionFuture(section); - section->_collectionType = [self typeForCollection:section.cachedCollection]; - section->_isMutable = [section->_cachedCollection respondsToSelector:@selector(filterUsingPredicate:)]; - return section; -} - - -#pragma mark - Misc - -+ (FLEXCollectionType)typeForCollection:(id)collection { - // Order matters here, as NSDictionary is keyed but it responds to allObjects - if ([collection respondsToSelector:@selector(objectAtIndex:)]) { - return FLEXOrderedCollection; - } - if ([collection respondsToSelector:@selector(objectForKey:)]) { - return FLEXKeyedCollection; - } - if ([collection respondsToSelector:@selector(allObjects)]) { - return FLEXUnorderedCollection; - } - - [NSException raise:NSInvalidArgumentException - format:@"Given collection does not properly conform to FLEXCollection"]; - return FLEXUnsupportedCollection; -} - -/// Row titles -/// - Ordered: the index -/// - Unordered: the object -/// - Keyed: the key -- (NSString *)titleForRow:(NSInteger)row { - switch (self.collectionType) { - case FLEXOrderedCollection: - if (!self.hideOrderIndexes) { - return @(row).stringValue; - } - // Fall-through - case FLEXUnorderedCollection: - return [self describe:[self objectForRow:row]]; - case FLEXKeyedCollection: - return [self describe:self.cachedCollection.allKeys[row]]; - - case FLEXUnsupportedCollection: - return nil; - } -} - -/// Row subtitles -/// - Ordered: the object -/// - Unordered: nothing -/// - Keyed: the value -- (NSString *)subtitleForRow:(NSInteger)row { - switch (self.collectionType) { - case FLEXOrderedCollection: - if (!self.hideOrderIndexes) { - nil; - } - // Fall-through - case FLEXKeyedCollection: - return [self describe:[self objectForRow:row]]; - case FLEXUnorderedCollection: - return nil; - - case FLEXUnsupportedCollection: - return nil; - } -} - -- (NSString *)describe:(id)object { - return [FLEXRuntimeUtility summaryForObject:object]; -} - -- (id)objectForRow:(NSInteger)row { - switch (self.collectionType) { - case FLEXOrderedCollection: - return self.cachedCollection[row]; - case FLEXUnorderedCollection: - return self.cachedCollection.allObjects[row]; - case FLEXKeyedCollection: - return self.cachedCollection[self.cachedCollection.allKeys[row]]; - - case FLEXUnsupportedCollection: - return nil; - } -} - -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row { - return UITableViewCellAccessoryDisclosureIndicator; -// return self.isMutable ? UITableViewCellAccessoryDetailDisclosureButton : UITableViewCellAccessoryDisclosureIndicator; -} - - -#pragma mark - Overrides - -- (NSString *)title { - if (!self.hideSectionTitle) { - if (self.customTitle) { - return self.customTitle; - } - - return FLEXPluralString(self.cachedCollection.count, @"Entries", @"Entry"); - } - - return nil; -} - -- (NSInteger)numberOfRows { - return self.cachedCollection.count; -} - -- (void)setFilterText:(NSString *)filterText { - super.filterText = filterText; - - if (filterText.length) { - BOOL (^matcher)(id, id) = self.customFilter ?: ^BOOL(NSString *query, id obj) { - return [[self describe:obj] localizedCaseInsensitiveContainsString:query]; - }; - - NSPredicate *filter = [NSPredicate predicateWithBlock:^BOOL(id obj, NSDictionary *bindings) { - return matcher(filterText, obj); - }]; - - id tmp = self.cachedCollection.mutableCopy; - [tmp filterUsingPredicate:filter]; - self.cachedCollection = tmp; - } else { - self.cachedCollection = self.collection ?: (id)self.collectionFuture(self); - } -} - -- (void)reloadData { - if (self.collectionFuture) { - self.cachedCollection = (id)self.collectionFuture(self); - } else { - self.cachedCollection = self.collection.copy; - } -} - -- (BOOL)canSelectRow:(NSInteger)row { - return YES; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:[self objectForRow:row]]; -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - return kFLEXDetailCell; -} - -- (void)configureCell:(__kindof FLEXTableViewCell *)cell forRow:(NSInteger)row { - cell.titleLabel.text = [self titleForRow:row]; - cell.subtitleLabel.text = [self subtitleForRow:row]; - cell.accessoryType = [self accessoryTypeForRow:row]; -} - -@end - - -#pragma mark - NSMutableDictionary - -@implementation NSMutableDictionary (FLEXMutableCollection) - -- (void)filterUsingPredicate:(NSPredicate *)predicate { - id test = ^BOOL(id key, NSUInteger idx, BOOL *stop) { - if ([predicate evaluateWithObject:key]) { - return NO; - } - - return ![predicate evaluateWithObject:self[key]]; - }; - - NSArray *keys = self.allKeys; - NSIndexSet *remove = [keys indexesOfObjectsPassingTest:test]; - - [self removeObjectsForKeys:[keys objectsAtIndexes:remove]]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.h deleted file mode 100644 index 90e771cf..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// FLEXColorPreviewSection.h -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXSingleRowSection.h" -#import "FLEXObjectInfoSection.h" - -@interface FLEXColorPreviewSection : FLEXSingleRowSection - -+ (instancetype)forObject:(UIColor *)color; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.m deleted file mode 100644 index 5fb4c8bb..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXColorPreviewSection.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// FLEXColorPreviewSection.m -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColorPreviewSection.h" - -@implementation FLEXColorPreviewSection - -+ (instancetype)forObject:(UIColor *)color { - return [self title:@"Color" reuse:nil cell:^(__kindof UITableViewCell *cell) { - cell.backgroundColor = color; - }]; -} - -- (BOOL)canSelectRow:(NSInteger)row { - return NO; -} - -- (BOOL (^)(NSString *))filterMatcher { - return ^BOOL(NSString *filterText) { - // Hide when searching - return !filterText.length; - }; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.h deleted file mode 100644 index d794c76c..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// FLEXDefaultsContentSection.h -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCollectionContentSection.h" -#import "FLEXObjectInfoSection.h" - -@interface FLEXDefaultsContentSection : FLEXCollectionContentSection - -/// Uses \c NSUserDefaults.standardUserDefaults -+ (instancetype)standard; -+ (instancetype)forDefaults:(NSUserDefaults *)userDefaults; - -/// Whether or not to filter out keys not present in the app's user defaults file. -/// -/// This is useful for filtering out some useless keys that seem to appear -/// in every app's defaults but are never actually used or touched by the app. -/// Only applies to instances using \c NSUserDefaults.standardUserDefaults. -/// This is the default for any instance using \c standardUserDefaults, so -/// you must opt-out in those instances if you don't want this behavior. -@property (nonatomic) BOOL onlyShowKeysForAppPrefs; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.m deleted file mode 100644 index 15ef0337..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXDefaultsContentSection.m +++ /dev/null @@ -1,117 +0,0 @@ -// -// FLEXDefaultsContentSection.m -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXDefaultsContentSection.h" -#import "FLEXDefaultEditorViewController.h" -#import "FLEXUtility.h" - -@interface FLEXDefaultsContentSection () -@property (nonatomic) NSUserDefaults *defaults; -@property (nonatomic) NSArray *keys; -@property (nonatomic, readonly) NSDictionary *unexcludedDefaults; -@end - -@implementation FLEXDefaultsContentSection -@synthesize keys = _keys; - -#pragma mark Initialization - -+ (instancetype)forObject:(id)object { - return [self forDefaults:object]; -} - -+ (instancetype)standard { - return [self forDefaults:NSUserDefaults.standardUserDefaults]; -} - -+ (instancetype)forDefaults:(NSUserDefaults *)userDefaults { - FLEXDefaultsContentSection *section = [self forReusableFuture:^id(FLEXDefaultsContentSection *section) { - section.defaults = userDefaults; - section.onlyShowKeysForAppPrefs = YES; - return section.unexcludedDefaults; - }]; - return section; -} - -#pragma mark - Overrides - -- (NSString *)title { - return @"Defaults"; -} - -- (void (^)(__kindof UIViewController *))didPressInfoButtonAction:(NSInteger)row { - return ^(UIViewController *host) { - if ([FLEXDefaultEditorViewController canEditDefaultWithValue:[self objectForRow:row]]) { - // We use titleForRow: to get the key because self.keys is not - // necessarily in the same order as the keys being displayed - FLEXVariableEditorViewController *controller = [FLEXDefaultEditorViewController - target:self.defaults key:[self titleForRow:row] commitHandler:^{ - [self reloadData:YES]; - } - ]; - [host.navigationController pushViewController:controller animated:YES]; - } else { - [FLEXAlert showAlert:@"Oh No…" message:@"We can't edit this entry :(" from:host]; - } - }; -} - -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row { - return UITableViewCellAccessoryDetailDisclosureButton; -} - -#pragma mark - Private - -- (NSArray *)keys { - if (!_keys) { - if (self.onlyShowKeysForAppPrefs) { - // Read keys from preferences file - NSString *bundle = NSBundle.mainBundle.bundleIdentifier; - NSString *prefsPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Preferences"]; - NSString *filePath = [NSString stringWithFormat:@"%@/%@.plist", prefsPath, bundle]; - self.keys = [NSDictionary dictionaryWithContentsOfFile:filePath].allKeys; - } else { - self.keys = self.defaults.dictionaryRepresentation.allKeys; - } - } - - return _keys; -} - -- (void)setKeys:(NSArray *)keys { - _keys = [keys sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)]; -} - -- (NSDictionary *)unexcludedDefaults { - // Case: no excluding - if (!self.onlyShowKeysForAppPrefs) { - return self.defaults.dictionaryRepresentation; - } - - // Always regenerate key allowlist when this method is called - _keys = nil; - - // Generate new dictionary from unexcluded keys - NSArray *values = [self.defaults.dictionaryRepresentation - objectsForKeys:self.keys notFoundMarker:NSNull.null - ]; - return [NSDictionary dictionaryWithObjects:values forKeys:self.keys]; -} - -#pragma mark - Public - -- (void)setOnlyShowKeysForAppPrefs:(BOOL)onlyShowKeysForAppPrefs { - if (onlyShowKeysForAppPrefs) { - // This property only applies if we're using standardUserDefaults - if (self.defaults != NSUserDefaults.standardUserDefaults) return; - } - - _onlyShowKeysForAppPrefs = onlyShowKeysForAppPrefs; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.h deleted file mode 100644 index e96724f7..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// FLEXMetadataSection.h -// FLEX -// -// Created by Tanner Bennett on 9/19/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" -#import "FLEXObjectExplorer.h" - -typedef NS_ENUM(NSUInteger, FLEXMetadataKind) { - FLEXMetadataKindProperties = 1, - FLEXMetadataKindClassProperties, - FLEXMetadataKindIvars, - FLEXMetadataKindMethods, - FLEXMetadataKindClassMethods, - FLEXMetadataKindClassHierarchy, - FLEXMetadataKindProtocols, - FLEXMetadataKindOther -}; - -/// This section is used for displaying ObjC runtime metadata -/// about a class or object, such as listing methods, properties, etc. -@interface FLEXMetadataSection : FLEXTableViewSection - -+ (instancetype)explorer:(FLEXObjectExplorer *)explorer kind:(FLEXMetadataKind)metadataKind; - -@property (nonatomic, readonly) FLEXMetadataKind metadataKind; - -/// The names of metadata to exclude. Useful if you wish to group specific -/// properties or methods together in their own section outside of this one. -/// -/// Setting this property calls \c reloadData on this section. -@property (nonatomic) NSSet *excludedMetadata; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.m deleted file mode 100644 index 0413f73c..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMetadataSection.m +++ /dev/null @@ -1,233 +0,0 @@ -// -// FLEXMetadataSection.m -// FLEX -// -// Created by Tanner Bennett on 9/19/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMetadataSection.h" -#import "FLEXTableView.h" -#import "FLEXTableViewCell.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXFieldEditorViewController.h" -#import "FLEXMethodCallingViewController.h" -#import "FLEXIvar.h" -#import "NSArray+FLEX.h" -#import "FLEXRuntime+UIKitHelpers.h" - -@interface FLEXMetadataSection () -@property (nonatomic, readonly) FLEXObjectExplorer *explorer; -/// Filtered -@property (nonatomic, copy) NSArray> *metadata; -/// Unfiltered -@property (nonatomic, copy) NSArray> *allMetadata; -@end - -@implementation FLEXMetadataSection - -#pragma mark - Initialization - -+ (instancetype)explorer:(FLEXObjectExplorer *)explorer kind:(FLEXMetadataKind)metadataKind { - return [[self alloc] initWithExplorer:explorer kind:metadataKind]; -} - -- (id)initWithExplorer:(FLEXObjectExplorer *)explorer kind:(FLEXMetadataKind)metadataKind { - self = [super init]; - if (self) { - _explorer = explorer; - _metadataKind = metadataKind; - - [self reloadData]; - } - - return self; -} - -#pragma mark - Private - -- (NSString *)titleWithBaseName:(NSString *)baseName { - unsigned long totalCount = self.allMetadata.count; - unsigned long filteredCount = self.metadata.count; - - if (totalCount == filteredCount) { - return [baseName stringByAppendingFormat:@" (%lu)", totalCount]; - } else { - return [baseName stringByAppendingFormat:@" (%lu of %lu)", filteredCount, totalCount]; - } -} - -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row { - return [self.metadata[row] suggestedAccessoryTypeWithTarget:self.explorer.object]; -} - -#pragma mark - Public - -- (void)setExcludedMetadata:(NSSet *)excludedMetadata { - _excludedMetadata = excludedMetadata; - [self reloadData]; -} - -#pragma mark - Overrides - -- (NSString *)titleForRow:(NSInteger)row { - return [self.metadata[row] description]; -} - -- (NSString *)subtitleForRow:(NSInteger)row { - return [self.metadata[row] previewWithTarget:self.explorer.object]; -} - -- (NSString *)title { - switch (self.metadataKind) { - case FLEXMetadataKindProperties: - return [self titleWithBaseName:@"Properties"]; - case FLEXMetadataKindClassProperties: - return [self titleWithBaseName:@"Class Properties"]; - case FLEXMetadataKindIvars: - return [self titleWithBaseName:@"Ivars"]; - case FLEXMetadataKindMethods: - return [self titleWithBaseName:@"Methods"]; - case FLEXMetadataKindClassMethods: - return [self titleWithBaseName:@"Class Methods"]; - case FLEXMetadataKindClassHierarchy: - return [self titleWithBaseName:@"Class Hierarchy"]; - case FLEXMetadataKindProtocols: - return [self titleWithBaseName:@"Protocols"]; - case FLEXMetadataKindOther: - return @"Miscellaneous"; - } -} - -- (NSInteger)numberOfRows { - return self.metadata.count; -} - -- (void)setFilterText:(NSString *)filterText { - super.filterText = filterText; - - if (!self.filterText.length) { - self.metadata = self.allMetadata; - } else { - self.metadata = [self.allMetadata flex_filtered:^BOOL(FLEXProperty *obj, NSUInteger idx) { - return [obj.description localizedCaseInsensitiveContainsString:self.filterText]; - }]; - } -} - -- (void)reloadData { - switch (self.metadataKind) { - case FLEXMetadataKindProperties: - self.allMetadata = self.explorer.properties; - break; - case FLEXMetadataKindClassProperties: - self.allMetadata = self.explorer.classProperties; - break; - case FLEXMetadataKindIvars: - self.allMetadata = self.explorer.ivars; - break; - case FLEXMetadataKindMethods: - self.allMetadata = self.explorer.methods; - break; - case FLEXMetadataKindClassMethods: - self.allMetadata = self.explorer.classMethods; - break; - case FLEXMetadataKindProtocols: - self.allMetadata = self.explorer.conformedProtocols; - break; - case FLEXMetadataKindClassHierarchy: - self.allMetadata = self.explorer.classHierarchy; - break; - case FLEXMetadataKindOther: - self.allMetadata = @[self.explorer.instanceSize, self.explorer.imageName]; - break; - } - - // Remove excluded metadata - if (self.excludedMetadata.count) { - id filterBlock = ^BOOL(id obj, NSUInteger idx) { - return ![self.excludedMetadata containsObject:obj.name]; - }; - - // Filter exclusions and sort - self.allMetadata = [[self.allMetadata flex_filtered:filterBlock] - sortedArrayUsingSelector:@selector(compare:) - ]; - } - - // Re-filter data - self.filterText = self.filterText; -} - -- (BOOL)canSelectRow:(NSInteger)row { - UITableViewCellAccessoryType accessory = [self accessoryTypeForRow:row]; - return accessory == UITableViewCellAccessoryDisclosureIndicator || - accessory == UITableViewCellAccessoryDetailDisclosureButton; -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - return [self.metadata[row] reuseIdentifierWithTarget:self.explorer.object] ?: kFLEXCodeFontCell; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return [self.metadata[row] viewerWithTarget:self.explorer.object]; -} - -- (void (^)(__kindof UIViewController *))didPressInfoButtonAction:(NSInteger)row { - return ^(UIViewController *host) { - [host.navigationController pushViewController:[self editorForRow:row] animated:YES]; - }; -} - -- (UIViewController *)editorForRow:(NSInteger)row { - return [self.metadata[row] editorWithTarget:self.explorer.object section:self]; -} - -- (void)configureCell:(__kindof FLEXTableViewCell *)cell forRow:(NSInteger)row { - cell.titleLabel.text = [self titleForRow:row]; - cell.subtitleLabel.text = [self subtitleForRow:row]; - cell.accessoryType = [self accessoryTypeForRow:row]; -} - -- (NSString *)menuSubtitleForRow:(NSInteger)row { - return [self.metadata[row] contextualSubtitleWithTarget:self.explorer.object]; -} - -- (NSArray *)menuItemsForRow:(NSInteger)row sender:(UIViewController *)sender { - NSArray *existingItems = [super menuItemsForRow:row sender:sender]; - - // These two metadata kinds don't any of the additional options below - switch (self.metadataKind) { - case FLEXMetadataKindClassHierarchy: - case FLEXMetadataKindOther: - return existingItems; - - default: break; - } - - id metadata = self.metadata[row]; - NSMutableArray *menuItems = [NSMutableArray new]; - - [menuItems addObject:[UIAction - actionWithTitle:@"Explore Metadata" - image:nil - identifier:nil - handler:^(__kindof UIAction *action) { - [sender.navigationController pushViewController:[FLEXObjectExplorerFactory - explorerViewControllerForObject:metadata - ] animated:YES]; - } - ]]; - [menuItems addObjectsFromArray:[metadata - additionalActionsWithTarget:self.explorer.object sender:sender - ]]; - [menuItems addObjectsFromArray:existingItems]; - - return menuItems.copy; -} - -- (NSArray *)copyMenuItemsForRow:(NSInteger)row { - return [self.metadata[row] copiableMetadataWithTarget:self.explorer.object]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.h deleted file mode 100644 index 6b49a02c..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// FLEXMutableListSection.h -// FLEX -// -// Created by Tanner on 3/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXCollectionContentSection.h" - -typedef void (^FLEXMutableListCellForElement)(__kindof UITableViewCell *cell, id element, NSInteger row); - -/// A section aimed at meeting the needs of table views with one section -/// (or, a section that shouldn't warrant the code duplication that comes -/// with creating a new section just for some specific table view) -/// -/// Use this section if you want to display a growing list of rows, -/// or even if you want to display a static list of rows. -/// -/// To support editing or inserting, implement the appropriate -/// table view delegate methods in your table view delegate class -/// and call \c mutate: (or \c setList: ) before updating the table view. -/// -/// By default, no section title is shown. Assign one to \c customTitle -/// -/// By default, \c kFLEXDetailCell is the reuse identifier used. If you need -/// to support multiple reuse identifiers in a single section, implement the -/// \c cellForRowAtIndexPath: method, dequeue the cell yourself and call -/// \c -configureCell: on the appropriate section object, passing in the cell -@interface FLEXMutableListSection<__covariant ObjectType> : FLEXCollectionContentSection - -/// Initializes a section with an empty list. -+ (instancetype)list:(NSArray *)list - cellConfiguration:(FLEXMutableListCellForElement)configurationBlock - filterMatcher:(BOOL(^)(NSString *filterText, id element))filterBlock; - -/// By default, rows are not selectable. If you want rows -/// to be selectable, provide a selection handler here. -@property (nonatomic, copy) void (^selectionHandler)(__kindof UIViewController *host, id element); - -/// The objects representing all possible rows in the section. -@property (nonatomic) NSArray *list; -/// The objects representing the currently unfiltered rows in the section. -@property (nonatomic, readonly) NSArray *filteredList; - -/// A readwrite version of the same property in \c FLEXTableViewSection.h -/// -/// This property expects one entry. An exception is thrown if more than one -/// entry is supplied. If you need more than one reuse identifier within a single -/// section, your view probably has more complexity than this class can handle. -@property (nonatomic, readwrite) NSDictionary *cellRegistrationMapping; - -/// Call this method to mutate the full, unfiltered list. -/// This ensures that \c filteredList is updated after any mutations. -- (void)mutate:(void(^)(NSMutableArray *list))block; - -@end - diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.m deleted file mode 100644 index d63c344f..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXMutableListSection.m +++ /dev/null @@ -1,110 +0,0 @@ -// -// FLEXMutableListSection.m -// FLEX -// -// Created by Tanner on 3/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMutableListSection.h" -#import "FLEXMacros.h" - -@interface FLEXMutableListSection () -@property (nonatomic, readonly) FLEXMutableListCellForElement configureCell; -@end - -@implementation FLEXMutableListSection -@synthesize cellRegistrationMapping = _cellRegistrationMapping; - -#pragma mark - Initialization - -+ (instancetype)list:(NSArray *)list - cellConfiguration:(FLEXMutableListCellForElement)cellConfig - filterMatcher:(BOOL(^)(NSString *, id))filterBlock { - return [[self alloc] initWithList:list configurationBlock:cellConfig filterMatcher:filterBlock]; -} - -- (id)initWithList:(NSArray *)list -configurationBlock:(FLEXMutableListCellForElement)cellConfig - filterMatcher:(BOOL(^)(NSString *, id))filterBlock { - self = [super init]; - if (self) { - _configureCell = cellConfig; - - self.list = list.mutableCopy; - self.customFilter = filterBlock; - self.hideSectionTitle = YES; - } - - return self; -} - - -#pragma mark - Public - -- (NSArray *)list { - return (id)_collection; -} - -- (void)setList:(NSMutableArray *)list { - NSParameterAssert(list); - _collection = (id)list; - - [self reloadData]; -} - -- (NSArray *)filteredList { - return (id)_cachedCollection; -} - -- (void)mutate:(void (^)(NSMutableArray *))block { - block((NSMutableArray *)_collection); - [self reloadData]; -} - - -#pragma mark - Overrides - -- (void)setCustomTitle:(NSString *)customTitle { - super.customTitle = customTitle; - self.hideSectionTitle = customTitle == nil; -} - -- (BOOL)canSelectRow:(NSInteger)row { - return self.selectionHandler != nil; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - return nil; -} - -- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row { - if (self.selectionHandler) { weakify(self) - return ^(UIViewController *host) { strongify(self) - if (self) { - self.selectionHandler(host, self.filteredList[row]); - } - }; - } - - return nil; -} - -- (void)configureCell:(__kindof UITableViewCell *)cell forRow:(NSInteger)row { - self.configureCell(cell, self.filteredList[row], row); -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - if (self.cellRegistrationMapping.count) { - return self.cellRegistrationMapping.allKeys.firstObject; - } - - return [super reuseIdentifierForRow:row]; -} - -- (void)setCellRegistrationMapping:(NSDictionary *)cellRegistrationMapping { - NSParameterAssert(cellRegistrationMapping.count <= 1); - _cellRegistrationMapping = cellRegistrationMapping; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXObjectInfoSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/FLEXObjectInfoSection.h deleted file mode 100644 index 656955b5..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/FLEXObjectInfoSection.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXObjectInfoSection.h -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -/// \c FLEXTableViewSection itself doesn't know about the object being explored. -/// Subclasses might need this info to provide useful information about the object. Instead -/// of adding an abstract class to the class hierarchy, subclasses can conform to this protocol -/// to indicate that the only info they need to be initialized is the object being explored. -@protocol FLEXObjectInfoSection - -+ (instancetype)forObject:(id)object; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.h deleted file mode 100644 index 45cbed5f..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXBlockShortcuts.h -// FLEX -// -// Created by Tanner on 1/30/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Provides a description of the block's signature -/// and access to an NSMethodSignature of the block -@interface FLEXBlockShortcuts : FLEXShortcutsSection - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.m deleted file mode 100644 index b2b71363..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBlockShortcuts.m +++ /dev/null @@ -1,59 +0,0 @@ -// -// FLEXBlockShortcuts.m -// FLEX -// -// Created by Tanner on 1/30/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXBlockShortcuts.h" -#import "FLEXShortcut.h" -#import "FLEXBlockDescription.h" -#import "FLEXObjectExplorerFactory.h" - -#pragma mark - -@implementation FLEXBlockShortcuts - -#pragma mark Overrides - -+ (instancetype)forObject:(id)block { - NSParameterAssert([block isKindOfClass:NSClassFromString(@"NSBlock")]); - - FLEXBlockDescription *blockInfo = [FLEXBlockDescription describing:block]; - NSMethodSignature *signature = blockInfo.signature; - NSArray *blockShortcutRows = @[blockInfo.summary]; - - if (signature) { - blockShortcutRows = @[ - blockInfo.summary, - blockInfo.sourceDeclaration, - signature.debugDescription, - [FLEXActionShortcut title:@"View Method Signature" - subtitle:^NSString *(id block) { - return signature.description ?: @"unsupported signature"; - } - viewer:^UIViewController *(id block) { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:signature]; - } - accessoryType:^UITableViewCellAccessoryType(id view) { - if (signature) { - return UITableViewCellAccessoryDisclosureIndicator; - } - return UITableViewCellAccessoryNone; - } - ] - ]; - } - - return [self forObject:block additionalRows:blockShortcutRows]; -} - -- (NSString *)title { - return @"Metadata"; -} - -- (NSInteger)numberOfLines { - return 0; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.h deleted file mode 100644 index b88fb68d..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// FLEXBundleShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Provides a "Browse Bundle Directory" action -@interface FLEXBundleShortcuts : FLEXShortcutsSection - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.m deleted file mode 100644 index a51db87e..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXBundleShortcuts.m +++ /dev/null @@ -1,114 +0,0 @@ -// -// FLEXBundleShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXBundleShortcuts.h" -#import "FLEXShortcut.h" -#import "FLEXAlert.h" -#import "FLEXMacros.h" -#import "FLEXRuntimeExporter.h" -#import "FLEXTableListViewController.h" -#import "FLEXFileBrowserController.h" - -#pragma mark - -@implementation FLEXBundleShortcuts -#pragma mark Overrides - -+ (instancetype)forObject:(NSBundle *)bundle { weakify(self) - return [self forObject:bundle additionalRows:@[ - [FLEXActionShortcut - title:@"Browse Bundle Directory" subtitle:nil - viewer:^UIViewController *(NSBundle *bundle) { - return [FLEXFileBrowserController path:bundle.bundlePath]; - } - accessoryType:^UITableViewCellAccessoryType(NSBundle *bundle) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - [FLEXActionShortcut title:@"Browse Bundle as Database…" subtitle:nil - selectionHandler:^(UIViewController *host, NSBundle *bundle) { strongify(self) - [self promptToExportBundleAsDatabase:bundle host:host]; - } - accessoryType:^UITableViewCellAccessoryType(NSBundle *bundle) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - ]]; -} - -+ (void)promptToExportBundleAsDatabase:(NSBundle *)bundle host:(UIViewController *)host { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Save As…").message( - @"The database be saved in the Library folder. " - "Depending on the number of classes, it may take " - "10 minutes or more to finish exporting. 20,000 " - "classes takes about 7 minutes." - ); - make.configuredTextField(^(UITextField *field) { - field.placeholder = @"FLEXRuntimeExport.objc.db"; - field.text = [NSString stringWithFormat: - @"%@.objc.db", bundle.executablePath.lastPathComponent - ]; - }); - make.button(@"Start").handler(^(NSArray *strings) { - [self browseBundleAsDatabase:bundle host:host name:strings[0]]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:host]; -} - -+ (void)browseBundleAsDatabase:(NSBundle *)bundle host:(UIViewController *)host name:(NSString *)name { - NSParameterAssert(name.length); - - UIAlertController *progress = [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Generating Database"); - // Some iOS version glitch out of there is - // no initial message and you add one later - make.message(@"…"); - }]; - - [host presentViewController:progress animated:YES completion:^{ - // Generate path to store db - NSString *path = [NSSearchPathForDirectoriesInDomains( - NSLibraryDirectory, NSUserDomainMask, YES - )[0] stringByAppendingPathComponent:name]; - - progress.message = [path stringByAppendingString:@"\n\nCreating database…"]; - - // Generate db and show progress - [FLEXRuntimeExporter createRuntimeDatabaseAtPath:path - forImages:@[bundle.executablePath] - progressHandler:^(NSString *status) { - dispatch_async(dispatch_get_main_queue(), ^{ - progress.message = [progress.message - stringByAppendingFormat:@"\n%@", status - ]; - [progress.view setNeedsLayout]; - [progress.view layoutIfNeeded]; - }); - } completion:^(NSString *error) { - // Display error if any - if (error) { - progress.title = @"Error"; - progress.message = error; - [progress addAction:[UIAlertAction - actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil] - ]; - } - // Browse database - else { - [progress dismissViewControllerAnimated:YES completion:nil]; - [host.navigationController pushViewController:[ - [FLEXTableListViewController alloc] initWithPath:path - ] animated:YES]; - } - } - ]; - }]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.h deleted file mode 100644 index 706ee2d1..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXClassShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 11/22/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -/// Provides handy shortcuts for class objects. -/// This is the default section used for all class objects. -@interface FLEXClassShortcuts : FLEXShortcutsSection - -+ (instancetype)forObject:(Class)cls; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.m deleted file mode 100644 index b650b9f2..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXClassShortcuts.m +++ /dev/null @@ -1,73 +0,0 @@ -// -// FLEXClassShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 11/22/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXClassShortcuts.h" -#import "FLEXShortcut.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXObjectListViewController.h" -#import "NSObject+FLEX_Reflection.h" - -@interface FLEXClassShortcuts () -@property (nonatomic, readonly) Class cls; -@end - -@implementation FLEXClassShortcuts - -+ (instancetype)forObject:(Class)cls { - // These additional rows will appear at the beginning of the shortcuts section. - // The methods below are written in such a way that they will not interfere - // with properties/etc being registered alongside these - return [self forObject:cls additionalRows:@[ - [FLEXActionShortcut title:@"Find Live Instances" subtitle:nil - viewer:^UIViewController *(id obj) { - return [FLEXObjectListViewController - instancesOfClassWithName:NSStringFromClass(obj) - retained:NO - ]; - } - accessoryType:^UITableViewCellAccessoryType(id obj) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - [FLEXActionShortcut title:@"List Subclasses" subtitle:nil - viewer:^UIViewController *(id obj) { - NSString *name = NSStringFromClass(obj); - return [FLEXObjectListViewController subclassesOfClassWithName:name]; - } - accessoryType:^UITableViewCellAccessoryType(id view) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - [FLEXActionShortcut title:@"Explore Bundle for Class" - subtitle:^NSString *(id obj) { - return [self shortNameForBundlePath:[NSBundle bundleForClass:obj].executablePath]; - } - viewer:^UIViewController *(id obj) { - NSBundle *bundle = [NSBundle bundleForClass:obj]; - return [FLEXObjectExplorerFactory explorerViewControllerForObject:bundle]; - } - accessoryType:^UITableViewCellAccessoryType(id view) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - ]]; -} - -+ (NSString *)shortNameForBundlePath:(NSString *)imageName { - NSArray *components = [imageName componentsSeparatedByString:@"/"]; - if (components.count >= 2) { - return [NSString stringWithFormat:@"%@/%@", - components[components.count - 2], - components[components.count - 1] - ]; - } - - return imageName.lastPathComponent; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.h deleted file mode 100644 index 59bbba39..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// FLEXImageShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -/// Provides "view image" and "save image" shortcuts for UIImage objects -@interface FLEXImageShortcuts : FLEXShortcutsSection - -+ (instancetype)forObject:(UIImage *)image; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.m deleted file mode 100644 index 95527354..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXImageShortcuts.m +++ /dev/null @@ -1,68 +0,0 @@ -// -// FLEXImageShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXImageShortcuts.h" -#import "FLEXImagePreviewViewController.h" -#import "FLEXShortcut.h" -#import "FLEXAlert.h" -#import "FLEXMacros.h" - -@interface UIAlertController (FLEXImageShortcuts) -- (void)flex_image:(UIImage *)image disSaveWithError:(NSError *)error :(void *)context; -@end - -@implementation FLEXImageShortcuts - -#pragma mark - Overrides - -+ (instancetype)forObject:(UIImage *)image { - // These additional rows will appear at the beginning of the shortcuts section. - // The methods below are written in such a way that they will not interfere - // with properties/etc being registered alongside these - return [self forObject:image additionalRows:@[ - [FLEXActionShortcut title:@"View Image" subtitle:nil - viewer:^UIViewController *(id image) { - return [FLEXImagePreviewViewController forImage:image]; - } - accessoryType:^UITableViewCellAccessoryType(id image) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ], - [FLEXActionShortcut title:@"Save Image" subtitle:nil - selectionHandler:^(UIViewController *host, id image) { - // Present modal alerting user about saving - UIAlertController *alert = [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Saving Image…"); - }]; - [host presentViewController:alert animated:YES completion:nil]; - - // Save the image - UIImageWriteToSavedPhotosAlbum( - image, alert, @selector(flex_image:disSaveWithError::), nil - ); - } - accessoryType:^UITableViewCellAccessoryType(id image) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ] - ]]; -} - -@end - - -@implementation UIAlertController (FLEXImageShortcuts) - -- (void)flex_image:(UIImage *)image disSaveWithError:(NSError *)error :(void *)context { - self.title = @"Image Saved"; - flex_dispatch_after(1, dispatch_get_main_queue(), ^{ - [self dismissViewControllerAnimated:YES completion:nil]; - }); -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.h deleted file mode 100644 index dad8d959..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// FLEXLayerShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -@interface FLEXLayerShortcuts : FLEXShortcutsSection - -+ (instancetype)forObject:(CALayer *)layer; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.m deleted file mode 100644 index 1cf4808a..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXLayerShortcuts.m +++ /dev/null @@ -1,28 +0,0 @@ -// -// FLEXLayerShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXLayerShortcuts.h" -#import "FLEXShortcut.h" -#import "FLEXImagePreviewViewController.h" - -@implementation FLEXLayerShortcuts - -+ (instancetype)forObject:(CALayer *)layer { - return [self forObject:layer additionalRows:@[ - [FLEXActionShortcut title:@"Preview Image" subtitle:nil - viewer:^UIViewController *(CALayer *layer) { - return [FLEXImagePreviewViewController previewForLayer:layer]; - } - accessoryType:^UITableViewCellAccessoryType(CALayer *layer) { - return CGRectIsEmpty(layer.bounds) ? UITableViewCellAccessoryNone : UITableViewCellAccessoryDisclosureIndicator; - } - ] - ]]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.h deleted file mode 100644 index 9023e038..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXNSDataShortcuts.h -// FLEX -// -// Created by Tanner on 3/29/21. -// - -#import "FLEXShortcutsSection.h" - -/// Adds a "UTF-8 String" shortcut -@interface FLEXNSDataShortcuts : FLEXShortcutsSection - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.m deleted file mode 100644 index 7de28cf5..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSDataShortcuts.m +++ /dev/null @@ -1,48 +0,0 @@ -// -// FLEXNSDataShortcuts.m -// FLEX -// -// Created by Tanner on 3/29/21. -// - -#import "FLEXNSDataShortcuts.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXShortcut.h" - -@implementation FLEXNSDataShortcuts - -+ (instancetype)forObject:(NSData *)data { - NSString *string = [self stringForData:data]; - - return [self forObject:data additionalRows:@[ - [FLEXActionShortcut title:@"UTF-8 String" subtitle:^(NSData *object) { - return string.length ? string : (string ? - @"Data is not a UTF8 String" : @"Empty string" - ); - } viewer:^UIViewController *(id object) { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:string]; - } accessoryType:^UITableViewCellAccessoryType(NSData *object) { - if (string.length) { - return UITableViewCellAccessoryDisclosureIndicator; - } - - return UITableViewCellAccessoryNone; - }] - ]]; -} - -+ (NSString *)stringForData:(NSData *)data { - return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -} - -@end - -@interface NSData (Overrides) @end -@implementation NSData (Overrides) - -// This normally crashes -- (NSUInteger)length { - return 0; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.h deleted file mode 100644 index 460dfc1e..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXNSStringShortcuts.h -// FLEX -// -// Created by Tanner on 3/29/21. -// - -#import "FLEXShortcutsSection.h" - -/// Adds a "UTF-8 Data" shortcut -@interface FLEXNSStringShortcuts : FLEXShortcutsSection - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.m deleted file mode 100644 index a236362a..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXNSStringShortcuts.m +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXNSStringShortcuts.m -// FLEX -// -// Created by Tanner on 3/29/21. -// - -#import "FLEXNSStringShortcuts.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXShortcut.h" - -@implementation FLEXNSStringShortcuts - -+ (instancetype)forObject:(NSString *)string { - NSUInteger length = [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; - NSData *data = [NSData dataWithBytesNoCopy:(void *)string.UTF8String length:length freeWhenDone:NO]; - - return [self forObject:string additionalRows:@[ - [FLEXActionShortcut title:@"UTF-8 Data" subtitle:^NSString *(id _) { - return data.description; - } viewer:^UIViewController *(id _) { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:data]; - } accessoryType:^UITableViewCellAccessoryType(id _) { - return UITableViewCellAccessoryDisclosureIndicator; - }] - ]]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h deleted file mode 100644 index cece75b4..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.h +++ /dev/null @@ -1,71 +0,0 @@ -// -// FLEXShortcut.h -// FLEX -// -// Created by Tanner Bennett on 12/10/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXObjectExplorer.h" - -NS_ASSUME_NONNULL_BEGIN - -/// Represents a row in a shortcut section. -/// -/// The purpsoe of this protocol is to allow delegating a small -/// subset of the responsibilities of a \c FLEXShortcutsSection -/// to another object, for a single arbitrary row. -/// -/// It is useful to make your own shortcuts to append/prepend -/// them to the existing list of shortcuts for a class. -@protocol FLEXShortcut - -- (nonnull NSString *)titleWith:(id)object; -- (nullable NSString *)subtitleWith:(id)object; -- (nullable void (^)(UIViewController *host))didSelectActionWith:(id)object; -/// Called when the row is selected -- (nullable UIViewController *)viewerWith:(id)object; -/// Basically, whether or not to show a detail disclosure indicator -- (UITableViewCellAccessoryType)accessoryTypeWith:(id)object; -/// If nil is returned, the default reuse identifier is used -- (nullable NSString *)customReuseIdentifierWith:(id)object; - -@optional -/// Called when the (i) button is pressed if the accessory type includes it -- (UIViewController *)editorWith:(id)object forSection:(FLEXTableViewSection *)section; - -@end - - -/// Provides default behavior for FLEX metadata objects. Also works in a limited way with strings. -/// Used internally. If you wish to use this object, only pass in \c FLEX* metadata objects. -@interface FLEXShortcut : NSObject - -/// @param item An \c NSString or \c FLEX* metadata object. -/// @note You may also pass a \c FLEXShortcut conforming object, -/// and that object will be returned instead. -+ (id)shortcutFor:(id)item; - -@end - - -/// Provides a quick and dirty implementation of the \c FLEXShortcut protocol, -/// allowing you to specify a static title and dynamic atttributes for everything else. -/// The object passed into each block is the object passed to each \c FLEXShortcut method. -/// -/// Does not support the \c -editorWith: method. -@interface FLEXActionShortcut : NSObject - -+ (instancetype)title:(NSString *)title - subtitle:(nullable NSString *(^)(id object))subtitleFuture - viewer:(nullable UIViewController *(^)(id object))viewerFuture - accessoryType:(nullable UITableViewCellAccessoryType(^)(id object))accessoryTypeFuture; - -+ (instancetype)title:(NSString *)title - subtitle:(nullable NSString *(^)(id object))subtitleFuture - selectionHandler:(nullable void (^)(UIViewController *host, id object))tapAction - accessoryType:(nullable UITableViewCellAccessoryType(^)(id object))accessoryTypeFuture; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.m deleted file mode 100644 index ac9c8928..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcut.m +++ /dev/null @@ -1,254 +0,0 @@ -// -// FLEXShortcut.m -// FLEX -// -// Created by Tanner Bennett on 12/10/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcut.h" -#import "FLEXProperty.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXIvar.h" -#import "FLEXMethod.h" -#import "FLEXRuntime+UIKitHelpers.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXFieldEditorViewController.h" -#import "FLEXMethodCallingViewController.h" -#import "FLEXMetadataSection.h" -#import "FLEXTableView.h" - - -#pragma mark - FLEXShortcut - -@interface FLEXShortcut () { - id _item; -} - -@property (nonatomic, readonly) FLEXMetadataKind metadataKind; -@property (nonatomic, readonly) FLEXProperty *property; -@property (nonatomic, readonly) FLEXMethod *method; -@property (nonatomic, readonly) FLEXIvar *ivar; -@property (nonatomic, readonly) id metadata; -@end - -@implementation FLEXShortcut -@synthesize defaults = _defaults; - -+ (id)shortcutFor:(id)item { - if ([item conformsToProtocol:@protocol(FLEXShortcut)]) { - return item; - } - - FLEXShortcut *shortcut = [self new]; - shortcut->_item = item; - - if ([item isKindOfClass:[FLEXProperty class]]) { - if (shortcut.property.isClassProperty) { - shortcut->_metadataKind = FLEXMetadataKindClassProperties; - } else { - shortcut->_metadataKind = FLEXMetadataKindProperties; - } - } - if ([item isKindOfClass:[FLEXIvar class]]) { - shortcut->_metadataKind = FLEXMetadataKindIvars; - } - if ([item isKindOfClass:[FLEXMethod class]]) { - // We don't care if it's a class method or not - shortcut->_metadataKind = FLEXMetadataKindMethods; - } - - return shortcut; -} - -- (id)propertyOrIvarValue:(id)object { - return [self.metadata currentValueWithTarget:object]; -} - -- (NSString *)titleWith:(id)object { - switch (self.metadataKind) { - case FLEXMetadataKindClassProperties: - case FLEXMetadataKindProperties: - // Since we're outside of the "properties" section, prepend @property for clarity. - return [@"@property " stringByAppendingString:[_item description]]; - - default: - return [_item description]; - } - - NSAssert( - [_item isKindOfClass:[NSString class]], - @"Unexpected type: %@", [_item class] - ); - - return _item; -} - -- (NSString *)subtitleWith:(id)object { - if (self.metadataKind) { - return [self.metadata previewWithTarget:object]; - } - - // Item is probably a string; must return empty string since - // these will be gathered into an array. If the object is a - // just a string, it doesn't get a subtitle. - return @""; -} - -- (void (^)(UIViewController *))didSelectActionWith:(id)object { - return nil; -} - -- (UIViewController *)viewerWith:(id)object { - NSAssert(self.metadataKind, @"Static titles cannot be viewed"); - return [self.metadata viewerWithTarget:object]; -} - -- (UIViewController *)editorWith:(id)object forSection:(FLEXTableViewSection *)section { - NSAssert(self.metadataKind, @"Static titles cannot be edited"); - return [self.metadata editorWithTarget:object section:section]; -} - -- (UITableViewCellAccessoryType)accessoryTypeWith:(id)object { - if (self.metadataKind) { - return [self.metadata suggestedAccessoryTypeWithTarget:object]; - } - - return UITableViewCellAccessoryNone; -} - -- (NSString *)customReuseIdentifierWith:(id)object { - if (self.metadataKind) { - return kFLEXCodeFontCell; - } - - return kFLEXMultilineCell; -} - -#pragma mark FLEXObjectExplorerDefaults - -- (void)setDefaults:(FLEXObjectExplorerDefaults *)defaults { - _defaults = defaults; - - if (_metadataKind) { - self.metadata.defaults = defaults; - } -} - -- (BOOL)isEditable { - if (_metadataKind) { - return self.metadata.isEditable; - } - - return NO; -} - -- (BOOL)isCallable { - if (_metadataKind) { - return self.metadata.isCallable; - } - - return NO; -} - -#pragma mark - Helpers - -- (FLEXProperty *)property { return _item; } -- (FLEXMethodBase *)method { return _item; } -- (FLEXIvar *)ivar { return _item; } -- (id)metadata { return _item; } - -@end - - -#pragma mark - FLEXActionShortcut - -@interface FLEXActionShortcut () -@property (nonatomic, readonly) NSString *title; -@property (nonatomic, readonly) NSString *(^subtitleFuture)(id); -@property (nonatomic, readonly) UIViewController *(^viewerFuture)(id); -@property (nonatomic, readonly) void (^selectionHandler)(UIViewController *, id); -@property (nonatomic, readonly) UITableViewCellAccessoryType (^accessoryTypeFuture)(id); -@end - -@implementation FLEXActionShortcut -@synthesize defaults = _defaults; - -+ (instancetype)title:(NSString *)title - subtitle:(NSString *(^)(id))subtitle - viewer:(UIViewController *(^)(id))viewer - accessoryType:(UITableViewCellAccessoryType (^)(id))type { - return [[self alloc] initWithTitle:title subtitle:subtitle viewer:viewer selectionHandler:nil accessoryType:type]; -} - -+ (instancetype)title:(NSString *)title - subtitle:(NSString * (^)(id))subtitle - selectionHandler:(void (^)(UIViewController *, id))tapAction - accessoryType:(UITableViewCellAccessoryType (^)(id))type { - return [[self alloc] initWithTitle:title subtitle:subtitle viewer:nil selectionHandler:tapAction accessoryType:type]; -} - -- (id)initWithTitle:(NSString *)title - subtitle:(id)subtitleFuture - viewer:(id)viewerFuture - selectionHandler:(id)tapAction - accessoryType:(id)accessoryTypeFuture { - NSParameterAssert(title.length); - - self = [super init]; - if (self) { - id nilBlock = ^id (id obj) { return nil; }; - - _title = title; - _subtitleFuture = subtitleFuture ?: nilBlock; - _viewerFuture = viewerFuture ?: nilBlock; - _selectionHandler = tapAction; - _accessoryTypeFuture = accessoryTypeFuture ?: nilBlock; - } - - return self; -} - -- (NSString *)titleWith:(id)object { - return self.title; -} - -- (NSString *)subtitleWith:(id)object { - if (self.defaults.wantsDynamicPreviews) { - return self.subtitleFuture(object); - } - - return nil; -} - -- (void (^)(UIViewController *))didSelectActionWith:(id)object { - if (self.selectionHandler) { - return ^(UIViewController *host) { - self.selectionHandler(host, object); - }; - } - - return nil; -} - -- (UIViewController *)viewerWith:(id)object { - return self.viewerFuture(object); -} - -- (UITableViewCellAccessoryType)accessoryTypeWith:(id)object { - return self.accessoryTypeFuture(object); -} - -- (NSString *)customReuseIdentifierWith:(id)object { - if (!self.subtitleFuture(object)) { - // The text is more centered with this style if there is no subtitle - return kFLEXDefaultCell; - } - - return nil; -} - -- (BOOL)isEditable { return NO; } -- (BOOL)isCallable { return NO; } - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.h deleted file mode 100644 index 22548681..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// FLEXShortcutsFactory+Defaults.h -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -@interface FLEXShortcutsFactory (UIApplication) @end - -@interface FLEXShortcutsFactory (Views) @end - -@interface FLEXShortcutsFactory (ViewControllers) @end - -@interface FLEXShortcutsFactory (UIImage) @end - -@interface FLEXShortcutsFactory (NSBundle) @end - -@interface FLEXShortcutsFactory (Classes) @end - -@interface FLEXShortcutsFactory (Activities) @end - -@interface FLEXShortcutsFactory (Blocks) @end - -@interface FLEXShortcutsFactory (Foundation) @end - -@interface FLEXShortcutsFactory (WebKit_Safari) @end - -@interface FLEXShortcutsFactory (Pasteboard) @end - -@interface FLEXShortcutsFactory (FirebaseFirestore) @end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.m deleted file mode 100644 index be9e6d02..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsFactory+Defaults.m +++ /dev/null @@ -1,456 +0,0 @@ -// -// FLEXShortcutsFactory+Defaults.m -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsFactory+Defaults.h" -#import "FLEXShortcut.h" -#import "FLEXMacros.h" -#import "FLEXRuntimeUtility.h" -#import "NSArray+FLEX.h" -#import "NSObject+FLEX_Reflection.h" -#import "FLEXObjcInternal.h" -#import "Cocoa+FLEXShortcuts.h" - -#pragma mark - UIApplication - -@implementation FLEXShortcutsFactory (UIApplication) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - // sharedApplication class property possibly not added - // as a literal class property until iOS 10 - FLEXRuntimeUtilityTryAddObjectProperty( - 2, sharedApplication, UIApplication.flex_metaclass, UIApplication, PropertyKey(ReadOnly) - ); - - self.append.classProperties(@[@"sharedApplication"]).forClass(UIApplication.flex_metaclass); - self.append.properties(@[ - @"delegate", @"keyWindow", @"windows" - ]).forClass(UIApplication.class); - - if (@available(iOS 13, *)) { - self.append.properties(@[ - @"connectedScenes", @"openSessions", @"supportsMultipleScenes" - ]).forClass(UIApplication.class); - } -} - -@end - -#pragma mark - Views - -@implementation FLEXShortcutsFactory (Views) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - // A quirk of UIView and some other classes: a lot of the `@property`s are - // not actually properties from the perspective of the runtime. - // - // We add these properties to the class at runtime if they haven't been added yet. - // This way, we can use our property editor to access and change them. - // The property attributes match the declared attributes in their headers. - - // UIView, public - Class UIView_ = UIView.class; - FLEXRuntimeUtilityTryAddNonatomicProperty(2, frame, UIView_, CGRect); - FLEXRuntimeUtilityTryAddNonatomicProperty(2, alpha, UIView_, CGFloat); - FLEXRuntimeUtilityTryAddNonatomicProperty(2, clipsToBounds, UIView_, BOOL); - FLEXRuntimeUtilityTryAddNonatomicProperty(2, opaque, UIView_, BOOL, PropertyKeyGetter(isOpaque)); - FLEXRuntimeUtilityTryAddNonatomicProperty(2, hidden, UIView_, BOOL, PropertyKeyGetter(isHidden)); - FLEXRuntimeUtilityTryAddObjectProperty(2, backgroundColor, UIView_, UIColor, PropertyKey(Copy)); - FLEXRuntimeUtilityTryAddObjectProperty(6, constraints, UIView_, NSArray, PropertyKey(ReadOnly)); - FLEXRuntimeUtilityTryAddObjectProperty(2, subviews, UIView_, NSArray, PropertyKey(ReadOnly)); - FLEXRuntimeUtilityTryAddObjectProperty(2, superview, UIView_, UIView, PropertyKey(ReadOnly)); - FLEXRuntimeUtilityTryAddObjectProperty(7, tintColor, UIView_, UIView); - - // UIButton, private - FLEXRuntimeUtilityTryAddObjectProperty(2, font, UIButton.class, UIFont, PropertyKey(ReadOnly)); - - // Only available since iOS 3.2, but we never supported iOS 3, so who cares - NSArray *ivars = @[@"_gestureRecognizers"]; - NSArray *methods = @[@"sizeToFit", @"setNeedsLayout", @"removeFromSuperview"]; - - // UIView - self.append.ivars(ivars).methods(methods).properties(@[ - @"frame", @"bounds", @"center", @"transform", - @"backgroundColor", @"alpha", @"opaque", @"hidden", - @"clipsToBounds", @"userInteractionEnabled", @"layer", - @"superview", @"subviews" - ]).forClass(UIView.class); - - // UILabel - self.append.ivars(ivars).methods(methods).properties(@[ - @"text", @"attributedText", @"font", @"frame", - @"textColor", @"textAlignment", @"numberOfLines", - @"lineBreakMode", @"enabled", @"backgroundColor", - @"alpha", @"hidden", @"preferredMaxLayoutWidth", - @"superview", @"subviews" - ]).forClass(UILabel.class); - - // UIWindow - self.append.ivars(ivars).properties(@[ - @"rootViewController", @"windowLevel", @"keyWindow", - @"frame", @"bounds", @"center", @"transform", - @"backgroundColor", @"alpha", @"opaque", @"hidden", - @"clipsToBounds", @"userInteractionEnabled", @"layer", - @"subviews" - ]).forClass(UIWindow.class); - - if (@available(iOS 13, *)) { - self.append.properties(@[@"windowScene"]).forClass(UIWindow.class); - } - - ivars = @[@"_targetActions", @"_gestureRecognizers"]; - - // Property was added in iOS 10 but we want it on iOS 9 too - FLEXRuntimeUtilityTryAddObjectProperty(9, allTargets, UIControl.class, NSArray, PropertyKey(ReadOnly)); - - // UIControl - self.append.ivars(ivars).methods(methods).properties(@[ - @"enabled", @"allTargets", @"frame", - @"backgroundColor", @"hidden", @"clipsToBounds", - @"userInteractionEnabled", @"superview", @"subviews" - ]).forClass(UIControl.class); - - // UIButton - self.append.ivars(ivars).properties(@[ - @"titleLabel", @"font", @"imageView", @"tintColor", - @"currentTitle", @"currentImage", @"enabled", @"frame", - @"superview", @"subviews" - ]).forClass(UIButton.class); - - // UIImageView - self.append.properties(@[ - @"image", @"animationImages", @"frame", @"bounds", @"center", - @"transform", @"alpha", @"hidden", @"clipsToBounds", - @"userInteractionEnabled", @"layer", @"superview", @"subviews", - ]).forClass(UIImageView.class); -} - -@end - - -#pragma mark - View Controllers - -@implementation FLEXShortcutsFactory (ViewControllers) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - // toolbarItems is not really a property, make it one - FLEXRuntimeUtilityTryAddObjectProperty(3, toolbarItems, UIViewController.class, NSArray); - - // UIViewController - self.append - .properties(@[ - @"viewIfLoaded", @"title", @"navigationItem", @"toolbarItems", @"tabBarItem", - @"childViewControllers", @"navigationController", @"tabBarController", @"splitViewController", - @"parentViewController", @"presentedViewController", @"presentingViewController", - ]) - .methods(@[@"view"]) - .forClass(UIViewController.class); - - // UIAlertController - NSMutableArray *alertControllerProps = @[ - @"title", @"message", @"actions", @"textFields", - @"preferredAction", @"presentingViewController", @"viewIfLoaded", - ].mutableCopy; - if (@available(iOS 14.0, *)) { - [alertControllerProps insertObject:@"image" atIndex:4]; - } - self.append - .properties(alertControllerProps) - .methods(@[@"addAction:"]) - .forClass(UIAlertController.class); - self.append.properties(@[ - @"title", @"style", @"enabled", @"flex_styleName", - @"image", @"keyCommandInput", @"_isPreferred", @"_alertController", - ]).forClass(UIAlertAction.class); -} - -@end - - -#pragma mark - UIImage - -@implementation FLEXShortcutsFactory (UIImage) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.methods(@[ - @"CGImage", @"CIImage" - ]).properties(@[ - @"scale", @"size", @"capInsets", - @"alignmentRectInsets", @"duration", @"images" - ]).forClass(UIImage.class); - - if (@available(iOS 13, *)) { - self.append.properties(@[@"symbolImage"]).forClass(UIImage.class); - } -} - -@end - - -#pragma mark - NSBundle - -@implementation FLEXShortcutsFactory (NSBundle) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.properties(@[ - @"bundleIdentifier", @"principalClass", - @"infoDictionary", @"bundlePath", - @"executablePath", @"loaded" - ]).forClass(NSBundle.class); -} - -@end - - -#pragma mark - Classes - -@implementation FLEXShortcutsFactory (Classes) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.classMethods(@[@"new", @"alloc"]).forClass(NSObject.flex_metaclass); -} - -@end - - -#pragma mark - Activities - -@implementation FLEXShortcutsFactory (Activities) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - // Property was added in iOS 10 but we want it on iOS 9 too - FLEXRuntimeUtilityTryAddNonatomicProperty(9, item, UIActivityItemProvider.class, id, PropertyKey(ReadOnly)); - - self.append.properties(@[ - @"item", @"placeholderItem", @"activityType" - ]).forClass(UIActivityItemProvider.class); - - self.append.properties(@[ - @"activityItems", @"applicationActivities", @"excludedActivityTypes", @"completionHandler" - ]).forClass(UIActivityViewController.class); -} - -@end - - -#pragma mark - Blocks - -@implementation FLEXShortcutsFactory (Blocks) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.methods(@[@"invoke"]).forClass(NSClassFromString(@"NSBlock")); -} - -@end - -#pragma mark - Foundation - -@implementation FLEXShortcutsFactory (Foundation) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.properties(@[ - @"configuration", @"delegate", @"delegateQueue", @"sessionDescription", - ]).methods(@[ - @"dataTaskWithURL:", @"finishTasksAndInvalidate", @"invalidateAndCancel", - ]).forClass(NSURLSession.class); - - self.append.methods(@[ - @"cachedResponseForRequest:", @"storeCachedResponse:forRequest:", - @"storeCachedResponse:forDataTask:", @"removeCachedResponseForRequest:", - @"removeCachedResponseForDataTask:", @"removeCachedResponsesSinceDate:", - @"removeAllCachedResponses", - ]).forClass(NSURLCache.class); - - - self.append.methods(@[ - @"postNotification:", @"postNotificationName:object:userInfo:", - @"addObserver:selector:name:object:", @"removeObserver:", - @"removeObserver:name:object:", - ]).forClass(NSNotificationCenter.class); - - // NSTimeZone class properties aren't real properties - FLEXRuntimeUtilityTryAddObjectProperty(2, localTimeZone, NSTimeZone.flex_metaclass, NSTimeZone); - FLEXRuntimeUtilityTryAddObjectProperty(2, systemTimeZone, NSTimeZone.flex_metaclass, NSTimeZone); - FLEXRuntimeUtilityTryAddObjectProperty(2, defaultTimeZone, NSTimeZone.flex_metaclass, NSTimeZone); - FLEXRuntimeUtilityTryAddObjectProperty(2, knownTimeZoneNames, NSTimeZone.flex_metaclass, NSArray); - FLEXRuntimeUtilityTryAddObjectProperty(2, abbreviationDictionary, NSTimeZone.flex_metaclass, NSDictionary); - - self.append.classMethods(@[ - @"timeZoneWithName:", @"timeZoneWithAbbreviation:", @"timeZoneForSecondsFromGMT:", - ]).forClass(NSTimeZone.flex_metaclass); - - self.append.classProperties(@[ - @"defaultTimeZone", @"systemTimeZone", @"localTimeZone", - ]).forClass(NSTimeZone.class); - - // UTF8String is not a real property under the hood - FLEXRuntimeUtilityTryAddNonatomicProperty(2, UTF8String, NSString.class, const char *, PropertyKey(ReadOnly)); - - self.append.properties(@[@"length"]).methods(@[@"characterAtIndex:"]).forClass(NSString.class); - self.append.methods(@[ - @"writeToFile:atomically:", @"subdataWithRange:", @"isEqualToData:", - ]).properties(@[ - @"length", @"bytes", - ]).forClass(NSData.class); - - self.append.classMethods(@[ - @"dataWithJSONObject:options:error:", - @"JSONObjectWithData:options:error:", - @"isValidJSONObject:", - ]).forClass(NSJSONSerialization.class); - - // NSArray - self.append.classMethods(@[ - @"arrayWithObject:", @"arrayWithContentsOfFile:" - ]).forClass(NSArray.flex_metaclass); - self.append.methods(@[ - @"valueForKeyPath:", @"subarrayWithRange:", - @"arrayByAddingObject:", @"arrayByAddingObjectsFromArray:", - @"filteredArrayUsingPredicate:", @"subarrayWithRange:", - @"containsObject:", @"objectAtIndex:", @"indexOfObject:", - @"makeObjectsPerformSelector:", @"makeObjectsPerformSelector:withObject:", - @"sortedArrayUsingSelector:", @"reverseObjectEnumerator", - @"isEqualToArray:", @"mutableCopy", - ]).forClass(NSArray.class); - // NSDictionary - self.append.methods(@[ - @"objectForKey:", @"valueForKeyPath:", - @"isEqualToDictionary:", @"mutableCopy", - ]).forClass(NSDictionary.class); - // NSSet - self.append.classMethods(@[ - @"setWithObject:", @"setWithArray:" - ]).forClass(NSSet.flex_metaclass); - self.append.methods(@[ - @"allObjects", @"valueForKeyPath:", @"containsObject:", - @"setByAddingObject:", @"setByAddingObjectsFromArray:", - @"filteredSetUsingPredicate:", @"isSubsetOfSet:", - @"makeObjectsPerformSelector:", @"makeObjectsPerformSelector:withObject:", - @"reverseObjectEnumerator", @"isEqualToSet:", @"mutableCopy", - ]).forClass(NSSet.class); - - // NSMutableArray - self.prepend.methods(@[ - @"addObject:", @"insertObject:atIndex:", @"addObjectsFromArray:", - @"removeObject:", @"removeObjectAtIndex:", - @"removeObjectsInArray:", @"removeAllObjects", - @"removeLastObject", @"filterUsingPredicate:", - @"sortUsingSelector:", @"copy", - ]).forClass(NSMutableArray.class); - // NSMutableDictionary - self.prepend.methods(@[ - @"setObject:forKey:", @"removeObjectForKey:", - @"removeAllObjects", @"removeObjectsForKeys:", @"copy", - ]).forClass(NSMutableDictionary.class); - // NSMutableSet - self.prepend.methods(@[ - @"addObject:", @"removeObject:", @"filterUsingPredicate:", - @"removeAllObjects", @"addObjectsFromArray:", - @"unionSet:", @"minusSet:", @"intersectSet:", @"copy" - ]).forClass(NSMutableSet.class); - - self.append.methods(@[@"nextObject", @"allObjects"]).forClass(NSEnumerator.class); - - self.append.properties(@[@"flex_observers"]).forClass(NSNotificationCenter.class); -} - -@end - -#pragma mark - WebKit / Safari - -@implementation FLEXShortcutsFactory (WebKit_Safari) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - Class WKWebView = NSClassFromString(@"WKWebView"); - Class SafariVC = NSClassFromString(@"SFSafariViewController"); - - if (WKWebView) { - self.append.properties(@[ - @"configuration", @"scrollView", @"title", @"URL", - @"customUserAgent", @"navigationDelegate" - ]).methods(@[@"reload", @"stopLoading"]).forClass(WKWebView); - } - - if (SafariVC) { - self.append.properties(@[ - @"delegate" - ]).forClass(SafariVC); - if (@available(iOS 10.0, *)) { - self.append.properties(@[ - @"preferredBarTintColor", @"preferredControlTintColor" - ]).forClass(SafariVC); - } - if (@available(iOS 11.0, *)) { - self.append.properties(@[ - @"configuration", @"dismissButtonStyle" - ]).forClass(SafariVC); - } - } -} - -@end - -#pragma mark - Pasteboard - -@implementation FLEXShortcutsFactory (Pasteboard) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - self.append.properties(@[ - @"name", @"numberOfItems", @"items", - @"string", @"image", @"color", @"URL", - ]).forClass(UIPasteboard.class); -} - -@end - -@interface NSNotificationCenter (Observers) -@property (readonly) NSArray *flex_observers; -@end - -@implementation NSNotificationCenter (Observers) -- (id)flex_observers { - NSString *debug = self.debugDescription; - NSArray *observers = [debug componentsSeparatedByString:@"\n"]; - NSArray *> *splitObservers = [observers flex_mapped:^id(NSString *entry, NSUInteger idx) { - return [entry componentsSeparatedByString:@","]; - }]; - - NSArray *names = [splitObservers flex_mapped:^id(NSArray *entry, NSUInteger idx) { - return entry[0]; - }]; - NSArray *objects = [splitObservers flex_mapped:^id(NSArray *entry, NSUInteger idx) { - if (entry.count < 2) return NSNull.null; - NSScanner *scanner = [NSScanner scannerWithString:entry[1]]; - - unsigned long long objectPointerValue; - if ([scanner scanHexLongLong:&objectPointerValue]) { - void *objectPointer = (void *)objectPointerValue; - if (FLEXPointerIsValidObjcObject(objectPointer)) - return (__bridge id)(void *)objectPointer; - } - - return NSNull.null; - }]; - - return [NSArray flex_forEachUpTo:names.count map:^id(NSUInteger i) { - return @[names[i], objects[i]]; - }]; -} -@end - -#pragma mark - Firebase Firestore - -@implementation FLEXShortcutsFactory (FirebaseFirestore) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - Class FIRDocumentSnap = NSClassFromString(@"FIRDocumentSnapshot"); - if (FIRDocumentSnap) { - FLEXRuntimeUtilityTryAddObjectProperty(2, data, FIRDocumentSnap, NSDictionary, PropertyKey(ReadOnly)); - } -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h deleted file mode 100644 index 2bf690a8..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.h +++ /dev/null @@ -1,134 +0,0 @@ -// -// FLEXShortcutsSection.h -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewSection.h" -#import "FLEXObjectInfoSection.h" -@class FLEXProperty, FLEXIvar, FLEXMethod; - -NS_ASSUME_NONNULL_BEGIN - -/// An abstract base class for custom object "shortcuts" where every -/// row can possibly have some action. The section title is "Shortcuts". -/// -/// You should only subclass this class if you need simple shortcuts -/// with plain titles and/or subtitles. This class will automatically -/// configure each cell appropriately. Since this is intended as a -/// static section, subclasses should only need to implement the -/// \c viewControllerToPushForRow: and/or \c didSelectRowAction: methods. -/// -/// If you create the section using \c forObject:rows:numberOfLines: -/// then it will provide a view controller from \c viewControllerToPushForRow: -/// automatically for rows that are a property/ivar/method. -@interface FLEXShortcutsSection : FLEXTableViewSection - -/// Uses \c kFLEXDefaultCell -+ (instancetype)forObject:(id)objectOrClass rowTitles:(nullable NSArray *)titles; -/// Uses \c kFLEXDetailCell for non-empty subtitles, otherwise uses \c kFLEXDefaultCell -+ (instancetype)forObject:(id)objectOrClass - rowTitles:(nullable NSArray *)titles - rowSubtitles:(nullable NSArray *)subtitles; - -/// Uses \c kFLEXDefaultCell for rows that are given a title, otherwise -/// this uses \c kFLEXDetailCell for any other allowed object. -/// -/// The section provide a view controller from \c viewControllerToPushForRow: -/// automatically for rows that are a property/ivar/method. -/// -/// @param rows A mixed array containing any of the following: -/// - any \c FLEXShortcut conforming object -/// - an \c NSString -/// - a \c FLEXProperty -/// - a \c FLEXIvar -/// - a \c FLEXMethodBase (includes \c FLEXMethod of course) -/// Passing one of the latter 3 will provide a shortcut to that property/ivar/method. -+ (instancetype)forObject:(id)objectOrClass rows:(nullable NSArray *)rows; - -/// Same as \c forObject:rows: but the given rows are prepended -/// to the shortcuts already registered for the object's class. -/// \c forObject:rows: does not use the registered shortcuts at all. -+ (instancetype)forObject:(id)objectOrClass additionalRows:(nullable NSArray *)rows; - -/// Calls into \c forObject:rows: using the registered shortcuts for the object's class. -/// @return An empty section if the object has no shortcuts registered at all. -+ (instancetype)forObject:(id)objectOrClass; - -/// Subclasses \e may override this to hide the disclosure indicator -/// for some rows. It is shown for all rows by default, unless -/// you initialize it with \c forObject:rowTitles:rowSubtitles: -/// -/// When you hide the disclosure indicator, the row is not selectable. -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row; - -/// The number of lines for the title and subtitle labels. Defaults to 1. -@property (nonatomic, readonly) NSInteger numberOfLines; -/// The object used to initialize this section. -@property (nonatomic, readonly) id object; - -/// Whether dynamic subtitles should always be computed as a cell is configured. -/// Defaults to NO. Has no effect on static subtitles that are passed explicitly. -@property (nonatomic) BOOL cacheSubtitles; - -/// Whether this shortcut section overrides the default section or not. -/// Subclasses should not override this method. To provide a second -/// section alongside the default shortcuts section, use \c forObject:rows: -/// @return \c NO if initialized with \c forObject: or \c forObject:additionalRows: -@property (nonatomic, readonly) BOOL isNewSection; - -@end - -@class FLEXShortcutsFactory; -typedef FLEXShortcutsFactory *_Nonnull(^FLEXShortcutsFactoryNames)(NSArray *names); -typedef void (^FLEXShortcutsFactoryTarget)(Class targetClass); - -/// The block properties below are to be used like SnapKit or Masonry. -/// \c FLEXShortcutsSection.append.properties(@[@"frame",@"bounds"]).forClass(UIView.class); -/// -/// To safely register your own classes at launch, subclass this class, -/// override \c +load, and call the appropriate methods on \c self -@interface FLEXShortcutsFactory : NSObject - -/// Returns the list of all registered shortcuts for the given object in this order: -/// Properties, ivars, methods. -/// -/// This method traverses up the object's class hierarchy until it finds -/// something registered. This allows you to show different shortcuts for -/// the same object in different parts of the class hierarchy. -/// -/// As an example, UIView may have a -layer shortcut registered. But if -/// you're inspecting a UIControl, you may not care about the layer or other -/// UIView-specific things; you might rather see the target-actions registered -/// for this control, and so you would register that property or ivar to UIControl, -/// And you would still be able to see the UIView-registered shorcuts by clicking -/// on the UIView "lens" at the top the explorer view controller screen. -+ (NSArray *)shortcutsForObjectOrClass:(id)objectOrClass; - -@property (nonatomic, readonly, class) FLEXShortcutsFactory *append; -@property (nonatomic, readonly, class) FLEXShortcutsFactory *prepend; -@property (nonatomic, readonly, class) FLEXShortcutsFactory *replace; - -@property (nonatomic, readonly) FLEXShortcutsFactoryNames properties; -/// Do not try to set \c classProperties at the same time as \c ivars or other instance things. -@property (nonatomic, readonly) FLEXShortcutsFactoryNames classProperties; -@property (nonatomic, readonly) FLEXShortcutsFactoryNames ivars; -@property (nonatomic, readonly) FLEXShortcutsFactoryNames methods; -/// Do not try to set \c classMethods at the same time as \c ivars or other instance things. -@property (nonatomic, readonly) FLEXShortcutsFactoryNames classMethods; - -/// Accepts the target class. If you pass a regular class object, -/// shortcuts will appear on instances. If you pass a metaclass object, -/// shortcuts will appear when exploring a class object. -/// -/// For example, some class method shortcuts are added to the NSObject meta -/// class by default so that you can see +alloc and +new when exploring -/// a class object. If you wanted these to show up when exploring -/// instances you would pass them to the classMethods method above. -@property (nonatomic, readonly) FLEXShortcutsFactoryTarget forClass; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.m deleted file mode 100644 index 69c95ea7..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXShortcutsSection.m +++ /dev/null @@ -1,482 +0,0 @@ -// -// FLEXShortcutsSection.m -// FLEX -// -// Created by Tanner Bennett on 8/29/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" -#import "FLEXTableView.h" -#import "FLEXTableViewCell.h" -#import "FLEXUtility.h" -#import "FLEXShortcut.h" -#import "FLEXProperty.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXIvar.h" -#import "FLEXMethod.h" -#import "FLEXRuntime+UIKitHelpers.h" -#import "FLEXObjectExplorer.h" - -#pragma mark Private - -@interface FLEXShortcutsSection () -@property (nonatomic, copy) NSArray *titles; -@property (nonatomic, copy) NSArray *subtitles; - -@property (nonatomic, copy) NSArray *allTitles; -@property (nonatomic, copy) NSArray *allSubtitles; - -// Shortcuts are not used if initialized with static titles and subtitles -@property (nonatomic, copy) NSArray> *shortcuts; -@property (nonatomic, readonly) NSArray> *allShortcuts; -@end - -@implementation FLEXShortcutsSection -@synthesize isNewSection = _isNewSection; - -#pragma mark Initialization - -+ (instancetype)forObject:(id)objectOrClass rowTitles:(NSArray *)titles { - return [self forObject:objectOrClass rowTitles:titles rowSubtitles:nil]; -} - -+ (instancetype)forObject:(id)objectOrClass - rowTitles:(NSArray *)titles - rowSubtitles:(NSArray *)subtitles { - return [[self alloc] initWithObject:objectOrClass titles:titles subtitles:subtitles]; -} - -+ (instancetype)forObject:(id)objectOrClass rows:(NSArray *)rows { - return [[self alloc] initWithObject:objectOrClass rows:rows isNewSection:YES]; -} - -+ (instancetype)forObject:(id)objectOrClass additionalRows:(NSArray *)toPrepend { - NSArray *rows = [FLEXShortcutsFactory shortcutsForObjectOrClass:objectOrClass]; - NSArray *allRows = [toPrepend arrayByAddingObjectsFromArray:rows] ?: rows; - return [[self alloc] initWithObject:objectOrClass rows:allRows isNewSection:NO]; -} - -+ (instancetype)forObject:(id)objectOrClass { - return [self forObject:objectOrClass additionalRows:nil]; -} - -- (id)initWithObject:(id)object - titles:(NSArray *)titles - subtitles:(NSArray *)subtitles { - - NSParameterAssert(titles.count == subtitles.count || !subtitles); - NSParameterAssert(titles.count); - - self = [super init]; - if (self) { - _object = object; - _allTitles = titles.copy; - _allSubtitles = subtitles.copy; - _isNewSection = YES; - _numberOfLines = 1; - } - - return self; -} - -- (id)initWithObject:object rows:(NSArray *)rows isNewSection:(BOOL)newSection { - self = [super init]; - if (self) { - _object = object; - _isNewSection = newSection; - - _allShortcuts = [rows flex_mapped:^id(id obj, NSUInteger idx) { - return [FLEXShortcut shortcutFor:obj]; - }]; - _numberOfLines = 1; - - // Populate titles and subtitles - [self reloadData]; - } - - return self; -} - - -#pragma mark - Public - -- (void)setCacheSubtitles:(BOOL)cacheSubtitles { - if (_cacheSubtitles == cacheSubtitles) return; - - // cacheSubtitles only applies if we have shortcut objects - if (self.allShortcuts) { - _cacheSubtitles = cacheSubtitles; - [self reloadData]; - } else { - NSLog(@"Warning: setting 'cacheSubtitles' on a shortcut section with static subtitles"); - } -} - - -#pragma mark - Overrides - -- (UITableViewCellAccessoryType)accessoryTypeForRow:(NSInteger)row { - if (_allShortcuts) { - return [self.shortcuts[row] accessoryTypeWith:self.object]; - } - - return UITableViewCellAccessoryNone; -} - -- (void)setFilterText:(NSString *)filterText { - super.filterText = filterText; - - NSAssert( - self.allTitles.count == self.allSubtitles.count, - @"Each title needs a (possibly empty) subtitle" - ); - - if (filterText.length) { - // Tally up indexes of titles and subtitles matching the filter - NSMutableIndexSet *filterMatches = [NSMutableIndexSet new]; - id filterBlock = ^BOOL(NSString *obj, NSUInteger idx) { - if ([obj localizedCaseInsensitiveContainsString:filterText]) { - [filterMatches addIndex:idx]; - return YES; - } - - return NO; - }; - - // Get all matching indexes, including subtitles - [self.allTitles flex_forEach:filterBlock]; - [self.allSubtitles flex_forEach:filterBlock]; - // Filter to matching indexes only - self.titles = [self.allTitles objectsAtIndexes:filterMatches]; - self.subtitles = [self.allSubtitles objectsAtIndexes:filterMatches]; - self.shortcuts = [self.allShortcuts objectsAtIndexes:filterMatches]; - } else { - self.shortcuts = self.allShortcuts; - self.titles = self.allTitles; - self.subtitles = [self.allSubtitles flex_filtered:^BOOL(NSString *sub, NSUInteger idx) { - return sub.length > 0; - }]; - } -} - -- (void)reloadData { - [FLEXObjectExplorer configureDefaultsForItems:self.allShortcuts]; - - // Generate all (sub)titles from shortcuts - if (self.allShortcuts) { - self.allTitles = [self.allShortcuts flex_mapped:^id(FLEXShortcut *s, NSUInteger idx) { - return [s titleWith:self.object]; - }]; - self.allSubtitles = [self.allShortcuts flex_mapped:^id(FLEXShortcut *s, NSUInteger idx) { - return [s subtitleWith:self.object] ?: @""; - }]; - } - - // Re-generate filtered (sub)titles and shortcuts - self.filterText = self.filterText; -} - -- (NSString *)title { - return @"Shortcuts"; -} - -- (NSInteger)numberOfRows { - return self.titles.count; -} - -- (BOOL)canSelectRow:(NSInteger)row { - UITableViewCellAccessoryType type = [self.shortcuts[row] accessoryTypeWith:self.object]; - BOOL hasDisclosure = NO; - hasDisclosure |= type == UITableViewCellAccessoryDisclosureIndicator; - hasDisclosure |= type == UITableViewCellAccessoryDetailDisclosureButton; - return hasDisclosure; -} - -- (void (^)(__kindof UIViewController *))didSelectRowAction:(NSInteger)row { - return [self.shortcuts[row] didSelectActionWith:self.object]; -} - -- (UIViewController *)viewControllerToPushForRow:(NSInteger)row { - /// Nil if shortcuts is nil, i.e. if initialized with forObject:rowTitles:rowSubtitles: - return [self.shortcuts[row] viewerWith:self.object]; -} - -- (void (^)(__kindof UIViewController *))didPressInfoButtonAction:(NSInteger)row { - id shortcut = self.shortcuts[row]; - if ([shortcut respondsToSelector:@selector(editorWith:forSection:)]) { - id object = self.object; - return ^(UIViewController *host) { - UIViewController *editor = [shortcut editorWith:object forSection:self]; - [host.navigationController pushViewController:editor animated:YES]; - }; - } - - return nil; -} - -- (NSString *)reuseIdentifierForRow:(NSInteger)row { - FLEXTableViewCellReuseIdentifier defaultReuse = kFLEXDetailCell; - if (@available(iOS 11, *)) { - defaultReuse = kFLEXMultilineDetailCell; - } - - return [self.shortcuts[row] customReuseIdentifierWith:self.object] ?: defaultReuse; -} - -- (void)configureCell:(__kindof FLEXTableViewCell *)cell forRow:(NSInteger)row { - cell.titleLabel.text = [self titleForRow:row]; - cell.titleLabel.numberOfLines = self.numberOfLines; - cell.subtitleLabel.text = [self subtitleForRow:row]; - cell.subtitleLabel.numberOfLines = self.numberOfLines; - cell.accessoryType = [self accessoryTypeForRow:row]; -} - -- (NSString *)titleForRow:(NSInteger)row { - return self.titles[row]; -} - -- (NSString *)subtitleForRow:(NSInteger)row { - // Case: dynamic, uncached subtitles - if (!self.cacheSubtitles) { - NSString *subtitle = [self.shortcuts[row] subtitleWith:self.object]; - return subtitle.length ? subtitle : nil; - } - - // Case: static subtitles, or cached subtitles - return self.subtitles[row]; -} - -@end - - -#pragma mark - Global shortcut registration - -@interface FLEXShortcutsFactory () { - BOOL _append, _prepend, _replace, _notInstance; - NSArray *_properties, *_ivars, *_methods; -} -@end - -#define NewAndSet(ivar) ({ FLEXShortcutsFactory *r = [self sharedFactory]; r->ivar = YES; r; }) -#define SetIvar(ivar) ({ self->ivar = YES; self; }) -#define SetParamBlock(ivar) ^(NSArray *p) { self->ivar = p; return self; } - -typedef NSMutableDictionary> *> RegistrationBuckets; - -@implementation FLEXShortcutsFactory { - // Class buckets - RegistrationBuckets *cProperties; - RegistrationBuckets *cIvars; - RegistrationBuckets *cMethods; - // Metaclass buckets - RegistrationBuckets *mProperties; - RegistrationBuckets *mMethods; -} - -+ (instancetype)sharedFactory { - static FLEXShortcutsFactory *shared = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - shared = [self new]; - }); - - return shared; -} - -- (id)init { - self = [super init]; - if (self) { - cProperties = [NSMutableDictionary new]; - cIvars = [NSMutableDictionary new]; - cMethods = [NSMutableDictionary new]; - - mProperties = [NSMutableDictionary new]; - mMethods = [NSMutableDictionary new]; - } - - return self; -} - -+ (NSArray> *)shortcutsForObjectOrClass:(id)objectOrClass { - return [[self sharedFactory] shortcutsForObjectOrClass:objectOrClass]; -} - -- (NSArray> *)shortcutsForObjectOrClass:(id)objectOrClass { - NSParameterAssert(objectOrClass); - - NSMutableArray> *shortcuts = [NSMutableArray new]; - BOOL isClass = object_isClass(objectOrClass); - // The -class does not give you a metaclass, and we want a metaclass - // if a class is passed in, or a class if an object is passed in - Class classKey = object_getClass(objectOrClass); - - RegistrationBuckets *propertyBucket = isClass ? mProperties : cProperties; - RegistrationBuckets *methodBucket = isClass ? mMethods : cMethods; - RegistrationBuckets *ivarBucket = isClass ? nil : cIvars; - - BOOL stop = NO; - while (!stop && classKey) { - NSArray *properties = propertyBucket[classKey]; - NSArray *ivars = ivarBucket[classKey]; - NSArray *methods = methodBucket[classKey]; - - // Stop if we found anything - stop = properties || ivars || methods; - if (stop) { - // Add things we found to the list - [shortcuts addObjectsFromArray:properties]; - [shortcuts addObjectsFromArray:ivars]; - [shortcuts addObjectsFromArray:methods]; - } else { - classKey = class_getSuperclass(classKey); - } - } - - [FLEXObjectExplorer configureDefaultsForItems:shortcuts]; - return shortcuts; -} - -+ (FLEXShortcutsFactory *)append { - return NewAndSet(_append); -} - -+ (FLEXShortcutsFactory *)prepend { - return NewAndSet(_prepend); -} - -+ (FLEXShortcutsFactory *)replace { - return NewAndSet(_replace); -} - -- (void)_register:(NSArray> *)items to:(RegistrationBuckets *)global class:(Class)key { - @synchronized (self) { - // Get (or initialize) the bucket for this class - NSMutableArray *bucket = ({ - id bucket = global[key]; - if (!bucket) { - bucket = [NSMutableArray new]; - global[(id)key] = bucket; - } - bucket; - }); - - if (self->_append) { [bucket addObjectsFromArray:items]; } - if (self->_replace) { [bucket setArray:items]; } - if (self->_prepend) { - if (bucket.count) { - // Set new items as array, add old items behind them - id copy = bucket.copy; - [bucket setArray:items]; - [bucket addObjectsFromArray:copy]; - } else { - [bucket addObjectsFromArray:items]; - } - } - } -} - -- (void)reset { - _append = NO; - _prepend = NO; - _replace = NO; - _notInstance = NO; - - _properties = nil; - _ivars = nil; - _methods = nil; -} - -- (FLEXShortcutsFactory *)class { - return SetIvar(_notInstance); -} - -- (FLEXShortcutsFactoryNames)properties { - NSAssert(!_notInstance, @"Do not try to set properties+classProperties at the same time"); - return SetParamBlock(_properties); -} - -- (FLEXShortcutsFactoryNames)classProperties { - _notInstance = YES; - return SetParamBlock(_properties); -} - -- (FLEXShortcutsFactoryNames)ivars { - return SetParamBlock(_ivars); -} - -- (FLEXShortcutsFactoryNames)methods { - NSAssert(!_notInstance, @"Do not try to set methods+classMethods at the same time"); - return SetParamBlock(_methods); -} - -- (FLEXShortcutsFactoryNames)classMethods { - _notInstance = YES; - return SetParamBlock(_methods); -} - -- (FLEXShortcutsFactoryTarget)forClass { - return ^(Class cls) { - NSAssert( - ( self->_append && !self->_prepend && !self->_replace) || - (!self->_append && self->_prepend && !self->_replace) || - (!self->_append && !self->_prepend && self->_replace), - @"You can only do one of [append, prepend, replace]" - ); - - - /// Whether the metadata we're about to add is instance or - /// class metadata, i.e. class properties vs instance properties - BOOL instanceMetadata = !self->_notInstance; - /// Whether the given class is a metaclass or not; we need to switch to - /// the metaclass to add class metadata if we are given the normal class object - BOOL isMeta = class_isMetaClass(cls); - /// Whether the shortcuts we're about to add should appear for classes or instances - BOOL instanceShortcut = !isMeta; - - if (instanceMetadata) { - NSAssert(!isMeta, - @"Instance metadata can only be added as an instance shortcut" - ); - } - - Class metaclass = isMeta ? cls : object_getClass(cls); - Class clsForMetadata = instanceMetadata ? cls : metaclass; - - // The factory is a singleton so we don't need to worry about "leaking" it - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wimplicit-retain-self" - - RegistrationBuckets *propertyBucket = instanceShortcut ? cProperties : mProperties; - RegistrationBuckets *methodBucket = instanceShortcut ? cMethods : mMethods; - RegistrationBuckets *ivarBucket = instanceShortcut ? cIvars : nil; - - #pragma clang diagnostic pop - - if (self->_properties) { - NSArray *items = [self->_properties flex_mapped:^id(NSString *name, NSUInteger idx) { - return [FLEXProperty named:name onClass:clsForMetadata]; - }]; - [self _register:items to:propertyBucket class:cls]; - } - - if (self->_methods) { - NSArray *items = [self->_methods flex_mapped:^id(NSString *name, NSUInteger idx) { - return [FLEXMethod selector:NSSelectorFromString(name) class:clsForMetadata]; - }]; - [self _register:items to:methodBucket class:cls]; - } - - if (self->_ivars) { - NSAssert(instanceMetadata, @"Instance metadata can only be added as an instance shortcut (%@)", cls); - NSArray *items = [self->_ivars flex_mapped:^id(NSString *name, NSUInteger idx) { - return [FLEXIvar named:name onClass:clsForMetadata]; - }]; - [self _register:items to:ivarBucket class:cls]; - } - - [self reset]; - }; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.h deleted file mode 100644 index d0b0db16..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXUIAppShortcuts.h -// FLEX -// -// Created by Tanner on 5/25/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -@interface FLEXUIAppShortcuts : FLEXShortcutsSection - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.m deleted file mode 100644 index 7946645f..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXUIAppShortcuts.m +++ /dev/null @@ -1,77 +0,0 @@ -// -// FLEXUIAppShortcuts.m -// FLEX -// -// Created by Tanner on 5/25/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXUIAppShortcuts.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXShortcut.h" -#import "FLEXAlert.h" - -@implementation FLEXUIAppShortcuts - -#pragma mark - Overrides - -+ (instancetype)forObject:(UIApplication *)application { - return [self forObject:application additionalRows:@[ - [FLEXActionShortcut title:@"Open URL…" - subtitle:^NSString *(UIViewController *controller) { - return nil; - } - selectionHandler:^void(UIViewController *host, UIApplication *app) { - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Open URL"); - make.message( - @"This will call openURL: or openURL:options:completion: " - "with the string below. 'Open if Universal' will only open " - "the URL if it is a registered Universal Link." - ); - - make.textField(@"twitter://user?id=12345"); - make.button(@"Open").handler(^(NSArray *strings) { - [self openURL:strings[0] inApp:app onlyIfUniveral:NO host:host]; - }); - make.button(@"Open if Universal").handler(^(NSArray *strings) { - [self openURL:strings[0] inApp:app onlyIfUniveral:YES host:host]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:host]; - } - accessoryType:^UITableViewCellAccessoryType(UIViewController *controller) { - return UITableViewCellAccessoryDisclosureIndicator; - } - ] - ]]; -} - -+ (void)openURL:(NSString *)urlString - inApp:(UIApplication *)app - onlyIfUniveral:(BOOL)universalOnly - host:(UIViewController *)host { - NSURL *url = [NSURL URLWithString:urlString]; - - if (url) { - if (@available(iOS 10, *)) { - [app openURL:url options:@{ - UIApplicationOpenURLOptionUniversalLinksOnly: @(universalOnly) - } completionHandler:^(BOOL success) { - if (!success) { - [FLEXAlert showAlert:@"No Universal Link Handler" - message:@"No installed application is registered to handle this link." - from:host - ]; - } - }]; - } else { - [app openURL:url]; - } - } else { - [FLEXAlert showAlert:@"Error" message:@"Invalid URL" from:host]; - } -} - -@end - diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.h deleted file mode 100644 index 1d09e696..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// FLEXViewControllerShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -@interface FLEXViewControllerShortcuts : FLEXShortcutsSection - -+ (instancetype)forObject:(UIViewController *)viewController; - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.m deleted file mode 100644 index 8f906fa7..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewControllerShortcuts.m +++ /dev/null @@ -1,58 +0,0 @@ -// -// FLEXViewControllerShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 12/12/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXViewControllerShortcuts.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXShortcut.h" -#import "FLEXAlert.h" - -@interface FLEXViewControllerShortcuts () -@end - -@implementation FLEXViewControllerShortcuts - -#pragma mark - Overrides - -+ (instancetype)forObject:(UIViewController *)viewController { - BOOL (^vcIsInuse)(UIViewController *) = ^BOOL(UIViewController *controller) { - if (controller.viewIfLoaded.window) { - return YES; - } - - return controller.navigationController != nil; - }; - - return [self forObject:viewController additionalRows:@[ - [FLEXActionShortcut title:@"Push View Controller" - subtitle:^NSString *(UIViewController *controller) { - return vcIsInuse(controller) ? @"In use, cannot push" : nil; - } - selectionHandler:^void(UIViewController *host, UIViewController *controller) { - if (!vcIsInuse(controller)) { - [host.navigationController pushViewController:controller animated:YES]; - } else { - [FLEXAlert - showAlert:@"Cannot Push View Controller" - message:@"This view controller's view is currently in use." - from:host - ]; - } - } - accessoryType:^UITableViewCellAccessoryType(UIViewController *controller) { - if (!vcIsInuse(controller)) { - return UITableViewCellAccessoryDisclosureIndicator; - } else { - return UITableViewCellAccessoryNone; - } - } - ] - ]]; -} - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.h b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.h deleted file mode 100644 index f1df0aa8..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// FLEXViewShortcuts.h -// FLEX -// -// Created by Tanner Bennett on 12/11/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXShortcutsSection.h" - -/// Adds "Nearest View Controller" and "Preview Image" shortcuts to all views -@interface FLEXViewShortcuts : FLEXShortcutsSection - -@end diff --git a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.m b/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.m deleted file mode 100644 index 058cd9b4..00000000 --- a/BHTwitter/Classes/ObjectExplorers/Sections/Shortcuts/FLEXViewShortcuts.m +++ /dev/null @@ -1,90 +0,0 @@ -// -// FLEXViewShortcuts.m -// FLEX -// -// Created by Tanner Bennett on 12/11/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXViewShortcuts.h" -#import "FLEXShortcut.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXImagePreviewViewController.h" - -@interface FLEXViewShortcuts () -@property (nonatomic, readonly) UIView *view; -@end - -@implementation FLEXViewShortcuts - -#pragma mark - Internal - -- (UIView *)view { - return self.object; -} - -+ (UIViewController *)viewControllerForView:(UIView *)view { - NSString *viewDelegate = @"viewDelegate"; - if ([view respondsToSelector:NSSelectorFromString(viewDelegate)]) { - return [view valueForKey:viewDelegate]; - } - - return nil; -} - -+ (UIViewController *)viewControllerForAncestralView:(UIView *)view { - NSString *_viewControllerForAncestor = @"_viewControllerForAncestor"; - if ([view respondsToSelector:NSSelectorFromString(_viewControllerForAncestor)]) { - return [view valueForKey:_viewControllerForAncestor]; - } - - return nil; -} - -+ (UIViewController *)nearestViewControllerForView:(UIView *)view { - return [self viewControllerForView:view] ?: [self viewControllerForAncestralView:view]; -} - - -#pragma mark - Overrides - -+ (instancetype)forObject:(UIView *)view { - // In the past, FLEX would not hold a strong reference to something like this. - // After using FLEX for so long, I am certain it is more useful to eagerly - // reference something as useful as a view controller so that the reference - // is not lost and swept out from under you before you can access it. - // - // The alternative here is to use a future in place of `controller` which would - // dynamically grab a reference to the view controller. 99% of the time, however, - // it is not all that useful. If you need it to refresh, you can simply go back - // and go forward again and it will show if the view controller is nil or changed. - UIViewController *controller = [FLEXViewShortcuts nearestViewControllerForView:view]; - - return [self forObject:view additionalRows:@[ - [FLEXActionShortcut title:@"Nearest View Controller" - subtitle:^NSString *(id view) { - return [FLEXRuntimeUtility safeDescriptionForObject:controller]; - } - viewer:^UIViewController *(id view) { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:controller]; - } - accessoryType:^UITableViewCellAccessoryType(id view) { - return controller ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - } - ], - [FLEXActionShortcut title:@"Preview Image" subtitle:^NSString *(UIView *view) { - return !CGRectIsEmpty(view.bounds) ? @"" : @"Unavailable with empty bounds"; - } - viewer:^UIViewController *(UIView *view) { - return [FLEXImagePreviewViewController previewForView:view]; - } - accessoryType:^UITableViewCellAccessoryType(UIView *view) { - // Disable preview if bounds are CGRectZero - return !CGRectIsEmpty(view.bounds) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone; - } - ] - ]]; -} - -@end diff --git a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.h b/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.h deleted file mode 100644 index f6cd0f9e..00000000 --- a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// FLEXExplorerToolbar.h -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@class FLEXExplorerToolbarItem; - -NS_ASSUME_NONNULL_BEGIN - -/// Users of the toolbar can configure the enabled state -/// and event target/actions for each item. -@interface FLEXExplorerToolbar : UIView - -/// The items to be displayed in the toolbar. Defaults to: -/// globalsItem, hierarchyItem, selectItem, moveItem, closeItem -@property (nonatomic, copy) NSArray *toolbarItems; - -/// Toolbar item for selecting views. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *selectItem; - -/// Toolbar item for presenting a list with the view hierarchy. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *hierarchyItem; - -/// Toolbar item for moving views. -/// Its \c sibling is the \c lastTabItem -@property (nonatomic, readonly) FLEXExplorerToolbarItem *moveItem; - -/// Toolbar item for presenting the currently active tab. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *recentItem; - -/// Toolbar item for presenting a screen with various tools for inspecting the app. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *globalsItem; - -/// Toolbar item for hiding the explorer. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *closeItem; - -/// A view for moving the entire toolbar. -/// Users of the toolbar can attach a pan gesture recognizer to decide how to reposition the toolbar. -@property (nonatomic, readonly) UIView *dragHandle; - -/// A color matching the overlay on color on the selected view. -@property (nonatomic) UIColor *selectedViewOverlayColor; - -/// Description text for the selected view displayed below the toolbar items. -@property (nonatomic, copy) NSString *selectedViewDescription; - -/// Area where details of the selected view are shown -/// Users of the toolbar can attach a tap gesture recognizer to show additional details. -@property (nonatomic, readonly) UIView *selectedViewDescriptionContainer; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.m b/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.m deleted file mode 100644 index 022999e7..00000000 --- a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbar.m +++ /dev/null @@ -1,256 +0,0 @@ -// -// FLEXExplorerToolbar.m -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXExplorerToolbar.h" -#import "FLEXExplorerToolbarItem.h" -#import "FLEXResources.h" -#import "FLEXUtility.h" - -@interface FLEXExplorerToolbar () - -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *globalsItem; -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *hierarchyItem; -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *selectItem; -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *recentItem; -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *moveItem; -@property (nonatomic, readwrite) FLEXExplorerToolbarItem *closeItem; -@property (nonatomic, readwrite) UIView *dragHandle; - -@property (nonatomic) UIImageView *dragHandleImageView; - -@property (nonatomic) UIView *selectedViewDescriptionContainer; -@property (nonatomic) UIView *selectedViewDescriptionSafeAreaContainer; -@property (nonatomic) UIView *selectedViewColorIndicator; -@property (nonatomic) UILabel *selectedViewDescriptionLabel; - -@property (nonatomic,readwrite) UIView *backgroundView; - -@end - -@implementation FLEXExplorerToolbar - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - // Background - self.backgroundView = [UIView new]; - self.backgroundView.backgroundColor = [FLEXColor secondaryBackgroundColorWithAlpha:0.95]; - [self addSubview:self.backgroundView]; - - // Drag handle - self.dragHandle = [UIView new]; - self.dragHandle.backgroundColor = UIColor.clearColor; - self.dragHandleImageView = [[UIImageView alloc] initWithImage:FLEXResources.dragHandle]; - self.dragHandleImageView.tintColor = [FLEXColor.iconColor colorWithAlphaComponent:0.666]; - [self.dragHandle addSubview:self.dragHandleImageView]; - [self addSubview:self.dragHandle]; - - // Buttons - self.globalsItem = [FLEXExplorerToolbarItem itemWithTitle:@"menu" image:FLEXResources.globalsIcon]; - self.hierarchyItem = [FLEXExplorerToolbarItem itemWithTitle:@"views" image:FLEXResources.hierarchyIcon]; - self.selectItem = [FLEXExplorerToolbarItem itemWithTitle:@"select" image:FLEXResources.selectIcon]; - self.recentItem = [FLEXExplorerToolbarItem itemWithTitle:@"recent" image:FLEXResources.recentIcon]; - self.moveItem = [FLEXExplorerToolbarItem itemWithTitle:@"move" image:FLEXResources.moveIcon sibling:self.recentItem]; - self.closeItem = [FLEXExplorerToolbarItem itemWithTitle:@"close" image:FLEXResources.closeIcon]; - - // Selected view box // - - self.selectedViewDescriptionContainer = [UIView new]; - self.selectedViewDescriptionContainer.backgroundColor = [FLEXColor tertiaryBackgroundColorWithAlpha:0.95]; - self.selectedViewDescriptionContainer.hidden = YES; - [self addSubview:self.selectedViewDescriptionContainer]; - - self.selectedViewDescriptionSafeAreaContainer = [UIView new]; - self.selectedViewDescriptionSafeAreaContainer.backgroundColor = UIColor.clearColor; - [self.selectedViewDescriptionContainer addSubview:self.selectedViewDescriptionSafeAreaContainer]; - - self.selectedViewColorIndicator = [UIView new]; - self.selectedViewColorIndicator.backgroundColor = UIColor.redColor; - [self.selectedViewDescriptionSafeAreaContainer addSubview:self.selectedViewColorIndicator]; - - self.selectedViewDescriptionLabel = [UILabel new]; - self.selectedViewDescriptionLabel.backgroundColor = UIColor.clearColor; - self.selectedViewDescriptionLabel.font = [[self class] descriptionLabelFont]; - [self.selectedViewDescriptionSafeAreaContainer addSubview:self.selectedViewDescriptionLabel]; - - // toolbarItems - self.toolbarItems = @[_globalsItem, _hierarchyItem, _selectItem, _moveItem, _closeItem]; - } - - return self; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - - CGRect safeArea = [self safeArea]; - // Drag Handle - const CGFloat kToolbarItemHeight = [[self class] toolbarItemHeight]; - self.dragHandle.frame = CGRectMake(CGRectGetMinX(safeArea), CGRectGetMinY(safeArea), [[self class] dragHandleWidth], kToolbarItemHeight); - CGRect dragHandleImageFrame = self.dragHandleImageView.frame; - dragHandleImageFrame.origin.x = FLEXFloor((self.dragHandle.frame.size.width - dragHandleImageFrame.size.width) / 2.0); - dragHandleImageFrame.origin.y = FLEXFloor((self.dragHandle.frame.size.height - dragHandleImageFrame.size.height) / 2.0); - self.dragHandleImageView.frame = dragHandleImageFrame; - - - // Toolbar Items - CGFloat originX = CGRectGetMaxX(self.dragHandle.frame); - CGFloat originY = CGRectGetMinY(safeArea); - CGFloat height = kToolbarItemHeight; - CGFloat width = FLEXFloor((CGRectGetWidth(safeArea) - CGRectGetWidth(self.dragHandle.frame)) / self.toolbarItems.count); - for (FLEXExplorerToolbarItem *toolbarItem in self.toolbarItems) { - toolbarItem.currentItem.frame = CGRectMake(originX, originY, width, height); - originX = CGRectGetMaxX(toolbarItem.currentItem.frame); - } - - // Make sure the last toolbar item goes to the edge to account for any accumulated rounding effects. - UIView *lastToolbarItem = self.toolbarItems.lastObject.currentItem; - CGRect lastToolbarItemFrame = lastToolbarItem.frame; - lastToolbarItemFrame.size.width = CGRectGetMaxX(safeArea) - lastToolbarItemFrame.origin.x; - lastToolbarItem.frame = lastToolbarItemFrame; - - self.backgroundView.frame = CGRectMake(0, 0, CGRectGetWidth(self.bounds), kToolbarItemHeight); - - const CGFloat kSelectedViewColorDiameter = [[self class] selectedViewColorIndicatorDiameter]; - const CGFloat kDescriptionLabelHeight = [[self class] descriptionLabelHeight]; - const CGFloat kHorizontalPadding = [[self class] horizontalPadding]; - const CGFloat kDescriptionVerticalPadding = [[self class] descriptionVerticalPadding]; - const CGFloat kDescriptionContainerHeight = [[self class] descriptionContainerHeight]; - - CGRect descriptionContainerFrame = CGRectZero; - descriptionContainerFrame.size.width = CGRectGetWidth(self.bounds); - descriptionContainerFrame.size.height = kDescriptionContainerHeight; - descriptionContainerFrame.origin.x = CGRectGetMinX(self.bounds); - descriptionContainerFrame.origin.y = CGRectGetMaxY(self.bounds) - kDescriptionContainerHeight; - self.selectedViewDescriptionContainer.frame = descriptionContainerFrame; - - CGRect descriptionSafeAreaContainerFrame = CGRectZero; - descriptionSafeAreaContainerFrame.size.width = CGRectGetWidth(safeArea); - descriptionSafeAreaContainerFrame.size.height = kDescriptionContainerHeight; - descriptionSafeAreaContainerFrame.origin.x = CGRectGetMinX(safeArea); - descriptionSafeAreaContainerFrame.origin.y = CGRectGetMinY(safeArea); - self.selectedViewDescriptionSafeAreaContainer.frame = descriptionSafeAreaContainerFrame; - - // Selected View Color - CGRect selectedViewColorFrame = CGRectZero; - selectedViewColorFrame.size.width = kSelectedViewColorDiameter; - selectedViewColorFrame.size.height = kSelectedViewColorDiameter; - selectedViewColorFrame.origin.x = kHorizontalPadding; - selectedViewColorFrame.origin.y = FLEXFloor((kDescriptionContainerHeight - kSelectedViewColorDiameter) / 2.0); - self.selectedViewColorIndicator.frame = selectedViewColorFrame; - self.selectedViewColorIndicator.layer.cornerRadius = ceil(selectedViewColorFrame.size.height / 2.0); - - // Selected View Description - CGRect descriptionLabelFrame = CGRectZero; - CGFloat descriptionOriginX = CGRectGetMaxX(selectedViewColorFrame) + kHorizontalPadding; - descriptionLabelFrame.size.height = kDescriptionLabelHeight; - descriptionLabelFrame.origin.x = descriptionOriginX; - descriptionLabelFrame.origin.y = kDescriptionVerticalPadding; - descriptionLabelFrame.size.width = CGRectGetMaxX(self.selectedViewDescriptionContainer.bounds) - kHorizontalPadding - descriptionOriginX; - self.selectedViewDescriptionLabel.frame = descriptionLabelFrame; -} - - -#pragma mark - Setter Overrides - -- (void)setToolbarItems:(NSArray *)toolbarItems { - if (_toolbarItems == toolbarItems) { - return; - } - - // Remove old toolbar items, if any - for (FLEXExplorerToolbarItem *item in _toolbarItems) { - [item.currentItem removeFromSuperview]; - } - - // Trim to 5 items if necessary - if (toolbarItems.count > 5) { - toolbarItems = [toolbarItems subarrayWithRange:NSMakeRange(0, 5)]; - } - - for (FLEXExplorerToolbarItem *item in toolbarItems) { - [self addSubview:item.currentItem]; - } - - _toolbarItems = toolbarItems.copy; - - // Lay out new items - [self setNeedsLayout]; - [self layoutIfNeeded]; -} - -- (void)setSelectedViewOverlayColor:(UIColor *)selectedViewOverlayColor { - if (![_selectedViewOverlayColor isEqual:selectedViewOverlayColor]) { - _selectedViewOverlayColor = selectedViewOverlayColor; - self.selectedViewColorIndicator.backgroundColor = selectedViewOverlayColor; - } -} - -- (void)setSelectedViewDescription:(NSString *)selectedViewDescription { - if (![_selectedViewDescription isEqual:selectedViewDescription]) { - _selectedViewDescription = selectedViewDescription; - self.selectedViewDescriptionLabel.text = selectedViewDescription; - BOOL showDescription = selectedViewDescription.length > 0; - self.selectedViewDescriptionContainer.hidden = !showDescription; - } -} - - -#pragma mark - Sizing Convenience Methods - -+ (UIFont *)descriptionLabelFont { - return [UIFont systemFontOfSize:12.0]; -} - -+ (CGFloat)toolbarItemHeight { - return 44.0; -} - -+ (CGFloat)dragHandleWidth { - return FLEXResources.dragHandle.size.width; -} - -+ (CGFloat)descriptionLabelHeight { - return ceil([[self descriptionLabelFont] lineHeight]); -} - -+ (CGFloat)descriptionVerticalPadding { - return 2.0; -} - -+ (CGFloat)descriptionContainerHeight { - return [self descriptionVerticalPadding] * 2.0 + [self descriptionLabelHeight]; -} - -+ (CGFloat)selectedViewColorIndicatorDiameter { - return ceil([self descriptionLabelHeight] / 2.0); -} - -+ (CGFloat)horizontalPadding { - return 11.0; -} - -- (CGSize)sizeThatFits:(CGSize)size { - CGFloat height = 0.0; - height += [[self class] toolbarItemHeight]; - height += [[self class] descriptionContainerHeight]; - return CGSizeMake(size.width, height); -} - -- (CGRect)safeArea { - CGRect safeArea = self.bounds; - if (@available(iOS 11.0, *)) { - safeArea = UIEdgeInsetsInsetRect(self.bounds, self.safeAreaInsets); - } - - return safeArea; -} - -@end diff --git a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.h b/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.h deleted file mode 100644 index 80db5b29..00000000 --- a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.h +++ /dev/null @@ -1,44 +0,0 @@ -// -// FLEXExplorerToolbarItem.h -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXExplorerToolbarItem : UIButton - -+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image; - -/// @param backupItem a toolbar item to use in place of this item when it becomes disabled. -/// Items without a sibling item exhibit expected behavior when they become disabled, and are greyed out. -+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image sibling:(nullable FLEXExplorerToolbarItem *)backupItem; - -/// If a toolbar item has a sibling, the item will replace itself with its -/// sibling when it becomes disabled, and vice versa when it becomes enabled again. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *sibling; - -/// When a toolbar item has a sibling and it becomes disabled, the sibling is the view -/// that should be added to or removed from a new or existing toolbar. This property -/// alleviates the programmer from determining whether to use \c item or \c item.sibling -/// or \c item.sibling.sibling and so on. Yes, sibling items can also have siblings so -/// that each item which becomes disabled may present another item in its place, creating -/// a "stack" of toolbar items. This behavior is useful for making buttons which occupy -/// the same space under different states. -/// -/// With this in mind, you should never access a stored toolbar item's view properties -/// such as \c frame or \c superview directly; you should access them on \c currentItem. -/// If you are trying to modify the frame of an item, and the item itself is not currently -/// displayed but instead its sibling is being displayed, then your changes could be ignored. -/// -/// @return the result of the item's sibling's \c currentItem, -/// if this item has a sibling and this item is disabled, otherwise this item. -@property (nonatomic, readonly) FLEXExplorerToolbarItem *currentItem; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.m b/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.m deleted file mode 100644 index 2c6bdb21..00000000 --- a/BHTwitter/Classes/Toolbar/FLEXExplorerToolbarItem.m +++ /dev/null @@ -1,155 +0,0 @@ -// -// FLEXExplorerToolbarItem.m -// Flipboard -// -// Created by Ryan Olson on 4/4/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXExplorerToolbarItem.h" -#import "FLEXUtility.h" - -@interface FLEXExplorerToolbarItem () - -@property (nonatomic) FLEXExplorerToolbarItem *sibling; -@property (nonatomic, copy) NSString *title; -@property (nonatomic) UIImage *image; - -@property (nonatomic, readonly, class) UIColor *defaultBackgroundColor; -@property (nonatomic, readonly, class) UIColor *highlightedBackgroundColor; -@property (nonatomic, readonly, class) UIColor *selectedBackgroundColor; - -@end - -@implementation FLEXExplorerToolbarItem - -#pragma mark - Public - -+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image { - return [self itemWithTitle:title image:image sibling:nil]; -} - -+ (instancetype)itemWithTitle:(NSString *)title image:(UIImage *)image sibling:(FLEXExplorerToolbarItem *)backupItem { - NSParameterAssert(title); NSParameterAssert(image); - - FLEXExplorerToolbarItem *toolbarItem = [self buttonWithType:UIButtonTypeSystem]; - toolbarItem.sibling = backupItem; - toolbarItem.title = title; - toolbarItem.image = image; - toolbarItem.tintColor = FLEXColor.iconColor; - toolbarItem.backgroundColor = self.defaultBackgroundColor; - toolbarItem.titleLabel.font = [UIFont systemFontOfSize:12.0]; - [toolbarItem setTitle:title forState:UIControlStateNormal]; - [toolbarItem setImage:image forState:UIControlStateNormal]; - [toolbarItem setTitleColor:FLEXColor.primaryTextColor forState:UIControlStateNormal]; - [toolbarItem setTitleColor:FLEXColor.deemphasizedTextColor forState:UIControlStateDisabled]; - return toolbarItem; -} - -- (FLEXExplorerToolbarItem *)currentItem { - if (!self.enabled && self.sibling) { - return self.sibling.currentItem; - } - - return self; -} - - -#pragma mark - Display Defaults - -+ (NSDictionary *)titleAttributes { - return @{ NSFontAttributeName : [UIFont systemFontOfSize:12.0] }; -} - -+ (UIColor *)highlightedBackgroundColor { - return FLEXColor.toolbarItemHighlightedColor; -} - -+ (UIColor *)selectedBackgroundColor { - return FLEXColor.toolbarItemSelectedColor; -} - -+ (UIColor *)defaultBackgroundColor { - return UIColor.clearColor; -} - -+ (CGFloat)topMargin { - return 2.0; -} - - -#pragma mark - State Changes - -- (void)setHighlighted:(BOOL)highlighted { - super.highlighted = highlighted; - [self updateColors]; -} - -- (void)setSelected:(BOOL)selected { - super.selected = selected; - [self updateColors]; -} - -- (void)setEnabled:(BOOL)enabled { - if (self.enabled != enabled) { - if (self.sibling) { - if (enabled) { // Replace sibling with myself - UIView *superview = self.sibling.superview; - [self.sibling removeFromSuperview]; - self.frame = self.sibling.frame; - [superview addSubview:self]; - } else { // Replace myself with sibling - UIView *superview = self.superview; - [self removeFromSuperview]; - self.sibling.frame = self.frame; - [superview addSubview:self.sibling]; - } - } - - super.enabled = enabled; - } -} - -+ (id)_selectedIndicatorImage { return nil; } - -- (void)updateColors { - // Background color - if (self.highlighted) { - self.backgroundColor = self.class.highlightedBackgroundColor; - } else if (self.selected) { - self.backgroundColor = self.class.selectedBackgroundColor; - } else { - self.backgroundColor = self.class.defaultBackgroundColor; - } -} - - -#pragma mark - UIButton Layout Overrides - -- (CGRect)titleRectForContentRect:(CGRect)contentRect { - NSDictionary *attrs = [[self class] titleAttributes]; - // Bottom aligned and centered. - CGRect titleRect = CGRectZero; - CGSize titleSize = [self.title boundingRectWithSize:contentRect.size - options:0 - attributes:attrs - context:nil].size; - titleSize = CGSizeMake(ceil(titleSize.width), ceil(titleSize.height)); - titleRect.size = titleSize; - titleRect.origin.y = contentRect.origin.y + CGRectGetMaxY(contentRect) - titleSize.height; - titleRect.origin.x = contentRect.origin.x + FLEXFloor((contentRect.size.width - titleSize.width) / 2.0); - return titleRect; -} - -- (CGRect)imageRectForContentRect:(CGRect)contentRect { - CGSize imageSize = self.image.size; - CGRect titleRect = [self titleRectForContentRect:contentRect]; - CGFloat availableHeight = contentRect.size.height - titleRect.size.height - [[self class] topMargin]; - CGFloat originY = [[self class] topMargin] + FLEXFloor((availableHeight - imageSize.height) / 2.0); - CGFloat originX = FLEXFloor((contentRect.size.width - imageSize.width) / 2.0); - CGRect imageRect = CGRectMake(originX, originY, imageSize.width, imageSize.height); - return imageRect; -} - -@end diff --git a/BHTwitter/Classes/Utility/APPLE_LICENSE b/BHTwitter/Classes/Utility/APPLE_LICENSE deleted file mode 100644 index c70995df..00000000 --- a/BHTwitter/Classes/Utility/APPLE_LICENSE +++ /dev/null @@ -1,367 +0,0 @@ -APPLE PUBLIC SOURCE LICENSE -Version 2.0 - August 6, 2003 - -Please read this License carefully before downloading this software. -By downloading or using this software, you are agreeing to be bound by -the terms of this License. If you do not or cannot agree to the terms -of this License, please do not download or use the software. - -1. General; Definitions. This License applies to any program or other -work which Apple Computer, Inc. ("Apple") makes publicly available and -which contains a notice placed by Apple identifying such program or -work as "Original Code" and stating that it is subject to the terms of -this Apple Public Source License version 2.0 ("License"). As used in -this License: - -1.1 "Applicable Patent Rights" mean: (a) in the case where Apple is -the grantor of rights, (i) claims of patents that are now or hereafter -acquired, owned by or assigned to Apple and (ii) that cover subject -matter contained in the Original Code, but only to the extent -necessary to use, reproduce and/or distribute the Original Code -without infringement; and (b) in the case where You are the grantor of -rights, (i) claims of patents that are now or hereafter acquired, -owned by or assigned to You and (ii) that cover subject matter in Your -Modifications, taken alone or in combination with Original Code. - -1.2 "Contributor" means any person or entity that creates or -contributes to the creation of Modifications. - -1.3 "Covered Code" means the Original Code, Modifications, the -combination of Original Code and any Modifications, and/or any -respective portions thereof. - -1.4 "Externally Deploy" means: (a) to sublicense, distribute or -otherwise make Covered Code available, directly or indirectly, to -anyone other than You; and/or (b) to use Covered Code, alone or as -part of a Larger Work, in any way to provide a service, including but -not limited to delivery of content, through electronic communication -with a client other than You. - -1.5 "Larger Work" means a work which combines Covered Code or portions -thereof with code not governed by the terms of this License. - -1.6 "Modifications" mean any addition to, deletion from, and/or change -to, the substance and/or structure of the Original Code, any previous -Modifications, the combination of Original Code and any previous -Modifications, and/or any respective portions thereof. When code is -released as a series of files, a Modification is: (a) any addition to -or deletion from the contents of a file containing Covered Code; -and/or (b) any new file or other representation of computer program -statements that contains any part of Covered Code. - -1.7 "Original Code" means (a) the Source Code of a program or other -work as originally made available by Apple under this License, -including the Source Code of any updates or upgrades to such programs -or works made available by Apple under this License, and that has been -expressly identified by Apple as such in the header file(s) of such -work; and (b) the object code compiled from such Source Code and -originally made available by Apple under this License. - -1.8 "Source Code" means the human readable form of a program or other -work that is suitable for making modifications to it, including all -modules it contains, plus any associated interface definition files, -scripts used to control compilation and installation of an executable -(object code). - -1.9 "You" or "Your" means an individual or a legal entity exercising -rights under this License. For legal entities, "You" or "Your" -includes any entity which controls, is controlled by, or is under -common control with, You, where "control" means (a) the power, direct -or indirect, to cause the direction or management of such entity, -whether by contract or otherwise, or (b) ownership of fifty percent -(50%) or more of the outstanding shares or beneficial ownership of -such entity. - -2. Permitted Uses; Conditions & Restrictions. Subject to the terms -and conditions of this License, Apple hereby grants You, effective on -the date You accept this License and download the Original Code, a -world-wide, royalty-free, non-exclusive license, to the extent of -Apple's Applicable Patent Rights and copyrights covering the Original -Code, to do the following: - -2.1 Unmodified Code. You may use, reproduce, display, perform, -internally distribute within Your organization, and Externally Deploy -verbatim, unmodified copies of the Original Code, for commercial or -non-commercial purposes, provided that in each instance: - -(a) You must retain and reproduce in all copies of Original Code the -copyright and other proprietary notices and disclaimers of Apple as -they appear in the Original Code, and keep intact all notices in the -Original Code that refer to this License; and - -(b) You must include a copy of this License with every copy of Source -Code of Covered Code and documentation You distribute or Externally -Deploy, and You may not offer or impose any terms on such Source Code -that alter or restrict this License or the recipients' rights -hereunder, except as permitted under Section 6. - -2.2 Modified Code. You may modify Covered Code and use, reproduce, -display, perform, internally distribute within Your organization, and -Externally Deploy Your Modifications and Covered Code, for commercial -or non-commercial purposes, provided that in each instance You also -meet all of these conditions: - -(a) You must satisfy all the conditions of Section 2.1 with respect to -the Source Code of the Covered Code; - -(b) You must duplicate, to the extent it does not already exist, the -notice in Exhibit A in each file of the Source Code of all Your -Modifications, and cause the modified files to carry prominent notices -stating that You changed the files and the date of any change; and - -(c) If You Externally Deploy Your Modifications, You must make -Source Code of all Your Externally Deployed Modifications either -available to those to whom You have Externally Deployed Your -Modifications, or publicly available. Source Code of Your Externally -Deployed Modifications must be released under the terms set forth in -this License, including the license grants set forth in Section 3 -below, for as long as you Externally Deploy the Covered Code or twelve -(12) months from the date of initial External Deployment, whichever is -longer. You should preferably distribute the Source Code of Your -Externally Deployed Modifications electronically (e.g. download from a -web site). - -2.3 Distribution of Executable Versions. In addition, if You -Externally Deploy Covered Code (Original Code and/or Modifications) in -object code, executable form only, You must include a prominent -notice, in the code itself as well as in related documentation, -stating that Source Code of the Covered Code is available under the -terms of this License with information on how and where to obtain such -Source Code. - -2.4 Third Party Rights. You expressly acknowledge and agree that -although Apple and each Contributor grants the licenses to their -respective portions of the Covered Code set forth herein, no -assurances are provided by Apple or any Contributor that the Covered -Code does not infringe the patent or other intellectual property -rights of any other entity. Apple and each Contributor disclaim any -liability to You for claims brought by any other entity based on -infringement of intellectual property rights or otherwise. As a -condition to exercising the rights and licenses granted hereunder, You -hereby assume sole responsibility to secure any other intellectual -property rights needed, if any. For example, if a third party patent -license is required to allow You to distribute the Covered Code, it is -Your responsibility to acquire that license before distributing the -Covered Code. - -3. Your Grants. In consideration of, and as a condition to, the -licenses granted to You under this License, You hereby grant to any -person or entity receiving or distributing Covered Code under this -License a non-exclusive, royalty-free, perpetual, irrevocable license, -under Your Applicable Patent Rights and other intellectual property -rights (other than patent) owned or controlled by You, to use, -reproduce, display, perform, modify, sublicense, distribute and -Externally Deploy Your Modifications of the same scope and extent as -Apple's licenses under Sections 2.1 and 2.2 above. - -4. Larger Works. You may create a Larger Work by combining Covered -Code with other code not governed by the terms of this License and -distribute the Larger Work as a single product. In each such instance, -You must make sure the requirements of this License are fulfilled for -the Covered Code or any portion thereof. - -5. Limitations on Patent License. Except as expressly stated in -Section 2, no other patent rights, express or implied, are granted by -Apple herein. Modifications and/or Larger Works may require additional -patent licenses from Apple which Apple may grant in its sole -discretion. - -6. Additional Terms. You may choose to offer, and to charge a fee for, -warranty, support, indemnity or liability obligations and/or other -rights consistent with the scope of the license granted herein -("Additional Terms") to one or more recipients of Covered Code. -However, You may do so only on Your own behalf and as Your sole -responsibility, and not on behalf of Apple or any Contributor. You -must obtain the recipient's agreement that any such Additional Terms -are offered by You alone, and You hereby agree to indemnify, defend -and hold Apple and every Contributor harmless for any liability -incurred by or claims asserted against Apple or such Contributor by -reason of any such Additional Terms. - -7. Versions of the License. Apple may publish revised and/or new -versions of this License from time to time. Each version will be given -a distinguishing version number. Once Original Code has been published -under a particular version of this License, You may continue to use it -under the terms of that version. You may also choose to use such -Original Code under the terms of any subsequent version of this -License published by Apple. No one other than Apple has the right to -modify the terms applicable to Covered Code created under this -License. - -8. NO WARRANTY OR SUPPORT. The Covered Code may contain in whole or in -part pre-release, untested, or not fully tested works. The Covered -Code may contain errors that could cause failures or loss of data, and -may be incomplete or contain inaccuracies. You expressly acknowledge -and agree that use of the Covered Code, or any portion thereof, is at -Your sole and entire risk. THE COVERED CODE IS PROVIDED "AS IS" AND -WITHOUT WARRANTY, UPGRADES OR SUPPORT OF ANY KIND AND APPLE AND -APPLE'S LICENSOR(S) (COLLECTIVELY REFERRED TO AS "APPLE" FOR THE -PURPOSES OF SECTIONS 8 AND 9) AND ALL CONTRIBUTORS EXPRESSLY DISCLAIM -ALL WARRANTIES AND/OR CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT -NOT LIMITED TO, THE IMPLIED WARRANTIES AND/OR CONDITIONS OF -MERCHANTABILITY, OF SATISFACTORY QUALITY, OF FITNESS FOR A PARTICULAR -PURPOSE, OF ACCURACY, OF QUIET ENJOYMENT, AND NONINFRINGEMENT OF THIRD -PARTY RIGHTS. APPLE AND EACH CONTRIBUTOR DOES NOT WARRANT AGAINST -INTERFERENCE WITH YOUR ENJOYMENT OF THE COVERED CODE, THAT THE -FUNCTIONS CONTAINED IN THE COVERED CODE WILL MEET YOUR REQUIREMENTS, -THAT THE OPERATION OF THE COVERED CODE WILL BE UNINTERRUPTED OR -ERROR-FREE, OR THAT DEFECTS IN THE COVERED CODE WILL BE CORRECTED. NO -ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN BY APPLE, AN APPLE -AUTHORIZED REPRESENTATIVE OR ANY CONTRIBUTOR SHALL CREATE A WARRANTY. -You acknowledge that the Covered Code is not intended for use in the -operation of nuclear facilities, aircraft navigation, communication -systems, or air traffic control machines in which case the failure of -the Covered Code could lead to death, personal injury, or severe -physical or environmental damage. - -9. LIMITATION OF LIABILITY. TO THE EXTENT NOT PROHIBITED BY LAW, IN NO -EVENT SHALL APPLE OR ANY CONTRIBUTOR BE LIABLE FOR ANY INCIDENTAL, -SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR RELATING -TO THIS LICENSE OR YOUR USE OR INABILITY TO USE THE COVERED CODE, OR -ANY PORTION THEREOF, WHETHER UNDER A THEORY OF CONTRACT, WARRANTY, -TORT (INCLUDING NEGLIGENCE), PRODUCTS LIABILITY OR OTHERWISE, EVEN IF -APPLE OR SUCH CONTRIBUTOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES AND NOTWITHSTANDING THE FAILURE OF ESSENTIAL PURPOSE OF ANY -REMEDY. SOME JURISDICTIONS DO NOT ALLOW THE LIMITATION OF LIABILITY OF -INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS LIMITATION MAY NOT APPLY -TO YOU. In no event shall Apple's total liability to You for all -damages (other than as may be required by applicable law) under this -License exceed the amount of fifty dollars ($50.00). - -10. Trademarks. This License does not grant any rights to use the -trademarks or trade names "Apple", "Apple Computer", "Mac", "Mac OS", -"QuickTime", "QuickTime Streaming Server" or any other trademarks, -service marks, logos or trade names belonging to Apple (collectively -"Apple Marks") or to any trademark, service mark, logo or trade name -belonging to any Contributor. You agree not to use any Apple Marks in -or as part of the name of products derived from the Original Code or -to endorse or promote products derived from the Original Code other -than as expressly permitted by and in strict compliance at all times -with Apple's third party trademark usage guidelines which are posted -at http://www.apple.com/legal/guidelinesfor3rdparties.html. - -11. Ownership. Subject to the licenses granted under this License, -each Contributor retains all rights, title and interest in and to any -Modifications made by such Contributor. Apple retains all rights, -title and interest in and to the Original Code and any Modifications -made by or on behalf of Apple ("Apple Modifications"), and such Apple -Modifications will not be automatically subject to this License. Apple -may, at its sole discretion, choose to license such Apple -Modifications under this License, or on different terms from those -contained in this License or may choose not to license them at all. - -12. Termination. - -12.1 Termination. This License and the rights granted hereunder will -terminate: - -(a) automatically without notice from Apple if You fail to comply with -any term(s) of this License and fail to cure such breach within 30 -days of becoming aware of such breach; - -(b) immediately in the event of the circumstances described in Section -13.5(b); or - -(c) automatically without notice from Apple if You, at any time during -the term of this License, commence an action for patent infringement -against Apple; provided that Apple did not first commence -an action for patent infringement against You in that instance. - -12.2 Effect of Termination. Upon termination, You agree to immediately -stop any further use, reproduction, modification, sublicensing and -distribution of the Covered Code. All sublicenses to the Covered Code -which have been properly granted prior to termination shall survive -any termination of this License. Provisions which, by their nature, -should remain in effect beyond the termination of this License shall -survive, including but not limited to Sections 3, 5, 8, 9, 10, 11, -12.2 and 13. No party will be liable to any other for compensation, -indemnity or damages of any sort solely as a result of terminating -this License in accordance with its terms, and termination of this -License will be without prejudice to any other right or remedy of -any party. - -13. Miscellaneous. - -13.1 Government End Users. The Covered Code is a "commercial item" as -defined in FAR 2.101. Government software and technical data rights in -the Covered Code include only those rights customarily provided to the -public as defined in this License. This customary commercial license -in technical data and software is provided in accordance with FAR -12.211 (Technical Data) and 12.212 (Computer Software) and, for -Department of Defense purchases, DFAR 252.227-7015 (Technical Data -- -Commercial Items) and 227.7202-3 (Rights in Commercial Computer -Software or Computer Software Documentation). Accordingly, all U.S. -Government End Users acquire Covered Code with only those rights set -forth herein. - -13.2 Relationship of Parties. This License will not be construed as -creating an agency, partnership, joint venture or any other form of -legal association between or among You, Apple or any Contributor, and -You will not represent to the contrary, whether expressly, by -implication, appearance or otherwise. - -13.3 Independent Development. Nothing in this License will impair -Apple's right to acquire, license, develop, have others develop for -it, market and/or distribute technology or products that perform the -same or similar functions as, or otherwise compete with, -Modifications, Larger Works, technology or products that You may -develop, produce, market or distribute. - -13.4 Waiver; Construction. Failure by Apple or any Contributor to -enforce any provision of this License will not be deemed a waiver of -future enforcement of that or any other provision. Any law or -regulation which provides that the language of a contract shall be -construed against the drafter will not apply to this License. - -13.5 Severability. (a) If for any reason a court of competent -jurisdiction finds any provision of this License, or portion thereof, -to be unenforceable, that provision of the License will be enforced to -the maximum extent permissible so as to effect the economic benefits -and intent of the parties, and the remainder of this License will -continue in full force and effect. (b) Notwithstanding the foregoing, -if applicable law prohibits or restricts You from fully and/or -specifically complying with Sections 2 and/or 3 or prevents the -enforceability of either of those Sections, this License will -immediately terminate and You must immediately discontinue any use of -the Covered Code and destroy all copies of it that are in your -possession or control. - -13.6 Dispute Resolution. Any litigation or other dispute resolution -between You and Apple relating to this License shall take place in the -Northern District of California, and You and Apple hereby consent to -the personal jurisdiction of, and venue in, the state and federal -courts within that District with respect to this License. The -application of the United Nations Convention on Contracts for the -International Sale of Goods is expressly excluded. - -13.7 Entire Agreement; Governing Law. This License constitutes the -entire agreement between the parties with respect to the subject -matter hereof. This License shall be governed by the laws of the -United States and the State of California, except that body of -California law concerning conflicts of law. - -Where You are located in the province of Quebec, Canada, the following -clause applies: The parties hereby confirm that they have requested -that this License and all related documents be drafted in English. Les -parties ont exigé que le présent contrat et tous les documents -connexes soient rédigés en anglais. - -EXHIBIT A. - -"Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights -Reserved. - -This file contains Original Code and/or Modifications of Original Code -as defined in and that are subject to the Apple Public Source License -Version 2.0 (the 'License'). You may not use this file except in -compliance with the License. Please obtain a copy of the License at -http://www.opensource.apple.com/apsl/ and read it before using this -file. - -The Original Code and all software distributed under the License are -distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, -INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. -Please see the License for the specific language governing rights and -limitations under the License." diff --git a/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.h b/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.h deleted file mode 100644 index 0f84bd33..00000000 --- a/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// CALayer+FLEX.h -// FLEX -// -// Created by Tanner on 2/28/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface CALayer (FLEX) - -@property (nonatomic) BOOL flex_continuousCorners; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.m b/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.m deleted file mode 100644 index c68f53c5..00000000 --- a/BHTwitter/Classes/Utility/Categories/CALayer+FLEX.m +++ /dev/null @@ -1,46 +0,0 @@ -// -// CALayer+FLEX.m -// FLEX -// -// Created by Tanner on 2/28/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "CALayer+FLEX.h" - -@interface CALayer (Private) -@property (nonatomic) BOOL continuousCorners; -@end - -@implementation CALayer (FLEX) - -static BOOL respondsToContinuousCorners = NO; - -+ (void)load { - respondsToContinuousCorners = [CALayer - instancesRespondToSelector:@selector(setContinuousCorners:) - ]; -} - -- (BOOL)flex_continuousCorners { - if (respondsToContinuousCorners) { - return self.continuousCorners; - } - - return NO; -} - -- (void)setFlex_continuousCorners:(BOOL)enabled { - if (respondsToContinuousCorners) { - if (@available(iOS 13, *)) { - self.cornerCurve = kCACornerCurveContinuous; - } else { - self.continuousCorners = enabled; -// self.masksToBounds = NO; - // self.allowsEdgeAntialiasing = YES; - // self.edgeAntialiasingMask = kCALayerLeftEdge | kCALayerRightEdge | kCALayerTopEdge | kCALayerBottomEdge; - } - } -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.h b/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.h deleted file mode 100644 index 7c602f3f..00000000 --- a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXRuntime+Compare.h -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import "FLEXProperty.h" -#import "FLEXIvar.h" -#import "FLEXMethodBase.h" -#import "FLEXProtocol.h" - -@interface FLEXProperty (Compare) -- (NSComparisonResult)compare:(FLEXProperty *)other; -@end - -@interface FLEXIvar (Compare) -- (NSComparisonResult)compare:(FLEXIvar *)other; -@end - -@interface FLEXMethodBase (Compare) -- (NSComparisonResult)compare:(FLEXMethodBase *)other; -@end - -@interface FLEXProtocol (Compare) -- (NSComparisonResult)compare:(FLEXProtocol *)other; -@end diff --git a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.m b/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.m deleted file mode 100644 index 9c17a5a8..00000000 --- a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+Compare.m +++ /dev/null @@ -1,47 +0,0 @@ -// -// FLEXRuntime+Compare.m -// FLEX -// -// Created by Tanner Bennett on 8/28/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntime+Compare.h" - -@implementation FLEXProperty (Compare) - -- (NSComparisonResult)compare:(FLEXProperty *)other { - NSComparisonResult r = [self.name caseInsensitiveCompare:other.name]; - if (r == NSOrderedSame) { - // TODO make sure empty image name sorts above an image name - return [self.imageName ?: @"" compare:other.imageName]; - } - - return r; -} - -@end - -@implementation FLEXIvar (Compare) - -- (NSComparisonResult)compare:(FLEXIvar *)other { - return [self.name caseInsensitiveCompare:other.name]; -} - -@end - -@implementation FLEXMethodBase (Compare) - -- (NSComparisonResult)compare:(FLEXMethodBase *)other { - return [self.name caseInsensitiveCompare:other.name]; -} - -@end - -@implementation FLEXProtocol (Compare) - -- (NSComparisonResult)compare:(FLEXProtocol *)other { - return [self.name caseInsensitiveCompare:other.name]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.h b/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.h deleted file mode 100644 index 888910ee..00000000 --- a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.h +++ /dev/null @@ -1,90 +0,0 @@ -// -// FLEXRuntime+UIKitHelpers.h -// FLEX -// -// Created by Tanner Bennett on 12/16/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import "FLEXProperty.h" -#import "FLEXIvar.h" -#import "FLEXMethod.h" -#import "FLEXProtocol.h" -#import "FLEXTableViewSection.h" - -@class FLEXObjectExplorerDefaults; - -/// Model objects of an object explorer screen adopt this -/// protocol in order respond to user defaults changes -@protocol FLEXObjectExplorerItem -/// Current explorer settings. Set when settings change. -@property (nonatomic) FLEXObjectExplorerDefaults *defaults; - -/// YES for properties and ivars which surely support editing, NO for all methods. -@property (nonatomic, readonly) BOOL isEditable; -/// NO for ivars, YES for supported methods and properties -@property (nonatomic, readonly) BOOL isCallable; -@end - -@protocol FLEXRuntimeMetadata -/// Used as the main title of the row -- (NSString *)description; -/// Used to compare metadata objects for uniqueness -@property (nonatomic, readonly) NSString *name; - -/// For internal use -@property (nonatomic) id tag; - -/// Should return \c nil if not applicable -- (id)currentValueWithTarget:(id)object; -/// Used as the subtitle or description of a property, ivar, or method -- (NSString *)previewWithTarget:(id)object; -/// For methods, a method calling screen. For all else, an object explorer. -- (UIViewController *)viewerWithTarget:(id)object; -/// For methods and protocols, nil. For all else, an a field editor screen. -/// The given section is reloaded on commit of any changes. -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section; -/// Used to determine present which interactions are possible to the user -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object; -/// Return nil to use the default reuse identifier -- (NSString *)reuseIdentifierWithTarget:(id)object; - -/// An array of actions to place in the first section of the context menu. -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender API_AVAILABLE(ios(13.0)); -/// An array where every 2 elements are a key-value pair. The key is a description -/// of what to copy like "Name" and the values are what will be copied. -- (NSArray *)copiableMetadataWithTarget:(id)object; -/// Properties and ivars return the address of an object, if they hold one. -- (NSString *)contextualSubtitleWithTarget:(id)object; - -@end - -// Even if a property is readonly, it still may be editable -// via a setter. Checking isEditable will not reflect that -// unless the property was initialized with a class. -@interface FLEXProperty (UIKitHelpers) @end -@interface FLEXIvar (UIKitHelpers) @end -@interface FLEXMethodBase (UIKitHelpers) @end -@interface FLEXMethod (UIKitHelpers) @end -@interface FLEXProtocol (UIKitHelpers) @end - -typedef NS_ENUM(NSUInteger, FLEXStaticMetadataRowStyle) { - FLEXStaticMetadataRowStyleSubtitle, - FLEXStaticMetadataRowStyleKeyValue, - FLEXStaticMetadataRowStyleDefault = FLEXStaticMetadataRowStyleSubtitle, -}; - -/// Displays a small row as a static key-value pair of information. -@interface FLEXStaticMetadata : NSObject - -+ (instancetype)style:(FLEXStaticMetadataRowStyle)style title:(NSString *)title string:(NSString *)string; -+ (instancetype)style:(FLEXStaticMetadataRowStyle)style title:(NSString *)title number:(NSNumber *)number; - -+ (NSArray *)classHierarchy:(NSArray *)classes; - -@end - - -/// This is assigned to the \c tag property of each metadata. - diff --git a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.m b/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.m deleted file mode 100644 index 079ff970..00000000 --- a/BHTwitter/Classes/Utility/Categories/FLEXRuntime+UIKitHelpers.m +++ /dev/null @@ -1,634 +0,0 @@ -// -// FLEXRuntime+UIKitHelpers.m -// FLEX -// -// Created by Tanner Bennett on 12/16/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntime+UIKitHelpers.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXArgumentInputViewFactory.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXFieldEditorViewController.h" -#import "FLEXMethodCallingViewController.h" -#import "FLEXObjectListViewController.h" -#import "FLEXTableView.h" -#import "FLEXUtility.h" -#import "NSArray+FLEX.h" -#import "NSString+FLEX.h" - -#define FLEXObjectExplorerDefaultsImpl \ -- (FLEXObjectExplorerDefaults *)defaults { \ - return self.tag; \ -} \ - \ -- (void)setDefaults:(FLEXObjectExplorerDefaults *)defaults { \ - self.tag = defaults; \ -} - -#pragma mark FLEXProperty -@implementation FLEXProperty (UIKitHelpers) -FLEXObjectExplorerDefaultsImpl - -/// Decide whether to use potentialTarget or [potentialTarget class] to get or set property -- (id)appropriateTargetForPropertyType:(id)potentialTarget { - if (!object_isClass(potentialTarget)) { - if (self.isClassProperty) { - return [potentialTarget class]; - } else { - return potentialTarget; - } - } else { - if (self.isClassProperty) { - return potentialTarget; - } else { - // Instance property with a class object - return nil; - } - } -} - -- (BOOL)isEditable { - if (self.attributes.isReadOnly) { - return self.likelySetterExists; - } - - const FLEXTypeEncoding *typeEncoding = self.attributes.typeEncoding.UTF8String; - return [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:typeEncoding currentValue:nil]; -} - -- (BOOL)isCallable { - return YES; -} - -- (id)currentValueWithTarget:(id)object { - return [self getPotentiallyUnboxedValue: - [self appropriateTargetForPropertyType:object] - ]; -} - -- (id)currentValueBeforeUnboxingWithTarget:(id)object { - return [self getValue: - [self appropriateTargetForPropertyType:object] - ]; -} - -- (NSString *)previewWithTarget:(id)object { - if (object_isClass(object) && !self.isClassProperty) { - return self.attributes.fullDeclaration; - } else if (self.defaults.wantsDynamicPreviews) { - return [FLEXRuntimeUtility - summaryForObject:[self currentValueWithTarget:object] - ]; - } - - return nil; -} - -- (UIViewController *)viewerWithTarget:(id)object { - id value = [self currentValueWithTarget:object]; - return [FLEXObjectExplorerFactory explorerViewControllerForObject:value]; -} - -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section { - id target = [self appropriateTargetForPropertyType:object]; - return [FLEXFieldEditorViewController target:target property:self commitHandler:^{ - [section reloadData:YES]; - }]; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - id targetForValueCheck = [self appropriateTargetForPropertyType:object]; - if (!targetForValueCheck) { - // Instance property with a class object - return UITableViewCellAccessoryNone; - } - - // We use .tag to store the cached value of .isEditable that is - // initialized by FLEXObjectExplorer in -reloadMetada - if ([self getPotentiallyUnboxedValue:targetForValueCheck]) { - if (self.defaults.isEditable) { - // Editable non-nil value, both - return UITableViewCellAccessoryDetailDisclosureButton; - } else { - // Uneditable non-nil value, chevron only - return UITableViewCellAccessoryDisclosureIndicator; - } - } else { - if (self.defaults.isEditable) { - // Editable nil value, just (i) - return UITableViewCellAccessoryDetailButton; - } else { - // Non-editable nil value, neither - return UITableViewCellAccessoryNone; - } - } -} - -- (NSString *)reuseIdentifierWithTarget:(id)object { return nil; } - -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender __IOS_AVAILABLE(13.0) { - BOOL returnsObject = self.attributes.typeEncoding.flex_typeIsObjectOrClass; - BOOL targetNotNil = [self appropriateTargetForPropertyType:object] != nil; - - // "Explore PropertyClass" for properties with a concrete class name - if (returnsObject) { - NSMutableArray *actions = [NSMutableArray new]; - - // Action for exploring class of this property - Class propertyClass = self.attributes.typeEncoding.flex_typeClass; - if (propertyClass) { - NSString *title = [NSString stringWithFormat:@"Explore %@", NSStringFromClass(propertyClass)]; - [actions addObject:[UIAction actionWithTitle:title image:nil identifier:nil handler:^(UIAction *action) { - UIViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:propertyClass]; - [sender.navigationController pushViewController:explorer animated:YES]; - }]]; - } - - // Action for exploring references to this object - if (targetNotNil) { - // Since the property holder is not nil, check if the property value is nil - id value = [self currentValueBeforeUnboxingWithTarget:object]; - if (value) { - NSString *title = @"List all references"; - [actions addObject:[UIAction actionWithTitle:title image:nil identifier:nil handler:^(UIAction *action) { - UIViewController *list = [FLEXObjectListViewController - objectsWithReferencesToObject:value - retained:NO - ]; - [sender.navigationController pushViewController:list animated:YES]; - }]]; - } - } - - return actions; - } - - return nil; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - BOOL returnsObject = self.attributes.typeEncoding.flex_typeIsObjectOrClass; - BOOL targetNotNil = [self appropriateTargetForPropertyType:object] != nil; - - NSMutableArray *items = [NSMutableArray arrayWithArray:@[ - @"Name", self.name ?: @"", - @"Type", self.attributes.typeEncoding ?: @"", - @"Declaration", self.fullDescription ?: @"", - ]]; - - if (targetNotNil) { - id value = [self currentValueBeforeUnboxingWithTarget:object]; - [items addObjectsFromArray:@[ - @"Value Preview", [self previewWithTarget:object] ?: @"", - @"Value Address", returnsObject ? [FLEXUtility addressOfObject:value] : @"", - ]]; - } - - [items addObjectsFromArray:@[ - @"Getter", NSStringFromSelector(self.likelyGetter) ?: @"", - @"Setter", self.likelySetterExists ? NSStringFromSelector(self.likelySetter) : @"", - @"Image Name", self.imageName ?: @"", - @"Attributes", self.attributes.string ?: @"", - @"objc_property", [FLEXUtility pointerToString:self.objc_property], - @"objc_property_attribute_t", [FLEXUtility pointerToString:self.attributes.list], - ]]; - - return items; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - id target = [self appropriateTargetForPropertyType:object]; - if (target && self.attributes.typeEncoding.flex_typeIsObjectOrClass) { - return [FLEXUtility addressOfObject:[self currentValueBeforeUnboxingWithTarget:target]]; - } - - return nil; -} - -@end - - -#pragma mark FLEXIvar -@implementation FLEXIvar (UIKitHelpers) -FLEXObjectExplorerDefaultsImpl - -- (BOOL)isEditable { - const FLEXTypeEncoding *typeEncoding = self.typeEncoding.UTF8String; - return [FLEXArgumentInputViewFactory canEditFieldWithTypeEncoding:typeEncoding currentValue:nil]; -} - -- (BOOL)isCallable { - return NO; -} - -- (id)currentValueWithTarget:(id)object { - if (!object_isClass(object)) { - return [self getPotentiallyUnboxedValue:object]; - } - - return nil; -} - -- (NSString *)previewWithTarget:(id)object { - if (object_isClass(object)) { - return self.details; - } else if (self.defaults.wantsDynamicPreviews) { - return [FLEXRuntimeUtility - summaryForObject:[self currentValueWithTarget:object] - ]; - } - - return nil; -} - -- (UIViewController *)viewerWithTarget:(id)object { - NSAssert(!object_isClass(object), @"Unreachable state: viewing ivar on class object"); - id value = [self currentValueWithTarget:object]; - return [FLEXObjectExplorerFactory explorerViewControllerForObject:value]; -} - -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section { - NSAssert(!object_isClass(object), @"Unreachable state: editing ivar on class object"); - return [FLEXFieldEditorViewController target:object ivar:self commitHandler:^{ - [section reloadData:YES]; - }]; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - if (object_isClass(object)) { - return UITableViewCellAccessoryNone; - } - - // Could use .isEditable here, but we use .tag for speed since it is cached - if ([self getPotentiallyUnboxedValue:object]) { - if (self.defaults.isEditable) { - // Editable non-nil value, both - return UITableViewCellAccessoryDetailDisclosureButton; - } else { - // Uneditable non-nil value, chevron only - return UITableViewCellAccessoryDisclosureIndicator; - } - } else { - if (self.defaults.isEditable) { - // Editable nil value, just (i) - return UITableViewCellAccessoryDetailButton; - } else { - // Non-editable nil value, neither - return UITableViewCellAccessoryNone; - } - } -} - -- (NSString *)reuseIdentifierWithTarget:(id)object { return nil; } - -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender __IOS_AVAILABLE(13.0) { - Class ivarClass = self.typeEncoding.flex_typeClass; - - // "Explore PropertyClass" for properties with a concrete class name - if (ivarClass) { - NSString *title = [NSString stringWithFormat:@"Explore %@", NSStringFromClass(ivarClass)]; - return @[[UIAction actionWithTitle:title image:nil identifier:nil handler:^(UIAction *action) { - UIViewController *explorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:ivarClass]; - [sender.navigationController pushViewController:explorer animated:YES]; - }]]; - } - - return nil; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - BOOL isInstance = !object_isClass(object); - BOOL returnsObject = self.typeEncoding.flex_typeIsObjectOrClass; - id value = isInstance ? [self getValue:object] : nil; - - NSMutableArray *items = [NSMutableArray arrayWithArray:@[ - @"Name", self.name ?: @"", - @"Type", self.typeEncoding ?: @"", - @"Declaration", self.description ?: @"", - ]]; - - if (isInstance) { - [items addObjectsFromArray:@[ - @"Value Preview", isInstance ? [self previewWithTarget:object] : @"", - @"Value Address", returnsObject ? [FLEXUtility addressOfObject:value] : @"", - ]]; - } - - [items addObjectsFromArray:@[ - @"Size", @(self.size).stringValue, - @"Offset", @(self.offset).stringValue, - @"objc_ivar", [FLEXUtility pointerToString:self.objc_ivar], - ]]; - - return items; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - if (!object_isClass(object) && self.typeEncoding.flex_typeIsObjectOrClass) { - return [FLEXUtility addressOfObject:[self getValue:object]]; - } - - return nil; -} - -@end - - -#pragma mark FLEXMethod -@implementation FLEXMethodBase (UIKitHelpers) -FLEXObjectExplorerDefaultsImpl - -- (BOOL)isEditable { - return NO; -} - -- (BOOL)isCallable { - return NO; -} - -- (id)currentValueWithTarget:(id)object { - // Methods can't be "edited" and have no "value" - return nil; -} - -- (NSString *)previewWithTarget:(id)object { - return [self.selectorString stringByAppendingFormat:@" — %@", self.typeEncoding]; -} - -- (UIViewController *)viewerWithTarget:(id)object { - // We disallow calling of FLEXMethodBase methods - @throw NSInternalInconsistencyException; - return nil; -} - -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section { - // Methods cannot be edited - @throw NSInternalInconsistencyException; - return nil; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - // We shouldn't be using any FLEXMethodBase objects for this - @throw NSInternalInconsistencyException; - return UITableViewCellAccessoryNone; -} - -- (NSString *)reuseIdentifierWithTarget:(id)object { return nil; } - -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender __IOS_AVAILABLE(13.0) { - return nil; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - return @[ - @"Selector", self.name ?: @"", - @"Type Encoding", self.typeEncoding ?: @"", - @"Declaration", self.description ?: @"", - ]; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - return nil; -} - -@end - -@implementation FLEXMethod (UIKitHelpers) - -- (BOOL)isCallable { - return self.signature != nil; -} - -- (UIViewController *)viewerWithTarget:(id)object { - object = self.isInstanceMethod ? object : (object_isClass(object) ? object : [object class]); - return [FLEXMethodCallingViewController target:object method:self]; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - if (self.isInstanceMethod) { - if (object_isClass(object)) { - // Instance method from class, can't call - return UITableViewCellAccessoryNone; - } else { - // Instance method from instance, can call - return UITableViewCellAccessoryDisclosureIndicator; - } - } else { - return UITableViewCellAccessoryDisclosureIndicator; - } -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - return [[super copiableMetadataWithTarget:object] arrayByAddingObjectsFromArray:@[ - @"NSMethodSignature *", [FLEXUtility addressOfObject:self.signature], - @"Signature String", self.signatureString ?: @"", - @"Number of Arguments", @(self.numberOfArguments).stringValue, - @"Return Type", @(self.returnType ?: ""), - @"Return Size", @(self.returnSize).stringValue, - @"objc_method", [FLEXUtility pointerToString:self.objc_method], - ]]; -} - -@end - - -#pragma mark FLEXProtocol -@implementation FLEXProtocol (UIKitHelpers) -FLEXObjectExplorerDefaultsImpl - -- (BOOL)isEditable { - return NO; -} - -- (BOOL)isCallable { - return NO; -} - -- (id)currentValueWithTarget:(id)object { - return nil; -} - -- (NSString *)previewWithTarget:(id)object { - return nil; -} - -- (UIViewController *)viewerWithTarget:(id)object { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:self]; -} - -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section { - // Protocols cannot be edited - @throw NSInternalInconsistencyException; - return nil; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - return UITableViewCellAccessoryDisclosureIndicator; -} - -- (NSString *)reuseIdentifierWithTarget:(id)object { return nil; } - -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender __IOS_AVAILABLE(13.0) { - return nil; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - NSArray *conformanceNames = [self.protocols valueForKeyPath:@"name"]; - NSString *conformances = [conformanceNames componentsJoinedByString:@"\n"]; - return @[ - @"Name", self.name ?: @"", - @"Conformances", conformances ?: @"", - ]; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - return nil; -} - -@end - - -#pragma mark FLEXStaticMetadata -@interface FLEXStaticMetadata () { - @protected - NSString *_name; -} -@property (nonatomic) FLEXTableViewCellReuseIdentifier reuse; -@property (nonatomic) NSString *subtitle; -@property (nonatomic) id metadata; -@end - -@interface FLEXStaticMetadata_Class : FLEXStaticMetadata -+ (instancetype)withClass:(Class)cls; -@end - -@implementation FLEXStaticMetadata -@synthesize name = _name; -@synthesize tag = _tag; - -FLEXObjectExplorerDefaultsImpl - -+ (NSArray *)classHierarchy:(NSArray *)classes { - return [classes flex_mapped:^id(Class cls, NSUInteger idx) { - return [FLEXStaticMetadata_Class withClass:cls]; - }]; -} - -+ (instancetype)style:(FLEXStaticMetadataRowStyle)style title:(NSString *)title string:(NSString *)string { - return [[self alloc] initWithStyle:style title:title subtitle:string]; -} - -+ (instancetype)style:(FLEXStaticMetadataRowStyle)style title:(NSString *)title number:(NSNumber *)number { - return [[self alloc] initWithStyle:style title:title subtitle:number.stringValue]; -} - -- (id)initWithStyle:(FLEXStaticMetadataRowStyle)style title:(NSString *)title subtitle:(NSString *)subtitle { - self = [super init]; - if (self) { - if (style == FLEXStaticMetadataRowStyleKeyValue) { - _reuse = kFLEXKeyValueCell; - } else { - _reuse = kFLEXMultilineDetailCell; - } - - _name = title; - _subtitle = subtitle; - } - - return self; -} - -- (NSString *)description { - return self.name; -} - -- (NSString *)reuseIdentifierWithTarget:(id)object { - return self.reuse; -} - -- (BOOL)isEditable { - return NO; -} - -- (BOOL)isCallable { - return NO; -} - -- (id)currentValueWithTarget:(id)object { - return nil; -} - -- (NSString *)previewWithTarget:(id)object { - return self.subtitle; -} - -- (UIViewController *)viewerWithTarget:(id)object { - return nil; -} - -- (UIViewController *)editorWithTarget:(id)object section:(FLEXTableViewSection *)section { - // Static metadata cannot be edited - @throw NSInternalInconsistencyException; - return nil; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - return UITableViewCellAccessoryNone; -} - -- (NSArray *)additionalActionsWithTarget:(id)object sender:(UIViewController *)sender __IOS_AVAILABLE(13.0) { - return nil; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - return @[self.name, self.subtitle]; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - return nil; -} - -@end - - -#pragma mark FLEXStaticMetadata_Class -@implementation FLEXStaticMetadata_Class - -+ (instancetype)withClass:(Class)cls { - NSParameterAssert(cls); - - FLEXStaticMetadata_Class *metadata = [self new]; - metadata.metadata = cls; - metadata->_name = NSStringFromClass(cls); - metadata.reuse = kFLEXDefaultCell; - return metadata; -} - -- (id)initWithStyle:(FLEXStaticMetadataRowStyle)style title:(NSString *)title subtitle:(NSString *)subtitle { - @throw NSInternalInconsistencyException; - return nil; -} - -- (UIViewController *)viewerWithTarget:(id)object { - return [FLEXObjectExplorerFactory explorerViewControllerForObject:self.metadata]; -} - -- (UITableViewCellAccessoryType)suggestedAccessoryTypeWithTarget:(id)object { - return UITableViewCellAccessoryDisclosureIndicator; -} - -- (NSArray *)copiableMetadataWithTarget:(id)object { - return @[ - @"Class Name", self.name, - @"Class", [FLEXUtility addressOfObject:self.metadata] - ]; -} - -- (NSString *)contextualSubtitleWithTarget:(id)object { - return [FLEXUtility addressOfObject:self.metadata]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.h b/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.h deleted file mode 100644 index 885a2a4c..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// NSArray+FLEX.h -// FLEX -// -// Created by Tanner Bennett on 9/25/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface NSArray (Functional) - -/// Actually more like flatmap, but it seems like the objc way to allow returning nil to omit objects. -/// So, return nil from the block to omit objects, and return an object to include it in the new array. -/// Unlike flatmap, however, this will not flatten arrays of arrays into a single array. -- (__kindof NSArray *)flex_mapped:(id(^)(T obj, NSUInteger idx))mapFunc; -/// Like flex_mapped, but expects arrays to be returned, and flattens them into one array. -- (__kindof NSArray *)flex_flatmapped:(NSArray *(^)(id, NSUInteger idx))block; -- (instancetype)flex_filtered:(BOOL(^)(T obj, NSUInteger idx))filterFunc; -- (void)flex_forEach:(void(^)(T obj, NSUInteger idx))block; - -/// Unlike \c subArrayWithRange: this will not throw an exception if \c maxLength -/// is greater than the size of the array. If the array has one element and -/// \c maxLength is greater than 1, you get an array with 1 element back. -- (instancetype)flex_subArrayUpto:(NSUInteger)maxLength; - -+ (instancetype)flex_forEachUpTo:(NSUInteger)bound map:(T(^)(NSUInteger i))block; -+ (instancetype)flex_mapped:(id)collection block:(id(^)(T obj, NSUInteger idx))mapFunc; - -- (instancetype)flex_sortedUsingSelector:(SEL)selector; - -- (T)flex_firstWhere:(BOOL(^)(T obj))meetingCriteria; - -@end - -@interface NSMutableArray (Functional) - -- (void)flex_filter:(BOOL(^)(T obj, NSUInteger idx))filterFunc; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.m b/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.m deleted file mode 100644 index 0f09c255..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSArray+FLEX.m +++ /dev/null @@ -1,143 +0,0 @@ -// -// NSArray+FLEX.m -// FLEX -// -// Created by Tanner Bennett on 9/25/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "NSArray+FLEX.h" - -#define FLEXArrayClassIsMutable(me) ([[self class] isSubclassOfClass:[NSMutableArray class]]) - -@implementation NSArray (Functional) - -- (__kindof NSArray *)flex_mapped:(id (^)(id, NSUInteger))mapFunc { - NSMutableArray *map = [NSMutableArray new]; - [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - id ret = mapFunc(obj, idx); - if (ret) { - [map addObject:ret]; - } - }]; - - if (self.count < 2048 && !FLEXArrayClassIsMutable(self)) { - return map.copy; - } - - return map; -} - -- (__kindof NSArray *)flex_flatmapped:(NSArray *(^)(id, NSUInteger))block { - NSMutableArray *array = [NSMutableArray new]; - [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - NSArray *toAdd = block(obj, idx); - if (toAdd) { - [array addObjectsFromArray:toAdd]; - } - }]; - - if (array.count < 2048 && !FLEXArrayClassIsMutable(self)) { - return array.copy; - } - - return array; -} - -- (NSArray *)flex_filtered:(BOOL (^)(id, NSUInteger))filterFunc { - return [self flex_mapped:^id(id obj, NSUInteger idx) { - return filterFunc(obj, idx) ? obj : nil; - }]; -} - -- (void)flex_forEach:(void(^)(id, NSUInteger))block { - [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - block(obj, idx); - }]; -} - -- (instancetype)flex_subArrayUpto:(NSUInteger)maxLength { - if (maxLength > self.count) { - if (FLEXArrayClassIsMutable(self)) { - return self.mutableCopy; - } - - return self; - } - - return [self subarrayWithRange:NSMakeRange(0, maxLength)]; -} - -+ (__kindof NSArray *)flex_forEachUpTo:(NSUInteger)bound map:(id(^)(NSUInteger))block { - NSMutableArray *array = [NSMutableArray new]; - for (NSUInteger i = 0; i < bound; i++) { - id obj = block(i); - if (obj) { - [array addObject:obj]; - } - } - - // For performance reasons, don't copy large arrays - if (bound < 2048 && !FLEXArrayClassIsMutable(self)) { - return array.copy; - } - - return array; -} - -+ (instancetype)flex_mapped:(id)collection block:(id(^)(id obj, NSUInteger idx))mapFunc { - NSMutableArray *array = [NSMutableArray new]; - NSInteger idx = 0; - for (id obj in collection) { - id ret = mapFunc(obj, idx++); - if (ret) { - [array addObject:ret]; - } - } - - // For performance reasons, don't copy large arrays - if (array.count < 2048) { - return array.copy; - } - - return array; -} - -- (instancetype)flex_sortedUsingSelector:(SEL)selector { - if (FLEXArrayClassIsMutable(self)) { - NSMutableArray *me = (id)self; - [me sortUsingSelector:selector]; - return me; - } else { - return [self sortedArrayUsingSelector:selector]; - } -} - -- (id)flex_firstWhere:(BOOL (^)(id))meetsCriteria { - for (id e in self) { - if (meetsCriteria(e)) { - return e; - } - } - - return nil; -} - -@end - - -@implementation NSMutableArray (Functional) - -- (void)flex_filter:(BOOL (^)(id, NSUInteger))keepObject { - NSMutableIndexSet *toRemove = [NSMutableIndexSet new]; - - [self enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { - if (!keepObject(obj, idx)) { - [toRemove addIndex:idx]; - } - }]; - - [self removeObjectsAtIndexes:toRemove]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.h b/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.h deleted file mode 100644 index 876ff7e2..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.h +++ /dev/null @@ -1,234 +0,0 @@ -// -// NSObject+FLEX_Reflection.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import -@class FLEXMirror, FLEXMethod, FLEXIvar, FLEXProperty, FLEXMethodBase, FLEXPropertyAttributes, FLEXProtocol; - -NS_ASSUME_NONNULL_BEGIN - -/// Returns the type encoding string given the encoding for the return type and parameters, if any. -/// @discussion Example usage for a \c void returning method which takes -/// an \c int: @code FLEXTypeEncoding(@encode(void), @encode(int)); -/// @param returnType The encoded return type. \c void for exmaple would be \c @encode(void). -/// @param count The number of parameters in this type encoding string. -/// @return The type encoding string, or \c nil if \e returnType is \c NULL. -NSString * FLEXTypeEncodingString(const char *returnType, NSUInteger count, ...); - -NSArray * _Nullable FLEXGetAllSubclasses(_Nullable Class cls, BOOL includeSelf); -NSArray * _Nullable FLEXGetClassHierarchy(_Nullable Class cls, BOOL includeSelf); -NSArray * _Nullable FLEXGetConformedProtocols(_Nullable Class cls); - -NSArray * _Nullable FLEXGetAllIvars(_Nullable Class cls); -/// @param cls a class object to get instance properties, -/// or a metaclass object to get class properties -NSArray * _Nullable FLEXGetAllProperties(_Nullable Class cls); -/// @param cls a class object to get instance methods, -/// or a metaclass object to get class methods -/// @param instance used to mark methods as instance methods or not. -/// Not used to determine whether to get instance or class methods. -NSArray * _Nullable FLEXGetAllMethods(_Nullable Class cls, BOOL instance); -/// @param cls a class object to get all instance and class methods. -NSArray * _Nullable FLEXGetAllInstanceAndClassMethods(_Nullable Class cls); - - - -#pragma mark Reflection -@interface NSObject (Reflection) - -@property (nonatomic, readonly ) FLEXMirror *flex_reflection; -@property (nonatomic, readonly, class) FLEXMirror *flex_reflection; - -/// Calls into /c FLEXGetAllSubclasses -/// @return Every subclass of the receiving class, including the receiver itself. -@property (nonatomic, readonly, class) NSArray *flex_allSubclasses; - -/// @return The \c Class object for the metaclass of the recieving class, or \c Nil if the class is Nil or not registered. -@property (nonatomic, readonly, class) Class flex_metaclass; -/// @return The size in bytes of instances of the recieving class, or \c 0 if \e cls is \c Nil. -@property (nonatomic, readonly, class) size_t flex_instanceSize; - -/// Changes the class of an object instance. -/// @return The previous value of the objects \c class, or \c Nil if the object is \c nil. -- (Class)flex_setClass:(Class)cls; -/// Sets the recieving class's superclass. "You should not use this method" — Apple. -/// @return The old superclass. -+ (Class)flex_setSuperclass:(Class)superclass; - -/// Calls into \c FLEXGetClassHierarchy() -/// @return a list of classes going up the class hierarchy, -/// starting with the receiver and ending with the root class. -@property (nonatomic, readonly, class) NSArray *flex_classHierarchy; - -/// Calls into \c FLEXGetConformedProtocols -/// @return a list of protocols this class itself conforms to. -@property (nonatomic, readonly, class) NSArray *flex_protocols; - -@end - - -#pragma mark Methods -@interface NSObject (Methods) - -/// All instance and class methods specific to the recieving class. -/// @discussion This method will only retrieve methods specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXMethod objects. -@property (nonatomic, readonly, class) NSArray *flex_allMethods; -/// All instance methods specific to the recieving class. -/// @discussion This method will only retrieve methods specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXMethod objects. -@property (nonatomic, readonly, class) NSArray *flex_allInstanceMethods; -/// All class methods specific to the recieving class. -/// @discussion This method will only retrieve methods specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXMethod objects. -@property (nonatomic, readonly, class) NSArray *flex_allClassMethods; - -/// Retrieves the class's instance method with the given name. -/// @return An initialized \c FLEXMethod object, or \c nil if the method wasn't found. -+ (FLEXMethod *)flex_methodNamed:(NSString *)name; - -/// Retrieves the class's class method with the given name. -/// @return An initialized \c FLEXMethod object, or \c nil if the method wasn't found. -+ (FLEXMethod *)flex_classMethodNamed:(NSString *)name; - -/// Adds a new method to the recieving class with a given name and implementation. -/// @discussion This method will add an override of a superclass's implementation, -/// but will not replace an existing implementation in the class. -/// To change an existing implementation, use \c replaceImplementationOfMethod:with:. -/// -/// Type encodings start with the return type and end with the parameter types in order. -/// The type encoding for \c NSArray's \c count property getter looks like this: -/// @code [NSString stringWithFormat:@"%s%s%s%s", @encode(void), @encode(id), @encode(SEL), @encode(NSUInteger)] @endcode -/// Using the \c FLEXTypeEncoding function for the same method looks like this: -/// @code FLEXTypeEncodingString(@encode(void), 1, @encode(NSUInteger)) @endcode -/// @param typeEncoding The type encoding string. Consider using the \c FLEXTypeEncodingString() function. -/// @param instanceMethod NO to add the method to the class itself or YES to add it as an instance method. -/// @return YES if the method was added successfully, \c NO otherwise -/// (for example, the class already contains a method implementation with that name). -+ (BOOL)addMethod:(SEL)selector - typeEncoding:(NSString *)typeEncoding - implementation:(IMP)implementaiton - toInstances:(BOOL)instanceMethod; - -/// Replaces the implementation of a method in the recieving class. -/// @param instanceMethod YES to replace the instance method, NO to replace the class method. -/// @note This function behaves in two different ways: -/// -/// - If the method does not yet exist in the recieving class, it is added as if -/// \c addMethod:typeEncoding:implementation were called. -/// -/// - If the method does exist, its \c IMP is replaced. -/// @return The previous \c IMP of \e method. -+ (IMP)replaceImplementationOfMethod:(FLEXMethodBase *)method with:(IMP)implementation useInstance:(BOOL)instanceMethod; -/// Swaps the implementations of the given methods. -/// @discussion If one or neither of the given methods exist in the recieving class, -/// they are added to the class with their implementations swapped as if each method did exist. -/// This method will not fail if each \c FLEXSimpleMethod contains a valid selector. -/// @param instanceMethod YES to swizzle the instance method, NO to swizzle the class method. -+ (void)swizzle:(FLEXMethodBase *)original with:(FLEXMethodBase *)other onInstance:(BOOL)instanceMethod; -/// Swaps the implementations of the given methods. -/// @param instanceMethod YES to swizzle the instance method, NO to swizzle the class method. -/// @return \c YES if successful, and \c NO if selectors could not be retrieved from the given strings. -+ (BOOL)swizzleByName:(NSString *)original with:(NSString *)other onInstance:(BOOL)instanceMethod; -/// Swaps the implementations of methods corresponding to the given selectors. -+ (void)swizzleBySelector:(SEL)original with:(SEL)other onInstance:(BOOL)instanceMethod; - -@end - - -#pragma mark Properties -@interface NSObject (Ivars) - -/// All of the instance variables specific to the recieving class. -/// @discussion This method will only retrieve instance varibles specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call \c [[self superclass] allIvars]. -/// @return An array of \c FLEXIvar objects. -@property (nonatomic, readonly, class) NSArray *flex_allIvars; - -/// Retrieves an instance variable with the corresponding name. -/// @return An initialized \c FLEXIvar object, or \c nil if the Ivar wasn't found. -+ (FLEXIvar *)flex_ivarNamed:(NSString *)name; - -/// @return The address of the given ivar in the recieving object in memory, -/// or \c NULL if it could not be found. -- (void *)flex_getIvarAddress:(FLEXIvar *)ivar; -/// @return The address of the given ivar in the recieving object in memory, -/// or \c NULL if it could not be found. -- (void *)flex_getIvarAddressByName:(NSString *)name; -/// @discussion This method faster than creating an \c FLEXIvar and calling -/// \c -getIvarAddress: if you already have an \c Ivar on hand -/// @return The address of the given ivar in the recieving object in memory, -/// or \c NULL if it could not be found\. -- (void *)flex_getObjcIvarAddress:(Ivar)ivar; - -/// Sets the value of the given instance variable on the recieving object. -/// @discussion Use only when the target instance variable is an object. -- (void)flex_setIvar:(FLEXIvar *)ivar object:(id)value; -/// Sets the value of the given instance variable on the recieving object. -/// @discussion Use only when the target instance variable is an object. -/// @return \c YES if successful, or \c NO if the instance variable could not be found. -- (BOOL)flex_setIvarByName:(NSString *)name object:(id)value; -/// @discussion Use only when the target instance variable is an object. -/// This method is faster than creating an \c FLEXIvar and calling -/// \c -setIvar: if you already have an \c Ivar on hand. -- (void)flex_setObjcIvar:(Ivar)ivar object:(id)value; - -/// Sets the value of the given instance variable on the recieving object to the -/// \e size number of bytes of data at \e value. -/// @discussion Use one of the other methods if you can help it. -- (void)flex_setIvar:(FLEXIvar *)ivar value:(void *)value size:(size_t)size; -/// Sets the value of the given instance variable on the recieving object to the -/// \e size number of bytes of data at \e value. -/// @discussion Use one of the other methods if you can help it -/// @return \c YES if successful, or \c NO if the instance variable could not be found. -- (BOOL)flex_setIvarByName:(NSString *)name value:(void *)value size:(size_t)size; -/// Sets the value of the given instance variable on the recieving object to the -/// \e size number of bytes of data at \e value. -/// @discussion This is faster than creating an \c FLEXIvar and calling -/// \c -setIvar:value:size if you already have an \c Ivar on hand. -- (void)flex_setObjcIvar:(Ivar)ivar value:(void *)value size:(size_t)size; - -@end - -#pragma mark Properties -@interface NSObject (Properties) - -/// All instance and class properties specific to the recieving class. -/// @discussion This method will only retrieve properties specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXProperty objects. -@property (nonatomic, readonly, class) NSArray *flex_allProperties; -/// All instance properties specific to the recieving class. -/// @discussion This method will only retrieve properties specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXProperty objects. -@property (nonatomic, readonly, class) NSArray *flex_allInstanceProperties; -/// All class properties specific to the recieving class. -/// @discussion This method will only retrieve properties specific to the recieving class. -/// To retrieve instance variables on a parent class, simply call this on \c [self superclass]. -/// @return An array of \c FLEXProperty objects. -@property (nonatomic, readonly, class) NSArray *flex_allClassProperties; - -/// Retrieves the class's property with the given name. -/// @return An initialized \c FLEXProperty object, or \c nil if the property wasn't found. -+ (FLEXProperty *)flex_propertyNamed:(NSString *)name; -/// @return An initialized \c FLEXProperty object, or \c nil if the property wasn't found. -+ (FLEXProperty *)flex_classPropertyNamed:(NSString *)name; - -/// Replaces the given property on the recieving class. -+ (void)flex_replaceProperty:(FLEXProperty *)property; -/// Replaces the given property on the recieving class. Useful for changing a property's attributes. -+ (void)flex_replaceProperty:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.m b/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.m deleted file mode 100644 index d3ba9f0b..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSObject+FLEX_Reflection.m +++ /dev/null @@ -1,426 +0,0 @@ -// -// NSObject+FLEX_Reflection.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "NSObject+FLEX_Reflection.h" -#import "FLEXClassBuilder.h" -#import "FLEXMirror.h" -#import "FLEXProperty.h" -#import "FLEXMethod.h" -#import "FLEXIvar.h" -#import "FLEXProtocol.h" -#import "FLEXPropertyAttributes.h" -#import "NSArray+FLEX.h" -#import "FLEXUtility.h" - - -NSString * FLEXTypeEncodingString(const char *returnType, NSUInteger count, ...) { - if (!returnType) return nil; - - NSMutableString *encoding = [NSMutableString new]; - [encoding appendFormat:@"%s%s%s", returnType, @encode(id), @encode(SEL)]; - - va_list args; - va_start(args, count); - char *type = va_arg(args, char *); - for (NSUInteger i = 0; i < count; i++, type = va_arg(args, char *)) { - [encoding appendFormat:@"%s", type]; - } - va_end(args); - - return encoding.copy; -} - -NSArray *FLEXGetAllSubclasses(Class cls, BOOL includeSelf) { - if (!cls) return nil; - - Class *buffer = NULL; - - int count, size; - do { - count = objc_getClassList(NULL, 0); - buffer = (Class *)realloc(buffer, count * sizeof(*buffer)); - size = objc_getClassList(buffer, count); - } while (size != count); - - NSMutableArray *classes = [NSMutableArray new]; - if (includeSelf) { - [classes addObject:cls]; - } - - for (int i = 0; i < count; i++) { - Class candidate = buffer[i]; - Class superclass = candidate; - while ((superclass = class_getSuperclass(superclass))) { - if (superclass == cls) { - [classes addObject:candidate]; - break; - } - } - } - - free(buffer); - return classes.copy; -} - -NSArray *FLEXGetClassHierarchy(Class cls, BOOL includeSelf) { - if (!cls) return nil; - - NSMutableArray *classes = [NSMutableArray new]; - if (includeSelf) { - [classes addObject:cls]; - } - - while ((cls = [cls superclass])) { - [classes addObject:cls]; - }; - - return classes.copy; -} - -NSArray *FLEXGetConformedProtocols(Class cls) { - if (!cls) return nil; - - unsigned int count = 0; - Protocol *__unsafe_unretained *list = class_copyProtocolList(cls, &count); - NSArray *protocols = [NSArray arrayWithObjects:list count:count]; - free(list); - - return [protocols flex_mapped:^id(Protocol *pro, NSUInteger idx) { - return [FLEXProtocol protocol:pro]; - }]; -} - -NSArray *FLEXGetAllIvars(_Nullable Class cls) { - if (!cls) return nil; - - unsigned int ivcount; - Ivar *objcivars = class_copyIvarList(cls, &ivcount); - NSArray *ivars = [NSArray flex_forEachUpTo:ivcount map:^id(NSUInteger i) { - return [FLEXIvar ivar:objcivars[i]]; - }]; - - free(objcivars); - return ivars; -} - -NSArray *FLEXGetAllProperties(_Nullable Class cls) { - if (!cls) return nil; - - unsigned int pcount; - objc_property_t *objcproperties = class_copyPropertyList(cls, &pcount); - NSArray *properties = [NSArray flex_forEachUpTo:pcount map:^id(NSUInteger i) { - return [FLEXProperty property:objcproperties[i] onClass:cls]; - }]; - - free(objcproperties); - return properties; -} - -NSArray *FLEXGetAllMethods(_Nullable Class cls, BOOL instance) { - if (!cls) return nil; - - unsigned int mcount; - Method *objcmethods = class_copyMethodList(cls, &mcount); - NSArray *methods = [NSArray flex_forEachUpTo:mcount map:^id(NSUInteger i) { - return [FLEXMethod method:objcmethods[i] isInstanceMethod:instance]; - }]; - - free(objcmethods); - return methods; -} - - -#pragma mark NSProxy - -@interface NSProxy (AnyObjectAdditions) @end -@implementation NSProxy (AnyObjectAdditions) - -+ (void)load { FLEX_EXIT_IF_NO_CTORS() - // We need to get all of the methods in this file and add them to NSProxy. - // To do this we we need the class itself and it's metaclass. - // Edit: also add them to Swift._SwiftObject - Class NSProxyClass = [NSProxy class]; - Class NSProxy_meta = object_getClass(NSProxyClass); - Class SwiftObjectClass = ( - NSClassFromString(@"SwiftObject") ?: NSClassFromString(@"Swift._SwiftObject") - ); - - // Copy all of the "flex_" methods from NSObject - id filterFunc = ^BOOL(FLEXMethod *method, NSUInteger idx) { - return [method.name hasPrefix:@"flex_"]; - }; - NSArray *instanceMethods = [NSObject.flex_allInstanceMethods flex_filtered:filterFunc]; - NSArray *classMethods = [NSObject.flex_allClassMethods flex_filtered:filterFunc]; - - FLEXClassBuilder *proxy = [FLEXClassBuilder builderForClass:NSProxyClass]; - FLEXClassBuilder *proxyMeta = [FLEXClassBuilder builderForClass:NSProxy_meta]; - [proxy addMethods:instanceMethods]; - [proxyMeta addMethods:classMethods]; - - if (SwiftObjectClass) { - Class SwiftObject_meta = object_getClass(SwiftObjectClass); - FLEXClassBuilder *swiftObject = [FLEXClassBuilder builderForClass:SwiftObjectClass]; - FLEXClassBuilder *swiftObjectMeta = [FLEXClassBuilder builderForClass:SwiftObject_meta]; - [swiftObject addMethods:instanceMethods]; - [swiftObjectMeta addMethods:classMethods]; - - // So we can put Swift objects into dictionaries... - [swiftObjectMeta addMethods:@[ - [NSObject flex_classMethodNamed:@"copyWithZone:"]] - ]; - } -} - -@end - -#pragma mark Reflection - -@implementation NSObject (Reflection) - -+ (FLEXMirror *)flex_reflection { - return [FLEXMirror reflect:self]; -} - -- (FLEXMirror *)flex_reflection { - return [FLEXMirror reflect:self]; -} - -/// Code borrowed from MAObjCRuntime by Mike Ash -+ (NSArray *)flex_allSubclasses { - return FLEXGetAllSubclasses(self, YES); -} - -- (Class)flex_setClass:(Class)cls { - return object_setClass(self, cls); -} - -+ (Class)flex_metaclass { - return objc_getMetaClass(NSStringFromClass(self.class).UTF8String); -} - -+ (size_t)flex_instanceSize { - return class_getInstanceSize(self.class); -} - -+ (Class)flex_setSuperclass:(Class)superclass { - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdeprecated-declarations" - return class_setSuperclass(self, superclass); - #pragma clang diagnostic pop -} - -+ (NSArray *)flex_classHierarchy { - return FLEXGetClassHierarchy(self, YES); -} - -+ (NSArray *)flex_protocols { - return FLEXGetConformedProtocols(self); -} - -@end - - -#pragma mark Methods - -@implementation NSObject (Methods) - -+ (NSArray *)flex_allMethods { - NSMutableArray *instanceMethods = self.flex_allInstanceMethods.mutableCopy; - [instanceMethods addObjectsFromArray:self.flex_allClassMethods]; - return instanceMethods; -} - -+ (NSArray *)flex_allInstanceMethods { - return FLEXGetAllMethods(self, YES); -} - -+ (NSArray *)flex_allClassMethods { - return FLEXGetAllMethods(self.flex_metaclass, NO) ?: @[]; -} - -+ (FLEXMethod *)flex_methodNamed:(NSString *)name { - Method m = class_getInstanceMethod([self class], NSSelectorFromString(name)); - if (m == NULL) { - return nil; - } - - return [FLEXMethod method:m isInstanceMethod:YES]; -} - -+ (FLEXMethod *)flex_classMethodNamed:(NSString *)name { - Method m = class_getClassMethod([self class], NSSelectorFromString(name)); - if (m == NULL) { - return nil; - } - - return [FLEXMethod method:m isInstanceMethod:NO]; -} - -+ (BOOL)addMethod:(SEL)selector - typeEncoding:(NSString *)typeEncoding - implementation:(IMP)implementaiton - toInstances:(BOOL)instance { - return class_addMethod(instance ? self.class : self.flex_metaclass, selector, implementaiton, typeEncoding.UTF8String); -} - -+ (IMP)replaceImplementationOfMethod:(FLEXMethodBase *)method with:(IMP)implementation useInstance:(BOOL)instance { - return class_replaceMethod(instance ? self.class : self.flex_metaclass, method.selector, implementation, method.typeEncoding.UTF8String); -} - -+ (void)swizzle:(FLEXMethodBase *)original with:(FLEXMethodBase *)other onInstance:(BOOL)instance { - [self swizzleBySelector:original.selector with:other.selector onInstance:instance]; -} - -+ (BOOL)swizzleByName:(NSString *)original with:(NSString *)other onInstance:(BOOL)instance { - SEL originalMethod = NSSelectorFromString(original); - SEL newMethod = NSSelectorFromString(other); - if (originalMethod == 0 || newMethod == 0) { - return NO; - } - - [self swizzleBySelector:originalMethod with:newMethod onInstance:instance]; - return YES; -} - -+ (void)swizzleBySelector:(SEL)original with:(SEL)other onInstance:(BOOL)instance { - Class cls = instance ? self.class : self.flex_metaclass; - Method originalMethod = class_getInstanceMethod(cls, original); - Method newMethod = class_getInstanceMethod(cls, other); - if (class_addMethod(cls, original, method_getImplementation(newMethod), method_getTypeEncoding(newMethod))) { - class_replaceMethod(cls, other, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); - } else { - method_exchangeImplementations(originalMethod, newMethod); - } -} - -@end - - -#pragma mark Ivars - -@implementation NSObject (Ivars) - -+ (NSArray *)flex_allIvars { - return FLEXGetAllIvars(self); -} - -+ (FLEXIvar *)flex_ivarNamed:(NSString *)name { - Ivar i = class_getInstanceVariable([self class], name.UTF8String); - if (i == NULL) { - return nil; - } - - return [FLEXIvar ivar:i]; -} - -#pragma mark Get address -- (void *)flex_getIvarAddress:(FLEXIvar *)ivar { - return (uint8_t *)(__bridge void *)self + ivar.offset; -} - -- (void *)flex_getObjcIvarAddress:(Ivar)ivar { - return (uint8_t *)(__bridge void *)self + ivar_getOffset(ivar); -} - -- (void *)flex_getIvarAddressByName:(NSString *)name { - Ivar ivar = class_getInstanceVariable(self.class, name.UTF8String); - if (!ivar) return 0; - - return (uint8_t *)(__bridge void *)self + ivar_getOffset(ivar); -} - -#pragma mark Set ivar object -- (void)flex_setIvar:(FLEXIvar *)ivar object:(id)value { - object_setIvar(self, ivar.objc_ivar, value); -} - -- (BOOL)flex_setIvarByName:(NSString *)name object:(id)value { - Ivar ivar = class_getInstanceVariable(self.class, name.UTF8String); - if (!ivar) return NO; - - object_setIvar(self, ivar, value); - return YES; -} - -- (void)flex_setObjcIvar:(Ivar)ivar object:(id)value { - object_setIvar(self, ivar, value); -} - -#pragma mark Set ivar value -- (void)flex_setIvar:(FLEXIvar *)ivar value:(void *)value size:(size_t)size { - void *address = [self flex_getIvarAddress:ivar]; - memcpy(address, value, size); -} - -- (BOOL)flex_setIvarByName:(NSString *)name value:(void *)value size:(size_t)size { - Ivar ivar = class_getInstanceVariable(self.class, name.UTF8String); - if (!ivar) return NO; - - [self flex_setObjcIvar:ivar value:value size:size]; - return YES; -} - -- (void)flex_setObjcIvar:(Ivar)ivar value:(void *)value size:(size_t)size { - void *address = [self flex_getObjcIvarAddress:ivar]; - memcpy(address, value, size); -} - -@end - - -#pragma mark Properties - -@implementation NSObject (Properties) - -+ (NSArray *)flex_allProperties { - NSMutableArray *instanceProperties = self.flex_allInstanceProperties.mutableCopy; - [instanceProperties addObjectsFromArray:self.flex_allClassProperties]; - return instanceProperties; -} - -+ (NSArray *)flex_allInstanceProperties { - return FLEXGetAllProperties(self); -} - -+ (NSArray *)flex_allClassProperties { - return FLEXGetAllProperties(self.flex_metaclass) ?: @[]; -} - -+ (FLEXProperty *)flex_propertyNamed:(NSString *)name { - objc_property_t p = class_getProperty([self class], name.UTF8String); - if (p == NULL) { - return nil; - } - - return [FLEXProperty property:p onClass:self]; -} - -+ (FLEXProperty *)flex_classPropertyNamed:(NSString *)name { - objc_property_t p = class_getProperty(object_getClass(self), name.UTF8String); - if (p == NULL) { - return nil; - } - - return [FLEXProperty property:p onClass:object_getClass(self)]; -} - -+ (void)flex_replaceProperty:(FLEXProperty *)property { - [self flex_replaceProperty:property.name attributes:property.attributes]; -} - -+ (void)flex_replaceProperty:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes { - unsigned int count; - objc_property_attribute_t *objc_attributes = [attributes copyAttributesList:&count]; - class_replaceProperty([self class], name.UTF8String, objc_attributes, count); - free(objc_attributes); -} - -@end - - diff --git a/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.h b/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.h deleted file mode 100644 index c1e883c9..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// NSTimer+Blocks.h -// FLEX -// -// Created by Tanner on 3/23/17. -// - -#import - -typedef void (^VoidBlock)(void); - -@interface NSTimer (Blocks) - -+ (instancetype)flex_fireSecondsFromNow:(NSTimeInterval)delay block:(VoidBlock)block; - -// Forward declaration -//+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.m b/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.m deleted file mode 100644 index 2ea92910..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSTimer+FLEX.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// NSTimer+Blocks.m -// FLEX -// -// Created by Tanner on 3/23/17. -// - -#import "NSTimer+FLEX.h" - -@interface Block : NSObject -- (void)invoke; -@end - -#pragma clang diagnostic ignored "-Wincomplete-implementation" -@implementation NSTimer (Blocks) - -+ (instancetype)flex_fireSecondsFromNow:(NSTimeInterval)delay block:(VoidBlock)block { - if (@available(iOS 10, *)) { - return [self scheduledTimerWithTimeInterval:delay repeats:NO block:(id)block]; - } else { - return [self scheduledTimerWithTimeInterval:delay target:block selector:@selector(invoke) userInfo:nil repeats:NO]; - } -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.h b/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.h deleted file mode 100644 index 2e17011e..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.h +++ /dev/null @@ -1,48 +0,0 @@ -// -// NSUserDefaults+FLEX.h -// FLEX -// -// Created by Tanner on 3/10/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -// Only use these if the getters and setters aren't good enough for whatever reason -extern NSString * const kFLEXDefaultsToolbarTopMarginKey; -extern NSString * const kFLEXDefaultsiOSPersistentOSLogKey; -extern NSString * const kFLEXDefaultsHidePropertyIvarsKey; -extern NSString * const kFLEXDefaultsHidePropertyMethodsKey; -extern NSString * const kFLEXDefaultsHidePrivateMethodsKey; -extern NSString * const kFLEXDefaultsShowMethodOverridesKey; -extern NSString * const kFLEXDefaultsHideVariablePreviewsKey; -extern NSString * const kFLEXDefaultsNetworkObserverEnabledKey; -extern NSString * const kFLEXDefaultsNetworkHostDenylistKey; -extern NSString * const kFLEXDefaultsDisableOSLogForceASLKey; -extern NSString * const kFLEXDefaultsRegisterJSONExplorerKey; - -/// All BOOL preferences are NO by default -@interface NSUserDefaults (FLEX) - -- (void)flex_toggleBoolForKey:(NSString *)key; - -@property (nonatomic) double flex_toolbarTopMargin; - -@property (nonatomic) BOOL flex_networkObserverEnabled; -// Not actually stored in defaults, but written to a file -@property (nonatomic) NSArray *flex_networkHostDenylist; - -/// Whether or not to register the object explorer as a JSON viewer on launch -@property (nonatomic) BOOL flex_registerDictionaryJSONViewerOnLaunch; - -/// Disable os_log and re-enable ASL. May break Console.app output. -@property (nonatomic) BOOL flex_disableOSLog; -@property (nonatomic) BOOL flex_cacheOSLogMessages; - -@property (nonatomic) BOOL flex_explorerHidesPropertyIvars; -@property (nonatomic) BOOL flex_explorerHidesPropertyMethods; -@property (nonatomic) BOOL flex_explorerHidesPrivateMethods; -@property (nonatomic) BOOL flex_explorerShowsMethodOverrides; -@property (nonatomic) BOOL flex_explorerHidesVariablePreviews; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.m b/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.m deleted file mode 100644 index 434c0f57..00000000 --- a/BHTwitter/Classes/Utility/Categories/NSUserDefaults+FLEX.m +++ /dev/null @@ -1,179 +0,0 @@ -// -// NSUserDefaults+FLEX.m -// FLEX -// -// Created by Tanner on 3/10/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "NSUserDefaults+FLEX.h" - -NSString * const kFLEXDefaultsToolbarTopMarginKey = @"com.flex.FLEXToolbar.topMargin"; -NSString * const kFLEXDefaultsiOSPersistentOSLogKey = @"com.flipborad.flex.enable_persistent_os_log"; -NSString * const kFLEXDefaultsHidePropertyIvarsKey = @"com.flipboard.FLEX.hide_property_ivars"; -NSString * const kFLEXDefaultsHidePropertyMethodsKey = @"com.flipboard.FLEX.hide_property_methods"; -NSString * const kFLEXDefaultsHidePrivateMethodsKey = @"com.flipboard.FLEX.hide_private_or_namespaced_methods"; -NSString * const kFLEXDefaultsShowMethodOverridesKey = @"com.flipboard.FLEX.show_method_overrides"; -NSString * const kFLEXDefaultsHideVariablePreviewsKey = @"com.flipboard.FLEX.hide_variable_previews"; -NSString * const kFLEXDefaultsNetworkObserverEnabledKey = @"com.flex.FLEXNetworkObserver.enableOnLaunch"; -NSString * const kFLEXDefaultsNetworkHostDenylistKey = @"com.flipboard.FLEX.network_host_denylist"; -NSString * const kFLEXDefaultsDisableOSLogForceASLKey = @"com.flipboard.FLEX.try_disable_os_log"; -NSString * const kFLEXDefaultsRegisterJSONExplorerKey = @"com.flipboard.FLEX.view_json_as_object"; - -#define FLEXDefaultsPathForFile(name) ({ \ - NSArray *paths = NSSearchPathForDirectoriesInDomains( \ - NSLibraryDirectory, NSUserDomainMask, YES \ - ); \ - [paths[0] stringByAppendingPathComponent:@"Preferences"]; \ -}) - -@implementation NSUserDefaults (FLEX) - -#pragma mark Internal - -/// @param filename the name of a plist file without any extension -- (NSString *)flex_defaultsPathForFile:(NSString *)filename { - filename = [filename stringByAppendingPathExtension:@"plist"]; - - NSArray *paths = NSSearchPathForDirectoriesInDomains( - NSLibraryDirectory, NSUserDomainMask, YES - ); - NSString *preferences = [paths[0] stringByAppendingPathComponent:@"Preferences"]; - return [preferences stringByAppendingPathComponent:filename]; -} - -#pragma mark Helper - -- (void)flex_toggleBoolForKey:(NSString *)key { - [self setBool:![self boolForKey:key] forKey:key]; - [NSNotificationCenter.defaultCenter postNotificationName:key object:nil]; -} - -#pragma mark Misc - -- (double)flex_toolbarTopMargin { - if ([self objectForKey:kFLEXDefaultsToolbarTopMarginKey]) { - return [self doubleForKey:kFLEXDefaultsToolbarTopMarginKey]; - } - - return 100; -} - -- (void)setFlex_toolbarTopMargin:(double)margin { - [self setDouble:margin forKey:kFLEXDefaultsToolbarTopMarginKey]; -} - -- (BOOL)flex_networkObserverEnabled { - return [self boolForKey:kFLEXDefaultsNetworkObserverEnabledKey]; -} - -- (void)setFlex_networkObserverEnabled:(BOOL)enabled { - [self setBool:enabled forKey:kFLEXDefaultsNetworkObserverEnabledKey]; -} - -- (NSArray *)flex_networkHostDenylist { - return [NSArray arrayWithContentsOfFile:[ - self flex_defaultsPathForFile:kFLEXDefaultsNetworkHostDenylistKey - ]] ?: @[]; -} - -- (void)setFlex_networkHostDenylist:(NSArray *)denylist { - NSParameterAssert(denylist); - [denylist writeToFile:[ - self flex_defaultsPathForFile:kFLEXDefaultsNetworkHostDenylistKey - ] atomically:YES]; -} - -- (BOOL)flex_registerDictionaryJSONViewerOnLaunch { - return [self boolForKey:kFLEXDefaultsRegisterJSONExplorerKey]; -} - -- (void)setFlex_registerDictionaryJSONViewerOnLaunch:(BOOL)enable { - [self setBool:enable forKey:kFLEXDefaultsRegisterJSONExplorerKey]; -} - -#pragma mark System Log - -- (BOOL)flex_disableOSLog { - return [self boolForKey:kFLEXDefaultsDisableOSLogForceASLKey]; -} - -- (void)setFlex_disableOSLog:(BOOL)disable { - [self setBool:disable forKey:kFLEXDefaultsDisableOSLogForceASLKey]; -} - -- (BOOL)flex_cacheOSLogMessages { - return [self boolForKey:kFLEXDefaultsiOSPersistentOSLogKey]; -} - -- (void)setFlex_cacheOSLogMessages:(BOOL)cache { - [self setBool:cache forKey:kFLEXDefaultsiOSPersistentOSLogKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsiOSPersistentOSLogKey - object:nil - ]; -} - -#pragma mark Object Explorer - -- (BOOL)flex_explorerHidesPropertyIvars { - return [self boolForKey:kFLEXDefaultsHidePropertyIvarsKey]; -} - -- (void)setFlex_explorerHidesPropertyIvars:(BOOL)hide { - [self setBool:hide forKey:kFLEXDefaultsHidePropertyIvarsKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsHidePropertyIvarsKey - object:nil - ]; -} - -- (BOOL)flex_explorerHidesPropertyMethods { - return [self boolForKey:kFLEXDefaultsHidePropertyMethodsKey]; -} - -- (void)setFlex_explorerHidesPropertyMethods:(BOOL)hide { - [self setBool:hide forKey:kFLEXDefaultsHidePropertyMethodsKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsHidePropertyMethodsKey - object:nil - ]; -} - -- (BOOL)flex_explorerHidesPrivateMethods { - return [self boolForKey:kFLEXDefaultsHidePrivateMethodsKey]; -} - -- (void)setFlex_explorerHidesPrivateMethods:(BOOL)show { - [self setBool:show forKey:kFLEXDefaultsHidePrivateMethodsKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsHidePrivateMethodsKey - object:nil - ]; -} - -- (BOOL)flex_explorerShowsMethodOverrides { - return [self boolForKey:kFLEXDefaultsShowMethodOverridesKey]; -} - -- (void)setFlex_explorerShowsMethodOverrides:(BOOL)show { - [self setBool:show forKey:kFLEXDefaultsShowMethodOverridesKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsShowMethodOverridesKey - object:nil - ]; -} - -- (BOOL)flex_explorerHidesVariablePreviews { - return [self boolForKey:kFLEXDefaultsHideVariablePreviewsKey]; -} - -- (void)setFlex_explorerHidesVariablePreviews:(BOOL)hide { - [self setBool:hide forKey:kFLEXDefaultsHideVariablePreviewsKey]; - [NSNotificationCenter.defaultCenter - postNotificationName:kFLEXDefaultsHideVariablePreviewsKey - object:nil - ]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.h b/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.h deleted file mode 100644 index 379502fe..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Cocoa+FLEXShortcuts.h -// Pods -// -// Created by Tanner on 2/24/21. -// -// - -#import - -@interface UIAlertAction (FLEXShortcuts) -@property (nonatomic, readonly) NSString *flex_styleName; -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.m b/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.m deleted file mode 100644 index a9561e2d..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/Cocoa+FLEXShortcuts.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// Cocoa+FLEXShortcuts.m -// Pods -// -// Created by Tanner on 2/24/21. -// -// - -#import "Cocoa+FLEXShortcuts.h" - -@implementation UIAlertAction (FLEXShortcuts) -- (NSString *)flex_styleName { - switch (self.style) { - case UIAlertActionStyleDefault: - return @"Default style"; - case UIAlertActionStyleCancel: - return @"Cancel style"; - case UIAlertActionStyleDestructive: - return @"Destructive style"; - - default: - return [NSString stringWithFormat:@"Unknown (%@)", @(self.style)]; - } -} -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.h b/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.h deleted file mode 100644 index 60d73edb..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// NSDictionary+ObjcRuntime.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import - -@interface NSDictionary (ObjcRuntime) - -/// \c kFLEXPropertyAttributeKeyTypeEncoding is the only required key. -/// Keys representing a boolean value should have a value of \c YES instead of an empty string. -- (NSString *)propertyAttributesString; - -+ (instancetype)attributesDictionaryForProperty:(objc_property_t)property; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.m b/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.m deleted file mode 100644 index d0d96d39..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSDictionary+ObjcRuntime.m +++ /dev/null @@ -1,107 +0,0 @@ -// -// NSDictionary+ObjcRuntime.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "NSDictionary+ObjcRuntime.h" -#import "FLEXRuntimeUtility.h" - -@implementation NSDictionary (ObjcRuntime) - -/// See this link on how to construct a proper attributes string: -/// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html -- (NSString *)propertyAttributesString { - if (!self[kFLEXPropertyAttributeKeyTypeEncoding]) return nil; - - NSMutableString *attributes = [NSMutableString new]; - [attributes appendFormat:@"T%@,", self[kFLEXPropertyAttributeKeyTypeEncoding]]; - - for (NSString *attribute in self.allKeys) { - FLEXPropertyAttribute c = (FLEXPropertyAttribute)[attribute characterAtIndex:0]; - switch (c) { - case FLEXPropertyAttributeTypeEncoding: - break; - case FLEXPropertyAttributeBackingIvarName: - [attributes appendFormat:@"%@%@,", - kFLEXPropertyAttributeKeyBackingIvarName, - self[kFLEXPropertyAttributeKeyBackingIvarName] - ]; - break; - case FLEXPropertyAttributeCopy: - if ([self[kFLEXPropertyAttributeKeyCopy] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyCopy]; - break; - case FLEXPropertyAttributeCustomGetter: - [attributes appendFormat:@"%@%@,", - kFLEXPropertyAttributeKeyCustomGetter, - self[kFLEXPropertyAttributeKeyCustomGetter] - ]; - break; - case FLEXPropertyAttributeCustomSetter: - [attributes appendFormat:@"%@%@,", - kFLEXPropertyAttributeKeyCustomSetter, - self[kFLEXPropertyAttributeKeyCustomSetter] - ]; - break; - case FLEXPropertyAttributeDynamic: - if ([self[kFLEXPropertyAttributeKeyDynamic] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyDynamic]; - break; - case FLEXPropertyAttributeGarbageCollectible: - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyGarbageCollectable]; - break; - case FLEXPropertyAttributeNonAtomic: - if ([self[kFLEXPropertyAttributeKeyNonAtomic] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyNonAtomic]; - break; - case FLEXPropertyAttributeOldTypeEncoding: - [attributes appendFormat:@"%@%@,", - kFLEXPropertyAttributeKeyOldStyleTypeEncoding, - self[kFLEXPropertyAttributeKeyOldStyleTypeEncoding] - ]; - break; - case FLEXPropertyAttributeReadOnly: - if ([self[kFLEXPropertyAttributeKeyReadOnly] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyReadOnly]; - break; - case FLEXPropertyAttributeRetain: - if ([self[kFLEXPropertyAttributeKeyRetain] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyRetain]; - break; - case FLEXPropertyAttributeWeak: - if ([self[kFLEXPropertyAttributeKeyWeak] boolValue]) - [attributes appendFormat:@"%@,", kFLEXPropertyAttributeKeyWeak]; - break; - default: - return nil; - break; - } - } - - [attributes deleteCharactersInRange:NSMakeRange(attributes.length-1, 1)]; - return attributes.copy; -} - -+ (instancetype)attributesDictionaryForProperty:(objc_property_t)property { - NSMutableDictionary *attrs = [NSMutableDictionary new]; - - for (NSString *key in FLEXRuntimeUtility.allPropertyAttributeKeys) { - char *value = property_copyAttributeValue(property, key.UTF8String); - if (value) { - attrs[key] = [[NSString alloc] - initWithBytesNoCopy:value - length:strlen(value) - encoding:NSUTF8StringEncoding - freeWhenDone:YES - ]; - } - } - - return attrs.copy; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.h b/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.h deleted file mode 100644 index f3b660b5..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// NSMapTable+FLEX_Subscripting.h -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface NSMapTable (FLEX_Subscripting) - -- (nullable ObjectType)objectForKeyedSubscript:(KeyType)key; -- (void)setObject:(nullable ObjectType)obj forKeyedSubscript:(KeyType )key; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.m b/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.m deleted file mode 100644 index 47462d40..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSMapTable+FLEX_Subscripting.m +++ /dev/null @@ -1,21 +0,0 @@ -// -// NSMapTable+FLEX_Subscripting.m -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "NSMapTable+FLEX_Subscripting.h" - -@implementation NSMapTable (FLEX_Subscripting) - -- (id)objectForKeyedSubscript:(id)key { - return [self objectForKey:key]; -} - -- (void)setObject:(id)obj forKeyedSubscript:(id)key { - [self setObject:obj forKey:key]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.h b/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.h deleted file mode 100644 index 87194994..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// NSString+FLEX.h -// FLEX -// -// Created by Tanner on 3/26/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" - -@interface NSString (FLEXTypeEncoding) - -///@return whether this type starts with the const specifier -@property (nonatomic, readonly) BOOL flex_typeIsConst; -/// @return the first char in the type encoding that is not the const specifier -@property (nonatomic, readonly) FLEXTypeEncoding flex_firstNonConstType; -/// @return the first char in the type encoding after the pointer specifier, if it is a pointer -@property (nonatomic, readonly) FLEXTypeEncoding flex_pointeeType; -/// @return whether this type is an objc object of any kind, even if it's const -@property (nonatomic, readonly) BOOL flex_typeIsObjectOrClass; -/// @return the class named in this type encoding if it is of the form \c @"MYClass" -@property (nonatomic, readonly) Class flex_typeClass; -/// Includes C strings and selectors as well as regular pointers -@property (nonatomic, readonly) BOOL flex_typeIsNonObjcPointer; - -@end - -@interface NSString (KeyPaths) - -- (NSString *)flex_stringByRemovingLastKeyPathComponent; -- (NSString *)flex_stringByReplacingLastKeyPathComponent:(NSString *)replacement; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.m b/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.m deleted file mode 100644 index 20b25d3d..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSString+FLEX.m +++ /dev/null @@ -1,160 +0,0 @@ -// -// NSString+FLEX.m -// FLEX -// -// Created by Tanner on 3/26/17. -// Copyright © 2017 Tanner Bennett. All rights reserved. -// - -#import "NSString+FLEX.h" - -@interface NSMutableString (Replacement) -- (void)replaceOccurencesOfString:(NSString *)string with:(NSString *)replacement; -- (void)removeLastKeyPathComponent; -@end - -@implementation NSMutableString (Replacement) - -- (void)replaceOccurencesOfString:(NSString *)string with:(NSString *)replacement { - [self replaceOccurrencesOfString:string withString:replacement options:0 range:NSMakeRange(0, self.length)]; -} - -- (void)removeLastKeyPathComponent { - if (![self containsString:@"."]) { - [self deleteCharactersInRange:NSMakeRange(0, self.length)]; - return; - } - - BOOL putEscapesBack = NO; - if ([self containsString:@"\\."]) { - [self replaceOccurencesOfString:@"\\." with:@"\\~"]; - - // Case like "UIKit\.framework" - if (![self containsString:@"."]) { - [self deleteCharactersInRange:NSMakeRange(0, self.length)]; - return; - } - - putEscapesBack = YES; - } - - // Case like "Bund" or "Bundle.cla" - if (![self hasSuffix:@"."]) { - NSUInteger len = self.pathExtension.length; - [self deleteCharactersInRange:NSMakeRange(self.length-len, len)]; - } - - if (putEscapesBack) { - [self replaceOccurencesOfString:@"\\~" with:@"\\."]; - } -} - -@end - -@implementation NSString (FLEXTypeEncoding) - -- (NSCharacterSet *)flex_classNameAllowedCharactersSet { - static NSCharacterSet *classNameAllowedCharactersSet = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSMutableCharacterSet *temp = NSMutableCharacterSet.alphanumericCharacterSet; - [temp addCharactersInString:@"_"]; - classNameAllowedCharactersSet = temp.copy; - }); - - return classNameAllowedCharactersSet; -} - -- (BOOL)flex_typeIsConst { - if (!self.length) return NO; - return [self characterAtIndex:0] == FLEXTypeEncodingConst; -} - -- (FLEXTypeEncoding)flex_firstNonConstType { - if (!self.length) return FLEXTypeEncodingNull; - return [self characterAtIndex:(self.flex_typeIsConst ? 1 : 0)]; -} - -- (FLEXTypeEncoding)flex_pointeeType { - if (!self.length) return FLEXTypeEncodingNull; - - if (self.flex_firstNonConstType == FLEXTypeEncodingPointer) { - return [self characterAtIndex:(self.flex_typeIsConst ? 2 : 1)]; - } - - return FLEXTypeEncodingNull; -} - -- (BOOL)flex_typeIsObjectOrClass { - FLEXTypeEncoding type = self.flex_firstNonConstType; - return type == FLEXTypeEncodingObjcObject || type == FLEXTypeEncodingObjcClass; -} - -- (Class)flex_typeClass { - if (!self.flex_typeIsObjectOrClass) { - return nil; - } - - NSScanner *scan = [NSScanner scannerWithString:self]; - // Skip const - [scan scanString:@"r" intoString:nil]; - // Scan leading @" - if (![scan scanString:@"@\"" intoString:nil]) { - return nil; - } - - // Scan class name - NSString *name = nil; - if (![scan scanCharactersFromSet:self.flex_classNameAllowedCharactersSet intoString:&name]) { - return nil; - } - // Scan trailing quote - if (![scan scanString:@"\"" intoString:nil]) { - return nil; - } - - // Return found class - return NSClassFromString(name); -} - -- (BOOL)flex_typeIsNonObjcPointer { - FLEXTypeEncoding type = self.flex_firstNonConstType; - return type == FLEXTypeEncodingPointer || - type == FLEXTypeEncodingCString || - type == FLEXTypeEncodingSelector; -} - -@end - -@implementation NSString (KeyPaths) - -- (NSString *)flex_stringByRemovingLastKeyPathComponent { - if (![self containsString:@"."]) { - return @""; - } - - NSMutableString *mself = self.mutableCopy; - [mself removeLastKeyPathComponent]; - return mself; -} - -- (NSString *)flex_stringByReplacingLastKeyPathComponent:(NSString *)replacement { - // replacement should not have any escaped '.' in it, - // so we escape all '.' - if ([replacement containsString:@"."]) { - replacement = [replacement stringByReplacingOccurrencesOfString:@"." withString:@"\\."]; - } - - // Case like "Foo" - if (![self containsString:@"."]) { - return [replacement stringByAppendingString:@"."]; - } - - NSMutableString *mself = self.mutableCopy; - [mself removeLastKeyPathComponent]; - [mself appendString:replacement]; - [mself appendString:@"."]; - return mself; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.h b/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.h deleted file mode 100644 index 85cdae69..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// NSString+ObjcRuntime.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/1/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface NSString (Utilities) - -/// A dictionary of property attributes if the receiver is a valid property attributes string. -/// Values are either a string or \c YES. Boolean attributes which are false will not be -/// present in the dictionary. See this link on how to construct a proper attributes string: -/// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html -/// -/// Note: this method doesn't work properly for certain type encodings, and neither does -/// the property_copyAttributeValue function in the runtime itself. Radar: FB7499230 -- (NSDictionary *)propertyAttributes; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.m b/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.m deleted file mode 100644 index 42236649..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/NSString+ObjcRuntime.m +++ /dev/null @@ -1,75 +0,0 @@ -// -// NSString+ObjcRuntime.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/1/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "NSString+ObjcRuntime.h" -#import "FLEXRuntimeUtility.h" - -@implementation NSString (Utilities) - -- (NSString *)stringbyDeletingCharacterAtIndex:(NSUInteger)idx { - NSMutableString *string = self.mutableCopy; - [string replaceCharactersInRange:NSMakeRange(idx, 1) withString:@""]; - return string; -} - -/// See this link on how to construct a proper attributes string: -/// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html -- (NSDictionary *)propertyAttributes { - if (!self.length) return nil; - - NSMutableDictionary *attributes = [NSMutableDictionary new]; - - NSArray *components = [self componentsSeparatedByString:@","]; - for (NSString *attribute in components) { - FLEXPropertyAttribute c = (FLEXPropertyAttribute)[attribute characterAtIndex:0]; - switch (c) { - case FLEXPropertyAttributeTypeEncoding: - // Note: the type encoding here is not always correct. Radar: FB7499230 - attributes[kFLEXPropertyAttributeKeyTypeEncoding] = [attribute stringbyDeletingCharacterAtIndex:0]; - break; - case FLEXPropertyAttributeBackingIvarName: - attributes[kFLEXPropertyAttributeKeyBackingIvarName] = [attribute stringbyDeletingCharacterAtIndex:0]; - break; - case FLEXPropertyAttributeCopy: - attributes[kFLEXPropertyAttributeKeyCopy] = @YES; - break; - case FLEXPropertyAttributeCustomGetter: - attributes[kFLEXPropertyAttributeKeyCustomGetter] = [attribute stringbyDeletingCharacterAtIndex:0]; - break; - case FLEXPropertyAttributeCustomSetter: - attributes[kFLEXPropertyAttributeKeyCustomSetter] = [attribute stringbyDeletingCharacterAtIndex:0]; - break; - case FLEXPropertyAttributeDynamic: - attributes[kFLEXPropertyAttributeKeyDynamic] = @YES; - break; - case FLEXPropertyAttributeGarbageCollectible: - attributes[kFLEXPropertyAttributeKeyGarbageCollectable] = @YES; - break; - case FLEXPropertyAttributeNonAtomic: - attributes[kFLEXPropertyAttributeKeyNonAtomic] = @YES; - break; - case FLEXPropertyAttributeOldTypeEncoding: - attributes[kFLEXPropertyAttributeKeyOldStyleTypeEncoding] = [attribute stringbyDeletingCharacterAtIndex:0]; - break; - case FLEXPropertyAttributeReadOnly: - attributes[kFLEXPropertyAttributeKeyReadOnly] = @YES; - break; - case FLEXPropertyAttributeRetain: - attributes[kFLEXPropertyAttributeKeyRetain] = @YES; - break; - case FLEXPropertyAttributeWeak: - attributes[kFLEXPropertyAttributeKeyWeak] = @YES; - break; - } - } - - return attributes; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.h b/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.h deleted file mode 100644 index c50f7d17..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// UIView+FLEX_Layout.h -// FLEX -// -// Created by Tanner Bennett on 7/18/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -#define Padding(p) UIEdgeInsetsMake(p, p, p, p) - -@interface UIView (FLEX_Layout) - -- (void)flex_centerInView:(UIView *)view; -- (void)flex_pinEdgesTo:(UIView *)view; -- (void)flex_pinEdgesTo:(UIView *)view withInsets:(UIEdgeInsets)insets; -- (void)flex_pinEdgesToSuperview; -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)insets; -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)insets aboveView:(UIView *)sibling; -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)insets belowView:(UIView *)sibling; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.m b/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.m deleted file mode 100644 index c44222ef..00000000 --- a/BHTwitter/Classes/Utility/Categories/Private/UIView+FLEX_Layout.m +++ /dev/null @@ -1,66 +0,0 @@ -// -// UIView+FLEX_Layout.m -// FLEX -// -// Created by Tanner Bennett on 7/18/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIView+FLEX_Layout.h" - -@implementation UIView (FLEX_Layout) - -- (void)flex_centerInView:(UIView *)view { - [NSLayoutConstraint activateConstraints:@[ - [self.centerXAnchor constraintEqualToAnchor:view.centerXAnchor], - [self.centerYAnchor constraintEqualToAnchor:view.centerYAnchor], - ]]; -} - -- (void)flex_pinEdgesTo:(UIView *)view { - [NSLayoutConstraint activateConstraints:@[ - [self.topAnchor constraintEqualToAnchor:view.topAnchor], - [self.leftAnchor constraintEqualToAnchor:view.leftAnchor], - [self.bottomAnchor constraintEqualToAnchor:view.bottomAnchor], - [self.rightAnchor constraintEqualToAnchor:view.rightAnchor], - ]]; -} - -- (void)flex_pinEdgesTo:(UIView *)view withInsets:(UIEdgeInsets)i { - [NSLayoutConstraint activateConstraints:@[ - [self.topAnchor constraintEqualToAnchor:view.topAnchor constant:i.top], - [self.leftAnchor constraintEqualToAnchor:view.leftAnchor constant:i.left], - [self.bottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:-i.bottom], - [self.rightAnchor constraintEqualToAnchor:view.rightAnchor constant:-i.right], - ]]; -} - -- (void)flex_pinEdgesToSuperview { - [self flex_pinEdgesTo:self.superview]; -} - -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)insets { - [self flex_pinEdgesTo:self.superview withInsets:insets]; -} - -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)i aboveView:(UIView *)sibling { - UIView *view = self.superview; - [NSLayoutConstraint activateConstraints:@[ - [self.topAnchor constraintEqualToAnchor:view.topAnchor constant:i.top], - [self.leftAnchor constraintEqualToAnchor:view.leftAnchor constant:i.left], - [self.bottomAnchor constraintEqualToAnchor:sibling.topAnchor constant:-i.bottom], - [self.rightAnchor constraintEqualToAnchor:view.rightAnchor constant:-i.right], - ]]; -} - -- (void)flex_pinEdgesToSuperviewWithInsets:(UIEdgeInsets)i belowView:(UIView *)sibling { - UIView *view = self.superview; - [NSLayoutConstraint activateConstraints:@[ - [self.topAnchor constraintEqualToAnchor:sibling.bottomAnchor constant:i.top], - [self.leftAnchor constraintEqualToAnchor:view.leftAnchor constant:i.left], - [self.bottomAnchor constraintEqualToAnchor:view.bottomAnchor constant:-i.bottom], - [self.rightAnchor constraintEqualToAnchor:view.rightAnchor constant:-i.right], - ]]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.h b/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.h deleted file mode 100644 index 352b9f06..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// UIBarButtonItem+FLEX.h -// FLEX -// -// Created by Tanner on 2/4/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -#define FLEXBarButtonItem(title, tgt, sel) \ - [UIBarButtonItem flex_itemWithTitle:title target:tgt action:sel] -#define FLEXBarButtonItemSystem(item, tgt, sel) \ - [UIBarButtonItem flex_systemItem:UIBarButtonSystemItem##item target:tgt action:sel] - -@interface UIBarButtonItem (FLEX) - -@property (nonatomic, readonly, class) UIBarButtonItem *flex_flexibleSpace; -@property (nonatomic, readonly, class) UIBarButtonItem *flex_fixedSpace; - -+ (instancetype)flex_itemWithCustomView:(UIView *)customView; -+ (instancetype)flex_backItemWithTitle:(NSString *)title; - -+ (instancetype)flex_systemItem:(UIBarButtonSystemItem)item target:(id)target action:(SEL)action; - -+ (instancetype)flex_itemWithTitle:(NSString *)title target:(id)target action:(SEL)action; -+ (instancetype)flex_doneStyleitemWithTitle:(NSString *)title target:(id)target action:(SEL)action; - -+ (instancetype)flex_itemWithImage:(UIImage *)image target:(id)target action:(SEL)action; - -+ (instancetype)flex_disabledSystemItem:(UIBarButtonSystemItem)item; -+ (instancetype)flex_disabledItemWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style; -+ (instancetype)flex_disabledItemWithImage:(UIImage *)image; - -/// @return the receiver -- (UIBarButtonItem *)flex_withTintColor:(UIColor *)tint; - -- (void)_setWidth:(CGFloat)width; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.m b/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.m deleted file mode 100644 index c20fcfff..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIBarButtonItem+FLEX.m +++ /dev/null @@ -1,72 +0,0 @@ -// -// UIBarButtonItem+FLEX.m -// FLEX -// -// Created by Tanner on 2/4/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIBarButtonItem+FLEX.h" - -#pragma clang diagnostic ignored "-Wincomplete-implementation" - -@implementation UIBarButtonItem (FLEX) - -+ (UIBarButtonItem *)flex_flexibleSpace { - return [self flex_systemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; -} - -+ (UIBarButtonItem *)flex_fixedSpace { - UIBarButtonItem *fixed = [self flex_systemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; - fixed.width = 60; - return fixed; -} - -+ (instancetype)flex_systemItem:(UIBarButtonSystemItem)item target:(id)target action:(SEL)action { - return [[self alloc] initWithBarButtonSystemItem:item target:target action:action]; -} - -+ (instancetype)flex_itemWithCustomView:(UIView *)customView { - return [[self alloc] initWithCustomView:customView]; -} - -+ (instancetype)flex_backItemWithTitle:(NSString *)title { - return [self flex_itemWithTitle:title target:nil action:nil]; -} - -+ (instancetype)flex_itemWithTitle:(NSString *)title target:(id)target action:(SEL)action { - return [[self alloc] initWithTitle:title style:UIBarButtonItemStylePlain target:target action:action]; -} - -+ (instancetype)flex_doneStyleitemWithTitle:(NSString *)title target:(id)target action:(SEL)action { - return [[self alloc] initWithTitle:title style:UIBarButtonItemStyleDone target:target action:action]; -} - -+ (instancetype)flex_itemWithImage:(UIImage *)image target:(id)target action:(SEL)action { - return [[self alloc] initWithImage:image style:UIBarButtonItemStylePlain target:target action:action]; -} - -+ (instancetype)flex_disabledSystemItem:(UIBarButtonSystemItem)system { - UIBarButtonItem *item = [self flex_systemItem:system target:nil action:nil]; - item.enabled = NO; - return item; -} - -+ (instancetype)flex_disabledItemWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style { - UIBarButtonItem *item = [self flex_itemWithTitle:title target:nil action:nil]; - item.enabled = NO; - return item; -} - -+ (instancetype)flex_disabledItemWithImage:(UIImage *)image { - UIBarButtonItem *item = [self flex_itemWithImage:image target:nil action:nil]; - item.enabled = NO; - return item; -} - -- (UIBarButtonItem *)flex_withTintColor:(UIColor *)tint { - self.tintColor = tint; - return self; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.h b/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.h deleted file mode 100644 index b668ea2c..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// UIFont+FLEX.h -// FLEX -// -// Created by Tanner Bennett on 12/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface UIFont (FLEX) - -@property (nonatomic, readonly, class) UIFont *flex_defaultTableCellFont; -@property (nonatomic, readonly, class) UIFont *flex_codeFont; -@property (nonatomic, readonly, class) UIFont *flex_smallCodeFont; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.m b/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.m deleted file mode 100644 index 976c37b5..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIFont+FLEX.m +++ /dev/null @@ -1,43 +0,0 @@ -// -// UIFont+FLEX.m -// FLEX -// -// Created by Tanner Bennett on 12/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIFont+FLEX.h" - -#define kFLEXDefaultCellFontSize 12.0 - -@implementation UIFont (FLEX) - -+ (UIFont *)flex_defaultTableCellFont { - static UIFont *defaultTableCellFont = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - defaultTableCellFont = [UIFont systemFontOfSize:kFLEXDefaultCellFontSize]; - }); - - return defaultTableCellFont; -} - -+ (UIFont *)flex_codeFont { - // Actually only available in iOS 13, the SDK headers are wrong - if (@available(iOS 13, *)) { - return [self monospacedSystemFontOfSize:kFLEXDefaultCellFontSize weight:UIFontWeightRegular]; - } else { - return [self fontWithName:@"Menlo-Regular" size:kFLEXDefaultCellFontSize]; - } -} - -+ (UIFont *)flex_smallCodeFont { - // Actually only available in iOS 13, the SDK headers are wrong - if (@available(iOS 13, *)) { - return [self monospacedSystemFontOfSize:self.smallSystemFontSize weight:UIFontWeightRegular]; - } else { - return [self fontWithName:@"Menlo-Regular" size:self.smallSystemFontSize]; - } -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.h b/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.h deleted file mode 100644 index 91b39be4..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// UIGestureRecognizer+Blocks.h -// FLEX -// -// Created by Tanner Bennett on 12/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -typedef void (^GestureBlock)(UIGestureRecognizer *gesture); - - -@interface UIGestureRecognizer (Blocks) - -+ (instancetype)flex_action:(GestureBlock)action; - -@property (nonatomic, setter=flex_setAction:) GestureBlock flex_action; - -@end - diff --git a/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.m b/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.m deleted file mode 100644 index 45ed31b8..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIGestureRecognizer+Blocks.m +++ /dev/null @@ -1,36 +0,0 @@ -// -// UIGestureRecognizer+Blocks.m -// FLEX -// -// Created by Tanner Bennett on 12/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIGestureRecognizer+Blocks.h" -#import - - -@implementation UIGestureRecognizer (Blocks) - -static void * actionKey; - -+ (instancetype)flex_action:(GestureBlock)action { - UIGestureRecognizer *gesture = [[self alloc] initWithTarget:nil action:nil]; - [gesture addTarget:gesture action:@selector(flex_invoke)]; - gesture.flex_action = action; - return gesture; -} - -- (void)flex_invoke { - self.flex_action(self); -} - -- (GestureBlock)flex_action { - return objc_getAssociatedObject(self, &actionKey); -} - -- (void)flex_setAction:(GestureBlock)action { - objc_setAssociatedObject(self, &actionKey, action, OBJC_ASSOCIATION_COPY); -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.h b/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.h deleted file mode 100644 index 4ec59569..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// UIMenu+FLEX.h -// FLEX -// -// Created by Tanner on 1/28/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface UIMenu (FLEX) - -+ (instancetype)flex_inlineMenuWithTitle:(NSString *)title - image:(UIImage *)image - children:(NSArray *)children; - -- (instancetype)flex_collapsed; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.m b/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.m deleted file mode 100644 index c522ca70..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIMenu+FLEX.m +++ /dev/null @@ -1,39 +0,0 @@ -// -// UIMenu+FLEX.m -// FLEX -// -// Created by Tanner on 1/28/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIMenu+FLEX.h" - -@implementation UIMenu (FLEX) - -+ (instancetype)flex_inlineMenuWithTitle:(NSString *)title image:(UIImage *)image children:(NSArray *)children { - return [UIMenu - menuWithTitle:title - image:image - identifier:nil - options:UIMenuOptionsDisplayInline - children:children - ]; -} - -- (instancetype)flex_collapsed { - return [UIMenu - menuWithTitle:@"" - image:nil - identifier:nil - options:UIMenuOptionsDisplayInline - children:@[[UIMenu - menuWithTitle:self.title - image:self.image - identifier:self.identifier - options:0 - children:self.children - ]] - ]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.h b/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.h deleted file mode 100644 index 20f1b0c7..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// UIPasteboard+FLEX.h -// FLEX -// -// Created by Tanner Bennett on 12/9/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface UIPasteboard (FLEX) - -/// For copying an object which could be a string, data, or number -- (void)flex_copy:(id)unknownType; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.m b/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.m deleted file mode 100644 index 3edac662..00000000 --- a/BHTwitter/Classes/Utility/Categories/UIPasteboard+FLEX.m +++ /dev/null @@ -1,31 +0,0 @@ -// -// UIPasteboard+FLEX.m -// FLEX -// -// Created by Tanner Bennett on 12/9/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "UIPasteboard+FLEX.h" - -@implementation UIPasteboard (FLEX) - -- (void)flex_copy:(id)object { - if (!object) { - return; - } - - if ([object isKindOfClass:[NSString class]]) { - UIPasteboard.generalPasteboard.string = object; - } else if([object isKindOfClass:[NSData class]]) { - [UIPasteboard.generalPasteboard setData:object forPasteboardType:@"public.data"]; - } else if ([object isKindOfClass:[NSNumber class]]) { - UIPasteboard.generalPasteboard.string = [object stringValue]; - } else { - // TODO: make this an alert instead of an exception - [NSException raise:NSInternalInconsistencyException - format:@"Tried to copy unsupported type: %@", [object class]]; - } -} - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UITextField+Range.h b/BHTwitter/Classes/Utility/Categories/UITextField+Range.h deleted file mode 100644 index a86a4ce1..00000000 --- a/BHTwitter/Classes/Utility/Categories/UITextField+Range.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// UITextField+Range.h -// FLEX -// -// Created by Tanner on 6/13/17. -// - -#import - -@interface UITextField (Range) - -@property (nonatomic, readonly) NSRange flex_selectedRange; - -@end diff --git a/BHTwitter/Classes/Utility/Categories/UITextField+Range.m b/BHTwitter/Classes/Utility/Categories/UITextField+Range.m deleted file mode 100644 index e1edc1cb..00000000 --- a/BHTwitter/Classes/Utility/Categories/UITextField+Range.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// UITextField+Range.m -// FLEX -// -// Created by Tanner on 6/13/17. -// - -#import "UITextField+Range.h" - -@implementation UITextField (Range) - -- (NSRange)flex_selectedRange { - UITextRange *r = self.selectedTextRange; - if (r) { - NSInteger loc = [self offsetFromPosition:self.beginningOfDocument toPosition:r.start]; - NSInteger len = [self offsetFromPosition:r.start toPosition:r.end]; - return NSMakeRange(loc, len); - } - - return NSMakeRange(NSNotFound, 0); -} - -@end diff --git a/BHTwitter/Classes/Utility/FLEXAlert.h b/BHTwitter/Classes/Utility/FLEXAlert.h deleted file mode 100644 index 86492e6e..00000000 --- a/BHTwitter/Classes/Utility/FLEXAlert.h +++ /dev/null @@ -1,85 +0,0 @@ -// -// FLEXAlert.h -// FLEX -// -// Created by Tanner Bennett on 8/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@class FLEXAlert, FLEXAlertAction; - -typedef void (^FLEXAlertReveal)(void); -typedef void (^FLEXAlertBuilder)(FLEXAlert *make); -typedef FLEXAlert * _Nonnull (^FLEXAlertStringProperty)(NSString * _Nullable); -typedef FLEXAlert * _Nonnull (^FLEXAlertStringArg)(NSString * _Nullable); -typedef FLEXAlert * _Nonnull (^FLEXAlertTextField)(void(^configurationHandler)(UITextField *textField)); -typedef FLEXAlertAction * _Nonnull (^FLEXAlertAddAction)(NSString *title); -typedef FLEXAlertAction * _Nonnull (^FLEXAlertActionStringProperty)(NSString * _Nullable); -typedef FLEXAlertAction * _Nonnull (^FLEXAlertActionProperty)(void); -typedef FLEXAlertAction * _Nonnull (^FLEXAlertActionBOOLProperty)(BOOL); -typedef FLEXAlertAction * _Nonnull (^FLEXAlertActionHandler)(void(^handler)(NSArray *strings)); - -@interface FLEXAlert : NSObject - -/// Shows a simple alert with one button which says "Dismiss" -+ (void)showAlert:(NSString * _Nullable)title message:(NSString * _Nullable)message from:(UIViewController *)viewController; - -/// Construct and display an alert -+ (void)makeAlert:(FLEXAlertBuilder)block showFrom:(UIViewController *)viewController; -/// Construct and display an action sheet-style alert -+ (void)makeSheet:(FLEXAlertBuilder)block - showFrom:(UIViewController *)viewController - source:(id)viewOrBarItem; - -/// Construct an alert -+ (UIAlertController *)makeAlert:(FLEXAlertBuilder)block; -/// Construct an action sheet-style alert -+ (UIAlertController *)makeSheet:(FLEXAlertBuilder)block; - -/// Set the alert's title. -/// -/// Call in succession to append strings to the title. -@property (nonatomic, readonly) FLEXAlertStringProperty title; -/// Set the alert's message. -/// -/// Call in succession to append strings to the message. -@property (nonatomic, readonly) FLEXAlertStringProperty message; -/// Add a button with a given title with the default style and no action. -@property (nonatomic, readonly) FLEXAlertAddAction button; -/// Add a text field with the given (optional) placeholder text. -@property (nonatomic, readonly) FLEXAlertStringArg textField; -/// Add and configure the given text field. -/// -/// Use this if you need to more than set the placeholder, such as -/// supply a delegate, make it secure entry, or change other attributes. -@property (nonatomic, readonly) FLEXAlertTextField configuredTextField; - -@end - -@interface FLEXAlertAction : NSObject - -/// Set the action's title. -/// -/// Call in succession to append strings to the title. -@property (nonatomic, readonly) FLEXAlertActionStringProperty title; -/// Make the action destructive. It appears with red text. -@property (nonatomic, readonly) FLEXAlertActionProperty destructiveStyle; -/// Make the action cancel-style. It appears with a bolder font. -@property (nonatomic, readonly) FLEXAlertActionProperty cancelStyle; -/// Enable or disable the action. Enabled by default. -@property (nonatomic, readonly) FLEXAlertActionBOOLProperty enabled; -/// Give the button an action. The action takes an array of text field strings. -@property (nonatomic, readonly) FLEXAlertActionHandler handler; -/// Access the underlying UIAlertAction, should you need to change it while -/// the encompassing alert is being displayed. For example, you may want to -/// enable or disable a button based on the input of some text fields in the alert. -/// Do not call this more than once per instance. -@property (nonatomic, readonly) UIAlertAction *action; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/FLEXAlert.m b/BHTwitter/Classes/Utility/FLEXAlert.m deleted file mode 100644 index 293a9e62..00000000 --- a/BHTwitter/Classes/Utility/FLEXAlert.m +++ /dev/null @@ -1,233 +0,0 @@ -// -// FLEXAlert.m -// FLEX -// -// Created by Tanner Bennett on 8/20/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXAlert.h" -#import "FLEXMacros.h" - -@interface FLEXAlert () -@property (nonatomic, readonly) UIAlertController *_controller; -@property (nonatomic, readonly) NSMutableArray *_actions; -@end - -#define FLEXAlertActionMutationAssertion() \ -NSAssert(!self._action, @"Cannot mutate action after retreiving underlying UIAlertAction"); - -@interface FLEXAlertAction () -@property (nonatomic) UIAlertController *_controller; -@property (nonatomic) NSString *_title; -@property (nonatomic) UIAlertActionStyle _style; -@property (nonatomic) BOOL _disable; -@property (nonatomic) void(^_handler)(UIAlertAction *action); -@property (nonatomic) UIAlertAction *_action; -@end - -@implementation FLEXAlert - -+ (void)showAlert:(NSString *)title message:(NSString *)message from:(UIViewController *)viewController { - [self makeAlert:^(FLEXAlert *make) { - make.title(title).message(message).button(@"Dismiss").cancelStyle(); - } showFrom:viewController]; -} - -#pragma mark Initialization - -- (instancetype)initWithController:(UIAlertController *)controller { - self = [super init]; - if (self) { - __controller = controller; - __actions = [NSMutableArray new]; - } - - return self; -} - -+ (UIAlertController *)make:(FLEXAlertBuilder)block withStyle:(UIAlertControllerStyle)style { - // Create alert builder - FLEXAlert *alert = [[self alloc] initWithController: - [UIAlertController alertControllerWithTitle:nil message:nil preferredStyle:style] - ]; - - // Configure alert - block(alert); - - // Add actions - for (FLEXAlertAction *builder in alert._actions) { - [alert._controller addAction:builder.action]; - } - - return alert._controller; -} - -+ (void)make:(FLEXAlertBuilder)block - withStyle:(UIAlertControllerStyle)style - showFrom:(UIViewController *)viewController - source:(id)viewOrBarItem { - UIAlertController *alert = [self make:block withStyle:style]; - if ([viewOrBarItem isKindOfClass:[UIBarButtonItem class]]) { - alert.popoverPresentationController.barButtonItem = viewOrBarItem; - } else if ([viewOrBarItem isKindOfClass:[UIView class]]) { - alert.popoverPresentationController.sourceView = viewOrBarItem; - alert.popoverPresentationController.sourceRect = [viewOrBarItem bounds]; - } else if (viewOrBarItem) { - NSParameterAssert( - [viewOrBarItem isKindOfClass:[UIBarButtonItem class]] || - [viewOrBarItem isKindOfClass:[UIView class]] || - !viewOrBarItem - ); - } - [viewController presentViewController:alert animated:YES completion:nil]; -} - -+ (void)makeAlert:(FLEXAlertBuilder)block showFrom:(UIViewController *)controller { - [self make:block withStyle:UIAlertControllerStyleAlert showFrom:controller source:nil]; -} - -+ (void)makeSheet:(FLEXAlertBuilder)block showFrom:(UIViewController *)controller { - [self make:block withStyle:UIAlertControllerStyleActionSheet showFrom:controller source:nil]; -} - -/// Construct and display an action sheet-style alert -+ (void)makeSheet:(FLEXAlertBuilder)block - showFrom:(UIViewController *)controller - source:(id)viewOrBarItem { - [self make:block - withStyle:UIAlertControllerStyleActionSheet - showFrom:controller - source:viewOrBarItem]; -} - -+ (UIAlertController *)makeAlert:(FLEXAlertBuilder)block { - return [self make:block withStyle:UIAlertControllerStyleAlert]; -} - -+ (UIAlertController *)makeSheet:(FLEXAlertBuilder)block { - return [self make:block withStyle:UIAlertControllerStyleActionSheet]; -} - -#pragma mark Configuration - -- (FLEXAlertStringProperty)title { - return ^FLEXAlert *(NSString *title) { - if (self._controller.title) { - self._controller.title = [self._controller.title stringByAppendingString:title ?: @""]; - } else { - self._controller.title = title; - } - return self; - }; -} - -- (FLEXAlertStringProperty)message { - return ^FLEXAlert *(NSString *message) { - if (self._controller.message) { - self._controller.message = [self._controller.message stringByAppendingString:message ?: @""]; - } else { - self._controller.message = message; - } - return self; - }; -} - -- (FLEXAlertAddAction)button { - return ^FLEXAlertAction *(NSString *title) { - FLEXAlertAction *action = FLEXAlertAction.new.title(title); - action._controller = self._controller; - [self._actions addObject:action]; - return action; - }; -} - -- (FLEXAlertStringArg)textField { - return ^FLEXAlert *(NSString *placeholder) { - [self._controller addTextFieldWithConfigurationHandler:^(UITextField *textField) { - textField.placeholder = placeholder; - }]; - - return self; - }; -} - -- (FLEXAlertTextField)configuredTextField { - return ^FLEXAlert *(void(^configurationHandler)(UITextField *)) { - [self._controller addTextFieldWithConfigurationHandler:configurationHandler]; - return self; - }; -} - -@end - -@implementation FLEXAlertAction - -- (FLEXAlertActionStringProperty)title { - return ^FLEXAlertAction *(NSString *title) { - FLEXAlertActionMutationAssertion(); - if (self._title) { - self._title = [self._title stringByAppendingString:title ?: @""]; - } else { - self._title = title; - } - return self; - }; -} - -- (FLEXAlertActionProperty)destructiveStyle { - return ^FLEXAlertAction *() { - FLEXAlertActionMutationAssertion(); - self._style = UIAlertActionStyleDestructive; - return self; - }; -} - -- (FLEXAlertActionProperty)cancelStyle { - return ^FLEXAlertAction *() { - FLEXAlertActionMutationAssertion(); - self._style = UIAlertActionStyleCancel; - return self; - }; -} - -- (FLEXAlertActionBOOLProperty)enabled { - return ^FLEXAlertAction *(BOOL enabled) { - FLEXAlertActionMutationAssertion(); - self._disable = !enabled; - return self; - }; -} - -- (FLEXAlertActionHandler)handler { - return ^FLEXAlertAction *(void(^handler)(NSArray *)) { - FLEXAlertActionMutationAssertion(); - - // Get weak reference to the alert to avoid block <--> alert retain cycle - UIAlertController *controller = self._controller; weakify(controller) - self._handler = ^(UIAlertAction *action) { strongify(controller) - // Strongify that reference and pass the text field strings to the handler - NSArray *strings = [controller.textFields valueForKeyPath:@"text"]; - handler(strings); - }; - - return self; - }; -} - -- (UIAlertAction *)action { - if (self._action) { - return self._action; - } - - self._action = [UIAlertAction - actionWithTitle:self._title - style:self._style - handler:self._handler - ]; - self._action.enabled = !self._disable; - - return self._action; -} - -@end diff --git a/BHTwitter/Classes/Utility/FLEXColor.h b/BHTwitter/Classes/Utility/FLEXColor.h deleted file mode 100644 index e472ba4b..00000000 --- a/BHTwitter/Classes/Utility/FLEXColor.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// FLEXColor.h -// FLEX -// -// Created by Benny Wong on 6/18/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXColor : NSObject - -@property (readonly, class) UIColor *primaryBackgroundColor; -+ (UIColor *)primaryBackgroundColorWithAlpha:(CGFloat)alpha; - -@property (readonly, class) UIColor *secondaryBackgroundColor; -+ (UIColor *)secondaryBackgroundColorWithAlpha:(CGFloat)alpha; - -@property (readonly, class) UIColor *tertiaryBackgroundColor; -+ (UIColor *)tertiaryBackgroundColorWithAlpha:(CGFloat)alpha; - -@property (readonly, class) UIColor *groupedBackgroundColor; -+ (UIColor *)groupedBackgroundColorWithAlpha:(CGFloat)alpha; - -@property (readonly, class) UIColor *secondaryGroupedBackgroundColor; -+ (UIColor *)secondaryGroupedBackgroundColorWithAlpha:(CGFloat)alpha; - -// Text colors -@property (readonly, class) UIColor *primaryTextColor; -@property (readonly, class) UIColor *deemphasizedTextColor; - -// UI element colors -@property (readonly, class) UIColor *tintColor; -@property (readonly, class) UIColor *scrollViewBackgroundColor; -@property (readonly, class) UIColor *iconColor; -@property (readonly, class) UIColor *borderColor; -@property (readonly, class) UIColor *toolbarItemHighlightedColor; -@property (readonly, class) UIColor *toolbarItemSelectedColor; -@property (readonly, class) UIColor *hairlineColor; -@property (readonly, class) UIColor *destructiveColor; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/FLEXColor.m b/BHTwitter/Classes/Utility/FLEXColor.m deleted file mode 100644 index 95a995bf..00000000 --- a/BHTwitter/Classes/Utility/FLEXColor.m +++ /dev/null @@ -1,136 +0,0 @@ -// -// FLEXColor.m -// FLEX -// -// Created by Benny Wong on 6/18/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXUtility.h" - -#define FLEXDynamicColor(dynamic, static) ({ \ - UIColor *c; \ - if (@available(iOS 13.0, *)) { \ - c = [UIColor dynamic]; \ - } else { \ - c = [UIColor static]; \ - } \ - c; \ -}); - -@implementation FLEXColor - -#pragma mark - Background Colors - -+ (UIColor *)primaryBackgroundColor { - return FLEXDynamicColor(systemBackgroundColor, whiteColor); -} - -+ (UIColor *)primaryBackgroundColorWithAlpha:(CGFloat)alpha { - return [[self primaryBackgroundColor] colorWithAlphaComponent:alpha]; -} - -+ (UIColor *)secondaryBackgroundColor { - return FLEXDynamicColor( - secondarySystemBackgroundColor, - colorWithHue:2.0/3.0 saturation:0.02 brightness:0.97 alpha:1 - ); -} - -+ (UIColor *)secondaryBackgroundColorWithAlpha:(CGFloat)alpha { - return [[self secondaryBackgroundColor] colorWithAlphaComponent:alpha]; -} - -+ (UIColor *)tertiaryBackgroundColor { - // All the background/fill colors are varying shades - // of white and black with really low alpha levels. - // We use systemGray4Color instead to avoid alpha issues. - return FLEXDynamicColor(systemGray4Color, lightGrayColor); -} - -+ (UIColor *)tertiaryBackgroundColorWithAlpha:(CGFloat)alpha { - return [[self tertiaryBackgroundColor] colorWithAlphaComponent:alpha]; -} - -+ (UIColor *)groupedBackgroundColor { - return FLEXDynamicColor( - systemGroupedBackgroundColor, - colorWithHue:2.0/3.0 saturation:0.02 brightness:0.97 alpha:1 - ); -} - -+ (UIColor *)groupedBackgroundColorWithAlpha:(CGFloat)alpha { - return [[self groupedBackgroundColor] colorWithAlphaComponent:alpha]; -} - -+ (UIColor *)secondaryGroupedBackgroundColor { - return FLEXDynamicColor(secondarySystemGroupedBackgroundColor, whiteColor); -} - -+ (UIColor *)secondaryGroupedBackgroundColorWithAlpha:(CGFloat)alpha { - return [[self secondaryGroupedBackgroundColor] colorWithAlphaComponent:alpha]; -} - -#pragma mark - Text colors - -+ (UIColor *)primaryTextColor { - return FLEXDynamicColor(labelColor, blackColor); -} - -+ (UIColor *)deemphasizedTextColor { - return FLEXDynamicColor(secondaryLabelColor, lightGrayColor); -} - -#pragma mark - UI Element Colors - -+ (UIColor *)tintColor { - #if FLEX_AT_LEAST_IOS13_SDK - if (@available(iOS 13.0, *)) { - return UIColor.systemBlueColor; - } else { - return UIApplication.sharedApplication.keyWindow.tintColor; - } - #else - return UIApplication.sharedApplication.keyWindow.tintColor; - #endif -} - -+ (UIColor *)scrollViewBackgroundColor { - return FLEXDynamicColor( - systemGroupedBackgroundColor, - colorWithHue:2.0/3.0 saturation:0.02 brightness:0.95 alpha:1 - ); -} - -+ (UIColor *)iconColor { - return FLEXDynamicColor(labelColor, blackColor); -} - -+ (UIColor *)borderColor { - return [self primaryBackgroundColor]; -} - -+ (UIColor *)toolbarItemHighlightedColor { - return FLEXDynamicColor( - quaternaryLabelColor, - colorWithHue:2.0/3.0 saturation:0.1 brightness:0.25 alpha:0.6 - ); -} - -+ (UIColor *)toolbarItemSelectedColor { - return FLEXDynamicColor( - secondaryLabelColor, - colorWithHue:2.0/3.0 saturation:0.1 brightness:0.25 alpha:0.68 - ); -} - -+ (UIColor *)hairlineColor { - return FLEXDynamicColor(systemGray3Color, colorWithWhite:0.75 alpha:1); -} - -+ (UIColor *)destructiveColor { - return FLEXDynamicColor(systemRedColor, redColor); -} - -@end diff --git a/BHTwitter/Classes/Utility/FLEXHeapEnumerator.h b/BHTwitter/Classes/Utility/FLEXHeapEnumerator.h deleted file mode 100644 index 5c1545bc..00000000 --- a/BHTwitter/Classes/Utility/FLEXHeapEnumerator.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// FLEXHeapEnumerator.h -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -@class FLEXObjectRef; - -typedef void (^flex_object_enumeration_block_t)(__unsafe_unretained id object, __unsafe_unretained Class actualClass); - -@interface FLEXHeapEnumerator : NSObject - -+ (void)enumerateLiveObjectsUsingBlock:(flex_object_enumeration_block_t)block; - -/// Returned references are not validated beyond containing a valid isa. -/// To validate them yourself, pass each reference's object to \c FLEXPointerIsValidObjcObject -+ (NSArray *)instancesOfClassWithName:(NSString *)className retained:(BOOL)retain; -+ (NSArray *)subclassesOfClassWithName:(NSString *)className; -/// Returned references have been validated via \c FLEXPointerIsValidObjcObject -+ (NSArray *)objectsWithReferencesToObject:(id)object retained:(BOOL)retain; - -@end diff --git a/BHTwitter/Classes/Utility/FLEXHeapEnumerator.m b/BHTwitter/Classes/Utility/FLEXHeapEnumerator.m deleted file mode 100644 index 11d344bd..00000000 --- a/BHTwitter/Classes/Utility/FLEXHeapEnumerator.m +++ /dev/null @@ -1,197 +0,0 @@ -// -// FLEXHeapEnumerator.m -// Flipboard -// -// Created by Ryan Olson on 5/28/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXHeapEnumerator.h" -#import "FLEXObjcInternal.h" -#import "FLEXObjectRef.h" -#import "NSObject+FLEX_Reflection.h" -#import "NSString+FLEX.h" -#import -#import -#import - -static CFMutableSetRef registeredClasses; - -// Mimics the objective-c object structure for checking if a range of memory is an object. -typedef struct { - Class isa; -} flex_maybe_object_t; - -@implementation FLEXHeapEnumerator - -static void range_callback(task_t task, void *context, unsigned type, vm_range_t *ranges, unsigned rangeCount) { - if (!context) { - return; - } - - for (unsigned int i = 0; i < rangeCount; i++) { - vm_range_t range = ranges[i]; - flex_maybe_object_t *tryObject = (flex_maybe_object_t *)range.address; - Class tryClass = NULL; -#ifdef __arm64__ - // See http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html - extern uint64_t objc_debug_isa_class_mask WEAK_IMPORT_ATTRIBUTE; - tryClass = (__bridge Class)((void *)((uint64_t)tryObject->isa & objc_debug_isa_class_mask)); -#else - tryClass = tryObject->isa; -#endif - // If the class pointer matches one in our set of class pointers from the runtime, then we should have an object. - if (CFSetContainsValue(registeredClasses, (__bridge const void *)(tryClass))) { - (*(flex_object_enumeration_block_t __unsafe_unretained *)context)((__bridge id)tryObject, tryClass); - } - } -} - -static kern_return_t reader(__unused task_t remote_task, vm_address_t remote_address, __unused vm_size_t size, void **local_memory) { - *local_memory = (void *)remote_address; - return KERN_SUCCESS; -} - -+ (void)enumerateLiveObjectsUsingBlock:(flex_object_enumeration_block_t)block { - if (!block) { - return; - } - - // Refresh the class list on every call in case classes are added to the runtime. - [self updateRegisteredClasses]; - - // Inspired by: - // https://llvm.org/svn/llvm-project/lldb/tags/RELEASE_34/final/examples/darwin/heap_find/heap/heap_find.cpp - // https://gist.github.com/samdmarshall/17f4e66b5e2e579fd396 - - vm_address_t *zones = NULL; - unsigned int zoneCount = 0; - kern_return_t result = malloc_get_all_zones(TASK_NULL, reader, &zones, &zoneCount); - - if (result == KERN_SUCCESS) { - for (unsigned int i = 0; i < zoneCount; i++) { - malloc_zone_t *zone = (malloc_zone_t *)zones[i]; - malloc_introspection_t *introspection = zone->introspect; - - // This may explain why some zone functions are - // sometimes invalid; perhaps not all zones support them? - if (!introspection) { - continue; - } - - void (*lock_zone)(malloc_zone_t *zone) = introspection->force_lock; - void (*unlock_zone)(malloc_zone_t *zone) = introspection->force_unlock; - - // Callback has to unlock the zone so we freely allocate memory inside the given block - flex_object_enumeration_block_t callback = ^(__unsafe_unretained id object, __unsafe_unretained Class actualClass) { - unlock_zone(zone); - block(object, actualClass); - lock_zone(zone); - }; - - BOOL lockZoneValid = FLEXPointerIsReadable(lock_zone); - BOOL unlockZoneValid = FLEXPointerIsReadable(unlock_zone); - - // There is little documentation on when and why - // any of these function pointers might be NULL - // or garbage, so we resort to checking for NULL - // and whether the pointer is readable - if (introspection->enumerator && lockZoneValid && unlockZoneValid) { - lock_zone(zone); - introspection->enumerator(TASK_NULL, (void *)&callback, MALLOC_PTR_IN_USE_RANGE_TYPE, (vm_address_t)zone, reader, &range_callback); - unlock_zone(zone); - } - } - } -} - -+ (void)updateRegisteredClasses { - if (!registeredClasses) { - registeredClasses = CFSetCreateMutable(NULL, 0, NULL); - } else { - CFSetRemoveAllValues(registeredClasses); - } - unsigned int count = 0; - Class *classes = objc_copyClassList(&count); - for (unsigned int i = 0; i < count; i++) { - CFSetAddValue(registeredClasses, (__bridge const void *)(classes[i])); - } - free(classes); -} - -+ (NSArray *)instancesOfClassWithName:(NSString *)className retained:(BOOL)retain { - const char *classNameCString = className.UTF8String; - NSMutableArray *instances = [NSMutableArray new]; - [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id object, __unsafe_unretained Class actualClass) { - if (strcmp(classNameCString, class_getName(actualClass)) == 0) { - // Note: objects of certain classes crash when retain is called. - // It is up to the user to avoid tapping into instance lists for these classes. - // Ex. OS_dispatch_queue_specific_queue - // In the future, we could provide some kind of warning for classes that are known to be problematic. - if (malloc_size((__bridge const void *)(object)) > 0) { - [instances addObject:object]; - } - } - }]; - - NSArray *references = [FLEXObjectRef referencingAll:instances retained:retain]; - return references; -} - -+ (NSArray *)subclassesOfClassWithName:(NSString *)className { - NSArray *classes = FLEXGetAllSubclasses(NSClassFromString(className), NO); - NSArray *references = [FLEXObjectRef referencingClasses:classes]; - return references; -} - -+ (NSArray *)objectsWithReferencesToObject:(id)object retained:(BOOL)retain { - static Class SwiftObjectClass = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - SwiftObjectClass = NSClassFromString(@"SwiftObject"); - if (!SwiftObjectClass) { - SwiftObjectClass = NSClassFromString(@"Swift._SwiftObject"); - } - }); - - NSMutableArray *instances = [NSMutableArray new]; - [FLEXHeapEnumerator enumerateLiveObjectsUsingBlock:^(__unsafe_unretained id tryObject, __unsafe_unretained Class actualClass) { - // Skip known-invalid objects - if (!FLEXPointerIsValidObjcObject((__bridge void *)tryObject)) { - return; - } - - // Get all the ivars on the object. Start with the class and and travel up the - // inheritance chain. Once we find a match, record it and move on to the next object. - // There's no reason to find multiple matches within the same object. - Class tryClass = actualClass; - while (tryClass) { - unsigned int ivarCount = 0; - Ivar *ivars = class_copyIvarList(tryClass, &ivarCount); - - for (unsigned int ivarIndex = 0; ivarIndex < ivarCount; ivarIndex++) { - Ivar ivar = ivars[ivarIndex]; - NSString *typeEncoding = @(ivar_getTypeEncoding(ivar) ?: ""); - - if (typeEncoding.flex_typeIsObjectOrClass) { - ptrdiff_t offset = ivar_getOffset(ivar); - uintptr_t *fieldPointer = (__bridge void *)tryObject + offset; - - if (*fieldPointer == (uintptr_t)(__bridge void *)object) { - NSString *ivarName = @(ivar_getName(ivar) ?: "???"); - id ref = [FLEXObjectRef referencing:tryObject ivar:ivarName retained:retain]; - [instances addObject:ref]; - return; - } - } - } - - free(ivars); - tryClass = class_getSuperclass(tryClass); - } - }]; - - return instances; -} - -@end diff --git a/BHTwitter/Classes/Utility/FLEXMacros.h b/BHTwitter/Classes/Utility/FLEXMacros.h deleted file mode 100644 index 373c9c56..00000000 --- a/BHTwitter/Classes/Utility/FLEXMacros.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// FLEXMacros.h -// FLEX -// -// Created by Tanner on 3/12/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#ifndef FLEXMacros_h -#define FLEXMacros_h - - -#define flex_keywordify class NSObject; -#define ctor flex_keywordify __attribute__((constructor)) void __flex_ctor_##__LINE__() -#define dtor flex_keywordify __attribute__((destructor)) void __flex_dtor_##__LINE__() - -#ifndef strongify - -#define weakify(var) __weak __typeof(var) __weak__##var = var; - -#define strongify(var) \ -_Pragma("clang diagnostic push") \ -_Pragma("clang diagnostic ignored \"-Wshadow\"") \ -__strong typeof(var) var = __weak__##var; \ -_Pragma("clang diagnostic pop") - -#endif - -// A macro to check if we are running in a test environment -#define FLEX_IS_TESTING() (NSClassFromString(@"XCTest") != nil) - -/// Whether we want the majority of constructors to run upon load or not. -extern BOOL FLEXConstructorsShouldRun(void); - -/// A macro to return from the current procedure if we don't want to run constructors -#define FLEX_EXIT_IF_NO_CTORS() if (!FLEXConstructorsShouldRun()) return; - -/// Rounds down to the nearest "point" coordinate -NS_INLINE CGFloat FLEXFloor(CGFloat x) { - return floor(UIScreen.mainScreen.scale * (x)) / UIScreen.mainScreen.scale; -} - -/// Returns the given number of points in pixels -NS_INLINE CGFloat FLEXPointsToPixels(CGFloat points) { - return points / UIScreen.mainScreen.scale; -} - -/// Creates a CGRect with all members rounded down to the nearest "point" coordinate -NS_INLINE CGRect FLEXRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height) { - return CGRectMake(FLEXFloor(x), FLEXFloor(y), FLEXFloor(width), FLEXFloor(height)); -} - -/// Adjusts the origin of an existing rect -NS_INLINE CGRect FLEXRectSetOrigin(CGRect r, CGPoint origin) { - r.origin = origin; return r; -} - -/// Adjusts the size of an existing rect -NS_INLINE CGRect FLEXRectSetSize(CGRect r, CGSize size) { - r.size = size; return r; -} - -/// Adjusts the origin.x of an existing rect -NS_INLINE CGRect FLEXRectSetX(CGRect r, CGFloat x) { - r.origin.x = x; return r; -} - -/// Adjusts the origin.y of an existing rect -NS_INLINE CGRect FLEXRectSetY(CGRect r, CGFloat y) { - r.origin.y = y ; return r; -} - -/// Adjusts the size.width of an existing rect -NS_INLINE CGRect FLEXRectSetWidth(CGRect r, CGFloat width) { - r.size.width = width; return r; -} - -/// Adjusts the size.height of an existing rect -NS_INLINE CGRect FLEXRectSetHeight(CGRect r, CGFloat height) { - r.size.height = height; return r; -} - -#define FLEXPluralString(count, plural, singular) [NSString \ - stringWithFormat:@"%@ %@", @(count), (count == 1 ? singular : plural) \ -] - -#define FLEXPluralFormatString(count, pluralFormat, singularFormat) [NSString \ - stringWithFormat:(count == 1 ? singularFormat : pluralFormat), @(count) \ -] - -#define flex_dispatch_after(nSeconds, onQueue, block) \ - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, \ - (int64_t)(nSeconds * NSEC_PER_SEC)), onQueue, block) - -#endif /* FLEXMacros_h */ diff --git a/BHTwitter/Classes/Utility/FLEXResources.h b/BHTwitter/Classes/Utility/FLEXResources.h deleted file mode 100644 index 563be1e4..00000000 --- a/BHTwitter/Classes/Utility/FLEXResources.h +++ /dev/null @@ -1,59 +0,0 @@ -// -// FLEXResources.h -// FLEX -// -// Created by Ryan Olson on 6/8/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXResources : NSObject - -#pragma mark - FLEX Toolbar Icons - -@property (readonly, class) UIImage *closeIcon; -@property (readonly, class) UIImage *dragHandle; -@property (readonly, class) UIImage *globalsIcon; -@property (readonly, class) UIImage *hierarchyIcon; -@property (readonly, class) UIImage *recentIcon; -@property (readonly, class) UIImage *moveIcon; -@property (readonly, class) UIImage *selectIcon; - -#pragma mark - Toolbar Icons - -@property (readonly, class) UIImage *bookmarksIcon; -@property (readonly, class) UIImage *openTabsIcon; -@property (readonly, class) UIImage *moreIcon; -@property (readonly, class) UIImage *gearIcon; -@property (readonly, class) UIImage *scrollToBottomIcon; - -#pragma mark - Content Type Icons - -@property (readonly, class) UIImage *jsonIcon; -@property (readonly, class) UIImage *textPlainIcon; -@property (readonly, class) UIImage *htmlIcon; -@property (readonly, class) UIImage *audioIcon; -@property (readonly, class) UIImage *jsIcon; -@property (readonly, class) UIImage *plistIcon; -@property (readonly, class) UIImage *textIcon; -@property (readonly, class) UIImage *videoIcon; -@property (readonly, class) UIImage *xmlIcon; -@property (readonly, class) UIImage *binaryIcon; - -#pragma mark - 3D Explorer Icons - -@property (readonly, class) UIImage *toggle2DIcon; -@property (readonly, class) UIImage *toggle3DIcon; -@property (readonly, class) UIImage *rangeSliderLeftHandle; -@property (readonly, class) UIImage *rangeSliderRightHandle; -@property (readonly, class) UIImage *rangeSliderTrack; -@property (readonly, class) UIImage *rangeSliderFill; - -#pragma mark - Misc Icons - -@property (readonly, class) UIImage *checkerPattern; -@property (readonly, class) UIColor *checkerPatternColor; -@property (readonly, class) UIImage *hierarchyIndentPattern; - -@end diff --git a/BHTwitter/Classes/Utility/FLEXResources.m b/BHTwitter/Classes/Utility/FLEXResources.m deleted file mode 100644 index c90466e3..00000000 --- a/BHTwitter/Classes/Utility/FLEXResources.m +++ /dev/null @@ -1,8861 +0,0 @@ -// -// FLEXResources.m -// FLEX -// -// Created by Ryan Olson on 6/8/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXResources.h" - -// Useful regex for formatting pasted hex -// -// To replace something with a newline, you need to manually copy -// a newline from a text editor and paste it into the replace box. -// For the "find" box, you can simply copy and paste the regexes below. -// -// Split into rows of 16: -// ((?:0x[a-f\d][a-f\d], ){16}) -// Replace with: \n $1 -// -// Split last greater-than-16 row into two rows of 16 and less than 16: -// ((?:0x[a-f\d][a-f\d], ){16})((?:0x[a-f\d][a-f\d](?:, )?)+) -// Replace with: $1\n $2 -// -// Trim trailing spaces: -// , \n -// Replace with: ,\n -// -// Trim trailing newline after hex: -// \n\n\} -// Replace with: \n} - -// The 1x icons are unused now since some new icons don't have a 1x version at all -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused" - - -#pragma mark - FLEX Toolbar Icons - -static const u_int8_t FLEXCloseIcon[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x30, 0xae, - 0xa2, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0xca, 0x41, 0x37, 0x05, 0x00, 0x00, - 0x01, 0xd2, 0x49, 0x44, 0x41, 0x54, 0x48, 0x0d, 0xad, 0x96, 0x3b, 0x4e, 0xc3, 0x40, 0x10, 0x86, - 0xe3, 0x08, 0x51, 0x84, 0x0a, 0x24, 0x1e, 0xa2, 0x41, 0xa2, 0x41, 0x9c, 0x82, 0x82, 0x82, 0x23, - 0x20, 0x1a, 0xe0, 0x0c, 0xb4, 0x3c, 0x7c, 0x85, 0x9c, 0x80, 0x0b, 0xa4, 0x04, 0x51, 0x12, 0xe0, - 0x04, 0x08, 0xf1, 0xa8, 0x29, 0x10, 0x52, 0x3a, 0x1a, 0x40, 0xe2, 0x61, 0xbe, 0x89, 0x32, 0x96, - 0x33, 0xac, 0x37, 0xf6, 0x7a, 0x47, 0xfa, 0xb5, 0x8f, 0xf1, 0xfc, 0xdf, 0xec, 0x26, 0x8a, 0xd3, - 0x6a, 0x8d, 0x22, 0xcb, 0xb2, 0x79, 0xd4, 0xd6, 0x75, 0xec, 0x11, 0xef, 0x69, 0x34, 0x9b, 0xfb, - 0xb2, 0x48, 0x50, 0x0f, 0x7d, 0xa3, 0x67, 0xb4, 0x93, 0x27, 0x23, 0x4d, 0xf0, 0x3c, 0x40, 0x03, - 0xf4, 0x89, 0xba, 0x43, 0x5b, 0x26, 0x9b, 0xa8, 0x18, 0x3f, 0x2c, 0xf6, 0x23, 0x31, 0x5b, 0x78, - 0xa5, 0x45, 0xf3, 0xd1, 0x7c, 0x4d, 0x12, 0x5b, 0x8e, 0x44, 0x14, 0x38, 0xbe, 0xa9, 0xc3, 0x5b, - 0xb6, 0xd6, 0x05, 0xdc, 0x46, 0xb7, 0xb2, 0x32, 0xd1, 0x08, 0x8e, 0xd7, 0x89, 0xf1, 0xd3, 0xe5, - 0x79, 0x7e, 0x9b, 0xec, 0x2c, 0xa0, 0x7b, 0xcd, 0x14, 0xc6, 0x20, 0x38, 0xf5, 0x65, 0xd0, 0x6b, - 0x72, 0x33, 0x39, 0x58, 0x26, 0x6c, 0x44, 0x81, 0xe3, 0x73, 0x8c, 0x5c, 0xf1, 0x1f, 0xaa, 0x1d, - 0xf0, 0x74, 0x23, 0x38, 0xf5, 0x65, 0xd0, 0x2b, 0x72, 0xe3, 0x27, 0x55, 0xa8, 0x8e, 0xa1, 0x70, - 0xea, 0x8e, 0x90, 0x2b, 0x26, 0x43, 0x43, 0xe1, 0xd0, 0x9a, 0x43, 0xeb, 0xc2, 0x81, 0x1e, 0xba, - 0x8e, 0xc9, 0x5e, 0x1f, 0xf9, 0xaf, 0x57, 0x61, 0x76, 0xa4, 0xd0, 0xfb, 0x99, 0x93, 0xf7, 0x41, - 0x3b, 0xd6, 0xaf, 0xd6, 0xda, 0x03, 0xff, 0x25, 0xe7, 0x8a, 0x3e, 0x9b, 0xcd, 0xa0, 0xda, 0x21, - 0x46, 0x65, 0x27, 0xb7, 0xe0, 0xcb, 0x68, 0xd0, 0x1a, 0xf0, 0x5a, 0xd0, 0xca, 0xaf, 0xc1, 0x24, - 0x49, 0x06, 0x34, 0x71, 0xa1, 0x8d, 0x38, 0xc6, 0x1e, 0xcf, 0xbc, 0x3b, 0xf6, 0x9b, 0x6d, 0x71, - 0x85, 0xa9, 0xbd, 0x57, 0xb3, 0x0e, 0xfa, 0x79, 0xf5, 0x76, 0x55, 0x01, 0xaa, 0x3d, 0xc4, 0x83, - 0x7b, 0xa0, 0x37, 0xe4, 0xa2, 0xbd, 0x58, 0xc6, 0x4e, 0xee, 0x81, 0x0e, 0x7f, 0xf0, 0xc9, 0x97, - 0x7d, 0xdb, 0xc3, 0x4f, 0x3e, 0x09, 0xaa, 0x1d, 0x46, 0x85, 0x57, 0x85, 0x1a, 0xf8, 0x03, 0x75, - 0x36, 0xaa, 0x9f, 0x9c, 0xca, 0xd4, 0x56, 0x8f, 0xd6, 0xe5, 0xef, 0x53, 0x3a, 0xe0, 0x19, 0xb9, - 0xf6, 0x30, 0x38, 0x85, 0x29, 0x72, 0x85, 0x17, 0x5a, 0x38, 0xf9, 0x22, 0xc5, 0xf5, 0xe0, 0x14, - 0xa4, 0x2e, 0x22, 0x7b, 0x95, 0xa0, 0x41, 0x70, 0xcc, 0xab, 0xff, 0x47, 0x52, 0x82, 0x67, 0xc4, - 0x4f, 0x4e, 0xfe, 0x88, 0x6c, 0xc8, 0x67, 0xbe, 0x3b, 0x2c, 0x65, 0xb2, 0x82, 0x64, 0xc3, 0x46, - 0xad, 0x93, 0xda, 0x3e, 0x30, 0x2b, 0x83, 0xbf, 0x91, 0xeb, 0xc8, 0x97, 0x62, 0x0f, 0xd9, 0x68, - 0x04, 0xd5, 0x26, 0x30, 0x5d, 0x42, 0xae, 0x93, 0x6f, 0x08, 0x78, 0x0e, 0x7d, 0x20, 0x8d, 0x28, - 0x50, 0x03, 0x7f, 0x52, 0x73, 0xc6, 0x17, 0x34, 0x95, 0xc8, 0x03, 0x4c, 0x56, 0x19, 0xe4, 0xee, - 0xef, 0xd0, 0x19, 0x6f, 0x99, 0x2f, 0xc6, 0x68, 0x81, 0xbf, 0xfc, 0x31, 0xd8, 0x46, 0xcb, 0xe8, - 0x14, 0xff, 0xd7, 0x3f, 0x44, 0x89, 0xd3, 0x05, 0x85, 0xe7, 0xc6, 0x3e, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCloseIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3b, 0x30, 0xae, - 0xa2, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0xca, 0x41, 0x37, 0x05, 0x00, 0x00, - 0x01, 0xd2, 0x49, 0x44, 0x41, 0x54, 0x48, 0x0d, 0xad, 0x96, 0x3b, 0x4e, 0xc3, 0x40, 0x10, 0x86, - 0xe3, 0x08, 0x51, 0x84, 0x0a, 0x24, 0x1e, 0xa2, 0x41, 0xa2, 0x41, 0x9c, 0x82, 0x82, 0x82, 0x23, - 0x20, 0x1a, 0xe0, 0x0c, 0xb4, 0x3c, 0x7c, 0x85, 0x9c, 0x80, 0x0b, 0xa4, 0x04, 0x51, 0x12, 0xe0, - 0x04, 0x08, 0xf1, 0xa8, 0x29, 0x10, 0x52, 0x3a, 0x1a, 0x40, 0xe2, 0x61, 0xbe, 0x89, 0x32, 0x96, - 0x33, 0xac, 0x37, 0xf6, 0x7a, 0x47, 0xfa, 0xb5, 0x8f, 0xf1, 0xfc, 0xdf, 0xec, 0x26, 0x8a, 0xd3, - 0x6a, 0x8d, 0x22, 0xcb, 0xb2, 0x79, 0xd4, 0xd6, 0x75, 0xec, 0x11, 0xef, 0x69, 0x34, 0x9b, 0xfb, - 0xb2, 0x48, 0x50, 0x0f, 0x7d, 0xa3, 0x67, 0xb4, 0x93, 0x27, 0x23, 0x4d, 0xf0, 0x3c, 0x40, 0x03, - 0xf4, 0x89, 0xba, 0x43, 0x5b, 0x26, 0x9b, 0xa8, 0x18, 0x3f, 0x2c, 0xf6, 0x23, 0x31, 0x5b, 0x78, - 0xa5, 0x45, 0xf3, 0xd1, 0x7c, 0x4d, 0x12, 0x5b, 0x8e, 0x44, 0x14, 0x38, 0xbe, 0xa9, 0xc3, 0x5b, - 0xb6, 0xd6, 0x05, 0xdc, 0x46, 0xb7, 0xb2, 0x32, 0xd1, 0x08, 0x8e, 0xd7, 0x89, 0xf1, 0xd3, 0xe5, - 0x79, 0x7e, 0x9b, 0xec, 0x2c, 0xa0, 0x7b, 0xcd, 0x14, 0xc6, 0x20, 0x38, 0xf5, 0x65, 0xd0, 0x6b, - 0x72, 0x33, 0x39, 0x58, 0x26, 0x6c, 0x44, 0x81, 0xe3, 0x73, 0x8c, 0x5c, 0xf1, 0x1f, 0xaa, 0x1d, - 0xf0, 0x74, 0x23, 0x38, 0xf5, 0x65, 0xd0, 0x2b, 0x72, 0xe3, 0x27, 0x55, 0xa8, 0x8e, 0xa1, 0x70, - 0xea, 0x8e, 0x90, 0x2b, 0x26, 0x43, 0x43, 0xe1, 0xd0, 0x9a, 0x43, 0xeb, 0xc2, 0x81, 0x1e, 0xba, - 0x8e, 0xc9, 0x5e, 0x1f, 0xf9, 0xaf, 0x57, 0x61, 0x76, 0xa4, 0xd0, 0xfb, 0x99, 0x93, 0xf7, 0x41, - 0x3b, 0xd6, 0xaf, 0xd6, 0xda, 0x03, 0xff, 0x25, 0xe7, 0x8a, 0x3e, 0x9b, 0xcd, 0xa0, 0xda, 0x21, - 0x46, 0x65, 0x27, 0xb7, 0xe0, 0xcb, 0x68, 0xd0, 0x1a, 0xf0, 0x5a, 0xd0, 0xca, 0xaf, 0xc1, 0x24, - 0x49, 0x06, 0x34, 0x71, 0xa1, 0x8d, 0x38, 0xc6, 0x1e, 0xcf, 0xbc, 0x3b, 0xf6, 0x9b, 0x6d, 0x71, - 0x85, 0xa9, 0xbd, 0x57, 0xb3, 0x0e, 0xfa, 0x79, 0xf5, 0x76, 0x55, 0x01, 0xaa, 0x3d, 0xc4, 0x83, - 0x7b, 0xa0, 0x37, 0xe4, 0xa2, 0xbd, 0x58, 0xc6, 0x4e, 0xee, 0x81, 0x0e, 0x7f, 0xf0, 0xc9, 0x97, - 0x7d, 0xdb, 0xc3, 0x4f, 0x3e, 0x09, 0xaa, 0x1d, 0x46, 0x85, 0x57, 0x85, 0x1a, 0xf8, 0x03, 0x75, - 0x36, 0xaa, 0x9f, 0x9c, 0xca, 0xd4, 0x56, 0x8f, 0xd6, 0xe5, 0xef, 0x53, 0x3a, 0xe0, 0x19, 0xb9, - 0xf6, 0x30, 0x38, 0x85, 0x29, 0x72, 0x85, 0x17, 0x5a, 0x38, 0xf9, 0x22, 0xc5, 0xf5, 0xe0, 0x14, - 0xa4, 0x2e, 0x22, 0x7b, 0x95, 0xa0, 0x41, 0x70, 0xcc, 0xab, 0xff, 0x47, 0x52, 0x82, 0x67, 0xc4, - 0x4f, 0x4e, 0xfe, 0x88, 0x6c, 0xc8, 0x67, 0xbe, 0x3b, 0x2c, 0x65, 0xb2, 0x82, 0x64, 0xc3, 0x46, - 0xad, 0x93, 0xda, 0x3e, 0x30, 0x2b, 0x83, 0xbf, 0x91, 0xeb, 0xc8, 0x97, 0x62, 0x0f, 0xd9, 0x68, - 0x04, 0xd5, 0x26, 0x30, 0x5d, 0x42, 0xae, 0x93, 0x6f, 0x08, 0x78, 0x0e, 0x7d, 0x20, 0x8d, 0x28, - 0x50, 0x03, 0x7f, 0x52, 0x73, 0xc6, 0x17, 0x34, 0x95, 0xc8, 0x03, 0x4c, 0x56, 0x19, 0xe4, 0xee, - 0xef, 0xd0, 0x19, 0x6f, 0x99, 0x2f, 0xc6, 0x68, 0x81, 0xbf, 0xfc, 0x31, 0xd8, 0x46, 0xcb, 0xe8, - 0x14, 0xff, 0xd7, 0x3f, 0x44, 0x89, 0xd3, 0x05, 0x85, 0xe7, 0xc6, 0x3e, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCloseIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x2d, 0x08, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x1a, 0xe2, - 0x9a, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2d, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa8, 0x05, 0x50, 0x00, 0x00, - 0x02, 0xc0, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xd5, 0x99, 0xbf, 0x6b, 0x14, 0x41, 0x14, 0x80, - 0x6f, 0x4f, 0x0b, 0x83, 0x20, 0xb6, 0x42, 0xe2, 0xd8, 0x08, 0xe9, 0x2c, 0x15, 0xec, 0x2c, 0xb5, - 0x14, 0xff, 0x0a, 0xc1, 0xf8, 0x23, 0x88, 0x65, 0x2a, 0x3b, 0x3b, 0x5b, 0xe3, 0xaf, 0xc2, 0x4a, - 0x4b, 0x41, 0x50, 0x50, 0xac, 0xec, 0x45, 0x2c, 0x34, 0x03, 0x56, 0xc1, 0xd6, 0x42, 0x82, 0x9a, - 0xcb, 0x37, 0x61, 0xdf, 0xb2, 0xb7, 0x77, 0xb3, 0x6f, 0x76, 0x77, 0x66, 0x16, 0x1f, 0x7c, 0x79, - 0xbb, 0xfb, 0x66, 0xe6, 0x7d, 0x3b, 0xec, 0x91, 0x5c, 0x76, 0x32, 0xf9, 0x9f, 0x63, 0x36, 0x9b, - 0x5d, 0x83, 0x57, 0xf0, 0x1a, 0x36, 0xe0, 0xe8, 0x98, 0xf7, 0x43, 0xff, 0x13, 0x70, 0x1f, 0xde, - 0xc2, 0x73, 0x38, 0x3f, 0xe7, 0xc3, 0x85, 0x7b, 0xd0, 0x8c, 0xf7, 0x5c, 0x38, 0x3e, 0x37, 0x30, - 0xd3, 0x09, 0x7d, 0xcf, 0xc0, 0x4e, 0x43, 0xe8, 0x1f, 0xe7, 0x97, 0x0f, 0x15, 0x38, 0x38, 0x06, - 0xbf, 0x1b, 0x03, 0xe4, 0xf4, 0x03, 0x07, 0x59, 0xc5, 0xe9, 0x67, 0xc0, 0xc2, 0xb2, 0xf8, 0x2c, - 0xd2, 0xeb, 0xcb, 0xaa, 0xb5, 0x6b, 0xd9, 0xc4, 0xe9, 0x69, 0xc0, 0x82, 0x2f, 0xfe, 0x50, 0x98, - 0x4e, 0xf8, 0xb1, 0x02, 0x7b, 0xbe, 0x51, 0xe5, 0xf5, 0xe4, 0xe2, 0xf4, 0x31, 0x60, 0xa1, 0x2d, - 0xbe, 0x56, 0x4f, 0x28, 0xa3, 0xb6, 0xda, 0x46, 0x96, 0xb5, 0x64, 0xe2, 0xac, 0x6f, 0xa0, 0xf9, - 0x0c, 0x97, 0x6d, 0xe7, 0xd2, 0xd5, 0xba, 0xf4, 0x94, 0xd2, 0xa3, 0xb9, 0xf2, 0xf2, 0x93, 0xe8, - 0xe2, 0xb4, 0x39, 0x0d, 0x21, 0xc2, 0x9b, 0x95, 0xb0, 0x1c, 0x30, 0x31, 0xbb, 0x78, 0x07, 0xe1, - 0x3b, 0xe2, 0xb9, 0x90, 0x73, 0x8a, 0x47, 0x11, 0x96, 0x3b, 0xc8, 0x21, 0x5e, 0x0a, 0x7f, 0x27, - 0x6b, 0xe1, 0xdf, 0x61, 0x11, 0x96, 0xcc, 0x4a, 0xc9, 0x1e, 0x15, 0xd6, 0x5e, 0x83, 0x10, 0xe1, - 0xdb, 0xe2, 0x13, 0x9c, 0x53, 0x88, 0x27, 0x15, 0x96, 0x3b, 0x8b, 0x29, 0xde, 0x41, 0xf8, 0x96, - 0xf4, 0xef, 0x9d, 0x63, 0x88, 0x97, 0xc2, 0xdf, 0xc8, 0x5a, 0x0c, 0x17, 0x96, 0x3b, 0xa5, 0x53, - 0xef, 0x67, 0x9c, 0xb9, 0xab, 0x10, 0x22, 0x7c, 0x53, 0xfa, 0x45, 0xcb, 0x7d, 0xc4, 0x47, 0x15, - 0x96, 0x3b, 0xef, 0x28, 0xee, 0xfe, 0x10, 0x1b, 0x67, 0x87, 0x45, 0x58, 0x72, 0x07, 0xf1, 0xbf, - 0x8c, 0xd5, 0x62, 0x43, 0xd6, 0x4d, 0x9e, 0x31, 0x09, 0x7d, 0xc6, 0xdb, 0xa4, 0xf3, 0x09, 0xcb, - 0x8e, 0x94, 0xe2, 0xdb, 0x6d, 0x56, 0x2d, 0xb5, 0x1b, 0xb2, 0x4e, 0xf6, 0xdc, 0x53, 0x7c, 0x3c, - 0x61, 0xd9, 0xa1, 0x52, 0xfc, 0x45, 0xcb, 0xae, 0xd6, 0x4b, 0x77, 0x65, 0xde, 0x90, 0x3c, 0x1d, - 0x32, 0xb9, 0x9c, 0xbb, 0x46, 0xbe, 0x10, 0xb8, 0xce, 0x15, 0xee, 0x20, 0xeb, 0x77, 0xce, 0x05, - 0x2f, 0x04, 0x0c, 0x58, 0xe8, 0x12, 0xd1, 0xbf, 0x48, 0x2c, 0x88, 0xf9, 0x2e, 0x60, 0x69, 0xc0, - 0x42, 0x9f, 0xc8, 0x2f, 0x8e, 0xa5, 0x01, 0x0b, 0x43, 0x22, 0x9f, 0x38, 0x96, 0x06, 0x2c, 0x68, - 0xf1, 0x49, 0x1b, 0x40, 0x3d, 0xbd, 0x38, 0x4d, 0x0c, 0x58, 0xd0, 0x62, 0x93, 0x01, 0xa1, 0xbf, - 0x80, 0xd2, 0x89, 0x23, 0x61, 0xc0, 0x82, 0x16, 0xd5, 0xb7, 0x66, 0x06, 0x3a, 0xf1, 0x6d, 0x6d, - 0x02, 0xf5, 0xf8, 0xe2, 0x2c, 0x6a, 0xc0, 0x82, 0x16, 0x95, 0xb0, 0x7c, 0x80, 0x99, 0x90, 0x5f, - 0x9c, 0xa6, 0x06, 0x2c, 0x68, 0xb1, 0x20, 0xdc, 0x10, 0x7f, 0xac, 0x2d, 0x40, 0x7d, 0xf8, 0x8e, - 0xb3, 0x88, 0x01, 0x0b, 0x5a, 0x78, 0x85, 0xb3, 0x8a, 0x63, 0x69, 0xc0, 0x82, 0x16, 0xaa, 0x70, - 0x16, 0x71, 0x2c, 0x0d, 0x58, 0xd0, 0x22, 0x58, 0xb8, 0x21, 0xfe, 0x44, 0x5b, 0x98, 0x7a, 0xf8, - 0xa3, 0xc2, 0x60, 0x03, 0x16, 0xb4, 0xe8, 0x2c, 0x9c, 0x44, 0x1c, 0x4b, 0x03, 0x16, 0xb4, 0xe8, - 0x2d, 0xdc, 0x10, 0x7f, 0xaa, 0x35, 0xa2, 0xee, 0xdf, 0x71, 0x8a, 0x06, 0x2c, 0x68, 0x31, 0x58, - 0x38, 0x8a, 0x38, 0x96, 0xee, 0x5f, 0x55, 0x56, 0xb3, 0xa5, 0x1e, 0x4d, 0xb8, 0x21, 0xfe, 0x2c, - 0xa0, 0xb7, 0xdb, 0xf1, 0x15, 0x99, 0xe7, 0xde, 0x06, 0xbc, 0x0b, 0x98, 0x14, 0x5d, 0x58, 0x04, - 0xe8, 0xed, 0x7e, 0x01, 0x85, 0x88, 0x3f, 0x38, 0x9c, 0xc3, 0xe0, 0x53, 0x63, 0x0a, 0x77, 0x14, - 0xff, 0x29, 0xd2, 0x67, 0x15, 0xe9, 0x64, 0x3b, 0x2c, 0xc2, 0x92, 0xf1, 0x70, 0x3b, 0xee, 0xde, - 0x19, 0xfa, 0xe2, 0x17, 0x85, 0xc2, 0x3d, 0x1a, 0x6e, 0xe0, 0x8e, 0x67, 0x54, 0x36, 0xe1, 0x9a, - 0xf8, 0x11, 0x5c, 0x7c, 0xe2, 0x2f, 0x65, 0x9c, 0x13, 0xbf, 0x08, 0xbb, 0x35, 0x71, 0xf7, 0x5e, - 0xf1, 0x7a, 0x35, 0x20, 0xf3, 0x01, 0xbd, 0x9d, 0xf8, 0x43, 0xd8, 0x07, 0x89, 0x2f, 0x1c, 0xac, - 0x3a, 0x95, 0x42, 0x7c, 0xb8, 0x70, 0x92, 0xe3, 0x4b, 0xe0, 0x3e, 0xa1, 0x1f, 0x8b, 0xa2, 0xf8, - 0x21, 0xb5, 0xb1, 0x32, 0x4e, 0xe7, 0xe8, 0xed, 0x5e, 0x2f, 0xef, 0xc2, 0x1b, 0x9c, 0xf6, 0x9c, - 0xcb, 0x01, 0x48, 0xaa, 0xb6, 0x3e, 0x0f, 0xf9, 0xdb, 0x52, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXDragHandle[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x14, 0x08, 0x06, 0x00, 0x00, 0x01, 0x6d, 0xdf, 0x8a, - 0x41, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0xbf, 0x5b, 0x90, 0xfc, 0x00, 0x00, 0x00, 0x95, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, - 0x96, 0x51, 0x12, 0x00, 0x11, 0x08, 0x86, 0x73, 0xff, 0xeb, 0xac, 0xf3, 0xd9, 0xf6, 0xa1, 0x17, - 0x9b, 0xc9, 0x43, 0x46, 0xf4, 0x1b, 0xc6, 0x20, 0x93, 0x3e, 0x45, 0x85, 0x94, 0xd2, 0x88, 0xb8, - 0xae, 0x2e, 0xa5, 0x57, 0xa0, 0xa9, 0x65, 0xa1, 0x9f, 0x5c, 0xbf, 0x2f, 0xe5, 0x98, 0x61, 0xd5, - 0x0f, 0x98, 0xd5, 0x52, 0xc2, 0x81, 0xd1, 0x37, 0x13, 0x98, 0x75, 0x7d, 0x2b, 0x34, 0x64, 0xfd, - 0x66, 0x56, 0xba, 0x6d, 0xe1, 0x09, 0xca, 0xd5, 0x38, 0xf5, 0x55, 0xc7, 0x80, 0x59, 0x10, 0x38, - 0x98, 0x80, 0x53, 0x70, 0x48, 0x0a, 0xf1, 0x1c, 0x8c, 0x02, 0x47, 0xdf, 0x44, 0xc0, 0xd9, 0x07, - 0x63, 0x3e, 0xd4, 0x6c, 0xe4, 0x54, 0xae, 0xed, 0x0c, 0x43, 0x02, 0xd3, 0xea, 0x11, 0xb8, 0x9b, - 0x9c, 0x1f, 0x6a, 0x41, 0x20, 0x0b, 0x81, 0xe0, 0x6f, 0x60, 0xcc, 0x8f, 0x23, 0x8b, 0x73, 0xc0, - 0x4e, 0x10, 0x00, 0x01, 0x10, 0xb0, 0x08, 0x04, 0xff, 0x44, 0x86, 0x89, 0xf4, 0x0b, 0xbf, 0x81, - 0xca, 0xc9, 0x10, 0xe6, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, - 0x60, 0x82 -}; - -static const u_int8_t FLEXDragHandle2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x14, 0x08, 0x06, 0x00, 0x00, 0x01, 0x6d, 0xdf, 0x8a, - 0x41, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x50, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x00, 0xbf, 0x5b, 0x90, 0xfc, 0x00, 0x00, 0x00, 0x95, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, - 0x96, 0x51, 0x12, 0x00, 0x11, 0x08, 0x86, 0x73, 0xff, 0xeb, 0xac, 0xf3, 0xd9, 0xf6, 0xa1, 0x17, - 0x9b, 0xc9, 0x43, 0x46, 0xf4, 0x1b, 0xc6, 0x20, 0x93, 0x3e, 0x45, 0x85, 0x94, 0xd2, 0x88, 0xb8, - 0xae, 0x2e, 0xa5, 0x57, 0xa0, 0xa9, 0x65, 0xa1, 0x9f, 0x5c, 0xbf, 0x2f, 0xe5, 0x98, 0x61, 0xd5, - 0x0f, 0x98, 0xd5, 0x52, 0xc2, 0x81, 0xd1, 0x37, 0x13, 0x98, 0x75, 0x7d, 0x2b, 0x34, 0x64, 0xfd, - 0x66, 0x56, 0xba, 0x6d, 0xe1, 0x09, 0xca, 0xd5, 0x38, 0xf5, 0x55, 0xc7, 0x80, 0x59, 0x10, 0x38, - 0x98, 0x80, 0x53, 0x70, 0x48, 0x0a, 0xf1, 0x1c, 0x8c, 0x02, 0x47, 0xdf, 0x44, 0xc0, 0xd9, 0x07, - 0x63, 0x3e, 0xd4, 0x6c, 0xe4, 0x54, 0xae, 0xed, 0x0c, 0x43, 0x02, 0xd3, 0xea, 0x11, 0xb8, 0x9b, - 0x9c, 0x1f, 0x6a, 0x41, 0x20, 0x0b, 0x81, 0xe0, 0x6f, 0x60, 0xcc, 0x8f, 0x23, 0x8b, 0x73, 0xc0, - 0x4e, 0x10, 0x00, 0x01, 0x10, 0xb0, 0x08, 0x04, 0xff, 0x44, 0x86, 0x89, 0xf4, 0x0b, 0xbf, 0x81, - 0xca, 0xc9, 0x10, 0xe6, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, - 0x60, 0x82 -}; - -static const u_int8_t FLEXDragHandle3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x1e, 0x08, 0x06, 0x00, 0x00, 0x01, 0x9d, 0xd0, 0x9a, - 0x44, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x7e, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x00, 0x9a, 0x6c, 0x42, 0x31, 0x00, 0x00, 0x01, 0x8f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, - 0x9a, 0x4d, 0x4e, 0xc3, 0x30, 0x10, 0x46, 0x5d, 0x84, 0xca, 0x06, 0x4e, 0x01, 0xbd, 0x0b, 0x27, - 0x60, 0xc7, 0x41, 0xd8, 0x65, 0xc3, 0x49, 0xd8, 0x71, 0x25, 0xe8, 0x29, 0xca, 0xa6, 0x2b, 0xf8, - 0xbc, 0xa8, 0xd4, 0x4a, 0x1e, 0xb7, 0x8c, 0xd3, 0xb1, 0x62, 0x3d, 0x2b, 0x51, 0x5a, 0x3b, 0xdf, - 0xfc, 0x3c, 0x3b, 0x71, 0x9a, 0x7a, 0x95, 0x2a, 0xe5, 0x37, 0x25, 0x6d, 0xe5, 0xb2, 0x4a, 0x49, - 0xdb, 0x0c, 0xa5, 0x6a, 0x45, 0xee, 0x27, 0xcb, 0x87, 0x84, 0x66, 0x9b, 0xa5, 0x29, 0xd6, 0x9b, - 0x11, 0xc8, 0xfb, 0x5e, 0x8a, 0x75, 0x51, 0xa5, 0x4a, 0x09, 0x4d, 0xad, 0xa5, 0x29, 0xd6, 0x9b, - 0x56, 0x14, 0xc1, 0x9b, 0x14, 0x77, 0x45, 0x95, 0x2a, 0x25, 0x9c, 0xac, 0x36, 0xea, 0x97, 0x45, - 0xc0, 0x1c, 0x04, 0xb5, 0x34, 0x34, 0x40, 0xb4, 0xf9, 0x8a, 0x1c, 0xba, 0x7c, 0x9e, 0x78, 0xcb, - 0x01, 0x38, 0xf7, 0xf7, 0x13, 0x43, 0x7c, 0xe9, 0x41, 0xc0, 0x35, 0x00, 0xd4, 0xdf, 0x93, 0x33, - 0xd8, 0x0f, 0x39, 0xdc, 0x3a, 0xb5, 0x03, 0xc9, 0xbc, 0xd8, 0xbd, 0xd7, 0xfa, 0x8f, 0x1c, 0x3e, - 0x84, 0xf3, 0x53, 0xb4, 0x7b, 0xe7, 0xbd, 0xc1, 0x7b, 0x4f, 0xc9, 0x3a, 0xee, 0x2b, 0xe1, 0x3d, - 0xbd, 0x04, 0x87, 0xae, 0x6b, 0xce, 0x93, 0x58, 0x1e, 0xf2, 0x1e, 0x5d, 0xa3, 0xe6, 0x5b, 0x09, - 0x6e, 0x1a, 0x6d, 0x20, 0x87, 0x00, 0x04, 0xfe, 0x49, 0x20, 0x4f, 0x39, 0xf9, 0x9a, 0x0f, 0xde, - 0xf3, 0x4f, 0xd3, 0x6a, 0xb9, 0xa9, 0xb6, 0xd2, 0x08, 0x01, 0x08, 0x40, 0x00, 0x02, 0x63, 0x10, - 0x08, 0x79, 0xbc, 0xd5, 0x14, 0xf7, 0x25, 0x5c, 0x4f, 0xd1, 0xc8, 0x94, 0x5c, 0x35, 0xbf, 0xdb, - 0xa0, 0x80, 0x9e, 0xe5, 0xe7, 0x35, 0xc8, 0xd7, 0xc1, 0xcd, 0xd9, 0x79, 0xfe, 0x70, 0x22, 0x47, - 0x08, 0x40, 0x00, 0x02, 0xc3, 0x13, 0xa8, 0x4e, 0x05, 0x73, 0x65, 0xaf, 0xa9, 0x6e, 0x27, 0x5b, - 0xf7, 0x73, 0xd9, 0xbb, 0xd4, 0xce, 0xb9, 0xa9, 0x2e, 0x24, 0xf9, 0x4b, 0x83, 0x6d, 0x3d, 0xaf, - 0x17, 0xe4, 0xd6, 0xb8, 0x9d, 0xfa, 0x3e, 0xaf, 0xe1, 0x9d, 0xc1, 0x22, 0x83, 0x00, 0x04, 0x20, - 0x00, 0x01, 0x08, 0x40, 0x00, 0x02, 0x10, 0xb8, 0x22, 0x81, 0xd1, 0x9e, 0xea, 0x1f, 0xc5, 0xea, - 0x45, 0xbb, 0xb9, 0x72, 0xf1, 0x8a, 0x2c, 0x23, 0x4d, 0xe7, 0x97, 0x73, 0x9f, 0xea, 0x3c, 0xf7, - 0x9a, 0xa6, 0xd1, 0x3a, 0xbe, 0xcb, 0xeb, 0xe1, 0xc8, 0x1e, 0x3f, 0xf2, 0xc5, 0x8a, 0x8b, 0x23, - 0x18, 0x7c, 0x84, 0x00, 0x04, 0x20, 0x00, 0x01, 0x08, 0x40, 0x00, 0x02, 0x10, 0x18, 0x85, 0x80, - 0xfe, 0xa4, 0xc9, 0xeb, 0x1b, 0x7b, 0x2c, 0xe5, 0x0f, 0x5f, 0x53, 0x99, 0x73, 0x6d, 0xe9, 0x37, - 0xd6, 0x5c, 0xb6, 0xd0, 0x5b, 0xb0, 0xf6, 0x0f, 0x6b, 0x93, 0x2d, 0x3b, 0x32, 0x91, 0xf4, 0xb4, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXGlobalsIcon[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x26, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x3d, 0xe9, - 0xae, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x84, 0xf2, 0x20, 0x5b, 0x00, 0x00, - 0x03, 0x06, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xcd, 0x98, 0xc9, 0x6b, 0x14, 0x41, 0x14, 0x87, - 0x33, 0x31, 0x8a, 0x22, 0x44, 0x24, 0x0b, 0x6a, 0xc0, 0x10, 0x24, 0x2e, 0x88, 0x42, 0x84, 0x88, - 0x10, 0x24, 0x44, 0x3d, 0x84, 0x78, 0x50, 0x10, 0xd4, 0xa3, 0x20, 0xb8, 0xfc, 0x05, 0x1e, 0x24, - 0x10, 0x15, 0x0f, 0x41, 0x51, 0x24, 0x9e, 0x3d, 0xe8, 0xc1, 0x8b, 0x22, 0xb8, 0x5d, 0x3c, 0x0c, - 0x2a, 0xc4, 0x25, 0x68, 0x04, 0x15, 0xcd, 0x41, 0xdc, 0x0e, 0x8a, 0x5b, 0xa2, 0x12, 0xa2, 0x66, - 0x99, 0x7c, 0x6f, 0x98, 0x32, 0x8f, 0xb2, 0x6b, 0xba, 0x27, 0xa9, 0x6a, 0xfc, 0xc1, 0x47, 0xbd, - 0xae, 0xaa, 0x79, 0xef, 0x37, 0xd3, 0xdd, 0xd5, 0xd5, 0x53, 0x56, 0xf6, 0x9f, 0x2a, 0x13, 0xda, - 0x57, 0x2e, 0x97, 0xab, 0xa7, 0xc6, 0x36, 0x58, 0x05, 0x2b, 0x61, 0x3e, 0xf4, 0xc1, 0x03, 0xb8, - 0x9d, 0xc9, 0x64, 0xde, 0xd2, 0xa6, 0x27, 0x0c, 0xcd, 0x86, 0x43, 0x30, 0x0c, 0x2e, 0xfd, 0x61, - 0xa0, 0x13, 0x2a, 0x52, 0x71, 0x46, 0xa1, 0x3a, 0x78, 0x06, 0x49, 0xf5, 0x88, 0x89, 0x2b, 0x82, - 0x9a, 0xa3, 0xc0, 0x3c, 0xe8, 0x4b, 0xea, 0x48, 0xcd, 0x7b, 0x43, 0xbc, 0x30, 0x98, 0x39, 0x92, - 0x77, 0xab, 0x62, 0x71, 0xe1, 0x20, 0x13, 0x2e, 0xc3, 0x41, 0x68, 0x0c, 0x69, 0xaa, 0x92, 0x02, - 0xdf, 0xa1, 0x98, 0xc6, 0x18, 0x3c, 0x0b, 0xeb, 0xa1, 0x3c, 0x98, 0x19, 0x9d, 0x98, 0x42, 0x3b, - 0x21, 0x4e, 0x27, 0xf4, 0x67, 0x5c, 0xb1, 0x6f, 0xc7, 0xcd, 0xae, 0x42, 0xaa, 0xff, 0x9d, 0x8a, - 0x9d, 0xa1, 0x6f, 0x63, 0x4b, 0x9d, 0x95, 0xa6, 0x06, 0xaa, 0xa6, 0x42, 0x77, 0xe4, 0xdb, 0x58, - 0x75, 0x44, 0xa9, 0x51, 0xfa, 0x1e, 0xc2, 0x58, 0x61, 0xac, 0x3d, 0x62, 0x4e, 0xd8, 0x2e, 0x2e, - 0xae, 0xe7, 0xea, 0x02, 0xbb, 0x44, 0xdc, 0x01, 0xab, 0x61, 0x2f, 0xfc, 0x04, 0xd1, 0x38, 0xfc, - 0xf3, 0x05, 0xe8, 0x6b, 0x80, 0x7d, 0x70, 0x01, 0xca, 0x7d, 0xaf, 0xb8, 0x8b, 0xd5, 0x57, 0xaf, - 0x23, 0x3e, 0x03, 0xf2, 0x08, 0xba, 0x05, 0xf2, 0x18, 0x6a, 0x03, 0x39, 0x4b, 0xed, 0x14, 0xff, - 0x40, 0x2b, 0x8f, 0xa8, 0x35, 0xb0, 0x05, 0x96, 0x81, 0x28, 0xcb, 0x63, 0x6a, 0xc2, 0x9b, 0x31, - 0x0a, 0xcd, 0x25, 0xa9, 0x5e, 0x20, 0xe7, 0x70, 0xbc, 0x1b, 0x16, 0xc0, 0x66, 0x68, 0x05, 0xa3, - 0x0e, 0x82, 0x5e, 0xe8, 0x31, 0x1d, 0xaa, 0xcd, 0xaa, 0x78, 0xe6, 0x21, 0xc6, 0x5a, 0x41, 0x6b, - 0x82, 0x83, 0x1f, 0xd0, 0x0b, 0x47, 0x61, 0x0f, 0x18, 0x7d, 0x25, 0x68, 0x34, 0x07, 0xaa, 0xfd, - 0x48, 0x5c, 0x33, 0x73, 0x37, 0x2a, 0x03, 0x09, 0xcf, 0xab, 0x02, 0x26, 0xdc, 0x4e, 0x20, 0xd7, - 0xd7, 0x45, 0xf8, 0x64, 0x3a, 0x0b, 0x6d, 0x0b, 0xed, 0x0b, 0xab, 0x4f, 0x7e, 0x49, 0x7f, 0x22, - 0xf9, 0x56, 0x90, 0x5f, 0xa8, 0x14, 0x1d, 0x67, 0xf2, 0x49, 0xf5, 0x81, 0x63, 0xfe, 0x1c, 0x91, - 0x89, 0xc4, 0x1b, 0x40, 0x4e, 0x4d, 0xa9, 0xea, 0xe7, 0x03, 0x6d, 0x30, 0x04, 0x3b, 0x7c, 0x9b, - 0xda, 0x45, 0xd2, 0x11, 0x98, 0x8e, 0xe4, 0xcb, 0xd4, 0x40, 0x43, 0x94, 0xa9, 0x69, 0xef, 0x60, - 0x49, 0xd8, 0x49, 0xc2, 0x23, 0x10, 0x97, 0xe3, 0x31, 0x73, 0xee, 0xc1, 0x53, 0x18, 0x84, 0x61, - 0x18, 0x80, 0x57, 0x2c, 0x0b, 0x39, 0x5a, 0x3f, 0xc2, 0x50, 0x35, 0x5c, 0x81, 0x38, 0x7d, 0x61, - 0x82, 0xdf, 0x8b, 0xd9, 0xf5, 0x15, 0x28, 0x94, 0x5f, 0x18, 0xe3, 0x1c, 0x31, 0xfe, 0x19, 0x96, - 0xbb, 0xf2, 0x78, 0xeb, 0xa7, 0x88, 0xec, 0x4a, 0x7b, 0x20, 0x89, 0x7e, 0x31, 0xa9, 0xc5, 0x5b, - 0x71, 0x57, 0x22, 0x8a, 0x34, 0xc3, 0xcb, 0x24, 0x8e, 0x98, 0x23, 0x4b, 0x86, 0xac, 0xf6, 0xe1, - 0x44, 0x81, 0x0a, 0xe8, 0x82, 0x51, 0x48, 0xaa, 0xc3, 0xe1, 0x1c, 0x91, 0x19, 0x17, 0x8b, 0x40, - 0x1e, 0x25, 0xa5, 0xe8, 0x7a, 0x68, 0x53, 0xeb, 0x70, 0xf3, 0xbe, 0x14, 0x47, 0xcc, 0x95, 0x67, - 0x5c, 0x6d, 0x30, 0x63, 0x24, 0x97, 0xfd, 0x53, 0xb1, 0x17, 0x54, 0x86, 0x23, 0x15, 0x6e, 0xf3, - 0x47, 0xb9, 0x7a, 0x90, 0xd7, 0x29, 0xd1, 0x6f, 0xb8, 0x0a, 0xe7, 0x60, 0x00, 0x8a, 0x49, 0xf6, - 0x5c, 0xe1, 0x44, 0xe5, 0x6c, 0xa1, 0xba, 0xac, 0x41, 0xb2, 0x79, 0xcb, 0x8b, 0x58, 0x6e, 0x82, - 0x53, 0x85, 0x31, 0xbb, 0x91, 0x1d, 0xab, 0xec, 0xc3, 0xc2, 0x88, 0xe4, 0x72, 0xb1, 0x1b, 0xed, - 0xb7, 0xab, 0x30, 0x30, 0x0b, 0xec, 0x25, 0x43, 0xfe, 0x77, 0x68, 0xb2, 0xe7, 0xfa, 0x3a, 0x36, - 0x2f, 0x23, 0x1b, 0x55, 0xc2, 0x3b, 0x2a, 0xce, 0x87, 0x3c, 0xd3, 0xc6, 0x09, 0xee, 0x5b, 0xfd, - 0x5d, 0xf4, 0xf7, 0x5b, 0x7d, 0xde, 0x0e, 0x8d, 0xb1, 0x21, 0x95, 0xd1, 0x75, 0x77, 0xc9, 0x1e, - 0xde, 0x48, 0xcc, 0x77, 0x9b, 0x83, 0x60, 0x2d, 0xa7, 0xa4, 0x16, 0xcc, 0x46, 0xef, 0x9a, 0x5d, - 0x88, 0x31, 0x59, 0xfd, 0xe5, 0xed, 0x46, 0xf4, 0x1a, 0xfc, 0x6e, 0x7f, 0xed, 0x82, 0xfa, 0x98, - 0x62, 0xa7, 0xc1, 0xe8, 0x06, 0xc1, 0x26, 0x90, 0x57, 0xaf, 0x03, 0x60, 0x36, 0x82, 0xf2, 0x0a, - 0xf6, 0xf7, 0xc6, 0xd0, 0x9f, 0x0f, 0x16, 0x53, 0x50, 0x1e, 0xd4, 0x4f, 0xc0, 0x25, 0xb9, 0x5b, - 0xe5, 0x35, 0x2b, 0x7d, 0x51, 0x58, 0xcc, 0xc9, 0x2f, 0x67, 0x4e, 0x2b, 0x61, 0xfe, 0x14, 0xde, - 0xa4, 0x5d, 0x92, 0xa6, 0xa3, 0xc8, 0xdd, 0x27, 0x26, 0xaa, 0x30, 0xb1, 0x16, 0x2a, 0xe1, 0x2e, - 0x77, 0xdf, 0xb7, 0x34, 0x4d, 0x49, 0xad, 0x49, 0x44, 0x7e, 0xb1, 0xbc, 0xea, 0x50, 0x60, 0xc4, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXGlobalsIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x26, 0x08, 0x06, 0x00, 0x00, 0x00, 0xa8, 0x3d, 0xe9, - 0xae, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x84, 0xf2, 0x20, 0x5b, 0x00, 0x00, - 0x03, 0x06, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xcd, 0x98, 0xc9, 0x6b, 0x14, 0x41, 0x14, 0x87, - 0x33, 0x31, 0x8a, 0x22, 0x44, 0x24, 0x0b, 0x6a, 0xc0, 0x10, 0x24, 0x2e, 0x88, 0x42, 0x84, 0x88, - 0x10, 0x24, 0x44, 0x3d, 0x84, 0x78, 0x50, 0x10, 0xd4, 0xa3, 0x20, 0xb8, 0xfc, 0x05, 0x1e, 0x24, - 0x10, 0x15, 0x0f, 0x41, 0x51, 0x24, 0x9e, 0x3d, 0xe8, 0xc1, 0x8b, 0x22, 0xb8, 0x5d, 0x3c, 0x0c, - 0x2a, 0xc4, 0x25, 0x68, 0x04, 0x15, 0xcd, 0x41, 0xdc, 0x0e, 0x8a, 0x5b, 0xa2, 0x12, 0xa2, 0x66, - 0x99, 0x7c, 0x6f, 0x98, 0x32, 0x8f, 0xb2, 0x6b, 0xba, 0x27, 0xa9, 0x6a, 0xfc, 0xc1, 0x47, 0xbd, - 0xae, 0xaa, 0x79, 0xef, 0x37, 0xd3, 0xdd, 0xd5, 0xd5, 0x53, 0x56, 0xf6, 0x9f, 0x2a, 0x13, 0xda, - 0x57, 0x2e, 0x97, 0xab, 0xa7, 0xc6, 0x36, 0x58, 0x05, 0x2b, 0x61, 0x3e, 0xf4, 0xc1, 0x03, 0xb8, - 0x9d, 0xc9, 0x64, 0xde, 0xd2, 0xa6, 0x27, 0x0c, 0xcd, 0x86, 0x43, 0x30, 0x0c, 0x2e, 0xfd, 0x61, - 0xa0, 0x13, 0x2a, 0x52, 0x71, 0x46, 0xa1, 0x3a, 0x78, 0x06, 0x49, 0xf5, 0x88, 0x89, 0x2b, 0x82, - 0x9a, 0xa3, 0xc0, 0x3c, 0xe8, 0x4b, 0xea, 0x48, 0xcd, 0x7b, 0x43, 0xbc, 0x30, 0x98, 0x39, 0x92, - 0x77, 0xab, 0x62, 0x71, 0xe1, 0x20, 0x13, 0x2e, 0xc3, 0x41, 0x68, 0x0c, 0x69, 0xaa, 0x92, 0x02, - 0xdf, 0xa1, 0x98, 0xc6, 0x18, 0x3c, 0x0b, 0xeb, 0xa1, 0x3c, 0x98, 0x19, 0x9d, 0x98, 0x42, 0x3b, - 0x21, 0x4e, 0x27, 0xf4, 0x67, 0x5c, 0xb1, 0x6f, 0xc7, 0xcd, 0xae, 0x42, 0xaa, 0xff, 0x9d, 0x8a, - 0x9d, 0xa1, 0x6f, 0x63, 0x4b, 0x9d, 0x95, 0xa6, 0x06, 0xaa, 0xa6, 0x42, 0x77, 0xe4, 0xdb, 0x58, - 0x75, 0x44, 0xa9, 0x51, 0xfa, 0x1e, 0xc2, 0x58, 0x61, 0xac, 0x3d, 0x62, 0x4e, 0xd8, 0x2e, 0x2e, - 0xae, 0xe7, 0xea, 0x02, 0xbb, 0x44, 0xdc, 0x01, 0xab, 0x61, 0x2f, 0xfc, 0x04, 0xd1, 0x38, 0xfc, - 0xf3, 0x05, 0xe8, 0x6b, 0x80, 0x7d, 0x70, 0x01, 0xca, 0x7d, 0xaf, 0xb8, 0x8b, 0xd5, 0x57, 0xaf, - 0x23, 0x3e, 0x03, 0xf2, 0x08, 0xba, 0x05, 0xf2, 0x18, 0x6a, 0x03, 0x39, 0x4b, 0xed, 0x14, 0xff, - 0x40, 0x2b, 0x8f, 0xa8, 0x35, 0xb0, 0x05, 0x96, 0x81, 0x28, 0xcb, 0x63, 0x6a, 0xc2, 0x9b, 0x31, - 0x0a, 0xcd, 0x25, 0xa9, 0x5e, 0x20, 0xe7, 0x70, 0xbc, 0x1b, 0x16, 0xc0, 0x66, 0x68, 0x05, 0xa3, - 0x0e, 0x82, 0x5e, 0xe8, 0x31, 0x1d, 0xaa, 0xcd, 0xaa, 0x78, 0xe6, 0x21, 0xc6, 0x5a, 0x41, 0x6b, - 0x82, 0x83, 0x1f, 0xd0, 0x0b, 0x47, 0x61, 0x0f, 0x18, 0x7d, 0x25, 0x68, 0x34, 0x07, 0xaa, 0xfd, - 0x48, 0x5c, 0x33, 0x73, 0x37, 0x2a, 0x03, 0x09, 0xcf, 0xab, 0x02, 0x26, 0xdc, 0x4e, 0x20, 0xd7, - 0xd7, 0x45, 0xf8, 0x64, 0x3a, 0x0b, 0x6d, 0x0b, 0xed, 0x0b, 0xab, 0x4f, 0x7e, 0x49, 0x7f, 0x22, - 0xf9, 0x56, 0x90, 0x5f, 0xa8, 0x14, 0x1d, 0x67, 0xf2, 0x49, 0xf5, 0x81, 0x63, 0xfe, 0x1c, 0x91, - 0x89, 0xc4, 0x1b, 0x40, 0x4e, 0x4d, 0xa9, 0xea, 0xe7, 0x03, 0x6d, 0x30, 0x04, 0x3b, 0x7c, 0x9b, - 0xda, 0x45, 0xd2, 0x11, 0x98, 0x8e, 0xe4, 0xcb, 0xd4, 0x40, 0x43, 0x94, 0xa9, 0x69, 0xef, 0x60, - 0x49, 0xd8, 0x49, 0xc2, 0x23, 0x10, 0x97, 0xe3, 0x31, 0x73, 0xee, 0xc1, 0x53, 0x18, 0x84, 0x61, - 0x18, 0x80, 0x57, 0x2c, 0x0b, 0x39, 0x5a, 0x3f, 0xc2, 0x50, 0x35, 0x5c, 0x81, 0x38, 0x7d, 0x61, - 0x82, 0xdf, 0x8b, 0xd9, 0xf5, 0x15, 0x28, 0x94, 0x5f, 0x18, 0xe3, 0x1c, 0x31, 0xfe, 0x19, 0x96, - 0xbb, 0xf2, 0x78, 0xeb, 0xa7, 0x88, 0xec, 0x4a, 0x7b, 0x20, 0x89, 0x7e, 0x31, 0xa9, 0xc5, 0x5b, - 0x71, 0x57, 0x22, 0x8a, 0x34, 0xc3, 0xcb, 0x24, 0x8e, 0x98, 0x23, 0x4b, 0x86, 0xac, 0xf6, 0xe1, - 0x44, 0x81, 0x0a, 0xe8, 0x82, 0x51, 0x48, 0xaa, 0xc3, 0xe1, 0x1c, 0x91, 0x19, 0x17, 0x8b, 0x40, - 0x1e, 0x25, 0xa5, 0xe8, 0x7a, 0x68, 0x53, 0xeb, 0x70, 0xf3, 0xbe, 0x14, 0x47, 0xcc, 0x95, 0x67, - 0x5c, 0x6d, 0x30, 0x63, 0x24, 0x97, 0xfd, 0x53, 0xb1, 0x17, 0x54, 0x86, 0x23, 0x15, 0x6e, 0xf3, - 0x47, 0xb9, 0x7a, 0x90, 0xd7, 0x29, 0xd1, 0x6f, 0xb8, 0x0a, 0xe7, 0x60, 0x00, 0x8a, 0x49, 0xf6, - 0x5c, 0xe1, 0x44, 0xe5, 0x6c, 0xa1, 0xba, 0xac, 0x41, 0xb2, 0x79, 0xcb, 0x8b, 0x58, 0x6e, 0x82, - 0x53, 0x85, 0x31, 0xbb, 0x91, 0x1d, 0xab, 0xec, 0xc3, 0xc2, 0x88, 0xe4, 0x72, 0xb1, 0x1b, 0xed, - 0xb7, 0xab, 0x30, 0x30, 0x0b, 0xec, 0x25, 0x43, 0xfe, 0x77, 0x68, 0xb2, 0xe7, 0xfa, 0x3a, 0x36, - 0x2f, 0x23, 0x1b, 0x55, 0xc2, 0x3b, 0x2a, 0xce, 0x87, 0x3c, 0xd3, 0xc6, 0x09, 0xee, 0x5b, 0xfd, - 0x5d, 0xf4, 0xf7, 0x5b, 0x7d, 0xde, 0x0e, 0x8d, 0xb1, 0x21, 0x95, 0xd1, 0x75, 0x77, 0xc9, 0x1e, - 0xde, 0x48, 0xcc, 0x77, 0x9b, 0x83, 0x60, 0x2d, 0xa7, 0xa4, 0x16, 0xcc, 0x46, 0xef, 0x9a, 0x5d, - 0x88, 0x31, 0x59, 0xfd, 0xe5, 0xed, 0x46, 0xf4, 0x1a, 0xfc, 0x6e, 0x7f, 0xed, 0x82, 0xfa, 0x98, - 0x62, 0xa7, 0xc1, 0xe8, 0x06, 0xc1, 0x26, 0x90, 0x57, 0xaf, 0x03, 0x60, 0x36, 0x82, 0xf2, 0x0a, - 0xf6, 0xf7, 0xc6, 0xd0, 0x9f, 0x0f, 0x16, 0x53, 0x50, 0x1e, 0xd4, 0x4f, 0xc0, 0x25, 0xb9, 0x5b, - 0xe5, 0x35, 0x2b, 0x7d, 0x51, 0x58, 0xcc, 0xc9, 0x2f, 0x67, 0x4e, 0x2b, 0x61, 0xfe, 0x14, 0xde, - 0xa4, 0x5d, 0x92, 0xa6, 0xa3, 0xc8, 0xdd, 0x27, 0x26, 0xaa, 0x30, 0xb1, 0x16, 0x2a, 0xe1, 0x2e, - 0x77, 0xdf, 0xb7, 0x34, 0x4d, 0x49, 0xad, 0x49, 0x44, 0x7e, 0xb1, 0xbc, 0xea, 0x50, 0x60, 0xc4, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXGlobalsIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x39, 0x08, 0x06, 0x00, 0x00, 0x00, 0x8c, 0x18, 0x83, - 0x85, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x39, 0x00, 0x00, 0x00, 0x00, 0xb7, 0x91, 0x8a, 0xa0, 0x00, 0x00, - 0x04, 0xf1, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xe5, 0x9a, 0x6b, 0x88, 0x16, 0x55, 0x1c, 0xc6, - 0xf7, 0xf5, 0xb2, 0xa2, 0x82, 0x4a, 0x79, 0x43, 0x51, 0x89, 0x4c, 0x45, 0x83, 0x0c, 0x51, 0x04, - 0x2f, 0xa9, 0x6c, 0x45, 0x42, 0x5e, 0x82, 0x54, 0xf0, 0x83, 0x20, 0xa8, 0x81, 0x81, 0x10, 0x42, - 0x20, 0x91, 0x90, 0x12, 0x7d, 0x49, 0x08, 0xfa, 0x20, 0xda, 0x07, 0x05, 0xf1, 0x82, 0x60, 0x18, - 0x4a, 0x65, 0x42, 0xfa, 0x41, 0xb7, 0x22, 0x96, 0x50, 0x50, 0x5c, 0xf2, 0xb2, 0x25, 0xab, 0x99, - 0xe5, 0xad, 0x52, 0x33, 0x77, 0xfb, 0x3d, 0xaf, 0x33, 0xcb, 0xd9, 0xd3, 0xcc, 0xbc, 0xaf, 0x67, - 0xe6, 0x9d, 0x39, 0x2f, 0xfd, 0xe1, 0xc7, 0x9c, 0xf3, 0x9f, 0x73, 0xe6, 0x3c, 0xcf, 0xcc, 0xce, - 0x7b, 0xce, 0xcc, 0x6c, 0x43, 0xc3, 0xff, 0x20, 0x4a, 0x3e, 0x7b, 0xec, 0xec, 0xec, 0x1c, 0x88, - 0xbe, 0x51, 0x30, 0x08, 0x1a, 0xe1, 0x67, 0x51, 0x2a, 0x95, 0xee, 0xb1, 0xad, 0xdf, 0xc0, 0xd8, - 0x28, 0x78, 0x1f, 0xbe, 0x87, 0x87, 0x60, 0x47, 0x07, 0x89, 0x66, 0x78, 0x1b, 0x46, 0xd7, 0x95, - 0x53, 0x04, 0x3f, 0x09, 0x9f, 0xc0, 0xdf, 0x50, 0x6d, 0xdc, 0xa7, 0xe1, 0x47, 0x30, 0xc4, 0x7b, - 0xb3, 0x88, 0x9c, 0x06, 0x6d, 0xe0, 0x1a, 0xd7, 0xe8, 0x38, 0xdb, 0x5b, 0xa3, 0x88, 0x9b, 0x05, - 0xba, 0x22, 0x69, 0x43, 0x7f, 0x01, 0x2b, 0xbc, 0x33, 0x8a, 0xa8, 0x31, 0xa0, 0xab, 0x90, 0x55, - 0x3c, 0xe0, 0x40, 0x73, 0x6c, 0xa3, 0x3d, 0xec, 0x44, 0x5e, 0x75, 0xc4, 0xf4, 0x65, 0xac, 0x83, - 0x90, 0xd5, 0xfd, 0xf4, 0x90, 0x63, 0xb5, 0xc0, 0x64, 0xe8, 0x16, 0xbd, 0xba, 0xd5, 0xf2, 0xad, - 0xac, 0x62, 0xb8, 0xe7, 0x52, 0x0e, 0xd9, 0x4a, 0xff, 0xa3, 0x01, 0x5f, 0x33, 0xb5, 0xdc, 0x4c, - 0x79, 0xbc, 0xec, 0xba, 0x73, 0x15, 0x7b, 0xc2, 0x45, 0x70, 0x89, 0xe3, 0x74, 0x5a, 0x09, 0x7e, - 0x4f, 0x1f, 0x08, 0x5c, 0xe4, 0xe0, 0x4e, 0x73, 0xe6, 0x62, 0x97, 0x53, 0x5d, 0xd4, 0x3d, 0xf9, - 0x82, 0x83, 0xd8, 0x5d, 0xfc, 0x39, 0x7e, 0xea, 0xd0, 0xaf, 0xa1, 0x28, 0x93, 0x53, 0x1d, 0xc4, - 0x9e, 0x76, 0xe8, 0x53, 0xee, 0x52, 0x94, 0xc9, 0x49, 0x0e, 0x82, 0xb5, 0x86, 0x75, 0x8a, 0xdc, - 0x4d, 0x72, 0x5f, 0xe9, 0x17, 0x5d, 0x0b, 0xee, 0xc7, 0x0d, 0xe7, 0x15, 0x4d, 0xee, 0x26, 0x71, - 0xf6, 0xc4, 0xe3, 0xba, 0x0b, 0xda, 0x4f, 0xe6, 0x04, 0x8d, 0x70, 0xe9, 0x5b, 0x84, 0xc9, 0xa4, - 0xab, 0x78, 0x09, 0x13, 0xdb, 0x61, 0x29, 0xc8, 0xd0, 0x31, 0x30, 0x63, 0xbe, 0x59, 0x49, 0x2a, - 0x73, 0x42, 0x7a, 0xc0, 0xb0, 0xa4, 0x36, 0x35, 0xdb, 0xc7, 0xc0, 0x53, 0xc0, 0x8e, 0x8f, 0x49, - 0x3c, 0xad, 0x41, 0xd9, 0x8e, 0x06, 0xcd, 0x83, 0xbb, 0xc1, 0x7e, 0x22, 0x39, 0x90, 0x24, 0x8c, - 0xf6, 0x4f, 0xc1, 0x6a, 0xd8, 0x0f, 0xbf, 0xc1, 0x7b, 0x6a, 0x5f, 0xc4, 0x8a, 0x27, 0xea, 0x4a, - 0x4e, 0x44, 0xcb, 0x5b, 0x88, 0x6a, 0x62, 0x3b, 0x4e, 0xc2, 0x88, 0x36, 0xb8, 0x08, 0x61, 0x5d, - 0xb9, 0x26, 0xda, 0xf4, 0x66, 0x2b, 0xee, 0xc2, 0x50, 0x98, 0x09, 0xea, 0xf7, 0x22, 0x94, 0x4f, - 0x14, 0xdb, 0x30, 0xce, 0x85, 0x85, 0x5c, 0xb7, 0x88, 0x5c, 0x05, 0x51, 0x71, 0x8b, 0xe4, 0x41, - 0x58, 0x0b, 0x65, 0x63, 0x6c, 0xa7, 0x83, 0x1d, 0xf3, 0x48, 0x2c, 0x87, 0x7f, 0xec, 0x1d, 0x56, - 0x5d, 0xfb, 0x75, 0x12, 0x0a, 0x99, 0x27, 0x9f, 0x89, 0x38, 0xab, 0xbf, 0x92, 0x1b, 0x0e, 0x7a, - 0x54, 0x6a, 0x87, 0x75, 0x08, 0xd4, 0x55, 0x68, 0x06, 0x3b, 0x74, 0x5f, 0x7e, 0x01, 0x95, 0x5e, - 0xdd, 0x7c, 0xc5, 0xe2, 0xe1, 0x9a, 0xdd, 0x39, 0x97, 0x3a, 0xe2, 0xf5, 0xea, 0x22, 0x2a, 0x7e, - 0x24, 0x19, 0x5e, 0x9d, 0xdb, 0x94, 0x3f, 0x03, 0x99, 0x3d, 0x0c, 0x66, 0x9c, 0x95, 0x50, 0x12, - 0x27, 0xcc, 0x64, 0x44, 0x79, 0x56, 0x2e, 0x86, 0xec, 0x41, 0x10, 0x32, 0x2e, 0x42, 0x4c, 0x98, - 0xfa, 0x89, 0xc2, 0x46, 0x98, 0x01, 0xbd, 0x60, 0x10, 0x2c, 0x86, 0x56, 0xb0, 0x43, 0x3f, 0x30, - 0x1b, 0xec, 0xa4, 0x51, 0xdf, 0x67, 0x8f, 0x9d, 0x5b, 0x1d, 0x11, 0x5b, 0x0c, 0x21, 0x76, 0x71, - 0x27, 0x89, 0xb9, 0xb0, 0x09, 0xbe, 0x81, 0xf0, 0xaa, 0x52, 0xfc, 0x4f, 0xe8, 0xbe, 0xd5, 0xbc, - 0x19, 0x15, 0xe7, 0x49, 0x0e, 0xce, 0xcd, 0x94, 0x39, 0x10, 0x03, 0xcb, 0x40, 0xd4, 0xdb, 0xb7, - 0x28, 0xa1, 0x95, 0x72, 0x87, 0x75, 0x6c, 0x1a, 0x5d, 0xb6, 0x1a, 0xfe, 0x4e, 0x7d, 0x82, 0x39, - 0x6e, 0x6e, 0x65, 0x06, 0x1e, 0x06, 0x57, 0x2c, 0x41, 0x69, 0xaa, 0x7f, 0xd1, 0xb9, 0x2f, 0x6c, - 0x33, 0x0e, 0x72, 0x81, 0x72, 0x61, 0x06, 0xc7, 0x32, 0xf8, 0x39, 0x43, 0x4c, 0x56, 0xc5, 0x57, - 0x38, 0xd0, 0xc2, 0xe0, 0x60, 0x5f, 0xb2, 0x2d, 0x4f, 0x17, 0xb9, 0x5d, 0xb9, 0x70, 0x20, 0x06, - 0x9e, 0x0d, 0xd7, 0x03, 0x21, 0x59, 0x6f, 0xb4, 0x4a, 0xea, 0x0f, 0xcb, 0xc2, 0xf1, 0xe2, 0xb6, - 0x95, 0xe6, 0x9a, 0xb8, 0x7e, 0x15, 0xf3, 0x0c, 0xae, 0x39, 0x6f, 0x1b, 0x34, 0x56, 0x6c, 0x5c, - 0xb9, 0x41, 0x07, 0x4d, 0xb4, 0xc2, 0xb9, 0x01, 0x5a, 0x05, 0x7d, 0x07, 0x07, 0x98, 0x07, 0x4f, - 0xb2, 0xad, 0x18, 0x99, 0x9b, 0xc4, 0x9c, 0x8e, 0xb9, 0x19, 0x36, 0x54, 0x1c, 0x3d, 0xba, 0x81, - 0x16, 0x00, 0x7a, 0x39, 0xf5, 0x43, 0x40, 0x3b, 0x66, 0xfc, 0xf9, 0xf6, 0x81, 0xc1, 0xa1, 0x70, - 0x08, 0x5c, 0xa2, 0x8d, 0x4e, 0x2f, 0x45, 0xfb, 0xf6, 0x24, 0x8b, 0xc0, 0x57, 0xe1, 0x17, 0x17, - 0x77, 0xf4, 0xd1, 0xea, 0xa5, 0x98, 0x1f, 0x8e, 0x6a, 0xce, 0x1f, 0xe2, 0x74, 0xf3, 0x6f, 0x05, - 0xd7, 0x38, 0x45, 0xc7, 0x01, 0xd5, 0x8c, 0x55, 0x48, 0x1b, 0xc4, 0x4d, 0x85, 0x34, 0xd3, 0x43, - 0x3b, 0xfd, 0x9d, 0xdf, 0xdd, 0xd4, 0xd4, 0x34, 0xc2, 0xb4, 0xb6, 0xdc, 0x08, 0x0f, 0xc0, 0x35, - 0xfe, 0xa0, 0xe3, 0x94, 0x9a, 0x0a, 0x75, 0x3d, 0x38, 0xc2, 0xc6, 0xc3, 0xb7, 0xae, 0xce, 0x82, - 0x7e, 0x5a, 0xde, 0x2d, 0x70, 0xd5, 0x50, 0xb3, 0x7e, 0x88, 0x2a, 0xc1, 0x9b, 0xa0, 0x25, 0x55, - 0xda, 0x58, 0x57, 0x33, 0xa1, 0xae, 0x07, 0xc6, 0xd1, 0x48, 0x38, 0x92, 0xd6, 0x59, 0xd0, 0x5f, - 0x0b, 0x04, 0xbf, 0x02, 0x61, 0x4d, 0x90, 0xd5, 0x37, 0xc4, 0xb3, 0x1c, 0xab, 0x9f, 0x57, 0x0e, - 0x11, 0xa4, 0x07, 0xd3, 0xac, 0x1e, 0x8f, 0xf4, 0x35, 0xf9, 0x79, 0x6f, 0x0c, 0x22, 0x46, 0x9f, - 0xd6, 0xcc, 0xc7, 0x18, 0xaa, 0xa9, 0x63, 0xbd, 0x37, 0x06, 0x25, 0x04, 0x3b, 0x7b, 0x52, 0x5b, - 0xea, 0x7e, 0x80, 0xa3, 0x54, 0x33, 0x5f, 0x27, 0x3b, 0x9f, 0x34, 0xc4, 0xbc, 0xd1, 0x5d, 0x5f, - 0x57, 0x4d, 0x0f, 0xbd, 0x77, 0xba, 0x6a, 0xd5, 0x17, 0xf4, 0xa8, 0xa5, 0xb7, 0xe1, 0x7e, 0x04, - 0x62, 0x26, 0x81, 0x39, 0x45, 0xe8, 0x7e, 0xfc, 0x10, 0xf4, 0xba, 0x50, 0x57, 0x58, 0xd3, 0xc8, - 0xb3, 0xf0, 0x39, 0x54, 0x1b, 0xaf, 0xf9, 0xe1, 0x2e, 0x50, 0x81, 0xea, 0x66, 0x4b, 0xf9, 0xf2, - 0x38, 0x81, 0xb4, 0x4b, 0x7a, 0x29, 0x15, 0x1e, 0x66, 0x47, 0x5c, 0xff, 0x42, 0xf2, 0xa8, 0x1a, - 0x0c, 0x1d, 0xa1, 0x3a, 0xb6, 0x87, 0x92, 0x84, 0xb0, 0xbf, 0x0f, 0x24, 0xad, 0x5b, 0x2f, 0xb1, - 0xdf, 0x8b, 0x85, 0xb7, 0xf9, 0x55, 0x6b, 0x2e, 0xa6, 0xcc, 0x1f, 0x87, 0xbd, 0x49, 0x26, 0x79, - 0x90, 0xbd, 0xcf, 0xfe, 0xf2, 0x5b, 0xb3, 0x88, 0x76, 0x7a, 0x92, 0x5f, 0x41, 0x9b, 0xdb, 0x11, - 0xfb, 0x72, 0x4f, 0x99, 0x26, 0xa7, 0x5b, 0xa3, 0x97, 0xdf, 0x54, 0x5b, 0x39, 0xbb, 0xda, 0x6a, - 0x27, 0x82, 0xfa, 0x16, 0x0c, 0x1e, 0x8f, 0xd9, 0x97, 0x7b, 0xda, 0x34, 0xa9, 0x6f, 0x10, 0x66, - 0x8c, 0x31, 0x2b, 0x31, 0xe5, 0xb1, 0x11, 0xf9, 0x53, 0xe4, 0xde, 0x89, 0xc8, 0x17, 0x96, 0x32, - 0x4d, 0x4a, 0x9c, 0x19, 0xfa, 0x14, 0x16, 0x1b, 0xdc, 0x6f, 0x3d, 0xd9, 0xf9, 0xb2, 0xd5, 0xe0, - 0x0e, 0xf5, 0x25, 0xc1, 0x9f, 0xb2, 0xb5, 0xcb, 0x83, 0x2a, 0xa2, 0x87, 0x80, 0xf9, 0x6a, 0x5e, - 0xd3, 0xc7, 0x8c, 0x38, 0x69, 0xec, 0x5b, 0x0f, 0x76, 0xbc, 0x1e, 0xd7, 0xde, 0x9b, 0x3c, 0x8a, - 0xf5, 0x1d, 0xc2, 0x8c, 0x9b, 0x54, 0xd6, 0x40, 0xd7, 0x0f, 0x12, 0x65, 0xfd, 0xaa, 0x7e, 0x00, - 0xe6, 0x09, 0xa1, 0xfa, 0xe8, 0xab, 0xae, 0x37, 0x66, 0xe2, 0x84, 0x20, 0xb4, 0x37, 0xb4, 0x48, - 0xb1, 0x15, 0xfa, 0xc6, 0x70, 0x0c, 0x4e, 0xc2, 0x9f, 0xd6, 0x3e, 0x55, 0xf5, 0x9d, 0xbf, 0x7e, - 0x02, 0xc1, 0x5a, 0xf5, 0x5c, 0x95, 0xf2, 0x2a, 0x42, 0x57, 0xf3, 0x5d, 0x30, 0xef, 0xed, 0xfa, - 0x30, 0x8b, 0x68, 0x2d, 0x0c, 0xf6, 0x43, 0x52, 0x68, 0xb2, 0x8f, 0xbd, 0x67, 0xeb, 0xc3, 0x29, - 0x2a, 0x31, 0xb1, 0x04, 0xf6, 0xc1, 0x19, 0xd0, 0x4b, 0x2b, 0x3d, 0x3c, 0xef, 0x05, 0xfd, 0x87, - 0xc5, 0xc0, 0xba, 0x31, 0x52, 0xad, 0x50, 0x4c, 0x35, 0x42, 0xd7, 0x0f, 0x50, 0xb5, 0xfd, 0x7c, - 0x68, 0xf7, 0x2f, 0xa6, 0x49, 0x6c, 0x47, 0x4c, 0x46, 0x1e, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIcon[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x50, 0x21, 0x2b, - 0x21, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xeb, 0x6b, 0x49, 0x00, 0x00, - 0x01, 0xe9, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x98, 0xbf, 0x2f, 0x04, 0x41, 0x14, 0xc7, - 0x77, 0xb9, 0x82, 0x88, 0x82, 0x56, 0x4f, 0x68, 0x88, 0x48, 0x88, 0x6b, 0x2e, 0x21, 0x41, 0xe9, - 0x3f, 0x50, 0x88, 0x46, 0xc5, 0x3f, 0xa0, 0xd2, 0x8a, 0x44, 0xab, 0xf0, 0x0f, 0xe8, 0x28, 0x50, - 0x9f, 0x46, 0xa3, 0x11, 0x09, 0x11, 0xc5, 0x35, 0x2a, 0x91, 0x08, 0x22, 0x7e, 0x9c, 0xcf, 0x3b, - 0x7b, 0xc9, 0x4e, 0x76, 0x2e, 0xe6, 0xe6, 0x47, 0xf6, 0x24, 0xfb, 0x92, 0x6f, 0x76, 0xe6, 0xcd, - 0x7b, 0xdf, 0x79, 0x6f, 0xde, 0xde, 0xcc, 0xec, 0xc5, 0xf5, 0x7a, 0x3d, 0x8e, 0xa2, 0x68, 0x0b, - 0x2c, 0x83, 0x21, 0xe0, 0x2a, 0x6f, 0x10, 0x9c, 0x80, 0xed, 0x38, 0x8e, 0xef, 0x5d, 0xc9, 0x8c, - 0xfd, 0x49, 0xa4, 0x0c, 0x42, 0xc8, 0x8e, 0x71, 0x10, 0x1e, 0x0c, 0x4b, 0x70, 0x2c, 0x79, 0xe0, - 0xd1, 0x51, 0x2c, 0xa2, 0xdc, 0xd4, 0x0d, 0xa4, 0x75, 0xac, 0xe0, 0x00, 0xfd, 0xf1, 0xb4, 0xce, - 0xb0, 0x5d, 0xa3, 0xe2, 0x77, 0x4d, 0x5b, 0x49, 0xa4, 0xa7, 0xd9, 0xf1, 0xfc, 0xfc, 0x93, 0x97, - 0x24, 0x76, 0x99, 0x73, 0x1d, 0x48, 0x1c, 0x6d, 0x0b, 0xfe, 0x97, 0x38, 0xcd, 0x90, 0xd0, 0x7b, - 0x57, 0xdb, 0xde, 0x9e, 0x1c, 0x08, 0xa2, 0x0f, 0xaa, 0x35, 0x60, 0x95, 0x44, 0x12, 0xc6, 0x04, - 0xcf, 0x05, 0x69, 0xe7, 0x96, 0x08, 0x73, 0x8f, 0x81, 0x5e, 0x09, 0xc2, 0x51, 0xa6, 0xc4, 0x3f, - 0xcf, 0x44, 0x1c, 0xe3, 0x57, 0xdd, 0x8b, 0x44, 0xd4, 0xf5, 0xc8, 0xbf, 0x57, 0x54, 0x24, 0xff, - 0x1a, 0xa8, 0x11, 0x48, 0x45, 0x5e, 0x54, 0x95, 0xb7, 0x5e, 0x28, 0x5e, 0x6d, 0x80, 0x92, 0xc8, - 0x91, 0x76, 0xc4, 0x5d, 0x79, 0xec, 0x4e, 0x61, 0xce, 0x50, 0xe2, 0x54, 0xbc, 0xe0, 0x70, 0xda, - 0xc0, 0xc5, 0xd7, 0xa5, 0xf1, 0x15, 0x2e, 0xb9, 0x34, 0xee, 0x99, 0x87, 0xe1, 0x6e, 0xd9, 0x38, - 0x55, 0x49, 0x46, 0xae, 0x0a, 0x82, 0x7f, 0x2b, 0xc5, 0xae, 0xd5, 0x69, 0xa5, 0x2b, 0x2a, 0xd2, - 0x69, 0x15, 0xd1, 0x5e, 0xa1, 0xd9, 0xc5, 0x46, 0x09, 0x74, 0x15, 0x94, 0x41, 0xb7, 0x65, 0xd0, - 0x5f, 0xf8, 0x55, 0xc1, 0x3e, 0x9b, 0xc9, 0xb5, 0x25, 0x87, 0xb1, 0x9b, 0x36, 0x11, 0xbc, 0x65, - 0xeb, 0x9c, 0x33, 0x66, 0x69, 0x6d, 0x38, 0xcd, 0x90, 0x7c, 0xfd, 0xcd, 0xb7, 0x36, 0xf1, 0x33, - 0x92, 0xf9, 0x8d, 0x50, 0x8d, 0x7e, 0xa8, 0x2b, 0x7e, 0xe8, 0x1b, 0x2c, 0x95, 0x84, 0xd3, 0x23, - 0x65, 0x96, 0x2a, 0x93, 0x08, 0x26, 0xf2, 0xe5, 0x66, 0xfb, 0x3a, 0x65, 0x67, 0xf8, 0xe5, 0x12, - 0xce, 0xa0, 0xa2, 0x4b, 0x24, 0xe8, 0x84, 0xa1, 0xc8, 0x8b, 0x44, 0x42, 0xad, 0xac, 0x2d, 0x6f, - 0x9e, 0x15, 0xb9, 0x25, 0xe8, 0x0f, 0xdb, 0xc0, 0x53, 0x7e, 0x57, 0xd2, 0xce, 0x2d, 0x11, 0xce, - 0x96, 0x27, 0xe6, 0x3f, 0x4c, 0x05, 0x64, 0xd3, 0x7c, 0xc0, 0xa9, 0xf1, 0x19, 0x22, 0xff, 0xfb, - 0x2a, 0x92, 0x6c, 0x95, 0x8f, 0x28, 0x5b, 0x9d, 0x31, 0x8a, 0xbd, 0x41, 0xe7, 0x13, 0x9b, 0x41, - 0x02, 0x7f, 0xd6, 0xd9, 0x32, 0xdf, 0x08, 0xfa, 0x49, 0x90, 0x89, 0x45, 0x67, 0x9f, 0xd2, 0xd5, - 0x68, 0x57, 0xe1, 0xfd, 0x4e, 0xe9, 0xd4, 0x26, 0xe4, 0x67, 0xc0, 0x97, 0x9c, 0xaa, 0xec, 0x61, - 0x7a, 0xda, 0x55, 0x20, 0x83, 0x61, 0xa6, 0x5b, 0x01, 0xb3, 0xc0, 0xf6, 0x4c, 0x91, 0x2b, 0xca, - 0x39, 0x38, 0x60, 0xd5, 0x6e, 0x78, 0x16, 0x62, 0xb2, 0x02, 0x3f, 0xb2, 0x15, 0xf7, 0xb1, 0x2c, - 0xc1, 0x90, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x50, 0x21, 0x2b, - 0x21, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xeb, 0x6b, 0x49, 0x00, 0x00, - 0x01, 0xe9, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x98, 0xbf, 0x2f, 0x04, 0x41, 0x14, 0xc7, - 0x77, 0xb9, 0x82, 0x88, 0x82, 0x56, 0x4f, 0x68, 0x88, 0x48, 0x88, 0x6b, 0x2e, 0x21, 0x41, 0xe9, - 0x3f, 0x50, 0x88, 0x46, 0xc5, 0x3f, 0xa0, 0xd2, 0x8a, 0x44, 0xab, 0xf0, 0x0f, 0xe8, 0x28, 0x50, - 0x9f, 0x46, 0xa3, 0x11, 0x09, 0x11, 0xc5, 0x35, 0x2a, 0x91, 0x08, 0x22, 0x7e, 0x9c, 0xcf, 0x3b, - 0x7b, 0xc9, 0x4e, 0x76, 0x2e, 0xe6, 0xe6, 0x47, 0xf6, 0x24, 0xfb, 0x92, 0x6f, 0x76, 0xe6, 0xcd, - 0x7b, 0xdf, 0x79, 0x6f, 0xde, 0xde, 0xcc, 0xec, 0xc5, 0xf5, 0x7a, 0x3d, 0x8e, 0xa2, 0x68, 0x0b, - 0x2c, 0x83, 0x21, 0xe0, 0x2a, 0x6f, 0x10, 0x9c, 0x80, 0xed, 0x38, 0x8e, 0xef, 0x5d, 0xc9, 0x8c, - 0xfd, 0x49, 0xa4, 0x0c, 0x42, 0xc8, 0x8e, 0x71, 0x10, 0x1e, 0x0c, 0x4b, 0x70, 0x2c, 0x79, 0xe0, - 0xd1, 0x51, 0x2c, 0xa2, 0xdc, 0xd4, 0x0d, 0xa4, 0x75, 0xac, 0xe0, 0x00, 0xfd, 0xf1, 0xb4, 0xce, - 0xb0, 0x5d, 0xa3, 0xe2, 0x77, 0x4d, 0x5b, 0x49, 0xa4, 0xa7, 0xd9, 0xf1, 0xfc, 0xfc, 0x93, 0x97, - 0x24, 0x76, 0x99, 0x73, 0x1d, 0x48, 0x1c, 0x6d, 0x0b, 0xfe, 0x97, 0x38, 0xcd, 0x90, 0xd0, 0x7b, - 0x57, 0xdb, 0xde, 0x9e, 0x1c, 0x08, 0xa2, 0x0f, 0xaa, 0x35, 0x60, 0x95, 0x44, 0x12, 0xc6, 0x04, - 0xcf, 0x05, 0x69, 0xe7, 0x96, 0x08, 0x73, 0x8f, 0x81, 0x5e, 0x09, 0xc2, 0x51, 0xa6, 0xc4, 0x3f, - 0xcf, 0x44, 0x1c, 0xe3, 0x57, 0xdd, 0x8b, 0x44, 0xd4, 0xf5, 0xc8, 0xbf, 0x57, 0x54, 0x24, 0xff, - 0x1a, 0xa8, 0x11, 0x48, 0x45, 0x5e, 0x54, 0x95, 0xb7, 0x5e, 0x28, 0x5e, 0x6d, 0x80, 0x92, 0xc8, - 0x91, 0x76, 0xc4, 0x5d, 0x79, 0xec, 0x4e, 0x61, 0xce, 0x50, 0xe2, 0x54, 0xbc, 0xe0, 0x70, 0xda, - 0xc0, 0xc5, 0xd7, 0xa5, 0xf1, 0x15, 0x2e, 0xb9, 0x34, 0xee, 0x99, 0x87, 0xe1, 0x6e, 0xd9, 0x38, - 0x55, 0x49, 0x46, 0xae, 0x0a, 0x82, 0x7f, 0x2b, 0xc5, 0xae, 0xd5, 0x69, 0xa5, 0x2b, 0x2a, 0xd2, - 0x69, 0x15, 0xd1, 0x5e, 0xa1, 0xd9, 0xc5, 0x46, 0x09, 0x74, 0x15, 0x94, 0x41, 0xb7, 0x65, 0xd0, - 0x5f, 0xf8, 0x55, 0xc1, 0x3e, 0x9b, 0xc9, 0xb5, 0x25, 0x87, 0xb1, 0x9b, 0x36, 0x11, 0xbc, 0x65, - 0xeb, 0x9c, 0x33, 0x66, 0x69, 0x6d, 0x38, 0xcd, 0x90, 0x7c, 0xfd, 0xcd, 0xb7, 0x36, 0xf1, 0x33, - 0x92, 0xf9, 0x8d, 0x50, 0x8d, 0x7e, 0xa8, 0x2b, 0x7e, 0xe8, 0x1b, 0x2c, 0x95, 0x84, 0xd3, 0x23, - 0x65, 0x96, 0x2a, 0x93, 0x08, 0x26, 0xf2, 0xe5, 0x66, 0xfb, 0x3a, 0x65, 0x67, 0xf8, 0xe5, 0x12, - 0xce, 0xa0, 0xa2, 0x4b, 0x24, 0xe8, 0x84, 0xa1, 0xc8, 0x8b, 0x44, 0x42, 0xad, 0xac, 0x2d, 0x6f, - 0x9e, 0x15, 0xb9, 0x25, 0xe8, 0x0f, 0xdb, 0xc0, 0x53, 0x7e, 0x57, 0xd2, 0xce, 0x2d, 0x11, 0xce, - 0x96, 0x27, 0xe6, 0x3f, 0x4c, 0x05, 0x64, 0xd3, 0x7c, 0xc0, 0xa9, 0xf1, 0x19, 0x22, 0xff, 0xfb, - 0x2a, 0x92, 0x6c, 0x95, 0x8f, 0x28, 0x5b, 0x9d, 0x31, 0x8a, 0xbd, 0x41, 0xe7, 0x13, 0x9b, 0x41, - 0x02, 0x7f, 0xd6, 0xd9, 0x32, 0xdf, 0x08, 0xfa, 0x49, 0x90, 0x89, 0x45, 0x67, 0x9f, 0xd2, 0xd5, - 0x68, 0x57, 0xe1, 0xfd, 0x4e, 0xe9, 0xd4, 0x26, 0xe4, 0x67, 0xc0, 0x97, 0x9c, 0xaa, 0xec, 0x61, - 0x7a, 0xda, 0x55, 0x20, 0x83, 0x61, 0xa6, 0x5b, 0x01, 0xb3, 0xc0, 0xf6, 0x4c, 0x91, 0x2b, 0xca, - 0x39, 0x38, 0x60, 0xd5, 0x6e, 0x78, 0x16, 0x62, 0xb2, 0x02, 0x3f, 0xb2, 0x15, 0xf7, 0xb1, 0x2c, - 0xc1, 0x90, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x59, 0xab, 0x87, - 0xe8, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4b, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x09, 0xb6, 0x65, 0x00, 0x00, - 0x02, 0x81, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9b, 0x3d, 0x4b, 0xc4, 0x40, 0x10, 0x86, - 0x8d, 0x1f, 0xa0, 0x88, 0x82, 0x95, 0x36, 0x5a, 0x9c, 0x82, 0xf8, 0x07, 0x2c, 0xc5, 0x4a, 0x2c, - 0xac, 0x6c, 0xfc, 0x05, 0x5a, 0x9d, 0x56, 0x76, 0x36, 0xd7, 0x58, 0xc8, 0x29, 0x36, 0xfe, 0x03, - 0x7b, 0xc5, 0x4a, 0x0b, 0x11, 0x3c, 0x6b, 0x41, 0xad, 0x04, 0x3f, 0x8a, 0x03, 0xf1, 0xaa, 0x43, - 0x94, 0x13, 0x44, 0x24, 0xbe, 0x03, 0x6e, 0x8a, 0x80, 0xbb, 0x99, 0x4b, 0x76, 0xb3, 0xe1, 0x66, - 0x60, 0x88, 0x31, 0xb3, 0xf3, 0xce, 0x3c, 0x6e, 0x72, 0xd9, 0xe4, 0x0c, 0xba, 0x60, 0x61, 0x18, - 0x8e, 0x60, 0xb3, 0x05, 0x9f, 0x83, 0x8f, 0xc1, 0x03, 0xb8, 0x6d, 0x0b, 0x21, 0xd0, 0x80, 0x5f, - 0xc2, 0xb7, 0x83, 0x20, 0x78, 0xb3, 0x2d, 0x98, 0x49, 0x7e, 0xc0, 0xba, 0x80, 0xe7, 0x69, 0xe7, - 0x99, 0x34, 0x62, 0x39, 0x49, 0x00, 0x42, 0xd3, 0xd0, 0xb8, 0xb7, 0xac, 0x93, 0x24, 0xfd, 0x14, - 0x66, 0xd7, 0x53, 0x92, 0xc0, 0xbc, 0x62, 0xba, 0x21, 0x3c, 0x99, 0x97, 0x78, 0x4c, 0xb7, 0x14, - 0xdb, 0xf7, 0x6e, 0xb7, 0x17, 0x15, 0xf5, 0x7b, 0x52, 0x15, 0xbb, 0x0e, 0x9c, 0x15, 0x8b, 0xa8, - 0x7d, 0x03, 0x4e, 0xa0, 0x07, 0x32, 0xec, 0xa3, 0x85, 0x5c, 0x0f, 0xf0, 0x3d, 0xcc, 0xf6, 0x9a, - 0xca, 0x4b, 0xb0, 0x0a, 0x69, 0x00, 0x35, 0x8f, 0xc2, 0x4f, 0x2d, 0x16, 0x3f, 0x83, 0xdc, 0x4b, - 0xd0, 0x99, 0x05, 0xb0, 0x6b, 0xd2, 0xa1, 0xd3, 0xb0, 0xa8, 0xb6, 0xe6, 0xa0, 0x70, 0xe2, 0xb3, - 0xaa, 0x74, 0x8a, 0x0c, 0xab, 0xa4, 0x9a, 0xb0, 0xbc, 0x8d, 0xae, 0xe9, 0x45, 0x86, 0xc5, 0xbe, - 0xc6, 0xb5, 0x09, 0x35, 0xd2, 0x29, 0x32, 0xac, 0x36, 0x7b, 0x6f, 0x7f, 0x98, 0xc0, 0x62, 0xb0, - 0x13, 0x58, 0x02, 0x8b, 0x41, 0x80, 0x11, 0x2a, 0x33, 0x4b, 0x60, 0x31, 0x08, 0x30, 0x42, 0x65, - 0x66, 0x09, 0x2c, 0x06, 0x01, 0x46, 0x28, 0xcd, 0x2c, 0x5a, 0x34, 0xfa, 0x60, 0xbe, 0xd4, 0xf1, - 0x2f, 0x0b, 0x82, 0x45, 0xab, 0x6b, 0x1f, 0xec, 0xd1, 0x87, 0x22, 0x74, 0x35, 0x74, 0x63, 0x45, - 0xfd, 0x8c, 0x80, 0x13, 0x5d, 0x90, 0x83, 0x63, 0x47, 0xa8, 0xa3, 0xee, 0x40, 0x27, 0x95, 0x84, - 0x7a, 0x44, 0xb3, 0x82, 0x2c, 0xeb, 0x70, 0x7a, 0x06, 0x3f, 0x0a, 0x77, 0xf9, 0x0c, 0xbe, 0x06, - 0xbd, 0x03, 0xb8, 0x98, 0x2d, 0x02, 0x78, 0xce, 0x74, 0x03, 0x77, 0x61, 0x57, 0xaa, 0x07, 0xba, - 0x66, 0x89, 0x25, 0x24, 0x20, 0xb0, 0x12, 0x82, 0xa2, 0x30, 0x81, 0x25, 0xb0, 0x18, 0x04, 0x18, - 0xa1, 0x32, 0xb3, 0x04, 0x16, 0x83, 0x00, 0x23, 0x54, 0xdd, 0x67, 0x69, 0x87, 0xe0, 0xf3, 0xb9, - 0x0f, 0x01, 0x13, 0xf0, 0x61, 0x6d, 0x60, 0xba, 0x83, 0xef, 0x18, 0x5e, 0xc7, 0xcd, 0xe9, 0x77, - 0xba, 0x34, 0xf6, 0x46, 0x1b, 0x61, 0x01, 0xd4, 0x26, 0xe4, 0x2b, 0xf0, 0x41, 0x7b, 0x65, 0x44, - 0x99, 0x5b, 0xd0, 0xab, 0x00, 0xd8, 0x6e, 0xf4, 0x1b, 0x8f, 0x7e, 0xd0, 0x5e, 0xb3, 0x50, 0x38, - 0xdd, 0xd1, 0x57, 0xe1, 0x2e, 0x40, 0x11, 0x16, 0xd2, 0xa9, 0xfe, 0xe9, 0xd2, 0xbe, 0x57, 0xa6, - 0x85, 0x85, 0x4a, 0x17, 0x72, 0xaa, 0x36, 0x2f, 0x5d, 0x6d, 0xbb, 0x26, 0x58, 0xe3, 0xda, 0xd1, - 0xf6, 0x0e, 0xe6, 0xa5, 0xab, 0xed, 0xc8, 0x04, 0xab, 0x47, 0x3b, 0xda, 0xde, 0xc1, 0xbc, 0x74, - 0xb5, 0x1d, 0x99, 0x60, 0x69, 0x07, 0x77, 0xda, 0x41, 0x81, 0xc5, 0xf8, 0x8b, 0x0b, 0x2c, 0x81, - 0xc5, 0x20, 0xc0, 0x08, 0x95, 0x99, 0xd5, 0x21, 0xb0, 0x9a, 0x8c, 0x3e, 0xd3, 0x84, 0x46, 0x3a, - 0x45, 0x9e, 0x59, 0x77, 0x69, 0x08, 0x30, 0xc6, 0xde, 0xaa, 0xd8, 0x22, 0xc3, 0xda, 0x41, 0x13, - 0x2f, 0xaa, 0x11, 0x4b, 0x5b, 0xfa, 0xaa, 0xf9, 0xbe, 0xca, 0x6d, 0x5a, 0x48, 0xff, 0xa8, 0x40, - 0xc7, 0x5b, 0xa3, 0x2e, 0x16, 0xdb, 0xaf, 0x58, 0x43, 0xd2, 0x77, 0xf8, 0x97, 0xe1, 0x25, 0x78, - 0xf4, 0x0d, 0xbd, 0x0c, 0x6a, 0xfd, 0x44, 0x0e, 0x7a, 0x9f, 0x7a, 0x0c, 0x9d, 0x2f, 0x95, 0xcf, - 0x04, 0xab, 0xae, 0x02, 0x1d, 0x6f, 0x13, 0xe9, 0xa2, 0x11, 0x7a, 0x8b, 0x7d, 0xe8, 0xaa, 0x36, - 0xd3, 0x69, 0x78, 0xe6, 0xaa, 0x90, 0x98, 0x4e, 0x5e, 0xba, 0xb1, 0x32, 0x98, 0xbb, 0x98, 0xea, - 0x65, 0x78, 0x13, 0xee, 0xc2, 0x48, 0xa7, 0xcc, 0x2c, 0xd1, 0x59, 0x78, 0xe2, 0x37, 0xcf, 0x68, - 0x82, 0xfe, 0x5b, 0x6c, 0xc8, 0x62, 0x65, 0x1f, 0x38, 0xad, 0x1a, 0x16, 0xf3, 0x4b, 0x6a, 0x97, - 0x04, 0x7e, 0x01, 0x1e, 0xdc, 0xbb, 0x6b, 0x41, 0x9a, 0x28, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRecentTabIcon[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x28, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9b, 0xdc, 0x28, - 0xa4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x48, 0xca, 0xb9, 0xf5, 0x00, 0x00, - 0x02, 0x99, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xdd, 0x98, 0xcf, 0x6f, 0x0d, 0x51, 0x14, 0xc7, - 0x67, 0x8a, 0x60, 0x41, 0xfc, 0x4a, 0x10, 0x45, 0x35, 0x84, 0x26, 0x24, 0x62, 0x61, 0x41, 0xf0, - 0x22, 0x12, 0x1b, 0x61, 0x53, 0xec, 0x24, 0x76, 0x36, 0xfe, 0x00, 0x6b, 0x89, 0xa5, 0x85, 0xb5, - 0xb4, 0x76, 0x92, 0xb2, 0x22, 0xd6, 0x15, 0x0b, 0x56, 0x7e, 0x84, 0x1d, 0x41, 0xc2, 0x13, 0x21, - 0x0d, 0x0b, 0x91, 0x94, 0xb4, 0x9e, 0xcf, 0xf7, 0x71, 0xd3, 0xd3, 0xd7, 0x3b, 0xbd, 0xf7, 0xcd, - 0x9b, 0x3b, 0x1a, 0x27, 0xf9, 0x66, 0xce, 0x3d, 0x73, 0xee, 0xf7, 0x7c, 0xdf, 0xbd, 0xa7, 0x77, - 0x66, 0x9a, 0x65, 0x7f, 0xad, 0xd5, 0x6a, 0x9d, 0x01, 0xf7, 0xc1, 0x47, 0xd0, 0x8b, 0x4d, 0x33, - 0xf9, 0x2d, 0xb8, 0x07, 0x0e, 0x38, 0xfe, 0xa8, 0x2b, 0x13, 0xae, 0x82, 0x14, 0xf6, 0x0b, 0xd2, - 0x73, 0x31, 0x22, 0x72, 0x12, 0x77, 0x93, 0xf8, 0x0c, 0x2c, 0x32, 0x13, 0xbe, 0xe0, 0x4f, 0x9b, - 0x71, 0x37, 0xee, 0x52, 0x92, 0x57, 0x9a, 0x09, 0x13, 0xf8, 0x83, 0x79, 0x9e, 0x7f, 0x33, 0xb1, - 0xb9, 0x2e, 0x42, 0x2e, 0x9a, 0xa5, 0x78, 0x82, 0xbf, 0x69, 0x6e, 0x56, 0x77, 0x11, 0x38, 0xf6, - 0x82, 0x09, 0xc3, 0x7b, 0x28, 0xc4, 0xd0, 0x47, 0xc2, 0x76, 0x93, 0x74, 0x0d, 0xe5, 0x1f, 0xcc, - 0xb8, 0x94, 0x0b, 0x87, 0x56, 0xf8, 0xa6, 0x99, 0x6c, 0x6b, 0x98, 0xf0, 0x8c, 0x2b, 0x21, 0x2b, - 0x66, 0x86, 0x99, 0x96, 0xb1, 0x2a, 0xb3, 0x5c, 0xb6, 0x86, 0x97, 0x5f, 0x42, 0x16, 0x84, 0x2d, - 0x8e, 0x55, 0xc1, 0x7e, 0xef, 0x27, 0x77, 0x08, 0xa8, 0x87, 0x62, 0x7e, 0xc0, 0x61, 0xc3, 0x7d, - 0x9c, 0xf9, 0x6a, 0xe0, 0x16, 0xf8, 0x04, 0x5e, 0x82, 0x87, 0x6c, 0xe1, 0x14, 0xd7, 0x3f, 0x46, - 0xc2, 0x88, 0x69, 0xaa, 0x13, 0x2e, 0xee, 0xae, 0xdc, 0x1b, 0x00, 0xe3, 0x26, 0xa7, 0x2a, 0xf7, - 0x39, 0x44, 0xfb, 0x5c, 0x9d, 0x98, 0x5f, 0x76, 0x83, 0xe4, 0x86, 0x9b, 0x50, 0xe1, 0x75, 0x0f, - 0x5c, 0xb7, 0x11, 0xb3, 0x4c, 0x9c, 0xf3, 0x0a, 0x21, 0x49, 0x27, 0xe3, 0x11, 0x25, 0x26, 0xb2, - 0x6d, 0xf0, 0x9e, 0x15, 0xf7, 0xbc, 0x42, 0xb8, 0xaf, 0x9e, 0x48, 0x6d, 0xbb, 0x54, 0x20, 0x24, - 0x64, 0x4b, 0x6a, 0x15, 0xf0, 0x6f, 0x8e, 0x11, 0x12, 0x12, 0x5a, 0x85, 0xce, 0xf6, 0xa3, 0x25, - 0xfa, 0xcf, 0xd7, 0x53, 0xf1, 0x2e, 0xb1, 0xd8, 0x53, 0x78, 0x15, 0xb9, 0xc3, 0xa0, 0xb0, 0x5e, - 0xe1, 0x0d, 0x4f, 0x61, 0x1b, 0x6a, 0x72, 0x06, 0x9c, 0xb4, 0x81, 0x90, 0x4f, 0xe3, 0x6f, 0x20, - 0xa7, 0x51, 0x94, 0x57, 0x56, 0x48, 0x3f, 0xc4, 0x63, 0x90, 0xbe, 0x2b, 0x22, 0xee, 0x88, 0xaf, - 0x61, 0x7c, 0xb0, 0x23, 0x36, 0x6b, 0x58, 0x56, 0x88, 0x48, 0x4e, 0xcf, 0x62, 0xea, 0x71, 0x50, - 0x47, 0x33, 0x46, 0x49, 0xec, 0x65, 0x45, 0xee, 0x50, 0xa1, 0x19, 0x55, 0x25, 0xcb, 0x56, 0x93, - 0xa7, 0x66, 0x5d, 0x52, 0x94, 0x5f, 0x56, 0x88, 0x9a, 0xf5, 0x54, 0x11, 0xa9, 0x2f, 0x4e, 0x4f, - 0x6d, 0x24, 0xde, 0xf0, 0xdd, 0x53, 0xac, 0xac, 0x10, 0x35, 0xeb, 0x2d, 0xe6, 0xbf, 0x2f, 0x22, - 0xee, 0x88, 0x27, 0x6d, 0x56, 0x2d, 0x75, 0x65, 0xf6, 0xdf, 0x34, 0xab, 0x6f, 0x6b, 0x8e, 0xb2, - 0x4c, 0x5d, 0x3f, 0x2c, 0xcb, 0xf6, 0x48, 0x61, 0xb3, 0xd2, 0x3b, 0x0d, 0x84, 0x8c, 0x77, 0xbb, - 0x67, 0x12, 0xa2, 0xd7, 0x37, 0x67, 0xb9, 0x73, 0x02, 0x57, 0xd7, 0xac, 0x4d, 0x4f, 0xde, 0x31, - 0x4f, 0x2c, 0x18, 0x92, 0x90, 0xcf, 0x26, 0x6b, 0x87, 0xf1, 0x43, 0x6e, 0xa5, 0xcd, 0x2a, 0x21, - 0xaf, 0x4c, 0xc5, 0x4b, 0x2c, 0xad, 0xbe, 0xf2, 0x5e, 0x00, 0xbd, 0xd8, 0xae, 0x37, 0xf7, 0x92, - 0xba, 0x12, 0xa2, 0x13, 0xf2, 0x2b, 0xd0, 0xe9, 0xb7, 0x0e, 0x8c, 0x82, 0xda, 0xad, 0x8f, 0x13, - 0x52, 0x1f, 0x42, 0x17, 0xc0, 0xf7, 0xda, 0xab, 0x9b, 0x82, 0x5a, 0x91, 0x0c, 0x31, 0x63, 0x6c, - 0xc9, 0x23, 0xdc, 0xf3, 0x60, 0x27, 0xd0, 0xbb, 0x83, 0x1a, 0x77, 0x10, 0x6c, 0x05, 0xff, 0xd6, - 0x10, 0x77, 0x19, 0xa4, 0xb6, 0xf6, 0x37, 0xf2, 0x82, 0x39, 0x59, 0x43, 0x42, 0x7e, 0xd6, 0xb0, - 0x27, 0xed, 0x1a, 0x21, 0x21, 0x6f, 0x6a, 0x10, 0xd2, 0xae, 0x11, 0x12, 0xf2, 0x14, 0x21, 0xf6, - 0xe4, 0x4d, 0xa1, 0xeb, 0x71, 0x14, 0x29, 0x9d, 0x3a, 0x9a, 0xb0, 0x5b, 0x1f, 0x44, 0x89, 0x50, - 0x12, 0x22, 0x96, 0x83, 0x2b, 0x60, 0xb2, 0x42, 0x41, 0x53, 0x70, 0x5d, 0x07, 0x6b, 0x9d, 0x90, - 0xd8, 0x87, 0x9c, 0x04, 0xe9, 0xcc, 0x19, 0x00, 0xfd, 0x20, 0xb4, 0xa5, 0xa4, 0x78, 0x4d, 0xdb, - 0xac, 0xff, 0x8f, 0xbc, 0xe6, 0xec, 0xfa, 0x61, 0x33, 0x7e, 0x03, 0xf9, 0x2d, 0xce, 0xa7, 0xa9, - 0x35, 0x85, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRecentTabIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x28, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9b, 0xdc, 0x28, - 0xa4, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x22, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x48, 0xca, 0xb9, 0xf5, 0x00, 0x00, - 0x02, 0x99, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xdd, 0x98, 0xcf, 0x6f, 0x0d, 0x51, 0x14, 0xc7, - 0x67, 0x8a, 0x60, 0x41, 0xfc, 0x4a, 0x10, 0x45, 0x35, 0x84, 0x26, 0x24, 0x62, 0x61, 0x41, 0xf0, - 0x22, 0x12, 0x1b, 0x61, 0x53, 0xec, 0x24, 0x76, 0x36, 0xfe, 0x00, 0x6b, 0x89, 0xa5, 0x85, 0xb5, - 0xb4, 0x76, 0x92, 0xb2, 0x22, 0xd6, 0x15, 0x0b, 0x56, 0x7e, 0x84, 0x1d, 0x41, 0xc2, 0x13, 0x21, - 0x0d, 0x0b, 0x91, 0x94, 0xb4, 0x9e, 0xcf, 0xf7, 0x71, 0xd3, 0xd3, 0xd7, 0x3b, 0xbd, 0xf7, 0xcd, - 0x9b, 0x3b, 0x1a, 0x27, 0xf9, 0x66, 0xce, 0x3d, 0x73, 0xee, 0xf7, 0x7c, 0xdf, 0xbd, 0xa7, 0x77, - 0x66, 0x9a, 0x65, 0x7f, 0xad, 0xd5, 0x6a, 0x9d, 0x01, 0xf7, 0xc1, 0x47, 0xd0, 0x8b, 0x4d, 0x33, - 0xf9, 0x2d, 0xb8, 0x07, 0x0e, 0x38, 0xfe, 0xa8, 0x2b, 0x13, 0xae, 0x82, 0x14, 0xf6, 0x0b, 0xd2, - 0x73, 0x31, 0x22, 0x72, 0x12, 0x77, 0x93, 0xf8, 0x0c, 0x2c, 0x32, 0x13, 0xbe, 0xe0, 0x4f, 0x9b, - 0x71, 0x37, 0xee, 0x52, 0x92, 0x57, 0x9a, 0x09, 0x13, 0xf8, 0x83, 0x79, 0x9e, 0x7f, 0x33, 0xb1, - 0xb9, 0x2e, 0x42, 0x2e, 0x9a, 0xa5, 0x78, 0x82, 0xbf, 0x69, 0x6e, 0x56, 0x77, 0x11, 0x38, 0xf6, - 0x82, 0x09, 0xc3, 0x7b, 0x28, 0xc4, 0xd0, 0x47, 0xc2, 0x76, 0x93, 0x74, 0x0d, 0xe5, 0x1f, 0xcc, - 0xb8, 0x94, 0x0b, 0x87, 0x56, 0xf8, 0xa6, 0x99, 0x6c, 0x6b, 0x98, 0xf0, 0x8c, 0x2b, 0x21, 0x2b, - 0x66, 0x86, 0x99, 0x96, 0xb1, 0x2a, 0xb3, 0x5c, 0xb6, 0x86, 0x97, 0x5f, 0x42, 0x16, 0x84, 0x2d, - 0x8e, 0x55, 0xc1, 0x7e, 0xef, 0x27, 0x77, 0x08, 0xa8, 0x87, 0x62, 0x7e, 0xc0, 0x61, 0xc3, 0x7d, - 0x9c, 0xf9, 0x6a, 0xe0, 0x16, 0xf8, 0x04, 0x5e, 0x82, 0x87, 0x6c, 0xe1, 0x14, 0xd7, 0x3f, 0x46, - 0xc2, 0x88, 0x69, 0xaa, 0x13, 0x2e, 0xee, 0xae, 0xdc, 0x1b, 0x00, 0xe3, 0x26, 0xa7, 0x2a, 0xf7, - 0x39, 0x44, 0xfb, 0x5c, 0x9d, 0x98, 0x5f, 0x76, 0x83, 0xe4, 0x86, 0x9b, 0x50, 0xe1, 0x75, 0x0f, - 0x5c, 0xb7, 0x11, 0xb3, 0x4c, 0x9c, 0xf3, 0x0a, 0x21, 0x49, 0x27, 0xe3, 0x11, 0x25, 0x26, 0xb2, - 0x6d, 0xf0, 0x9e, 0x15, 0xf7, 0xbc, 0x42, 0xb8, 0xaf, 0x9e, 0x48, 0x6d, 0xbb, 0x54, 0x20, 0x24, - 0x64, 0x4b, 0x6a, 0x15, 0xf0, 0x6f, 0x8e, 0x11, 0x12, 0x12, 0x5a, 0x85, 0xce, 0xf6, 0xa3, 0x25, - 0xfa, 0xcf, 0xd7, 0x53, 0xf1, 0x2e, 0xb1, 0xd8, 0x53, 0x78, 0x15, 0xb9, 0xc3, 0xa0, 0xb0, 0x5e, - 0xe1, 0x0d, 0x4f, 0x61, 0x1b, 0x6a, 0x72, 0x06, 0x9c, 0xb4, 0x81, 0x90, 0x4f, 0xe3, 0x6f, 0x20, - 0xa7, 0x51, 0x94, 0x57, 0x56, 0x48, 0x3f, 0xc4, 0x63, 0x90, 0xbe, 0x2b, 0x22, 0xee, 0x88, 0xaf, - 0x61, 0x7c, 0xb0, 0x23, 0x36, 0x6b, 0x58, 0x56, 0x88, 0x48, 0x4e, 0xcf, 0x62, 0xea, 0x71, 0x50, - 0x47, 0x33, 0x46, 0x49, 0xec, 0x65, 0x45, 0xee, 0x50, 0xa1, 0x19, 0x55, 0x25, 0xcb, 0x56, 0x93, - 0xa7, 0x66, 0x5d, 0x52, 0x94, 0x5f, 0x56, 0x88, 0x9a, 0xf5, 0x54, 0x11, 0xa9, 0x2f, 0x4e, 0x4f, - 0x6d, 0x24, 0xde, 0xf0, 0xdd, 0x53, 0xac, 0xac, 0x10, 0x35, 0xeb, 0x2d, 0xe6, 0xbf, 0x2f, 0x22, - 0xee, 0x88, 0x27, 0x6d, 0x56, 0x2d, 0x75, 0x65, 0xf6, 0xdf, 0x34, 0xab, 0x6f, 0x6b, 0x8e, 0xb2, - 0x4c, 0x5d, 0x3f, 0x2c, 0xcb, 0xf6, 0x48, 0x61, 0xb3, 0xd2, 0x3b, 0x0d, 0x84, 0x8c, 0x77, 0xbb, - 0x67, 0x12, 0xa2, 0xd7, 0x37, 0x67, 0xb9, 0x73, 0x02, 0x57, 0xd7, 0xac, 0x4d, 0x4f, 0xde, 0x31, - 0x4f, 0x2c, 0x18, 0x92, 0x90, 0xcf, 0x26, 0x6b, 0x87, 0xf1, 0x43, 0x6e, 0xa5, 0xcd, 0x2a, 0x21, - 0xaf, 0x4c, 0xc5, 0x4b, 0x2c, 0xad, 0xbe, 0xf2, 0x5e, 0x00, 0xbd, 0xd8, 0xae, 0x37, 0xf7, 0x92, - 0xba, 0x12, 0xa2, 0x13, 0xf2, 0x2b, 0xd0, 0xe9, 0xb7, 0x0e, 0x8c, 0x82, 0xda, 0xad, 0x8f, 0x13, - 0x52, 0x1f, 0x42, 0x17, 0xc0, 0xf7, 0xda, 0xab, 0x9b, 0x82, 0x5a, 0x91, 0x0c, 0x31, 0x63, 0x6c, - 0xc9, 0x23, 0xdc, 0xf3, 0x60, 0x27, 0xd0, 0xbb, 0x83, 0x1a, 0x77, 0x10, 0x6c, 0x05, 0xff, 0xd6, - 0x10, 0x77, 0x19, 0xa4, 0xb6, 0xf6, 0x37, 0xf2, 0x82, 0x39, 0x59, 0x43, 0x42, 0x7e, 0xd6, 0xb0, - 0x27, 0xed, 0x1a, 0x21, 0x21, 0x6f, 0x6a, 0x10, 0xd2, 0xae, 0x11, 0x12, 0xf2, 0x14, 0x21, 0xf6, - 0xe4, 0x4d, 0xa1, 0xeb, 0x71, 0x14, 0x29, 0x9d, 0x3a, 0x9a, 0xb0, 0x5b, 0x1f, 0x44, 0x89, 0x50, - 0x12, 0x22, 0x96, 0x83, 0x2b, 0x60, 0xb2, 0x42, 0x41, 0x53, 0x70, 0x5d, 0x07, 0x6b, 0x9d, 0x90, - 0xd8, 0x87, 0x9c, 0x04, 0xe9, 0xcc, 0x19, 0x00, 0xfd, 0x20, 0xb4, 0xa5, 0xa4, 0x78, 0x4d, 0xdb, - 0xac, 0xff, 0x8f, 0xbc, 0xe6, 0xec, 0xfa, 0x61, 0x33, 0x7e, 0x03, 0xf9, 0x2d, 0xce, 0xa7, 0xa9, - 0x35, 0x85, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRecentTabIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0xcb, 0xf7, 0x82, - 0xff, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x33, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x5d, 0xda, 0x89, 0x00, 0x00, - 0x04, 0x11, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9a, 0xcb, 0x6f, 0x0d, 0x51, 0x1c, 0xc7, - 0x5d, 0x55, 0xb4, 0x44, 0x3c, 0x42, 0xbc, 0x42, 0x51, 0x8f, 0xa8, 0x56, 0xda, 0x84, 0x90, 0xc6, - 0x42, 0x54, 0x22, 0xc1, 0x86, 0x58, 0x49, 0x2c, 0x88, 0x34, 0x22, 0x65, 0xc3, 0xdf, 0x80, 0xa5, - 0xc4, 0x63, 0xd9, 0x74, 0x69, 0x61, 0x63, 0xd3, 0x04, 0xf1, 0x08, 0xb1, 0x13, 0x89, 0x54, 0x82, - 0xa6, 0x08, 0x8a, 0x8d, 0x44, 0x28, 0x25, 0x15, 0xd7, 0xe7, 0x7b, 0x73, 0x67, 0x32, 0x3d, 0x9d, - 0xa9, 0x39, 0x73, 0xe7, 0xdc, 0x19, 0xe5, 0x97, 0x7c, 0x73, 0xe6, 0x9c, 0x39, 0xbf, 0xdf, 0xf9, - 0x7e, 0xe7, 0xbc, 0xe6, 0xdc, 0xb9, 0x85, 0x49, 0x01, 0x2b, 0x16, 0x8b, 0xb5, 0x64, 0x8f, 0x81, - 0x6d, 0x60, 0x0d, 0x68, 0x04, 0xf5, 0xc0, 0x95, 0x7d, 0x24, 0xf0, 0xf3, 0x32, 0xae, 0x14, 0x0a, - 0x85, 0xde, 0x54, 0x1a, 0x42, 0x48, 0x3b, 0x78, 0x02, 0xb2, 0xb4, 0xab, 0x34, 0xbe, 0x28, 0xa9, - 0xa0, 0x82, 0x1c, 0x09, 0x30, 0x9f, 0x44, 0x4f, 0x68, 0xb6, 0xf2, 0x19, 0xdb, 0x4d, 0x7a, 0x68, - 0x67, 0x12, 0x0e, 0x93, 0xcb, 0x4e, 0xe7, 0x48, 0xf3, 0x20, 0x44, 0x74, 0x3a, 0x78, 0xb8, 0x07, - 0xca, 0xbc, 0xac, 0x92, 0x02, 0x8e, 0x75, 0x78, 0x7c, 0x05, 0xa5, 0x5e, 0x0a, 0x78, 0xdf, 0xe2, - 0xfa, 0x3a, 0xf8, 0x10, 0x28, 0x4b, 0xf3, 0xb2, 0x86, 0x60, 0x0d, 0xe0, 0x20, 0x58, 0x09, 0x82, - 0x76, 0x87, 0xde, 0xd9, 0x1e, 0x2c, 0x88, 0x75, 0x8d, 0x98, 0x66, 0x60, 0xda, 0xf9, 0x58, 0xce, - 0x29, 0x54, 0xa2, 0xe1, 0x3a, 0xd0, 0x67, 0x10, 0x18, 0x4c, 0x14, 0x9a, 0x20, 0xfb, 0x8c, 0x40, - 0xca, 0x2e, 0x4e, 0x14, 0x2c, 0xa1, 0x13, 0xed, 0x75, 0x86, 0x70, 0x98, 0x61, 0x1b, 0x4e, 0x73, - 0xc6, 0x24, 0x3e, 0x4c, 0x17, 0xbf, 0xb3, 0x0d, 0x54, 0x61, 0xfd, 0x81, 0x10, 0x7f, 0xeb, 0x55, - 0x4d, 0x62, 0xcc, 0xb9, 0xf2, 0x33, 0x24, 0xb0, 0xeb, 0xa2, 0x91, 0x90, 0x06, 0x4c, 0x5e, 0x21, - 0x55, 0x46, 0x17, 0x79, 0xab, 0xd9, 0xe8, 0xd2, 0xbf, 0x34, 0x37, 0xa1, 0xc4, 0x4c, 0x49, 0xda, - 0x09, 0x4c, 0x58, 0x0d, 0x03, 0x6d, 0x6e, 0x1b, 0x80, 0x5e, 0x7d, 0x96, 0x03, 0x2d, 0xb7, 0x49, - 0x6c, 0x4e, 0x88, 0x53, 0x37, 0x6d, 0x7c, 0x2b, 0x97, 0x17, 0x49, 0xdf, 0x03, 0x6d, 0xec, 0xcf, - 0x40, 0x2f, 0xf3, 0xda, 0xbb, 0x47, 0xb6, 0x6c, 0x38, 0x74, 0x81, 0xa0, 0x7d, 0xf6, 0xee, 0x45, - 0xa5, 0x54, 0x6e, 0x01, 0x0f, 0x82, 0x4e, 0x55, 0xbe, 0x7e, 0x45, 0x7b, 0x7b, 0x4d, 0x7e, 0xd6, - 0xc3, 0x8c, 0x20, 0x6d, 0x04, 0x79, 0x08, 0xb6, 0x9a, 0xc1, 0xaa, 0x98, 0xd7, 0x28, 0xb8, 0x06, - 0x97, 0xa3, 0xc1, 0x36, 0xad, 0xc4, 0xe0, 0xac, 0xa1, 0x75, 0x11, 0x24, 0x1e, 0x9e, 0xc1, 0xc6, - 0x53, 0xb8, 0x3e, 0x03, 0xa7, 0x79, 0x5e, 0x1c, 0x2b, 0x31, 0x38, 0xed, 0x06, 0x5b, 0x3c, 0xe7, - 0x1c, 0xa4, 0x12, 0x72, 0xd2, 0xe3, 0x61, 0x2b, 0xa6, 0xd9, 0x73, 0xcc, 0x51, 0xda, 0xe2, 0x71, - 0xb1, 0x15, 0xb3, 0xda, 0x73, 0xcc, 0x51, 0xea, 0x73, 0xb2, 0x15, 0xb3, 0x22, 0x47, 0x22, 0x3c, - 0x2a, 0x0d, 0xde, 0x85, 0xad, 0x98, 0x5a, 0xcf, 0x31, 0x47, 0xa9, 0xcf, 0xc9, 0x56, 0x4c, 0x8e, - 0x34, 0x8c, 0xa5, 0xe2, 0x6a, 0x89, 0xd5, 0x8e, 0x3d, 0x08, 0x94, 0x26, 0x35, 0x1d, 0xe5, 0xa7, - 0xdb, 0x38, 0xbb, 0x10, 0xa3, 0x37, 0x88, 0x56, 0x5e, 0x37, 0x5e, 0xd8, 0x10, 0x31, 0xeb, 0xb2, - 0x7f, 0xe8, 0x18, 0xaf, 0x93, 0xee, 0x26, 0xf3, 0x5e, 0x54, 0xde, 0xc5, 0x30, 0x1b, 0xa8, 0x54, - 0x88, 0xc8, 0x12, 0xe3, 0x13, 0x89, 0xde, 0x34, 0x62, 0x9b, 0x6d, 0xcf, 0xc4, 0x39, 0x63, 0xb4, - 0xf2, 0x54, 0x2f, 0xc0, 0xe0, 0x76, 0x6c, 0x16, 0xe1, 0x15, 0xd7, 0x51, 0xac, 0xdf, 0x07, 0x62, - 0x9b, 0xad, 0x98, 0xb8, 0x73, 0xe0, 0x38, 0x0c, 0x84, 0xaa, 0x9a, 0x8b, 0x61, 0x56, 0x55, 0x01, - 0xc1, 0xc6, 0xfe, 0x8b, 0x09, 0x3e, 0x8d, 0x3c, 0x5d, 0xdb, 0xce, 0x99, 0xb8, 0xdc, 0xbb, 0xa9, - 0x78, 0x0f, 0xc4, 0x9d, 0x63, 0x61, 0x71, 0x75, 0x7a, 0x3d, 0x01, 0x62, 0xff, 0xe4, 0xe4, 0x42, - 0xcc, 0x23, 0x96, 0xd5, 0xc3, 0x61, 0xec, 0x6c, 0xcb, 0x58, 0x15, 0xe7, 0xe2, 0xd3, 0x19, 0xd7, - 0xcf, 0xc5, 0x9c, 0x59, 0x05, 0x89, 0x25, 0x71, 0x09, 0x44, 0xd5, 0x23, 0x86, 0x7a, 0xa4, 0x35, - 0xea, 0x7e, 0x58, 0xb9, 0x8b, 0x9e, 0x99, 0x45, 0x43, 0x3a, 0xa3, 0xeb, 0xc7, 0x87, 0x4a, 0x6c, - 0x29, 0xce, 0x8a, 0x15, 0xdb, 0x5c, 0x88, 0x51, 0xe3, 0x8a, 0xbb, 0x3e, 0x36, 0x8b, 0x94, 0x2a, - 0xba, 0x18, 0x66, 0x29, 0x51, 0xb3, 0x0f, 0x33, 0xa1, 0xc4, 0xb8, 0x1a, 0x66, 0xbf, 0x78, 0xae, - 0xaf, 0x41, 0xd4, 0xd2, 0xac, 0x77, 0xbc, 0x65, 0x20, 0xd5, 0x87, 0xe9, 0x42, 0xcc, 0x17, 0x48, - 0x6e, 0x64, 0x79, 0x7e, 0x49, 0x1a, 0x69, 0x2c, 0x10, 0x3a, 0xbb, 0x3f, 0x06, 0x56, 0x67, 0x96, - 0xc8, 0x80, 0xdc, 0x48, 0xf5, 0xc9, 0x94, 0x1b, 0xea, 0xff, 0x93, 0x10, 0xd5, 0xa3, 0x4e, 0x3f, - 0x89, 0x7a, 0x2f, 0x35, 0x73, 0xd1, 0x33, 0x6d, 0x3c, 0xf5, 0x4b, 0x30, 0xbc, 0x0b, 0xc6, 0x1b, - 0x66, 0x1d, 0xdc, 0xd7, 0x2e, 0x9f, 0x9a, 0x49, 0xcc, 0x77, 0x23, 0x5a, 0x3d, 0x64, 0x6a, 0x79, - 0x72, 0x95, 0x7c, 0x33, 0xd1, 0x7f, 0x09, 0x84, 0xaa, 0x9a, 0x86, 0x99, 0xf9, 0xd5, 0x4a, 0xbf, - 0xe4, 0x6f, 0x8e, 0x60, 0x11, 0xf5, 0xa4, 0x23, 0xaa, 0x57, 0xb7, 0x58, 0x62, 0x34, 0x76, 0x4d, - 0xbb, 0x4c, 0xef, 0xac, 0x35, 0x0b, 0xf3, 0x9e, 0xd7, 0xa7, 0x73, 0x2d, 0x93, 0xfa, 0x86, 0xb9, - 0xd0, 0x20, 0xeb, 0x2d, 0xaf, 0xc1, 0x4f, 0xe7, 0xfa, 0x16, 0x33, 0xd3, 0xa8, 0x97, 0x75, 0x76, - 0x84, 0x29, 0x31, 0x55, 0x24, 0x4a, 0x67, 0x7a, 0x04, 0x1d, 0xe2, 0xba, 0x27, 0x6b, 0x56, 0x09, - 0xdb, 0x1f, 0x23, 0x46, 0xa2, 0x6e, 0x80, 0x1d, 0x09, 0x03, 0x66, 0xe9, 0xe6, 0x8b, 0x29, 0xed, - 0x33, 0x74, 0x93, 0x26, 0xf6, 0x2e, 0x70, 0x0a, 0x0c, 0x65, 0xc9, 0xac, 0x92, 0xb6, 0x4b, 0xc3, - 0x2c, 0x18, 0x80, 0x21, 0xa7, 0x5f, 0x12, 0xf5, 0x75, 0x4c, 0x7b, 0x80, 0x76, 0xe9, 0xe0, 0x49, - 0x6f, 0x0f, 0xf9, 0x05, 0x20, 0x4f, 0xe6, 0xf7, 0xcc, 0x18, 0x31, 0xe3, 0xb1, 0x44, 0xe8, 0x7d, - 0xee, 0xb7, 0x8f, 0x57, 0x27, 0x83, 0x7b, 0xbe, 0x98, 0xd2, 0x30, 0xcb, 0x80, 0x80, 0x93, 0x26, - 0xff, 0x69, 0x31, 0xda, 0x7b, 0xf2, 0x66, 0x3e, 0x27, 0xdb, 0x9e, 0x79, 0x93, 0x37, 0x25, 0xf0, - 0xf1, 0x39, 0xd9, 0x8a, 0xa9, 0xf4, 0x47, 0x0a, 0x17, 0xcf, 0xc2, 0xe7, 0x64, 0x2b, 0xe6, 0xa9, - 0x0b, 0x36, 0x15, 0xc6, 0xf4, 0x39, 0xd9, 0x2e, 0xcd, 0xd3, 0x68, 0xb8, 0x0f, 0x34, 0x56, 0x48, - 0x20, 0x2d, 0xf7, 0x61, 0x02, 0x35, 0xb1, 0xe9, 0x97, 0x4e, 0xb5, 0x56, 0x3d, 0x83, 0xd3, 0x0f, - 0x9c, 0xbb, 0xd2, 0x62, 0x92, 0x42, 0x9c, 0xb3, 0x9e, 0x90, 0xc4, 0xb1, 0xd8, 0x3c, 0xf7, 0x83, - 0xb7, 0x20, 0x2b, 0x1b, 0xa2, 0xe1, 0xd3, 0x40, 0x87, 0x4b, 0xdf, 0xac, 0x86, 0x99, 0xef, 0xc5, - 0x05, 0x81, 0x74, 0x14, 0x38, 0x02, 0x9a, 0x80, 0x5e, 0x7d, 0x1a, 0x40, 0x0d, 0x70, 0x61, 0x7a, - 0x77, 0xd4, 0x5f, 0xb4, 0xf4, 0xf7, 0x2c, 0x4d, 0xf8, 0x1e, 0x7a, 0xc4, 0x5f, 0xc5, 0xc8, 0x4f, - 0x3c, 0xfb, 0x0d, 0x29, 0x80, 0xc0, 0x68, 0xf7, 0x99, 0xb2, 0x13, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXMoveIcon[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x91, 0xda, - 0x8e, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x8e, 0x45, 0x3c, 0x00, 0x00, - 0x02, 0xa9, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x97, 0x3b, 0x68, 0x14, 0x51, 0x14, 0x86, - 0x77, 0x4c, 0x14, 0x1f, 0x60, 0x20, 0x22, 0x82, 0x8f, 0x80, 0x10, 0xd1, 0xa8, 0x08, 0x0a, 0x42, - 0x8a, 0x58, 0x18, 0x11, 0x8c, 0xa0, 0x95, 0x85, 0x69, 0xd2, 0x89, 0xa0, 0x8d, 0xd8, 0x58, 0x58, - 0x2b, 0xd8, 0x89, 0x95, 0x85, 0xd8, 0x68, 0x21, 0xd8, 0x88, 0x92, 0x20, 0x5a, 0xd9, 0x58, 0x85, - 0x24, 0x45, 0x50, 0x41, 0xc4, 0x80, 0x0a, 0xd1, 0x90, 0xd7, 0x82, 0x12, 0x0c, 0x71, 0xfd, 0x4e, - 0x9c, 0xbb, 0x9c, 0x3d, 0xf7, 0xcc, 0xce, 0xce, 0x82, 0x58, 0xb8, 0x17, 0x7e, 0xce, 0xeb, 0xff, - 0xcf, 0xbd, 0x73, 0x77, 0x76, 0xe6, 0x4e, 0xa9, 0xf4, 0x0f, 0x46, 0xa5, 0x52, 0x59, 0x03, 0x8e, - 0x8b, 0x6d, 0x7a, 0x7a, 0xc4, 0x9d, 0xe0, 0x04, 0x38, 0x07, 0xba, 0x41, 0xd2, 0x4c, 0x33, 0x74, - 0xb2, 0x98, 0xe7, 0x40, 0xc6, 0x30, 0x28, 0xd6, 0x07, 0xc1, 0x25, 0x30, 0x05, 0xec, 0x58, 0x24, - 0xf1, 0x00, 0x74, 0x16, 0x59, 0x18, 0xfc, 0x6b, 0xa6, 0xd1, 0xd5, 0x86, 0xf4, 0x88, 0xb6, 0x01, - 0xb9, 0x82, 0xbc, 0xf1, 0x05, 0xc2, 0xc9, 0x46, 0x9a, 0xc2, 0x3b, 0x02, 0x7e, 0x9a, 0x86, 0x4b, - 0xc4, 0x87, 0x72, 0xf5, 0x90, 0x5e, 0x19, 0x61, 0xbd, 0x50, 0x26, 0xd9, 0x57, 0xaf, 0x29, 0xf5, - 0x8d, 0xe0, 0x5d, 0x46, 0x93, 0x49, 0xf2, 0xeb, 0x33, 0xf5, 0x14, 0x07, 0x8d, 0x70, 0x8e, 0x58, - 0x7e, 0xba, 0x03, 0x60, 0x3b, 0x38, 0x0d, 0xec, 0x82, 0x5f, 0x66, 0x36, 0xa4, 0x00, 0xff, 0x2e, - 0xa8, 0x37, 0xee, 0xb8, 0x7a, 0x14, 0x6b, 0xc1, 0x67, 0xa5, 0xfc, 0x86, 0xbf, 0xcb, 0x92, 0xc9, - 0xc9, 0xcd, 0x79, 0x4f, 0xf1, 0xc4, 0x3d, 0x6b, 0x79, 0x12, 0x4b, 0xde, 0xf0, 0xb2, 0xc2, 0x53, - 0x91, 0x1e, 0x66, 0x8f, 0x61, 0x5f, 0x88, 0x48, 0x69, 0x02, 0x5e, 0x07, 0xf8, 0xaa, 0xf8, 0xb7, - 0x2d, 0x97, 0x5a, 0x3b, 0xf8, 0xa4, 0x38, 0xf5, 0xdc, 0x8f, 0xde, 0x73, 0x60, 0xbf, 0x69, 0xfa, - 0xd8, 0xc4, 0xd5, 0x30, 0x49, 0x92, 0x45, 0x82, 0x17, 0xd5, 0x44, 0xa9, 0x64, 0xb5, 0x52, 0x92, - 0xbf, 0xf5, 0xa4, 0xe2, 0xd4, 0x73, 0xdf, 0xb4, 0x3b, 0xd5, 0x1e, 0x95, 0x9b, 0x66, 0xd2, 0x05, - 0x15, 0x7b, 0xee, 0x5b, 0x95, 0x8c, 0x16, 0x84, 0x7e, 0x99, 0xfa, 0x00, 0xdb, 0xb2, 0x19, 0xdb, - 0x06, 0x7a, 0xc1, 0x08, 0x08, 0xa3, 0x1f, 0x67, 0x02, 0xac, 0xc0, 0x2d, 0x7b, 0x0b, 0xda, 0x19, - 0x98, 0xd8, 0x39, 0xe5, 0x67, 0xb9, 0xb3, 0xaa, 0xb0, 0x83, 0x89, 0xe9, 0x9b, 0x54, 0x54, 0x6e, - 0xd5, 0x95, 0xc9, 0xc4, 0xa1, 0xbe, 0x6a, 0x55, 0xbd, 0x4c, 0x6d, 0x3e, 0xc4, 0xde, 0x4f, 0x16, - 0x6a, 0xcd, 0xda, 0x62, 0x4f, 0x5e, 0x33, 0xcb, 0xdf, 0x58, 0x90, 0x99, 0xa2, 0x58, 0xd8, 0x5a, - 0x50, 0xde, 0x7e, 0xb5, 0x76, 0xa8, 0xb5, 0x43, 0x79, 0x3b, 0x90, 0x57, 0x6f, 0xdd, 0x43, 0xff, - 0xe5, 0x0e, 0x55, 0xdf, 0x43, 0xe9, 0xd5, 0x6f, 0xc8, 0xd9, 0x05, 0x5b, 0xaf, 0x7d, 0x5f, 0xf2, - 0xb2, 0xdb, 0x03, 0x9e, 0x80, 0x0f, 0x29, 0xca, 0xd8, 0x30, 0xe4, 0x68, 0x1a, 0xf2, 0xaf, 0xf1, - 0xfb, 0xed, 0x64, 0xe4, 0x0e, 0x06, 0x72, 0x6a, 0x0f, 0x5b, 0x8e, 0x8e, 0xe1, 0xc8, 0xc9, 0x33, - 0x8c, 0x1f, 0x38, 0xb5, 0xf7, 0x31, 0x89, 0xf3, 0xa1, 0xda, 0x80, 0x8d, 0x8e, 0x99, 0x68, 0xd6, - 0x81, 0x65, 0xa5, 0xbd, 0xa2, 0x17, 0x60, 0x7d, 0x78, 0x8f, 0x14, 0x77, 0xdc, 0xd6, 0xe5, 0x38, - 0x20, 0x47, 0xd6, 0x51, 0x45, 0xca, 0x72, 0x17, 0x28, 0x74, 0x45, 0x0d, 0x48, 0x90, 0x9f, 0x50, - 0xa2, 0x59, 0xfc, 0x2d, 0x19, 0xbc, 0x5e, 0x6a, 0xbf, 0x14, 0xf7, 0xbe, 0xc7, 0x93, 0x86, 0x7b, - 0xc1, 0x77, 0x45, 0xf4, 0xdc, 0x41, 0x57, 0xfc, 0x67, 0x41, 0x67, 0x8c, 0xe0, 0x3d, 0x71, 0x5f, - 0xe0, 0xe3, 0xb7, 0x01, 0xf9, 0x25, 0xe6, 0x41, 0x18, 0x4b, 0x38, 0xdd, 0x81, 0x13, 0x59, 0x8a, - 0x17, 0x03, 0xd3, 0xb1, 0x0f, 0x23, 0x81, 0x49, 0xa0, 0x79, 0xe6, 0xe8, 0xe4, 0x6b, 0x65, 0x0c, - 0x78, 0x17, 0x7b, 0xc3, 0xb4, 0x88, 0x43, 0x84, 0x4f, 0x9d, 0xa6, 0x53, 0xe4, 0x3a, 0x62, 0x76, - 0x6d, 0x06, 0x4e, 0x17, 0x18, 0x77, 0xf4, 0x5e, 0x6a, 0x84, 0xe4, 0xa6, 0xda, 0x0e, 0x4e, 0x04, - 0x69, 0x2b, 0x98, 0x56, 0x1d, 0x56, 0xf0, 0x8f, 0x39, 0x54, 0x37, 0x05, 0x57, 0x6e, 0xf0, 0x5b, - 0x40, 0x74, 0xde, 0x90, 0x7f, 0xd5, 0x65, 0x57, 0x9c, 0x26, 0xa3, 0xe3, 0x26, 0x82, 0x01, 0x6a, - 0xc3, 0x40, 0x6a, 0x37, 0x39, 0xef, 0x5e, 0x4f, 0xb9, 0x0d, 0x1b, 0x7a, 0xc8, 0x77, 0xdc, 0x51, - 0x20, 0x8f, 0x80, 0xdd, 0x40, 0x3e, 0x04, 0xc6, 0xc0, 0x28, 0xfd, 0x66, 0xb0, 0xc5, 0x06, 0x0d, - 0xfb, 0xc0, 0x10, 0x88, 0x16, 0x5c, 0xac, 0x53, 0x71, 0xf6, 0x6f, 0x9b, 0x02, 0x54, 0xeb, 0x7d, - 0xaa, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXMoveIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x7a, 0x91, 0xda, - 0x8e, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x8e, 0x45, 0x3c, 0x00, 0x00, - 0x02, 0xa9, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x97, 0x3b, 0x68, 0x14, 0x51, 0x14, 0x86, - 0x77, 0x4c, 0x14, 0x1f, 0x60, 0x20, 0x22, 0x82, 0x8f, 0x80, 0x10, 0xd1, 0xa8, 0x08, 0x0a, 0x42, - 0x8a, 0x58, 0x18, 0x11, 0x8c, 0xa0, 0x95, 0x85, 0x69, 0xd2, 0x89, 0xa0, 0x8d, 0xd8, 0x58, 0x58, - 0x2b, 0xd8, 0x89, 0x95, 0x85, 0xd8, 0x68, 0x21, 0xd8, 0x88, 0x92, 0x20, 0x5a, 0xd9, 0x58, 0x85, - 0x24, 0x45, 0x50, 0x41, 0xc4, 0x80, 0x0a, 0xd1, 0x90, 0xd7, 0x82, 0x12, 0x0c, 0x71, 0xfd, 0x4e, - 0x9c, 0xbb, 0x9c, 0x3d, 0xf7, 0xcc, 0xce, 0xce, 0x82, 0x58, 0xb8, 0x17, 0x7e, 0xce, 0xeb, 0xff, - 0xcf, 0xbd, 0x73, 0x77, 0x76, 0xe6, 0x4e, 0xa9, 0xf4, 0x0f, 0x46, 0xa5, 0x52, 0x59, 0x03, 0x8e, - 0x8b, 0x6d, 0x7a, 0x7a, 0xc4, 0x9d, 0xe0, 0x04, 0x38, 0x07, 0xba, 0x41, 0xd2, 0x4c, 0x33, 0x74, - 0xb2, 0x98, 0xe7, 0x40, 0xc6, 0x30, 0x28, 0xd6, 0x07, 0xc1, 0x25, 0x30, 0x05, 0xec, 0x58, 0x24, - 0xf1, 0x00, 0x74, 0x16, 0x59, 0x18, 0xfc, 0x6b, 0xa6, 0xd1, 0xd5, 0x86, 0xf4, 0x88, 0xb6, 0x01, - 0xb9, 0x82, 0xbc, 0xf1, 0x05, 0xc2, 0xc9, 0x46, 0x9a, 0xc2, 0x3b, 0x02, 0x7e, 0x9a, 0x86, 0x4b, - 0xc4, 0x87, 0x72, 0xf5, 0x90, 0x5e, 0x19, 0x61, 0xbd, 0x50, 0x26, 0xd9, 0x57, 0xaf, 0x29, 0xf5, - 0x8d, 0xe0, 0x5d, 0x46, 0x93, 0x49, 0xf2, 0xeb, 0x33, 0xf5, 0x14, 0x07, 0x8d, 0x70, 0x8e, 0x58, - 0x7e, 0xba, 0x03, 0x60, 0x3b, 0x38, 0x0d, 0xec, 0x82, 0x5f, 0x66, 0x36, 0xa4, 0x00, 0xff, 0x2e, - 0xa8, 0x37, 0xee, 0xb8, 0x7a, 0x14, 0x6b, 0xc1, 0x67, 0xa5, 0xfc, 0x86, 0xbf, 0xcb, 0x92, 0xc9, - 0xc9, 0xcd, 0x79, 0x4f, 0xf1, 0xc4, 0x3d, 0x6b, 0x79, 0x12, 0x4b, 0xde, 0xf0, 0xb2, 0xc2, 0x53, - 0x91, 0x1e, 0x66, 0x8f, 0x61, 0x5f, 0x88, 0x48, 0x69, 0x02, 0x5e, 0x07, 0xf8, 0xaa, 0xf8, 0xb7, - 0x2d, 0x97, 0x5a, 0x3b, 0xf8, 0xa4, 0x38, 0xf5, 0xdc, 0x8f, 0xde, 0x73, 0x60, 0xbf, 0x69, 0xfa, - 0xd8, 0xc4, 0xd5, 0x30, 0x49, 0x92, 0x45, 0x82, 0x17, 0xd5, 0x44, 0xa9, 0x64, 0xb5, 0x52, 0x92, - 0xbf, 0xf5, 0xa4, 0xe2, 0xd4, 0x73, 0xdf, 0xb4, 0x3b, 0xd5, 0x1e, 0x95, 0x9b, 0x66, 0xd2, 0x05, - 0x15, 0x7b, 0xee, 0x5b, 0x95, 0x8c, 0x16, 0x84, 0x7e, 0x99, 0xfa, 0x00, 0xdb, 0xb2, 0x19, 0xdb, - 0x06, 0x7a, 0xc1, 0x08, 0x08, 0xa3, 0x1f, 0x67, 0x02, 0xac, 0xc0, 0x2d, 0x7b, 0x0b, 0xda, 0x19, - 0x98, 0xd8, 0x39, 0xe5, 0x67, 0xb9, 0xb3, 0xaa, 0xb0, 0x83, 0x89, 0xe9, 0x9b, 0x54, 0x54, 0x6e, - 0xd5, 0x95, 0xc9, 0xc4, 0xa1, 0xbe, 0x6a, 0x55, 0xbd, 0x4c, 0x6d, 0x3e, 0xc4, 0xde, 0x4f, 0x16, - 0x6a, 0xcd, 0xda, 0x62, 0x4f, 0x5e, 0x33, 0xcb, 0xdf, 0x58, 0x90, 0x99, 0xa2, 0x58, 0xd8, 0x5a, - 0x50, 0xde, 0x7e, 0xb5, 0x76, 0xa8, 0xb5, 0x43, 0x79, 0x3b, 0x90, 0x57, 0x6f, 0xdd, 0x43, 0xff, - 0xe5, 0x0e, 0x55, 0xdf, 0x43, 0xe9, 0xd5, 0x6f, 0xc8, 0xd9, 0x05, 0x5b, 0xaf, 0x7d, 0x5f, 0xf2, - 0xb2, 0xdb, 0x03, 0x9e, 0x80, 0x0f, 0x29, 0xca, 0xd8, 0x30, 0xe4, 0x68, 0x1a, 0xf2, 0xaf, 0xf1, - 0xfb, 0xed, 0x64, 0xe4, 0x0e, 0x06, 0x72, 0x6a, 0x0f, 0x5b, 0x8e, 0x8e, 0xe1, 0xc8, 0xc9, 0x33, - 0x8c, 0x1f, 0x38, 0xb5, 0xf7, 0x31, 0x89, 0xf3, 0xa1, 0xda, 0x80, 0x8d, 0x8e, 0x99, 0x68, 0xd6, - 0x81, 0x65, 0xa5, 0xbd, 0xa2, 0x17, 0x60, 0x7d, 0x78, 0x8f, 0x14, 0x77, 0xdc, 0xd6, 0xe5, 0x38, - 0x20, 0x47, 0xd6, 0x51, 0x45, 0xca, 0x72, 0x17, 0x28, 0x74, 0x45, 0x0d, 0x48, 0x90, 0x9f, 0x50, - 0xa2, 0x59, 0xfc, 0x2d, 0x19, 0xbc, 0x5e, 0x6a, 0xbf, 0x14, 0xf7, 0xbe, 0xc7, 0x93, 0x86, 0x7b, - 0xc1, 0x77, 0x45, 0xf4, 0xdc, 0x41, 0x57, 0xfc, 0x67, 0x41, 0x67, 0x8c, 0xe0, 0x3d, 0x71, 0x5f, - 0xe0, 0xe3, 0xb7, 0x01, 0xf9, 0x25, 0xe6, 0x41, 0x18, 0x4b, 0x38, 0xdd, 0x81, 0x13, 0x59, 0x8a, - 0x17, 0x03, 0xd3, 0xb1, 0x0f, 0x23, 0x81, 0x49, 0xa0, 0x79, 0xe6, 0xe8, 0xe4, 0x6b, 0x65, 0x0c, - 0x78, 0x17, 0x7b, 0xc3, 0xb4, 0x88, 0x43, 0x84, 0x4f, 0x9d, 0xa6, 0x53, 0xe4, 0x3a, 0x62, 0x76, - 0x6d, 0x06, 0x4e, 0x17, 0x18, 0x77, 0xf4, 0x5e, 0x6a, 0x84, 0xe4, 0xa6, 0xda, 0x0e, 0x4e, 0x04, - 0x69, 0x2b, 0x98, 0x56, 0x1d, 0x56, 0xf0, 0x8f, 0x39, 0x54, 0x37, 0x05, 0x57, 0x6e, 0xf0, 0x5b, - 0x40, 0x74, 0xde, 0x90, 0x7f, 0xd5, 0x65, 0x57, 0x9c, 0x26, 0xa3, 0xe3, 0x26, 0x82, 0x01, 0x6a, - 0xc3, 0x40, 0x6a, 0x37, 0x39, 0xef, 0x5e, 0x4f, 0xb9, 0x0d, 0x1b, 0x7a, 0xc8, 0x77, 0xdc, 0x51, - 0x20, 0x8f, 0x80, 0xdd, 0x40, 0x3e, 0x04, 0xc6, 0xc0, 0x28, 0xfd, 0x66, 0xb0, 0xc5, 0x06, 0x0d, - 0xfb, 0xc0, 0x10, 0x88, 0x16, 0x5c, 0xac, 0x53, 0x71, 0xf6, 0x6f, 0x9b, 0x02, 0x54, 0xeb, 0x7d, - 0xaa, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXMoveIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x5a, 0x1c, 0x89, - 0xc0, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x03, 0xdb, 0x04, 0x00, 0x00, - 0x04, 0x37, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9a, 0x5b, 0x88, 0x8d, 0x51, 0x14, 0xc7, - 0xcf, 0x71, 0x8b, 0x71, 0x9b, 0xdc, 0x72, 0x8f, 0x22, 0x11, 0x73, 0x49, 0x4a, 0xb9, 0x24, 0x45, - 0xd2, 0x24, 0x25, 0xc2, 0x8b, 0xbc, 0xe0, 0x49, 0x52, 0xca, 0x25, 0xa4, 0xa6, 0x14, 0x4f, 0xca, - 0x93, 0xa4, 0x10, 0x29, 0xb7, 0x21, 0x2f, 0xf2, 0xe4, 0x49, 0x79, 0x10, 0xc6, 0x25, 0xa2, 0x91, - 0x72, 0x1d, 0x63, 0x34, 0xc8, 0x8c, 0xdb, 0xf8, 0xad, 0xa9, 0x73, 0x7c, 0xdf, 0x3e, 0x6b, 0xed, - 0xfd, 0x7d, 0xc7, 0xd0, 0x51, 0x67, 0xd5, 0xbf, 0xd9, 0xfb, 0xbf, 0xd6, 0xfa, 0xaf, 0xfd, 0x7d, - 0xfb, 0x3b, 0xfb, 0x7c, 0xb3, 0xf7, 0xc9, 0x64, 0xfe, 0x43, 0xeb, 0xec, 0xec, 0xac, 0xf8, 0x0f, - 0x87, 0xed, 0x1f, 0x32, 0x17, 0xb5, 0x13, 0x7c, 0x03, 0xf7, 0xc0, 0x18, 0x2b, 0x3a, 0x6b, 0x39, - 0x42, 0x3c, 0xa2, 0x7d, 0x88, 0x99, 0x0f, 0xa6, 0x82, 0x91, 0x60, 0x00, 0x78, 0x03, 0x5e, 0x82, - 0xeb, 0xd9, 0x6c, 0xb6, 0x89, 0xbf, 0xdd, 0x6a, 0xd4, 0x5c, 0x8e, 0xe0, 0xc5, 0x88, 0xe8, 0x0d, - 0xda, 0xf3, 0xa8, 0xf5, 0x23, 0xc2, 0x15, 0xd7, 0x44, 0x7c, 0x22, 0x38, 0x0e, 0xda, 0x80, 0xcf, - 0xe4, 0x8e, 0x6e, 0x00, 0x3d, 0x8b, 0xab, 0x14, 0xcf, 0x42, 0x67, 0x14, 0x78, 0x07, 0x5c, 0xdb, - 0x13, 0x8f, 0x4c, 0xd9, 0x43, 0x2d, 0x0b, 0xf6, 0x82, 0x76, 0x90, 0xc6, 0xee, 0x13, 0x5c, 0x9d, - 0xb2, 0x5c, 0x2c, 0x9c, 0x7c, 0xa9, 0x7d, 0xd5, 0x28, 0x2a, 0x8f, 0xe5, 0xec, 0x58, 0x42, 0xd2, - 0x0e, 0x89, 0x7d, 0xc0, 0x29, 0x43, 0x38, 0x09, 0x2d, 0xb3, 0xbb, 0x38, 0x69, 0x3d, 0x37, 0x8e, - 0xdc, 0x2d, 0x81, 0x22, 0x4f, 0xf0, 0xcb, 0x47, 0x21, 0x9d, 0x91, 0xb4, 0x3b, 0x20, 0x9c, 0xc4, - 0x2d, 0x17, 0x37, 0x3a, 0x5d, 0xe5, 0x4c, 0x86, 0x9c, 0x2a, 0x90, 0xe4, 0x29, 0x39, 0x96, 0x4a, - 0x1b, 0xd1, 0xf1, 0xe0, 0x33, 0xb0, 0xec, 0x15, 0x8e, 0x2b, 0xe0, 0x28, 0xb8, 0x09, 0xbe, 0x00, - 0xcb, 0x4e, 0xa7, 0x29, 0x8e, 0x48, 0x5f, 0xd0, 0x68, 0x89, 0x29, 0xfc, 0x8a, 0xc4, 0xfa, 0x24, - 0x9f, 0x55, 0x04, 0x84, 0x7a, 0x04, 0x66, 0xb9, 0x42, 0x70, 0xbd, 0xc0, 0x76, 0xf0, 0x15, 0x68, - 0xb6, 0xc0, 0xcd, 0xb1, 0xfa, 0x24, 0x1f, 0xd2, 0x04, 0x3c, 0x5c, 0x0b, 0xbe, 0xf0, 0x53, 0x41, - 0xd0, 0x42, 0x43, 0xa4, 0x01, 0xde, 0xfb, 0x25, 0x89, 0xbf, 0x16, 0x48, 0x21, 0xd7, 0x64, 0xb5, - 0xec, 0x65, 0x5d, 0x4c, 0x8e, 0x27, 0x66, 0x09, 0xf8, 0xe9, 0x26, 0x27, 0xe8, 0x5f, 0x23, 0xc6, - 0xff, 0x35, 0x46, 0xc0, 0x39, 0x45, 0xe8, 0x03, 0xdc, 0x88, 0xdc, 0x00, 0x7c, 0x7f, 0x89, 0xdb, - 0xa4, 0xe4, 0x0b, 0xb5, 0x28, 0x90, 0x57, 0x49, 0x8c, 0x3c, 0xe2, 0xc5, 0xda, 0x66, 0x53, 0x1f, - 0x45, 0x59, 0x62, 0x9b, 0x15, 0xe5, 0xad, 0x66, 0x92, 0xe3, 0x20, 0xb7, 0x07, 0xb8, 0xa5, 0x68, - 0xec, 0x77, 0x42, 0x63, 0x5d, 0xe2, 0x77, 0x28, 0x39, 0x69, 0xa8, 0xb7, 0x3d, 0x62, 0x8a, 0xf1, - 0xce, 0x14, 0xba, 0xc3, 0xe2, 0x54, 0x57, 0xaf, 0x41, 0xe1, 0x54, 0x8a, 0x37, 0x82, 0x9f, 0x38, - 0x2e, 0x29, 0xce, 0x79, 0x0a, 0x17, 0xa5, 0xbc, 0x8f, 0x79, 0x34, 0xd0, 0x68, 0x57, 0xf8, 0x9e, - 0xf5, 0x51, 0x4a, 0x52, 0x3b, 0xdc, 0x33, 0x85, 0xf7, 0x51, 0x0f, 0x15, 0x67, 0xe8, 0x03, 0x5e, - 0x4f, 0x4e, 0x33, 0x90, 0xd7, 0xb5, 0xe8, 0x9b, 0xcb, 0x2a, 0xfa, 0x83, 0x41, 0xd4, 0xae, 0xd2, - 0x79, 0x1e, 0x21, 0x5a, 0x68, 0x9f, 0x8b, 0xf4, 0xe3, 0x4d, 0xe6, 0x7d, 0xa5, 0x32, 0xf7, 0x77, - 0xe2, 0x51, 0xe1, 0x1e, 0x1a, 0xd3, 0x15, 0x9d, 0xb6, 0x70, 0x66, 0x61, 0x04, 0x3a, 0xb2, 0x12, - 0xbb, 0x56, 0x57, 0x18, 0x99, 0xc9, 0xf8, 0x1e, 0x45, 0xf7, 0xce, 0x48, 0x7e, 0xab, 0x26, 0x12, - 0xe0, 0xb4, 0x9c, 0x81, 0x8c, 0xce, 0x57, 0x3b, 0x20, 0x19, 0x76, 0xfb, 0xc4, 0xfd, 0x4b, 0x66, - 0x58, 0x3b, 0x14, 0xf1, 0x57, 0xf5, 0x7d, 0x17, 0x16, 0x1a, 0x58, 0x49, 0xfb, 0xcb, 0x17, 0x56, - 0xd2, 0xd3, 0xa3, 0x0c, 0xae, 0x3c, 0x63, 0xca, 0x4d, 0x29, 0x69, 0xaa, 0x3c, 0x63, 0x25, 0x3d, - 0x3d, 0xca, 0xe0, 0xca, 0x33, 0xa6, 0xdc, 0x94, 0x92, 0xa6, 0xca, 0x33, 0x56, 0xd2, 0xd3, 0xa3, - 0x0c, 0xae, 0x3c, 0x63, 0xca, 0x4d, 0x29, 0x69, 0xaa, 0x3c, 0x63, 0x25, 0x3d, 0x3d, 0xca, 0xe0, - 0xca, 0x33, 0xa6, 0xdc, 0x94, 0xa4, 0x54, 0x87, 0x11, 0xe8, 0xdb, 0x6f, 0x31, 0x52, 0x32, 0xbd, - 0x15, 0x87, 0xec, 0xc3, 0x14, 0x58, 0x97, 0x38, 0xff, 0xa6, 0xf7, 0xc7, 0x53, 0x0b, 0x2a, 0x23, - 0x11, 0x55, 0x91, 0x76, 0xae, 0x39, 0x94, 0xd8, 0xe8, 0x1e, 0xc3, 0x37, 0x1c, 0x8d, 0xec, 0x46, - 0xc9, 0x99, 0x98, 0x65, 0xef, 0x71, 0xc8, 0x6e, 0x95, 0xfb, 0x74, 0x4c, 0x82, 0xbb, 0x6f, 0x25, - 0xb9, 0x3c, 0x75, 0xe5, 0xa2, 0xc6, 0xb9, 0x3c, 0x7d, 0xd9, 0xbc, 0x29, 0x34, 0x12, 0x06, 0x80, - 0x26, 0x50, 0xac, 0x7d, 0x27, 0x31, 0xb4, 0x01, 0xaa, 0xed, 0x4f, 0xae, 0x2c, 0x1c, 0x8d, 0xcd, - 0x50, 0x63, 0x9a, 0x31, 0xc0, 0xb1, 0x5a, 0x96, 0xdc, 0x45, 0x99, 0xa5, 0x09, 0x9a, 0x33, 0x21, - 0x27, 0xdb, 0x63, 0x33, 0x02, 0xb1, 0xda, 0xee, 0xd6, 0xcc, 0x40, 0x8e, 0xeb, 0xd6, 0xe2, 0xe5, - 0x69, 0x78, 0xe1, 0x06, 0xe6, 0xfb, 0xdc, 0x09, 0x39, 0x2d, 0x29, 0xd6, 0xe4, 0x24, 0x46, 0xdb, - 0x83, 0x8c, 0xea, 0xcb, 0xb9, 0xb1, 0x6b, 0x1f, 0x21, 0x42, 0xfb, 0x8b, 0x5d, 0x1a, 0xc4, 0xc9, - 0xf9, 0xdc, 0x63, 0x57, 0x80, 0xfe, 0x85, 0x7c, 0x11, 0xad, 0x41, 0xc0, 0x38, 0xd0, 0xaa, 0x24, - 0x26, 0xa1, 0x36, 0x69, 0x9a, 0x51, 0x0e, 0x11, 0xd9, 0x5b, 0xfc, 0xa1, 0x88, 0x9d, 0x89, 0xc6, - 0x59, 0x6d, 0xf2, 0xe4, 0xf4, 0x46, 0xb3, 0x75, 0x56, 0x4e, 0x9e, 0x27, 0x6b, 0xb5, 0x96, 0x19, - 0xe0, 0x2e, 0xe7, 0x05, 0x02, 0x0d, 0x74, 0x8e, 0x18, 0x5a, 0xe7, 0xe1, 0x87, 0x6a, 0xe9, 0xf0, - 0x32, 0x53, 0x07, 0x80, 0x76, 0xea, 0x22, 0x67, 0x02, 0xee, 0x82, 0xa4, 0xc9, 0x74, 0x9d, 0x1e, - 0x9e, 0x24, 0x38, 0xa9, 0xbd, 0x26, 0x70, 0xb8, 0xae, 0x54, 0xc8, 0x12, 0x2b, 0x2b, 0xaa, 0x76, - 0xac, 0x24, 0xf5, 0xe4, 0x64, 0xe5, 0x20, 0x58, 0x0b, 0x6a, 0xc0, 0x32, 0xb0, 0x0f, 0xdc, 0x05, - 0x96, 0xcd, 0x29, 0xac, 0x62, 0x30, 0x28, 0x0c, 0x02, 0x4d, 0x96, 0x92, 0xc3, 0x2f, 0x35, 0x64, - 0x4c, 0x9a, 0xfc, 0x8d, 0x8e, 0x46, 0xb1, 0xdd, 0x13, 0x66, 0x11, 0xcb, 0x41, 0xa5, 0xb9, 0x40, - 0x96, 0x70, 0x9f, 0x1d, 0xb6, 0xf2, 0x7d, 0x3c, 0x82, 0x72, 0xac, 0x24, 0x07, 0x73, 0x7f, 0x62, - 0xcf, 0x49, 0xf6, 0x2e, 0x56, 0xe6, 0x18, 0x48, 0xac, 0xf7, 0x54, 0x7e, 0x80, 0xaf, 0x9f, 0x99, - 0x1c, 0x70, 0x90, 0xfb, 0x27, 0xbf, 0x40, 0xb8, 0x4d, 0x7e, 0xa2, 0x95, 0x54, 0x1d, 0x06, 0xc9, - 0x72, 0x8e, 0x2c, 0x07, 0xe5, 0xae, 0x75, 0x40, 0xd4, 0xa8, 0x49, 0x29, 0x49, 0x74, 0x56, 0x81, - 0xa7, 0x6e, 0x01, 0xa3, 0x2f, 0xbf, 0x38, 0xd8, 0x05, 0x8a, 0xbe, 0xa1, 0xf9, 0xe1, 0x21, 0x32, - 0x19, 0x7c, 0x02, 0x51, 0xdb, 0x96, 0x0f, 0xe8, 0x86, 0x06, 0xc2, 0x32, 0x7b, 0x75, 0x40, 0x56, - 0x4c, 0xf9, 0xa1, 0x4b, 0xee, 0x2b, 0x47, 0xbe, 0x1b, 0xe5, 0xa2, 0x2f, 0x80, 0xf5, 0x60, 0x48, - 0x37, 0x94, 0xfb, 0x2d, 0x81, 0xe0, 0x1a, 0x90, 0xfb, 0xbc, 0x35, 0xd0, 0xfe, 0xab, 0x27, 0x24, - 0x52, 0x99, 0x1a, 0xc5, 0xbc, 0x1c, 0xff, 0x1e, 0x74, 0xd2, 0x16, 0x85, 0xaa, 0x81, 0x2c, 0xbf, - 0xda, 0x9b, 0x75, 0x52, 0x99, 0x7f, 0x1e, 0xf7, 0x0b, 0x20, 0xe5, 0xc9, 0x35, 0x1c, 0xb8, 0x12, - 0x47, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXSelectIcon[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x33, 0x17, 0x79, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd7, 0xce, 0x93, 0x00, 0x00, - 0x04, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x99, 0x5b, 0x88, 0x0e, 0x61, 0x18, 0xc7, - 0x7d, 0xd6, 0x3a, 0x6c, 0x12, 0x42, 0x24, 0x17, 0x48, 0xb1, 0x21, 0x09, 0x37, 0x5c, 0x2d, 0xe5, - 0x74, 0x23, 0x11, 0x39, 0xad, 0xc3, 0x86, 0x12, 0x17, 0x8b, 0x52, 0xd2, 0xda, 0xa4, 0xb4, 0x29, - 0xa7, 0x24, 0xe4, 0xc2, 0x31, 0x57, 0x12, 0x52, 0x88, 0x1b, 0x09, 0xed, 0x0d, 0xc9, 0x46, 0x88, - 0x9c, 0x6e, 0x24, 0xe7, 0x8d, 0x65, 0xf7, 0xf3, 0x7b, 0x3e, 0x33, 0xdb, 0xe3, 0x6d, 0x66, 0xbe, - 0x99, 0xf9, 0xde, 0xd9, 0xa1, 0xe6, 0xa9, 0xff, 0xf7, 0x3e, 0xef, 0x73, 0x7e, 0xde, 0x99, 0xf9, - 0x66, 0xe6, 0x9d, 0x4e, 0x9d, 0x32, 0xca, 0x56, 0x20, 0x5b, 0x81, 0x6c, 0x05, 0xb2, 0x15, 0xc8, - 0x56, 0x20, 0xd9, 0x15, 0xc8, 0xe7, 0xf3, 0xd3, 0xc1, 0x33, 0xb0, 0x3d, 0xd9, 0x4c, 0x29, 0x45, - 0xa7, 0xb1, 0x8b, 0x40, 0xe8, 0x07, 0x28, 0x4b, 0xa9, 0x0c, 0xcf, 0xb4, 0x9d, 0x3d, 0xa5, 0xd1, - 0x85, 0xdd, 0x1d, 0x97, 0xae, 0x8c, 0xb6, 0x62, 0x46, 0xaf, 0xc2, 0xc3, 0xe3, 0x9f, 0x2a, 0xc6, - 0xa3, 0xbe, 0x92, 0x45, 0xbe, 0x0d, 0x72, 0xaa, 0x55, 0x80, 0x31, 0x25, 0x67, 0xf0, 0x08, 0x40, - 0xdc, 0xc1, 0x60, 0x88, 0x87, 0xaa, 0x63, 0x44, 0x24, 0xcf, 0x81, 0xc7, 0x40, 0xe8, 0x04, 0x08, - 0xbc, 0xae, 0xd0, 0x5f, 0x13, 0x43, 0x87, 0xca, 0x83, 0xaa, 0xc4, 0xa6, 0x1a, 0xfc, 0x04, 0xbf, - 0xc0, 0xc8, 0x20, 0xdb, 0xc4, 0x74, 0x24, 0xee, 0x02, 0xde, 0x02, 0x97, 0x4e, 0xc3, 0xf8, 0x36, - 0x89, 0xae, 0xce, 0x31, 0xbc, 0x1b, 0x54, 0x14, 0x36, 0xcb, 0x41, 0xab, 0x63, 0x2b, 0xc3, 0xc4, - 0x20, 0xfb, 0x44, 0x75, 0x24, 0x9f, 0x06, 0x9a, 0xa5, 0x0a, 0x87, 0xce, 0x30, 0x7a, 0x36, 0x89, - 0x5c, 0x8e, 0xf8, 0x44, 0xd0, 0xc3, 0xaf, 0x28, 0x74, 0x2b, 0x41, 0x1b, 0x70, 0x69, 0xa7, 0x9f, - 0x6d, 0x87, 0xc9, 0xa9, 0x64, 0x2a, 0xd0, 0x4d, 0x36, 0xc4, 0x49, 0x4e, 0x8c, 0x2a, 0xa0, 0x9b, - 0xdb, 0x11, 0x27, 0x4e, 0x22, 0x3e, 0x4e, 0x71, 0xdf, 0x18, 0x85, 0x6e, 0xc7, 0x49, 0x82, 0xdf, - 0xb6, 0x82, 0xf7, 0x9f, 0x9f, 0xfa, 0x38, 0x31, 0x12, 0xf5, 0xa1, 0xae, 0xf1, 0x60, 0x8f, 0x8c, - 0x71, 0x12, 0xe1, 0xd7, 0x0f, 0xec, 0x02, 0x0b, 0xe2, 0xf8, 0x67, 0x3e, 0xd9, 0x0a, 0x64, 0x2b, - 0xf0, 0xff, 0xae, 0x40, 0x4e, 0x97, 0xce, 0x9f, 0xc0, 0x5f, 0xf3, 0x5c, 0x2e, 0x97, 0xd7, 0x7a, - 0x3f, 0xde, 0xf1, 0x9b, 0x89, 0xbe, 0x15, 0x9f, 0x2b, 0x7e, 0x76, 0x5a, 0x6e, 0xe6, 0x12, 0x5d, - 0xd8, 0x7c, 0x3a, 0x4e, 0x28, 0x9e, 0x64, 0x4b, 0xc0, 0x47, 0x60, 0x92, 0xbc, 0xe3, 0x55, 0x16, - 0x0b, 0x82, 0xcd, 0x71, 0xe5, 0x78, 0x28, 0xc8, 0x1e, 0xbb, 0x32, 0x70, 0x55, 0xd9, 0xbb, 0xac, - 0x3c, 0xba, 0x1d, 0x0e, 0xf2, 0x8d, 0xad, 0x23, 0xf0, 0x05, 0x37, 0x8b, 0xc7, 0xb8, 0xbe, 0x58, - 0x60, 0x7c, 0xe4, 0x3d, 0x50, 0xd3, 0x58, 0x3f, 0x1f, 0x8c, 0x86, 0x6b, 0x43, 0x83, 0x97, 0x87, - 0x0a, 0x79, 0xe5, 0xb2, 0x46, 0x5d, 0x9c, 0x48, 0x75, 0x8c, 0xdf, 0x41, 0x6f, 0x23, 0xf2, 0x53, - 0xe6, 0xa7, 0x0d, 0x99, 0xd7, 0xb4, 0x09, 0xe1, 0x38, 0xa5, 0xa8, 0x85, 0x5f, 0xae, 0xe6, 0xed, - 0x2c, 0xa7, 0xa1, 0x9c, 0x15, 0x9b, 0x10, 0x4c, 0x6f, 0x17, 0xfe, 0x61, 0x5a, 0x19, 0x4e, 0xa2, - 0x6f, 0x31, 0xe4, 0xe9, 0x4f, 0x29, 0x78, 0xb5, 0x71, 0x24, 0xe4, 0x88, 0x0e, 0x4a, 0xbf, 0x32, - 0x4b, 0x15, 0xd0, 0x4c, 0x77, 0xf0, 0xce, 0x68, 0x32, 0xfd, 0x87, 0x69, 0x4b, 0xfd, 0x15, 0xc2, - 0xd0, 0xdc, 0x76, 0xa3, 0xc1, 0xf7, 0xcc, 0x2b, 0x6c, 0xe6, 0x48, 0x35, 0x16, 0xcd, 0x0c, 0x00, - 0xdf, 0x8d, 0x26, 0xd7, 0x15, 0x2b, 0x0a, 0xfb, 0x51, 0x60, 0x26, 0xe8, 0xeb, 0xda, 0xc2, 0xcb, - 0xdb, 0xc7, 0x26, 0x90, 0xde, 0xfb, 0xa2, 0x5b, 0x8c, 0x1e, 0x29, 0xe8, 0x28, 0xd0, 0xf4, 0x84, - 0x49, 0x67, 0x50, 0x0e, 0xe4, 0x56, 0xf2, 0x09, 0x3c, 0x00, 0x53, 0xc4, 0x8f, 0x71, 0x3e, 0x70, - 0x49, 0x8e, 0xb8, 0x2b, 0x77, 0x77, 0x13, 0x44, 0x77, 0x04, 0xf8, 0x6e, 0xad, 0xe8, 0xfc, 0xb1, - 0x79, 0x12, 0x6c, 0x00, 0x4d, 0x60, 0x45, 0x50, 0x10, 0xf4, 0x95, 0x40, 0xbf, 0xf7, 0x31, 0xcd, - 0xcf, 0x01, 0x3d, 0x81, 0xdc, 0xe7, 0x5c, 0xfa, 0x00, 0x33, 0x10, 0xc8, 0x91, 0xd3, 0xf4, 0x82, - 0x89, 0x5c, 0xcf, 0x9b, 0xb5, 0x10, 0x7e, 0x77, 0x50, 0xde, 0x92, 0x74, 0x04, 0xaf, 0x53, 0xc9, - 0x1a, 0x8b, 0x05, 0xc3, 0xf6, 0xb2, 0xb2, 0x17, 0xf6, 0xa6, 0xf8, 0x30, 0x9e, 0x35, 0xe4, 0xfb, - 0x99, 0xcb, 0x4e, 0xc0, 0x23, 0x43, 0xbe, 0x91, 0xb9, 0x9c, 0xa2, 0x9a, 0x7e, 0x32, 0xb1, 0xbf, - 0x01, 0x46, 0xd0, 0x7a, 0x95, 0x45, 0x8e, 0xcc, 0xa2, 0x10, 0x0d, 0xca, 0x2e, 0x80, 0x49, 0xb2, - 0x9d, 0x31, 0xc9, 0x10, 0x7e, 0x61, 0x2e, 0xd7, 0x6d, 0x83, 0x21, 0x97, 0x3d, 0x1b, 0xf3, 0x5a, - 0x16, 0x93, 0xf3, 0xc5, 0x72, 0x47, 0xd2, 0x13, 0x70, 0xab, 0x44, 0x75, 0x48, 0x9a, 0xab, 0x09, - 0x1b, 0x00, 0xdb, 0x7b, 0xae, 0xa3, 0x33, 0x9e, 0x15, 0x5f, 0xf8, 0x9b, 0x86, 0xfc, 0x29, 0x73, - 0xf3, 0xf6, 0x62, 0x98, 0xb4, 0x4f, 0xa5, 0xf1, 0x11, 0x61, 0x6b, 0x08, 0xb4, 0x23, 0x50, 0x57, - 0xd0, 0xec, 0x84, 0x96, 0xe6, 0x56, 0x05, 0x3a, 0x18, 0x4a, 0xec, 0x97, 0x39, 0xbe, 0xee, 0x20, - 0xd7, 0xdf, 0x50, 0xb0, 0xc6, 0x15, 0xc4, 0x1c, 0x0f, 0x1a, 0xa9, 0xe2, 0x4f, 0x29, 0xe0, 0x18, - 0x90, 0xad, 0xc3, 0xa5, 0x51, 0xa3, 0xe0, 0x23, 0xff, 0x9a, 0x6f, 0x80, 0x26, 0xf9, 0xf7, 0x6c, - 0xd4, 0x82, 0x18, 0xfc, 0x57, 0x7c, 0x7a, 0x46, 0xad, 0x27, 0x11, 0x7b, 0x0a, 0xd9, 0x12, 0xa3, - 0x81, 0x30, 0x2e, 0xd5, 0x89, 0x14, 0xec, 0x15, 0x94, 0x6a, 0xe4, 0x1e, 0x57, 0x0b, 0xe4, 0x1e, - 0x57, 0xa5, 0x6d, 0x98, 0xf7, 0x01, 0xb2, 0xe2, 0xb6, 0xe9, 0xba, 0xce, 0x93, 0x28, 0x4f, 0xe5, - 0x35, 0xaa, 0x7a, 0xb9, 0x56, 0x37, 0xe8, 0x84, 0xcc, 0x0f, 0x28, 0xbd, 0x2d, 0xb6, 0x85, 0x40, - 0xdd, 0x74, 0x9e, 0x20, 0xbe, 0xd4, 0x27, 0x84, 0xe1, 0x2a, 0xb8, 0xec, 0x06, 0xec, 0x23, 0x79, - 0xbd, 0x92, 0xed, 0x85, 0x6f, 0x53, 0x73, 0x1b, 0x6c, 0x39, 0x41, 0x46, 0xdb, 0x08, 0x54, 0x34, - 0x06, 0xcd, 0x8c, 0x01, 0xe6, 0xcb, 0x2e, 0xa2, 0xc2, 0x91, 0x2b, 0x6c, 0x7f, 0xc0, 0x9f, 0x13, - 0x81, 0x65, 0xea, 0xd0, 0xeb, 0x70, 0x2e, 0xc5, 0xcb, 0x93, 0x86, 0x49, 0xf2, 0xc1, 0x46, 0x3e, - 0xe2, 0x4c, 0x36, 0x15, 0x16, 0xe6, 0x6b, 0x8a, 0xae, 0xbe, 0x4d, 0x03, 0x0a, 0x96, 0x87, 0x66, - 0xfd, 0xac, 0xe9, 0xf6, 0x70, 0x09, 0xa6, 0x07, 0x68, 0x72, 0x05, 0x96, 0xc6, 0xb5, 0x36, 0xeb, - 0x0f, 0x15, 0x8b, 0xc2, 0x17, 0x02, 0xaf, 0x26, 0x5f, 0x22, 0x97, 0x3f, 0x06, 0x9b, 0x34, 0x2b, - 0x54, 0x51, 0xb6, 0x8d, 0xe8, 0x60, 0x31, 0x90, 0x47, 0xaa, 0xa4, 0xa9, 0xbf, 0xed, 0xda, 0x43, - 0xc7, 0xa3, 0xb3, 0x6a, 0x90, 0x64, 0x93, 0x77, 0x42, 0x17, 0x93, 0x94, 0x21, 0x0d, 0xae, 0x04, - 0x72, 0x5f, 0x4c, 0x82, 0xe6, 0x26, 0x55, 0x77, 0xa4, 0xb8, 0x74, 0x26, 0x3b, 0x6d, 0xb6, 0x9b, - 0xbc, 0x41, 0xcc, 0x52, 0xef, 0xdd, 0x91, 0xfa, 0x08, 0x34, 0xa6, 0x18, 0xb9, 0x26, 0xbd, 0x6e, - 0x21, 0x88, 0x23, 0xd3, 0x2b, 0x3c, 0x06, 0x04, 0x26, 0x4c, 0x43, 0x49, 0x51, 0xb3, 0x81, 0xd7, - 0x67, 0x81, 0x28, 0x1d, 0x3e, 0xc4, 0x58, 0x3f, 0x35, 0xa5, 0xd1, 0x8a, 0x7f, 0x4e, 0x8a, 0x93, - 0x77, 0xc1, 0xbb, 0x51, 0x3a, 0x72, 0x6c, 0xe5, 0x14, 0x3f, 0x05, 0x7a, 0xf9, 0x47, 0xff, 0x47, - 0x34, 0x14, 0x59, 0x06, 0x56, 0x81, 0xd7, 0xa0, 0x18, 0x49, 0x63, 0xd7, 0xc0, 0x84, 0x52, 0xcb, - 0x2f, 0x3c, 0x2f, 0x96, 0x1a, 0x24, 0x8a, 0x3f, 0x45, 0xcb, 0xc7, 0x95, 0x19, 0x60, 0x1e, 0x90, - 0xef, 0x19, 0xc3, 0x80, 0x7c, 0xa6, 0xfb, 0x0c, 0xee, 0x83, 0x5b, 0xe0, 0x0c, 0xdf, 0x28, 0x9e, - 0x33, 0x66, 0x94, 0xad, 0x40, 0xb6, 0x02, 0xd9, 0x0a, 0x64, 0x2b, 0x90, 0xea, 0x0a, 0xfc, 0x06, - 0x2b, 0x3f, 0x89, 0x0a, 0x68, 0xdb, 0xdf, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, - 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXSelectIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x3c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x33, 0x17, 0x79, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd7, 0xce, 0x93, 0x00, 0x00, - 0x04, 0x7e, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x99, 0x5b, 0x88, 0x0e, 0x61, 0x18, 0xc7, - 0x7d, 0xd6, 0x3a, 0x6c, 0x12, 0x42, 0x24, 0x17, 0x48, 0xb1, 0x21, 0x09, 0x37, 0x5c, 0x2d, 0xe5, - 0x74, 0x23, 0x11, 0x39, 0xad, 0xc3, 0x86, 0x12, 0x17, 0x8b, 0x52, 0xd2, 0xda, 0xa4, 0xb4, 0x29, - 0xa7, 0x24, 0xe4, 0xc2, 0x31, 0x57, 0x12, 0x52, 0x88, 0x1b, 0x09, 0xed, 0x0d, 0xc9, 0x46, 0x88, - 0x9c, 0x6e, 0x24, 0xe7, 0x8d, 0x65, 0xf7, 0xf3, 0x7b, 0x3e, 0x33, 0xdb, 0xe3, 0x6d, 0x66, 0xbe, - 0x99, 0xf9, 0xde, 0xd9, 0xa1, 0xe6, 0xa9, 0xff, 0xf7, 0x3e, 0xef, 0x73, 0x7e, 0xde, 0x99, 0xf9, - 0x66, 0xe6, 0x9d, 0x4e, 0x9d, 0x32, 0xca, 0x56, 0x20, 0x5b, 0x81, 0x6c, 0x05, 0xb2, 0x15, 0xc8, - 0x56, 0x20, 0xd9, 0x15, 0xc8, 0xe7, 0xf3, 0xd3, 0xc1, 0x33, 0xb0, 0x3d, 0xd9, 0x4c, 0x29, 0x45, - 0xa7, 0xb1, 0x8b, 0x40, 0xe8, 0x07, 0x28, 0x4b, 0xa9, 0x0c, 0xcf, 0xb4, 0x9d, 0x3d, 0xa5, 0xd1, - 0x85, 0xdd, 0x1d, 0x97, 0xae, 0x8c, 0xb6, 0x62, 0x46, 0xaf, 0xc2, 0xc3, 0xe3, 0x9f, 0x2a, 0xc6, - 0xa3, 0xbe, 0x92, 0x45, 0xbe, 0x0d, 0x72, 0xaa, 0x55, 0x80, 0x31, 0x25, 0x67, 0xf0, 0x08, 0x40, - 0xdc, 0xc1, 0x60, 0x88, 0x87, 0xaa, 0x63, 0x44, 0x24, 0xcf, 0x81, 0xc7, 0x40, 0xe8, 0x04, 0x08, - 0xbc, 0xae, 0xd0, 0x5f, 0x13, 0x43, 0x87, 0xca, 0x83, 0xaa, 0xc4, 0xa6, 0x1a, 0xfc, 0x04, 0xbf, - 0xc0, 0xc8, 0x20, 0xdb, 0xc4, 0x74, 0x24, 0xee, 0x02, 0xde, 0x02, 0x97, 0x4e, 0xc3, 0xf8, 0x36, - 0x89, 0xae, 0xce, 0x31, 0xbc, 0x1b, 0x54, 0x14, 0x36, 0xcb, 0x41, 0xab, 0x63, 0x2b, 0xc3, 0xc4, - 0x20, 0xfb, 0x44, 0x75, 0x24, 0x9f, 0x06, 0x9a, 0xa5, 0x0a, 0x87, 0xce, 0x30, 0x7a, 0x36, 0x89, - 0x5c, 0x8e, 0xf8, 0x44, 0xd0, 0xc3, 0xaf, 0x28, 0x74, 0x2b, 0x41, 0x1b, 0x70, 0x69, 0xa7, 0x9f, - 0x6d, 0x87, 0xc9, 0xa9, 0x64, 0x2a, 0xd0, 0x4d, 0x36, 0xc4, 0x49, 0x4e, 0x8c, 0x2a, 0xa0, 0x9b, - 0xdb, 0x11, 0x27, 0x4e, 0x22, 0x3e, 0x4e, 0x71, 0xdf, 0x18, 0x85, 0x6e, 0xc7, 0x49, 0x82, 0xdf, - 0xb6, 0x82, 0xf7, 0x9f, 0x9f, 0xfa, 0x38, 0x31, 0x12, 0xf5, 0xa1, 0xae, 0xf1, 0x60, 0x8f, 0x8c, - 0x71, 0x12, 0xe1, 0xd7, 0x0f, 0xec, 0x02, 0x0b, 0xe2, 0xf8, 0x67, 0x3e, 0xd9, 0x0a, 0x64, 0x2b, - 0xf0, 0xff, 0xae, 0x40, 0x4e, 0x97, 0xce, 0x9f, 0xc0, 0x5f, 0xf3, 0x5c, 0x2e, 0x97, 0xd7, 0x7a, - 0x3f, 0xde, 0xf1, 0x9b, 0x89, 0xbe, 0x15, 0x9f, 0x2b, 0x7e, 0x76, 0x5a, 0x6e, 0xe6, 0x12, 0x5d, - 0xd8, 0x7c, 0x3a, 0x4e, 0x28, 0x9e, 0x64, 0x4b, 0xc0, 0x47, 0x60, 0x92, 0xbc, 0xe3, 0x55, 0x16, - 0x0b, 0x82, 0xcd, 0x71, 0xe5, 0x78, 0x28, 0xc8, 0x1e, 0xbb, 0x32, 0x70, 0x55, 0xd9, 0xbb, 0xac, - 0x3c, 0xba, 0x1d, 0x0e, 0xf2, 0x8d, 0xad, 0x23, 0xf0, 0x05, 0x37, 0x8b, 0xc7, 0xb8, 0xbe, 0x58, - 0x60, 0x7c, 0xe4, 0x3d, 0x50, 0xd3, 0x58, 0x3f, 0x1f, 0x8c, 0x86, 0x6b, 0x43, 0x83, 0x97, 0x87, - 0x0a, 0x79, 0xe5, 0xb2, 0x46, 0x5d, 0x9c, 0x48, 0x75, 0x8c, 0xdf, 0x41, 0x6f, 0x23, 0xf2, 0x53, - 0xe6, 0xa7, 0x0d, 0x99, 0xd7, 0xb4, 0x09, 0xe1, 0x38, 0xa5, 0xa8, 0x85, 0x5f, 0xae, 0xe6, 0xed, - 0x2c, 0xa7, 0xa1, 0x9c, 0x15, 0x9b, 0x10, 0x4c, 0x6f, 0x17, 0xfe, 0x61, 0x5a, 0x19, 0x4e, 0xa2, - 0x6f, 0x31, 0xe4, 0xe9, 0x4f, 0x29, 0x78, 0xb5, 0x71, 0x24, 0xe4, 0x88, 0x0e, 0x4a, 0xbf, 0x32, - 0x4b, 0x15, 0xd0, 0x4c, 0x77, 0xf0, 0xce, 0x68, 0x32, 0xfd, 0x87, 0x69, 0x4b, 0xfd, 0x15, 0xc2, - 0xd0, 0xdc, 0x76, 0xa3, 0xc1, 0xf7, 0xcc, 0x2b, 0x6c, 0xe6, 0x48, 0x35, 0x16, 0xcd, 0x0c, 0x00, - 0xdf, 0x8d, 0x26, 0xd7, 0x15, 0x2b, 0x0a, 0xfb, 0x51, 0x60, 0x26, 0xe8, 0xeb, 0xda, 0xc2, 0xcb, - 0xdb, 0xc7, 0x26, 0x90, 0xde, 0xfb, 0xa2, 0x5b, 0x8c, 0x1e, 0x29, 0xe8, 0x28, 0xd0, 0xf4, 0x84, - 0x49, 0x67, 0x50, 0x0e, 0xe4, 0x56, 0xf2, 0x09, 0x3c, 0x00, 0x53, 0xc4, 0x8f, 0x71, 0x3e, 0x70, - 0x49, 0x8e, 0xb8, 0x2b, 0x77, 0x77, 0x13, 0x44, 0x77, 0x04, 0xf8, 0x6e, 0xad, 0xe8, 0xfc, 0xb1, - 0x79, 0x12, 0x6c, 0x00, 0x4d, 0x60, 0x45, 0x50, 0x10, 0xf4, 0x95, 0x40, 0xbf, 0xf7, 0x31, 0xcd, - 0xcf, 0x01, 0x3d, 0x81, 0xdc, 0xe7, 0x5c, 0xfa, 0x00, 0x33, 0x10, 0xc8, 0x91, 0xd3, 0xf4, 0x82, - 0x89, 0x5c, 0xcf, 0x9b, 0xb5, 0x10, 0x7e, 0x77, 0x50, 0xde, 0x92, 0x74, 0x04, 0xaf, 0x53, 0xc9, - 0x1a, 0x8b, 0x05, 0xc3, 0xf6, 0xb2, 0xb2, 0x17, 0xf6, 0xa6, 0xf8, 0x30, 0x9e, 0x35, 0xe4, 0xfb, - 0x99, 0xcb, 0x4e, 0xc0, 0x23, 0x43, 0xbe, 0x91, 0xb9, 0x9c, 0xa2, 0x9a, 0x7e, 0x32, 0xb1, 0xbf, - 0x01, 0x46, 0xd0, 0x7a, 0x95, 0x45, 0x8e, 0xcc, 0xa2, 0x10, 0x0d, 0xca, 0x2e, 0x80, 0x49, 0xb2, - 0x9d, 0x31, 0xc9, 0x10, 0x7e, 0x61, 0x2e, 0xd7, 0x6d, 0x83, 0x21, 0x97, 0x3d, 0x1b, 0xf3, 0x5a, - 0x16, 0x93, 0xf3, 0xc5, 0x72, 0x47, 0xd2, 0x13, 0x70, 0xab, 0x44, 0x75, 0x48, 0x9a, 0xab, 0x09, - 0x1b, 0x00, 0xdb, 0x7b, 0xae, 0xa3, 0x33, 0x9e, 0x15, 0x5f, 0xf8, 0x9b, 0x86, 0xfc, 0x29, 0x73, - 0xf3, 0xf6, 0x62, 0x98, 0xb4, 0x4f, 0xa5, 0xf1, 0x11, 0x61, 0x6b, 0x08, 0xb4, 0x23, 0x50, 0x57, - 0xd0, 0xec, 0x84, 0x96, 0xe6, 0x56, 0x05, 0x3a, 0x18, 0x4a, 0xec, 0x97, 0x39, 0xbe, 0xee, 0x20, - 0xd7, 0xdf, 0x50, 0xb0, 0xc6, 0x15, 0xc4, 0x1c, 0x0f, 0x1a, 0xa9, 0xe2, 0x4f, 0x29, 0xe0, 0x18, - 0x90, 0xad, 0xc3, 0xa5, 0x51, 0xa3, 0xe0, 0x23, 0xff, 0x9a, 0x6f, 0x80, 0x26, 0xf9, 0xf7, 0x6c, - 0xd4, 0x82, 0x18, 0xfc, 0x57, 0x7c, 0x7a, 0x46, 0xad, 0x27, 0x11, 0x7b, 0x0a, 0xd9, 0x12, 0xa3, - 0x81, 0x30, 0x2e, 0xd5, 0x89, 0x14, 0xec, 0x15, 0x94, 0x6a, 0xe4, 0x1e, 0x57, 0x0b, 0xe4, 0x1e, - 0x57, 0xa5, 0x6d, 0x98, 0xf7, 0x01, 0xb2, 0xe2, 0xb6, 0xe9, 0xba, 0xce, 0x93, 0x28, 0x4f, 0xe5, - 0x35, 0xaa, 0x7a, 0xb9, 0x56, 0x37, 0xe8, 0x84, 0xcc, 0x0f, 0x28, 0xbd, 0x2d, 0xb6, 0x85, 0x40, - 0xdd, 0x74, 0x9e, 0x20, 0xbe, 0xd4, 0x27, 0x84, 0xe1, 0x2a, 0xb8, 0xec, 0x06, 0xec, 0x23, 0x79, - 0xbd, 0x92, 0xed, 0x85, 0x6f, 0x53, 0x73, 0x1b, 0x6c, 0x39, 0x41, 0x46, 0xdb, 0x08, 0x54, 0x34, - 0x06, 0xcd, 0x8c, 0x01, 0xe6, 0xcb, 0x2e, 0xa2, 0xc2, 0x91, 0x2b, 0x6c, 0x7f, 0xc0, 0x9f, 0x13, - 0x81, 0x65, 0xea, 0xd0, 0xeb, 0x70, 0x2e, 0xc5, 0xcb, 0x93, 0x86, 0x49, 0xf2, 0xc1, 0x46, 0x3e, - 0xe2, 0x4c, 0x36, 0x15, 0x16, 0xe6, 0x6b, 0x8a, 0xae, 0xbe, 0x4d, 0x03, 0x0a, 0x96, 0x87, 0x66, - 0xfd, 0xac, 0xe9, 0xf6, 0x70, 0x09, 0xa6, 0x07, 0x68, 0x72, 0x05, 0x96, 0xc6, 0xb5, 0x36, 0xeb, - 0x0f, 0x15, 0x8b, 0xc2, 0x17, 0x02, 0xaf, 0x26, 0x5f, 0x22, 0x97, 0x3f, 0x06, 0x9b, 0x34, 0x2b, - 0x54, 0x51, 0xb6, 0x8d, 0xe8, 0x60, 0x31, 0x90, 0x47, 0xaa, 0xa4, 0xa9, 0xbf, 0xed, 0xda, 0x43, - 0xc7, 0xa3, 0xb3, 0x6a, 0x90, 0x64, 0x93, 0x77, 0x42, 0x17, 0x93, 0x94, 0x21, 0x0d, 0xae, 0x04, - 0x72, 0x5f, 0x4c, 0x82, 0xe6, 0x26, 0x55, 0x77, 0xa4, 0xb8, 0x74, 0x26, 0x3b, 0x6d, 0xb6, 0x9b, - 0xbc, 0x41, 0xcc, 0x52, 0xef, 0xdd, 0x91, 0xfa, 0x08, 0x34, 0xa6, 0x18, 0xb9, 0x26, 0xbd, 0x6e, - 0x21, 0x88, 0x23, 0xd3, 0x2b, 0x3c, 0x06, 0x04, 0x26, 0x4c, 0x43, 0x49, 0x51, 0xb3, 0x81, 0xd7, - 0x67, 0x81, 0x28, 0x1d, 0x3e, 0xc4, 0x58, 0x3f, 0x35, 0xa5, 0xd1, 0x8a, 0x7f, 0x4e, 0x8a, 0x93, - 0x77, 0xc1, 0xbb, 0x51, 0x3a, 0x72, 0x6c, 0xe5, 0x14, 0x3f, 0x05, 0x7a, 0xf9, 0x47, 0xff, 0x47, - 0x34, 0x14, 0x59, 0x06, 0x56, 0x81, 0xd7, 0xa0, 0x18, 0x49, 0x63, 0xd7, 0xc0, 0x84, 0x52, 0xcb, - 0x2f, 0x3c, 0x2f, 0x96, 0x1a, 0x24, 0x8a, 0x3f, 0x45, 0xcb, 0xc7, 0x95, 0x19, 0x60, 0x1e, 0x90, - 0xef, 0x19, 0xc3, 0x80, 0x7c, 0xa6, 0xfb, 0x0c, 0xee, 0x83, 0x5b, 0xe0, 0x0c, 0xdf, 0x28, 0x9e, - 0x33, 0x66, 0x94, 0xad, 0x40, 0xb6, 0x02, 0xd9, 0x0a, 0x64, 0x2b, 0x90, 0xea, 0x0a, 0xfc, 0x06, - 0x2b, 0x3f, 0x89, 0x0a, 0x68, 0xdb, 0xdf, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, - 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXSelectIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x5a, 0x08, 0x06, 0x00, 0x00, 0x00, 0x26, 0x61, 0x71, - 0xb1, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x54, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x08, 0x58, 0x73, 0x21, 0x00, 0x00, - 0x07, 0x8e, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, 0x9c, 0x6b, 0xa8, 0x55, 0x45, 0x14, 0xc7, - 0xbd, 0xbe, 0x25, 0x95, 0xac, 0x30, 0x0d, 0xba, 0xbe, 0xa2, 0xf2, 0x55, 0x64, 0xd0, 0x4b, 0x0a, - 0xa2, 0xd0, 0xa2, 0x07, 0x81, 0x2f, 0x34, 0x84, 0x08, 0xb5, 0x8c, 0x88, 0x50, 0xa8, 0x88, 0xca, - 0x0f, 0x41, 0x51, 0x91, 0x19, 0x29, 0x96, 0x50, 0xe0, 0x87, 0x50, 0x22, 0xf1, 0x59, 0x4a, 0x85, - 0xa9, 0x65, 0x65, 0x24, 0xa6, 0xe0, 0x07, 0x2b, 0xbc, 0x5a, 0x99, 0xa8, 0x44, 0xa5, 0x99, 0xe5, - 0xeb, 0xf6, 0xfb, 0x5f, 0xce, 0x3e, 0xcc, 0x9d, 0x3b, 0xfb, 0x38, 0xfb, 0x9c, 0xfd, 0xb8, 0xf7, - 0x38, 0x0b, 0xfe, 0xcc, 0xcc, 0x9a, 0x35, 0x6b, 0xd6, 0xfa, 0x9f, 0x73, 0xe6, 0xce, 0x9e, 0xbd, - 0xf7, 0xed, 0xd4, 0x29, 0x48, 0x60, 0x20, 0x30, 0x10, 0x18, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, - 0x81, 0x81, 0xc0, 0x40, 0x60, 0x20, 0x30, 0x10, 0x18, 0x08, 0x0c, 0xb4, 0x66, 0xa0, 0xa1, 0x75, - 0x33, 0xbb, 0x56, 0x73, 0x73, 0x73, 0x0f, 0xbc, 0x4f, 0x06, 0xa7, 0xc0, 0x87, 0x0d, 0x0d, 0x0d, - 0xa7, 0xb3, 0x9b, 0xed, 0x3c, 0xf0, 0x0c, 0xa1, 0x1b, 0x40, 0x24, 0xcb, 0xce, 0x83, 0x94, 0xb3, - 0x4b, 0x11, 0x16, 0x2f, 0x8c, 0x98, 0x2c, 0x95, 0xa7, 0x28, 0xbb, 0x66, 0x37, 0x63, 0x71, 0x9e, - 0x3b, 0xe7, 0x34, 0x75, 0x2f, 0x6b, 0x1e, 0x91, 0x19, 0x08, 0xb5, 0x48, 0x09, 0x4d, 0x07, 0x03, - 0x79, 0x7d, 0x43, 0x1d, 0x53, 0xd7, 0xa7, 0x2a, 0x10, 0x9a, 0xf2, 0xe7, 0xea, 0xb5, 0x8e, 0xf1, - 0x07, 0xa4, 0x27, 0xf3, 0x4e, 0x02, 0xc7, 0xc0, 0x6a, 0xb6, 0x3c, 0xcd, 0x29, 0xc7, 0xe1, 0xe5, - 0x8e, 0x38, 0xba, 0x60, 0x38, 0x01, 0xa8, 0xd4, 0xd6, 0x4b, 0x5b, 0xb0, 0x8e, 0x27, 0x24, 0xb2, - 0x05, 0x44, 0xb2, 0x9a, 0x4a, 0xf7, 0x24, 0x59, 0x60, 0x3f, 0x30, 0x1a, 0x6c, 0x94, 0xfa, 0x90, - 0xbc, 0x85, 0x71, 0x17, 0x80, 0x8d, 0xc6, 0xf8, 0x35, 0xde, 0x83, 0xdb, 0x93, 0x21, 0x09, 0xb8, - 0xc8, 0x58, 0x87, 0x5e, 0x1b, 0x75, 0x2f, 0xc1, 0xb6, 0x9f, 0x41, 0x84, 0xaa, 0x89, 0xb6, 0x4d, - 0xd8, 0x8b, 0xcc, 0xcd, 0x1a, 0x68, 0x89, 0xbd, 0x7b, 0xf0, 0x8a, 0xa7, 0x50, 0x23, 0x12, 0xe8, - 0x02, 0xf6, 0x5a, 0x89, 0xa8, 0xf9, 0x31, 0x48, 0x42, 0xea, 0xa7, 0x86, 0x8f, 0x0f, 0x7c, 0x93, - 0x62, 0x4c, 0x6f, 0x60, 0xfe, 0x42, 0x22, 0x37, 0x3b, 0x7d, 0x7d, 0xb4, 0x3b, 0x3b, 0x32, 0xb8, - 0x06, 0x1c, 0x89, 0x32, 0x31, 0xca, 0xf5, 0xd4, 0xbd, 0x48, 0xc5, 0xae, 0x27, 0x78, 0x18, 0x4c, - 0x07, 0xdd, 0x7c, 0x92, 0xc4, 0x4e, 0x64, 0x7e, 0x01, 0x6c, 0xf9, 0x05, 0xc5, 0x15, 0x3e, 0x3e, - 0xda, 0xad, 0x0d, 0x09, 0x8c, 0x06, 0x87, 0xed, 0xcc, 0x68, 0xeb, 0x92, 0x32, 0xd1, 0x7a, 0xe8, - 0x93, 0x24, 0x3e, 0xfb, 0x80, 0x2f, 0x81, 0x2d, 0x22, 0x73, 0x98, 0x8f, 0x8f, 0x76, 0x6f, 0x43, - 0x22, 0xa3, 0xc0, 0x21, 0x3b, 0x43, 0xda, 0x0b, 0xd2, 0x0e, 0x1e, 0x9f, 0x4b, 0x1d, 0xf3, 0xfc, - 0x8c, 0x6e, 0x68, 0xda, 0x73, 0x15, 0xea, 0x8f, 0x84, 0x46, 0x02, 0x9b, 0xd4, 0xed, 0x69, 0x07, - 0xc5, 0x1c, 0xf6, 0xba, 0xbd, 0x1f, 0xdd, 0x90, 0xb4, 0xe7, 0x69, 0x17, 0xfe, 0x48, 0x6c, 0x04, - 0x38, 0x08, 0x22, 0x99, 0x97, 0x76, 0x60, 0x38, 0x5e, 0x10, 0x39, 0xa7, 0x6c, 0x02, 0xf5, 0x49, - 0x66, 0x44, 0x1c, 0x09, 0xf6, 0x07, 0x4f, 0x80, 0x07, 0x22, 0x5d, 0x9a, 0x25, 0x7e, 0x3b, 0x83, - 0x29, 0xe0, 0x71, 0xd0, 0x2f, 0x4d, 0xdf, 0xc1, 0x57, 0x60, 0x20, 0x30, 0x10, 0x18, 0x08, 0x0c, - 0x04, 0x06, 0x02, 0x03, 0x81, 0x81, 0x0e, 0xc0, 0x00, 0x5b, 0xa0, 0x3e, 0x1d, 0x20, 0xcc, 0xaa, - 0x43, 0x2c, 0xdf, 0x97, 0x27, 0xd1, 0x8b, 0xf1, 0x32, 0x1d, 0x5c, 0x14, 0xe3, 0x4d, 0x87, 0xca, - 0x3b, 0x38, 0xd4, 0x5d, 0x15, 0xd3, 0x5f, 0x51, 0x8d, 0xff, 0x7b, 0x31, 0x58, 0x08, 0x06, 0x81, - 0x9f, 0xc0, 0x4c, 0x7c, 0x6d, 0xa2, 0xf4, 0x16, 0x7c, 0x28, 0x5e, 0xdd, 0xdb, 0x1f, 0x59, 0x61, - 0xd0, 0x11, 0xfa, 0x96, 0xe2, 0xfb, 0x68, 0x05, 0x9b, 0x6c, 0xbb, 0x08, 0xb4, 0x1b, 0xd8, 0x03, - 0x7c, 0xe4, 0xe9, 0xa4, 0xd1, 0xe0, 0xf4, 0x6a, 0x70, 0xd2, 0x72, 0xfe, 0x37, 0xed, 0x44, 0x57, - 0x3f, 0xd8, 0xbf, 0x6c, 0xf9, 0x88, 0x6b, 0x6e, 0xa7, 0xa3, 0xfc, 0x65, 0x49, 0x1a, 0x6f, 0xcd, - 0xf6, 0x4c, 0xae, 0x4b, 0x49, 0x5f, 0xd9, 0x92, 0x74, 0x42, 0x1c, 0xcf, 0x89, 0x71, 0xbe, 0x2c, - 0x89, 0x2f, 0x7c, 0xec, 0x8a, 0xf1, 0xe3, 0x52, 0x0f, 0x4c, 0xe2, 0x3b, 0x2d, 0xdb, 0xe8, 0x26, - 0xdd, 0x5e, 0x1c, 0xfe, 0xea, 0xe9, 0x74, 0xb3, 0xa7, 0x9d, 0x69, 0x76, 0xd2, 0x6c, 0x18, 0xf5, - 0x89, 0x30, 0xd1, 0x68, 0xb4, 0xcf, 0x55, 0xf5, 0xfd, 0x30, 0xf7, 0xe0, 0xe8, 0xd0, 0xb9, 0x9c, - 0x65, 0xd1, 0x5f, 0xfe, 0x59, 0x90, 0x98, 0xd6, 0xb6, 0x47, 0x40, 0xdc, 0x1a, 0x7a, 0x96, 0xbe, - 0x1d, 0xe0, 0x3d, 0xd6, 0xa7, 0x33, 0x94, 0xde, 0x82, 0x6f, 0x1d, 0x06, 0xff, 0x00, 0xca, 0xf3, - 0x19, 0x83, 0xe7, 0xe3, 0x6f, 0xae, 0xd1, 0x8e, 0xad, 0xe2, 0x47, 0xf7, 0xb2, 0x66, 0x01, 0xad, - 0xa1, 0x2e, 0x5f, 0x1a, 0x7b, 0x18, 0x2c, 0xc6, 0xe7, 0x41, 0x35, 0xea, 0x56, 0x20, 0x43, 0xb7, - 0x4c, 0x5c, 0xf2, 0x17, 0xca, 0xbe, 0x75, 0x9b, 0x78, 0x56, 0x89, 0x41, 0xda, 0x1d, 0x2e, 0x36, - 0x4b, 0xba, 0x39, 0x59, 0xcd, 0x5b, 0xd7, 0x7e, 0x21, 0xef, 0xfb, 0x18, 0x52, 0xf7, 0xa1, 0xd7, - 0xbd, 0xf6, 0x20, 0x49, 0x18, 0x80, 0x34, 0xdd, 0xa0, 0x8b, 0x93, 0x29, 0x49, 0x7c, 0x05, 0x5b, - 0x18, 0x80, 0xc9, 0xee, 0xe0, 0x40, 0x0c, 0xa3, 0xdf, 0x06, 0x92, 0xaa, 0x60, 0x00, 0x32, 0x9f, - 0x89, 0x21, 0x54, 0xea, 0x5b, 0x93, 0xba, 0x64, 0xcc, 0xb5, 0x40, 0xa7, 0xfa, 0xb3, 0xc1, 0x70, - 0x73, 0x3c, 0xed, 0xbe, 0x60, 0x21, 0xd0, 0x7d, 0xfd, 0x65, 0xe0, 0x1e, 0xb3, 0xbf, 0x2e, 0xea, - 0x24, 0xa5, 0xa7, 0x48, 0x74, 0x95, 0xe4, 0x92, 0x95, 0x66, 0x92, 0x18, 0xe8, 0x3e, 0xbe, 0x6e, - 0x25, 0xcb, 0x7e, 0x27, 0x98, 0x61, 0xf5, 0xcf, 0x43, 0x67, 0xca, 0x69, 0x1a, 0x2f, 0x46, 0x36, - 0xd4, 0x75, 0x0b, 0xc5, 0x96, 0x95, 0x28, 0xda, 0xdf, 0x79, 0x02, 0x41, 0xe9, 0x21, 0x84, 0xa9, - 0x60, 0x6c, 0x94, 0x80, 0x6f, 0xc9, 0x98, 0xb7, 0x80, 0x4b, 0xce, 0xa0, 0x6c, 0x79, 0x80, 0x81, - 0x32, 0xee, 0xea, 0xed, 0x95, 0x68, 0x1e, 0x6c, 0xd6, 0xb9, 0x9c, 0xa0, 0x9b, 0x29, 0x1b, 0x4a, - 0x3d, 0x39, 0x7d, 0xcc, 0x61, 0xb3, 0x09, 0x5d, 0x8f, 0xc8, 0x4f, 0xe1, 0x25, 0xc1, 0x34, 0x82, - 0x1f, 0x8d, 0x40, 0x9f, 0x4c, 0x12, 0x14, 0xe3, 0x86, 0x01, 0x91, 0xe7, 0x92, 0x45, 0xf2, 0x45, - 0x87, 0xc8, 0x38, 0xe1, 0x30, 0xd0, 0xb8, 0x1b, 0x4b, 0x36, 0x93, 0x1d, 0xfd, 0x52, 0x69, 0x6f, - 0xab, 0xc3, 0x1e, 0xf9, 0x89, 0xfb, 0xf0, 0x5e, 0x50, 0x7f, 0xe1, 0x42, 0x80, 0x83, 0x40, 0x13, - 0x30, 0xe5, 0xbb, 0xa4, 0x81, 0x31, 0x78, 0x85, 0xe9, 0xc0, 0xa8, 0x1f, 0xa7, 0xde, 0x72, 0xb5, - 0x46, 0xf9, 0x8e, 0xa1, 0x37, 0xab, 0x1b, 0x35, 0x1f, 0x8a, 0x2e, 0xa0, 0xc9, 0xec, 0x30, 0xea, - 0xcf, 0x97, 0x6c, 0x26, 0x1a, 0x3a, 0xb3, 0xfa, 0x0f, 0x8d, 0x21, 0x49, 0xe3, 0x4e, 0xd5, 0x9e, - 0x00, 0x06, 0x83, 0x26, 0x60, 0xcb, 0x92, 0xa4, 0x13, 0xe1, 0x60, 0xac, 0xed, 0xc4, 0x68, 0x3f, - 0x5b, 0x22, 0x43, 0xa7, 0x54, 0x67, 0x0d, 0xbd, 0x59, 0xbd, 0xae, 0x64, 0xf3, 0x94, 0xa9, 0x34, - 0xea, 0x5a, 0x77, 0xe7, 0x82, 0xcf, 0x0c, 0x9d, 0x5d, 0x5d, 0x91, 0x34, 0xee, 0xd4, 0xec, 0x89, - 0x64, 0x08, 0xd8, 0x67, 0x47, 0x44, 0xfb, 0x6b, 0x50, 0xd5, 0xa5, 0x23, 0xe3, 0xbe, 0x71, 0xf8, - 0x93, 0xea, 0x37, 0xd0, 0xf2, 0x0c, 0x2a, 0x65, 0xdc, 0x3a, 0xd9, 0x72, 0x2e, 0x4b, 0xff, 0x38, - 0x50, 0xad, 0xe8, 0xc3, 0xba, 0x2a, 0x35, 0x92, 0x7c, 0x1d, 0x31, 0xe9, 0x50, 0xa0, 0x47, 0x61, - 0x6c, 0xf9, 0x0a, 0x45, 0x55, 0x64, 0x6a, 0x6e, 0xc6, 0x4e, 0xb2, 0x1d, 0x1a, 0xed, 0x87, 0x4a, - 0x36, 0xb7, 0x1b, 0x3a, 0xbb, 0xba, 0x0a, 0x45, 0x92, 0x23, 0x3d, 0x7b, 0xbc, 0xda, 0x6f, 0x6b, - 0x9e, 0xdc, 0x84, 0x09, 0xf5, 0x04, 0xc7, 0x6e, 0xcd, 0x6c, 0xc9, 0x56, 0xda, 0x35, 0x6d, 0x3f, - 0x18, 0x5f, 0x69, 0x0d, 0xdc, 0x15, 0x25, 0x89, 0xdd, 0x0e, 0x6b, 0xee, 0x34, 0x9b, 0x5a, 0x4b, - 0x2f, 0x89, 0xe6, 0xaa, 0xb5, 0x8c, 0xce, 0x43, 0x2b, 0xf9, 0x19, 0x40, 0xe7, 0x08, 0xcb, 0x60, - 0x2b, 0xed, 0xbb, 0x38, 0x22, 0x3b, 0x66, 0xe9, 0x13, 0x35, 0x4b, 0xc7, 0x80, 0x6f, 0xc6, 0x0c, - 0xd2, 0xe3, 0x93, 0x77, 0x97, 0xfa, 0x3e, 0x8f, 0xb1, 0x49, 0x43, 0xdd, 0x0b, 0x27, 0xb3, 0xd3, - 0x70, 0xe4, 0xe5, 0x83, 0xa4, 0x1a, 0x80, 0x79, 0xa8, 0xa1, 0xab, 0x8e, 0xde, 0x5e, 0x83, 0x3d, - 0x8c, 0xf0, 0xa5, 0xe7, 0x40, 0xff, 0x04, 0x2e, 0xd1, 0x03, 0x69, 0x33, 0x80, 0xef, 0xed, 0x19, - 0x97, 0x0f, 0x1f, 0x9d, 0xd6, 0xec, 0xfc, 0x0e, 0x67, 0x98, 0x4c, 0x7b, 0x42, 0xdd, 0xc6, 0x98, - 0x05, 0x12, 0xbd, 0xb0, 0xe0, 0xc1, 0xa9, 0xd6, 0xd2, 0xd7, 0x40, 0xd1, 0x12, 0xfd, 0x1a, 0x7c, - 0x42, 0x8e, 0xb5, 0x89, 0x3b, 0xf5, 0x8e, 0x1d, 0x90, 0x45, 0x07, 0x4c, 0x5e, 0x8e, 0xdf, 0xbd, - 0xa0, 0x6b, 0x16, 0xfe, 0x3d, 0x7d, 0x2e, 0x67, 0x09, 0x9a, 0xea, 0x69, 0x1b, 0x6b, 0x96, 0x39, - 0xa1, 0x90, 0xd5, 0xc8, 0xec, 0x13, 0x80, 0xde, 0x29, 0x5a, 0x49, 0xd0, 0x07, 0x5c, 0xd1, 0x60, - 0xf7, 0x3e, 0xfa, 0x69, 0xae, 0xbe, 0x9c, 0x74, 0x27, 0x98, 0x67, 0x00, 0xf1, 0x1d, 0xcd, 0x69, - 0xbe, 0xe4, 0xd3, 0x40, 0xd2, 0x18, 0xa0, 0xcb, 0xc0, 0x48, 0x54, 0xd7, 0x7d, 0xf5, 0x36, 0x82, - 0xfe, 0xfa, 0xc8, 0xa8, 0xc0, 0xb2, 0xc8, 0x0f, 0xb4, 0x0d, 0x27, 0x6d, 0x14, 0x10, 0xf3, 0x91, - 0x83, 0x1c, 0x5d, 0x8b, 0x3f, 0xd6, 0xc6, 0x18, 0x05, 0xfa, 0x4d, 0x0e, 0xfb, 0x3c, 0x55, 0xf3, - 0x5d, 0x71, 0x25, 0xd1, 0xf9, 0x6c, 0x9b, 0x92, 0xf8, 0xb3, 0x6d, 0x5d, 0xd7, 0xca, 0x9a, 0x73, - 0x11, 0x2c, 0x3d, 0x67, 0x1b, 0xd3, 0x7e, 0xdd, 0xa1, 0xcb, 0x53, 0x35, 0x26, 0xcf, 0xc9, 0x12, - 0xcf, 0x05, 0x69, 0x4b, 0xcf, 0xf1, 0xf5, 0x7a, 0x83, 0xfe, 0xf2, 0x3a, 0xae, 0x3a, 0xc8, 0x7a, - 0x8b, 0x54, 0x29, 0x24, 0x2d, 0x49, 0xe5, 0x78, 0x12, 0x27, 0x9c, 0xf5, 0x00, 0x82, 0x6b, 0x04, - 0x71, 0x7b, 0xcc, 0x28, 0x31, 0x91, 0x5e, 0xfe, 0xeb, 0x4e, 0xfd, 0xd1, 0xa8, 0xa3, 0xa0, 0xf2, - 0xd2, 0xac, 0x79, 0xa9, 0xc9, 0x3f, 0xa4, 0xdc, 0x06, 0x74, 0xf2, 0x53, 0x49, 0x56, 0xd3, 0xd9, - 0xf2, 0xf2, 0x18, 0x65, 0x2f, 0xe0, 0x7a, 0x6b, 0xaf, 0xd2, 0xf8, 0x34, 0xfb, 0x2e, 0xab, 0x25, - 0xe1, 0xac, 0xd7, 0xd0, 0x4e, 0x6c, 0x43, 0xb6, 0x10, 0xe0, 0x7d, 0x40, 0xdb, 0x92, 0x38, 0xb9, - 0x9f, 0x0e, 0xbd, 0x91, 0xd7, 0x17, 0x7b, 0xd9, 0x2d, 0x8e, 0x33, 0xcc, 0x41, 0x9f, 0x39, 0x27, - 0xa9, 0xe4, 0x00, 0x59, 0x77, 0x02, 0xd7, 0x09, 0xbc, 0xf9, 0xed, 0xd2, 0x53, 0x73, 0xfd, 0x81, - 0xde, 0x2d, 0x2d, 0x4a, 0x74, 0x91, 0x51, 0xb5, 0xe4, 0xba, 0x00, 0xc3, 0xd0, 0x38, 0x22, 0x5d, - 0x03, 0x2a, 0xdd, 0xcf, 0x39, 0x44, 0xff, 0x7e, 0x70, 0x03, 0xc8, 0x5b, 0xfe, 0x65, 0x42, 0xfd, - 0x4a, 0xaa, 0xfe, 0xc7, 0x06, 0xb9, 0x12, 0x2a, 0x76, 0x20, 0x55, 0xd7, 0xcc, 0x3a, 0x1c, 0x4e, - 0xfd, 0x4c, 0x40, 0xfe, 0x6b, 0x94, 0x6d, 0x90, 0x79, 0x53, 0x2d, 0x3e, 0x72, 0x5f, 0x2f, 0x08, - 0x78, 0x3d, 0x01, 0x4f, 0x04, 0x27, 0x6b, 0x09, 0x3c, 0xa3, 0xb1, 0x35, 0x3f, 0x6c, 0x91, 0x3b, - 0xa1, 0x22, 0x02, 0x52, 0xd7, 0x52, 0x4c, 0x01, 0x55, 0xff, 0xb4, 0xe4, 0x27, 0x03, 0xd9, 0x50, - 0xab, 0xcf, 0xdc, 0x7f, 0xf2, 0x66, 0xc0, 0xfc, 0xfc, 0x75, 0x68, 0xb2, 0x1c, 0x94, 0xf7, 0xa1, - 0x66, 0x7f, 0xce, 0xf5, 0xdd, 0xcc, 0x37, 0x9a, 0x0f, 0x5b, 0xef, 0x12, 0x54, 0x2d, 0x85, 0x7c, - 0x43, 0xa3, 0x68, 0x09, 0x5e, 0x77, 0x1d, 0x1f, 0x04, 0x67, 0x22, 0x5d, 0x81, 0xe5, 0xab, 0xb5, - 0x92, 0x59, 0x60, 0xec, 0xad, 0xa7, 0xe6, 0x9b, 0x3a, 0x0d, 0xe8, 0x31, 0x9a, 0xa2, 0x44, 0xdb, - 0xb5, 0x6e, 0xad, 0xa3, 0xea, 0xe0, 0x2d, 0x12, 0x9a, 0x0c, 0xec, 0x37, 0x45, 0xf2, 0x20, 0xf8, - 0x77, 0x26, 0x19, 0xdc, 0xc1, 0xe9, 0x73, 0x87, 0x4f, 0x62, 0xe3, 0xc1, 0xf1, 0x3c, 0x58, 0x2c, - 0xcd, 0xa1, 0xa3, 0xc4, 0xf1, 0xee, 0x68, 0xea, 0x44, 0x4b, 0x82, 0xb7, 0x00, 0x7d, 0x6b, 0xb2, - 0x16, 0x3d, 0x44, 0xa6, 0x4b, 0xde, 0xfa, 0x17, 0x12, 0xd5, 0x29, 0x95, 0xee, 0xfb, 0x67, 0x25, - 0x4d, 0x38, 0x1e, 0x5d, 0xff, 0x4c, 0x1a, 0x19, 0x92, 0x70, 0x57, 0xf0, 0x12, 0x88, 0x7b, 0x4a, - 0x8f, 0xae, 0xc4, 0x22, 0x5f, 0xef, 0x82, 0xd4, 0x1e, 0x6c, 0x30, 0x42, 0xee, 0x18, 0x55, 0x92, - 0xd7, 0x13, 0xca, 0x3a, 0x89, 0xaa, 0x55, 0x74, 0x3b, 0x66, 0x54, 0xc7, 0xc8, 0x3a, 0x87, 0x28, - 0x21, 0x43, 0xaf, 0xe5, 0xac, 0x01, 0x49, 0x76, 0x02, 0x7f, 0x60, 0xbf, 0x04, 0xdc, 0x9c, 0x43, - 0x88, 0x2d, 0x53, 0x14, 0x7a, 0xa5, 0x54, 0x4d, 0x92, 0x90, 0xa3, 0xff, 0x90, 0xa3, 0x2b, 0x2c, - 0x91, 0x34, 0x1c, 0x5c, 0x09, 0x74, 0xd0, 0xf2, 0x1f, 0xd0, 0x59, 0xaa, 0xae, 0x78, 0xb6, 0x83, - 0x6d, 0xe0, 0x13, 0x36, 0xeb, 0xd2, 0x07, 0x09, 0x0c, 0x04, 0x06, 0x02, 0x03, 0x81, 0x81, 0xc0, - 0x40, 0x60, 0x20, 0x30, 0x10, 0x18, 0x08, 0x0c, 0x04, 0x06, 0x02, 0x03, 0xfe, 0x0c, 0xfc, 0x0f, - 0x72, 0x11, 0x0f, 0x81, 0x42, 0xe0, 0xea, 0xeb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, - 0xae, 0x42, 0x60, 0x82 -}; - - -#pragma mark - Toolbar Icons - -static const u_int8_t FLEXBookmarksIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x79, 0x47, 0xd8, - 0x15, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x24, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x6e, 0xd2, 0xbe, 0x00, 0x00, - 0x03, 0x25, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x99, 0xdb, 0x8b, 0x4d, 0x71, 0x14, 0xc7, - 0xcf, 0x76, 0xab, 0x51, 0x4a, 0x52, 0x2e, 0x45, 0xa9, 0xe3, 0xf2, 0x40, 0x8a, 0x29, 0x3c, 0x32, - 0x63, 0xf2, 0x36, 0x4a, 0x22, 0x49, 0x4a, 0x4a, 0x09, 0x85, 0x47, 0x5e, 0xa6, 0x3c, 0x69, 0x22, - 0xb9, 0x65, 0x5c, 0x1a, 0xe1, 0xd1, 0xcb, 0x78, 0x51, 0xfe, 0x01, 0xf7, 0x4b, 0x29, 0x22, 0x79, - 0xa3, 0x63, 0xcc, 0x18, 0x42, 0x53, 0x72, 0x7c, 0xd6, 0x99, 0xdf, 0xda, 0x2d, 0xbf, 0xdf, 0xde, - 0x67, 0x66, 0xef, 0x39, 0x73, 0x92, 0xf6, 0xaa, 0xef, 0xac, 0xcb, 0x5e, 0xbf, 0xb5, 0xbe, 0x7b, - 0xfd, 0x7e, 0xe7, 0x9c, 0xf6, 0x9e, 0x52, 0xe9, 0x1f, 0x93, 0x28, 0x89, 0x4f, 0xb5, 0x5a, 0x5d, - 0x42, 0x7c, 0x19, 0x58, 0x0c, 0xe6, 0x80, 0xc4, 0x3c, 0xe2, 0x79, 0xa4, 0xca, 0xa2, 0x0a, 0x78, - 0x03, 0x5e, 0x47, 0x51, 0xf4, 0x2a, 0xb5, 0x08, 0x44, 0x16, 0x82, 0xdb, 0xa0, 0x99, 0xd2, 0x47, - 0xb3, 0x45, 0x4a, 0x2a, 0xbe, 0x73, 0x82, 0x0b, 0x08, 0xbe, 0x04, 0x33, 0xf4, 0x62, 0x13, 0xf5, - 0x0f, 0x7a, 0xad, 0x60, 0x5a, 0xef, 0xa6, 0x98, 0xa6, 0xdd, 0xd8, 0x3e, 0x19, 0x19, 0xef, 0x00, - 0xf8, 0x6d, 0xf2, 0xc6, 0x6b, 0x4e, 0xa2, 0xc0, 0x2c, 0x10, 0x0f, 0x03, 0x7b, 0x3a, 0x38, 0x05, - 0x3a, 0x41, 0xa9, 0x24, 0x23, 0xf3, 0xf6, 0xa8, 0x1f, 0x7f, 0x3b, 0x90, 0xc4, 0x86, 0x0b, 0x75, - 0x5b, 0xc0, 0x56, 0x50, 0x01, 0x56, 0xe4, 0xdc, 0xd6, 0x08, 0x6d, 0xb2, 0x51, 0xec, 0x1d, 0x0d, - 0x67, 0x91, 0x50, 0x90, 0x3e, 0x5b, 0xbc, 0xbe, 0x9b, 0x65, 0x7c, 0x22, 0xe5, 0x11, 0x15, 0xff, - 0xed, 0x8b, 0xad, 0x89, 0x35, 0xee, 0x50, 0xde, 0x1e, 0x87, 0xb2, 0x12, 0x9a, 0x67, 0xfa, 0x7e, - 0xe5, 0x70, 0x7d, 0x33, 0xfe, 0x84, 0x99, 0xf4, 0x19, 0xa6, 0x78, 0xbf, 0x69, 0x30, 0x57, 0x09, - 0x99, 0x58, 0x49, 0x0e, 0x72, 0x33, 0xc5, 0xf6, 0x8b, 0x92, 0x08, 0x35, 0x93, 0x4c, 0xd0, 0xab, - 0x20, 0x14, 0x8c, 0xc4, 0x0b, 0x14, 0x13, 0xf2, 0x06, 0x12, 0xb8, 0xc5, 0x84, 0x82, 0x91, 0x78, - 0x81, 0x62, 0x42, 0xde, 0x40, 0x02, 0xb7, 0x98, 0x50, 0x30, 0x12, 0x2f, 0x50, 0x4c, 0xc8, 0x1b, - 0x48, 0xe0, 0x16, 0x13, 0x0a, 0x46, 0xe2, 0x05, 0x8a, 0x09, 0x79, 0x03, 0x09, 0xdc, 0x62, 0x42, - 0xc1, 0x48, 0xbc, 0xc0, 0xff, 0x39, 0x21, 0x9e, 0xad, 0x8e, 0x81, 0x4f, 0xa0, 0xcb, 0xbb, 0xe1, - 0xcc, 0xae, 0x7d, 0x94, 0xce, 0xbc, 0x58, 0x16, 0x40, 0xe2, 0x24, 0xea, 0xa8, 0x5b, 0x7c, 0x1c, - 0x7f, 0x26, 0x8f, 0x37, 0x07, 0x9d, 0x9f, 0x59, 0x8d, 0x6b, 0xcb, 0x68, 0x2e, 0xef, 0x03, 0x94, - 0x8c, 0x36, 0x3f, 0x40, 0xfc, 0x2c, 0xb0, 0xcf, 0xee, 0x7a, 0x6d, 0x54, 0x9d, 0x9b, 0x10, 0x0d, - 0x4f, 0x53, 0xfd, 0x70, 0x4a, 0x87, 0xfd, 0xc4, 0xcf, 0xe7, 0x21, 0x95, 0x8b, 0x10, 0x8d, 0xce, - 0xd0, 0xf0, 0x90, 0x21, 0x23, 0x4f, 0xba, 0x47, 0xc0, 0x17, 0x13, 0xdb, 0x87, 0x7d, 0x31, 0x0f, - 0x29, 0x39, 0x07, 0x27, 0x80, 0x8a, 0x2d, 0x6a, 0xea, 0xd7, 0xce, 0x4b, 0x44, 0xd2, 0x39, 0x4d, - 0x74, 0x7a, 0x08, 0xbd, 0x4e, 0x12, 0xd1, 0xad, 0x60, 0xc0, 0xc5, 0x55, 0x5d, 0xc6, 0x48, 0xdd, - 0x3e, 0xae, 0x7d, 0xd4, 0x44, 0xb4, 0x1c, 0x81, 0x5a, 0xa1, 0x51, 0x09, 0x49, 0x51, 0x70, 0xc1, - 0x2c, 0x16, 0x53, 0xc8, 0xac, 0xad, 0x15, 0x71, 0x7f, 0xf0, 0x57, 0x03, 0x9f, 0xd4, 0x55, 0x62, - 0x89, 0xbb, 0x41, 0x3c, 0x3b, 0x21, 0x16, 0x09, 0x99, 0x4b, 0xc0, 0x8a, 0x90, 0x59, 0x63, 0xc9, - 0xa8, 0x4d, 0x7c, 0x15, 0xf0, 0x49, 0xf5, 0x12, 0x0b, 0x48, 0x11, 0xfb, 0x8b, 0x50, 0x90, 0xa0, - 0x45, 0x55, 0xbb, 0x22, 0x3d, 0xf8, 0x7b, 0x35, 0x86, 0x1e, 0x02, 0x1d, 0x7c, 0xbc, 0xef, 0x9b, - 0x58, 0x6c, 0x12, 0x7f, 0x82, 0xd3, 0x0e, 0xe4, 0xed, 0x9b, 0xca, 0x2e, 0x0c, 0x21, 0x35, 0x59, - 0x03, 0x49, 0xba, 0x2e, 0x21, 0x47, 0xe6, 0x0a, 0x0b, 0xf7, 0x98, 0xc5, 0x75, 0xc9, 0x68, 0x5e, - 0x0a, 0xa9, 0x9d, 0x5c, 0xbf, 0x5e, 0x8f, 0x54, 0x2a, 0x21, 0x47, 0xe6, 0x1a, 0x05, 0x76, 0x6b, - 0x13, 0xb4, 0x1c, 0xf8, 0x8d, 0x34, 0x7b, 0x60, 0x62, 0xa9, 0x26, 0x79, 0x4f, 0xb9, 0xd8, 0x06, - 0x3e, 0x9b, 0x24, 0x79, 0x3b, 0x77, 0x93, 0xfa, 0x89, 0x5f, 0xca, 0x89, 0x84, 0xdc, 0x1d, 0xf4, - 0xb2, 0x50, 0xc6, 0xac, 0xa2, 0x64, 0x1e, 0x6a, 0x60, 0x2c, 0x1a, 0x52, 0xcf, 0xc8, 0x93, 0xed, - 0xb3, 0xa4, 0xb6, 0xe1, 0xdf, 0x4a, 0x23, 0xe5, 0x7f, 0xec, 0x7f, 0x91, 0x78, 0x17, 0x58, 0x19, - 0xc4, 0x69, 0x1d, 0x0b, 0x81, 0xb4, 0x1c, 0xd6, 0xaf, 0x04, 0xf2, 0x32, 0xd5, 0xca, 0x3d, 0x9c, - 0x61, 0x13, 0xe8, 0x4e, 0x9a, 0x90, 0x1c, 0xba, 0x0e, 0x53, 0x78, 0x10, 0xbb, 0x9d, 0x3b, 0x7d, - 0x64, 0x62, 0x99, 0x4d, 0xd6, 0x3f, 0x67, 0xd1, 0x06, 0x60, 0x5f, 0xe1, 0xc9, 0x76, 0x4e, 0xb3, - 0xc5, 0x94, 0x90, 0x7d, 0xad, 0x66, 0xaf, 0x2b, 0x99, 0xc7, 0x36, 0x98, 0xd7, 0x86, 0xd4, 0x0b, - 0xd6, 0x0a, 0x09, 0x4b, 0xca, 0x96, 0x8b, 0xbf, 0x17, 0x3e, 0xd8, 0xa8, 0xb3, 0x65, 0xcf, 0xdb, - 0x28, 0x22, 0x1f, 0xe1, 0x86, 0x89, 0x23, 0xb5, 0x9e, 0x82, 0xf2, 0xff, 0x0e, 0x5f, 0x46, 0x78, - 0xb0, 0x87, 0xf2, 0x3f, 0x8e, 0xef, 0x66, 0x2f, 0xdf, 0x63, 0x2f, 0xf7, 0xb3, 0x1b, 0xe9, 0x53, - 0x7f, 0x29, 0x78, 0x6b, 0x7a, 0xfe, 0xc4, 0x2e, 0xc7, 0xbf, 0x31, 0x38, 0xb3, 0x69, 0x28, 0xdf, - 0x13, 0x53, 0x41, 0x0f, 0x77, 0x92, 0xfa, 0x9b, 0xd6, 0x28, 0x62, 0xf4, 0x6c, 0xa1, 0x56, 0x27, - 0x98, 0x0f, 0x6e, 0xd0, 0xb3, 0xf2, 0x07, 0x6f, 0x8f, 0xd6, 0x17, 0xd8, 0x01, 0xed, 0x4d, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXBookmarksIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x48, 0x08, 0x06, 0x00, 0x00, 0x00, 0xbd, 0x6d, 0x06, - 0x6c, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xa1, 0x70, 0x0a, 0x00, 0x00, - 0x04, 0xb4, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9b, 0x7b, 0x48, 0x64, 0x55, 0x1c, 0xc7, - 0x1d, 0xd3, 0xde, 0x9b, 0xab, 0x59, 0xd0, 0x03, 0x42, 0xd6, 0x30, 0xf6, 0x8f, 0x36, 0x42, 0x7a, - 0x10, 0x25, 0x15, 0x12, 0x11, 0x49, 0x84, 0x2c, 0x44, 0xd4, 0x2e, 0x19, 0x44, 0xd0, 0x2e, 0x58, - 0x4a, 0xd9, 0x53, 0x2b, 0xcb, 0xa0, 0xa4, 0x88, 0x10, 0xa2, 0xa2, 0x07, 0x14, 0xc5, 0xe2, 0xb2, - 0x1a, 0xed, 0x56, 0xbb, 0x20, 0xd5, 0x1f, 0x51, 0x54, 0x94, 0xb4, 0x3d, 0x76, 0x33, 0x22, 0x7a, - 0x48, 0x41, 0x14, 0xd1, 0xc3, 0x34, 0xfb, 0xfc, 0xe4, 0xce, 0xcc, 0x99, 0xd3, 0x39, 0x73, 0xef, - 0x3d, 0x33, 0xe3, 0xb9, 0xc2, 0x39, 0xf0, 0x65, 0xce, 0xf9, 0x3d, 0xbf, 0xdf, 0x73, 0xee, 0x0c, - 0x83, 0x73, 0xac, 0xab, 0x0b, 0x63, 0x6d, 0xed, 0x40, 0xae, 0x1c, 0xdd, 0xe5, 0xe5, 0xe5, 0x26, - 0xfc, 0xe7, 0x80, 0x53, 0x15, 0x9c, 0xc0, 0xbc, 0x6c, 0x1e, 0xfe, 0x5a, 0x8d, 0xbf, 0x28, 0xfc, - 0x15, 0x38, 0x10, 0x61, 0x7f, 0x2e, 0x97, 0xfb, 0x28, 0x71, 0x33, 0x04, 0xe5, 0xc0, 0x16, 0x30, - 0x0f, 0xb2, 0x3e, 0x5e, 0x85, 0x60, 0x5b, 0xac, 0x38, 0x09, 0x02, 0x6f, 0x65, 0x5d, 0x8d, 0xc6, - 0xef, 0x0f, 0xd6, 0x43, 0xaa, 0xb8, 0xff, 0x3d, 0x52, 0x04, 0xcc, 0x10, 0xd0, 0xa5, 0x06, 0xad, - 0xa1, 0x79, 0x0f, 0x8f, 0xe6, 0xb4, 0xf0, 0x2d, 0x11, 0x86, 0xa8, 0xab, 0xb0, 0xbd, 0xb8, 0x86, - 0x84, 0xe8, 0x54, 0xe7, 0x30, 0x6c, 0x44, 0xdc, 0xdf, 0x05, 0x61, 0x88, 0x3a, 0x0a, 0xe3, 0x17, - 0xe0, 0x24, 0x3d, 0x9a, 0xf5, 0x22, 0x90, 0x9d, 0xd8, 0x0f, 0xbe, 0x8e, 0xd6, 0xbc, 0xac, 0xfa, - 0x58, 0x4f, 0xc7, 0x0e, 0x70, 0x21, 0x38, 0xcd, 0xd2, 0xfd, 0x4e, 0x84, 0x8d, 0x16, 0x7c, 0x08, - 0xeb, 0x02, 0xa6, 0x31, 0x8b, 0xf1, 0xf4, 0x42, 0x60, 0x06, 0x26, 0xf0, 0x69, 0x00, 0x83, 0x26, - 0xb2, 0xd8, 0xde, 0x2f, 0xa1, 0x88, 0xa1, 0xcf, 0x10, 0xb8, 0x88, 0x6d, 0x53, 0x49, 0x60, 0x86, - 0x16, 0x70, 0x7b, 0xce, 0xc0, 0xf9, 0x97, 0x12, 0x8a, 0x04, 0x8c, 0x19, 0x82, 0xa6, 0x4a, 0x82, - 0x32, 0xb6, 0x80, 0x6f, 0x87, 0x81, 0xb3, 0x98, 0x5a, 0xeb, 0x15, 0xae, 0xed, 0xca, 0x3c, 0x3f, - 0xfd, 0x2c, 0x3f, 0xc9, 0xe8, 0xeb, 0x41, 0x78, 0x2d, 0x18, 0xb8, 0xb5, 0xab, 0xc2, 0x4c, 0x1f, - 0x1a, 0xdf, 0x18, 0x92, 0x32, 0x63, 0xe2, 0x43, 0x62, 0x09, 0x32, 0xdf, 0x19, 0x08, 0x9d, 0xa8, - 0x0a, 0x2b, 0x7c, 0x42, 0x2a, 0x81, 0xff, 0x2a, 0xf3, 0xac, 0x4e, 0x4d, 0x1c, 0xeb, 0x55, 0x61, - 0x59, 0x25, 0xee, 0xc4, 0x2b, 0x08, 0x73, 0xda, 0x36, 0x8f, 0x49, 0xe1, 0xc4, 0x3c, 0x6e, 0xbe, - 0x53, 0xeb, 0x70, 0x62, 0x4e, 0xdb, 0xe6, 0x31, 0x29, 0x9c, 0x98, 0xc7, 0xcd, 0x77, 0x6a, 0x1d, - 0x4e, 0xcc, 0x69, 0xdb, 0x3c, 0x26, 0x85, 0x13, 0xf3, 0xb8, 0xf9, 0x4e, 0xad, 0xc3, 0x89, 0x39, - 0x6d, 0x9b, 0xc7, 0xa4, 0x70, 0x62, 0x1e, 0x37, 0xdf, 0xa9, 0x75, 0x38, 0x31, 0xa7, 0x6d, 0xf3, - 0x98, 0x14, 0x4e, 0xcc, 0xe3, 0xe6, 0x3b, 0xb5, 0x0e, 0x27, 0xe6, 0xb4, 0x6d, 0x1e, 0x93, 0xc2, - 0x89, 0x79, 0xdc, 0x7c, 0xa7, 0xd6, 0xe1, 0xc4, 0x9c, 0xb6, 0xcd, 0x63, 0x52, 0x38, 0x31, 0x8f, - 0x9b, 0xef, 0xd4, 0x3a, 0x9c, 0x98, 0xd3, 0xb6, 0x79, 0x4c, 0x5a, 0xb5, 0x13, 0xe3, 0xe7, 0xd3, - 0x7e, 0xf0, 0x2d, 0x98, 0x01, 0xf2, 0xcb, 0x7f, 0x4d, 0xc7, 0xaa, 0x08, 0x43, 0xc8, 0x38, 0x2a, - 0x04, 0x27, 0x03, 0xb9, 0x1c, 0xf3, 0x0e, 0xb6, 0x9a, 0xfe, 0x68, 0x5f, 0x73, 0x61, 0x08, 0x78, - 0x0c, 0x21, 0xfd, 0x40, 0x1d, 0xad, 0x2c, 0xf6, 0xe1, 0x3b, 0x43, 0x35, 0x56, 0x73, 0x5e, 0x33, - 0x61, 0x90, 0x96, 0x8b, 0x66, 0x8f, 0x43, 0x76, 0xbb, 0x85, 0xf0, 0xb1, 0xd8, 0x45, 0xdc, 0x99, - 0x16, 0x7f, 0x45, 0xe6, 0x9a, 0x08, 0x13, 0x51, 0xb0, 0x7a, 0x02, 0xdc, 0x14, 0xc3, 0xae, 0x05, - 0xff, 0x5e, 0xe2, 0x3b, 0x63, 0xe2, 0x52, 0xbb, 0xab, 0x2e, 0x2c, 0x12, 0x35, 0x01, 0x93, 0x1b, - 0x13, 0xb2, 0x69, 0x26, 0xee, 0x4d, 0xf2, 0xce, 0x4a, 0x18, 0x9f, 0x28, 0xac, 0xaa, 0xc2, 0x22, - 0x51, 0x4f, 0xd2, 0xf9, 0x06, 0x4b, 0xf7, 0x17, 0xb0, 0xcb, 0x45, 0x2e, 0x7d, 0xc8, 0x1d, 0xa9, - 0x37, 0xc8, 0x3f, 0x5b, 0x77, 0xb8, 0xae, 0xab, 0x26, 0x0c, 0x52, 0x52, 0xeb, 0x29, 0x70, 0xbd, - 0x85, 0xcc, 0x08, 0xf7, 0x32, 0xae, 0xc5, 0x77, 0x01, 0xf8, 0xd2, 0x10, 0xd3, 0x84, 0x4d, 0xc4, - 0x9d, 0x6b, 0xf0, 0xa5, 0x36, 0x55, 0x45, 0x58, 0x24, 0xea, 0x69, 0xba, 0x5f, 0x67, 0x61, 0x30, - 0x8c, 0xa8, 0x61, 0xf1, 0xf1, 0x2a, 0x17, 0x4e, 0xe4, 0xf6, 0x9a, 0x49, 0xdc, 0x31, 0xd8, 0x5f, - 0xa7, 0xde, 0x79, 0xbc, 0x56, 0x34, 0x2a, 0x16, 0x16, 0x89, 0x7a, 0x16, 0x16, 0x5b, 0x2d, 0x4c, - 0xee, 0x41, 0xcc, 0x88, 0xea, 0x63, 0xfd, 0x3d, 0x6b, 0x11, 0x27, 0xd7, 0x08, 0xf5, 0xb1, 0x0e, - 0xc3, 0x1e, 0xea, 0x9e, 0xaf, 0x3b, 0xd2, 0xac, 0x2b, 0x12, 0x46, 0xf3, 0x43, 0x68, 0xf6, 0x3c, - 0xb8, 0xc6, 0xd2, 0xf4, 0x6e, 0x44, 0xdc, 0x6b, 0xf2, 0xc5, 0x88, 0x3b, 0x9a, 0x9c, 0xdd, 0xd4, - 0x77, 0xbe, 0xe9, 0xea, 0x2c, 0x2c, 0x12, 0x25, 0x1f, 0x06, 0x57, 0x9b, 0x88, 0x63, 0xbb, 0x0b, - 0xf2, 0xf7, 0x59, 0x7c, 0x2b, 0x66, 0xfc, 0x3f, 0x30, 0x91, 0x93, 0xfb, 0xdc, 0x10, 0x27, 0x17, - 0x43, 0x5f, 0xa3, 0x8f, 0xf8, 0x53, 0x0f, 0x27, 0x61, 0x34, 0x6b, 0xa0, 0x93, 0x5c, 0xb1, 0x95, - 0xab, 0xb6, 0xa6, 0x21, 0xb7, 0x3c, 0xef, 0x37, 0x39, 0x74, 0x5b, 0x8c, 0xb8, 0x23, 0x89, 0x97, - 0x5b, 0xda, 0x17, 0xeb, 0x79, 0x71, 0xeb, 0xd4, 0xc2, 0x22, 0x51, 0x2f, 0x51, 0x78, 0xb3, 0xa5, - 0xf8, 0x1d, 0x90, 0x2d, 0x5e, 0x5d, 0xb5, 0x04, 0xa9, 0x66, 0xe2, 0x7f, 0x64, 0x2d, 0x27, 0x63, - 0xba, 0x46, 0x28, 0xe2, 0xa6, 0xe9, 0xdb, 0xad, 0xe6, 0xc4, 0xcd, 0x53, 0x09, 0xa3, 0x78, 0x23, - 0x05, 0x5f, 0x06, 0xbd, 0x96, 0xc2, 0xb7, 0x43, 0xf2, 0x01, 0x8b, 0xaf, 0xac, 0x39, 0x46, 0xdc, - 0x11, 0x24, 0x4f, 0xd1, 0xff, 0x92, 0xb2, 0x45, 0x14, 0x67, 0x62, 0x61, 0x91, 0xa8, 0x57, 0xc8, - 0xbd, 0x52, 0xc9, 0x57, 0xa7, 0x43, 0x90, 0x7b, 0x50, 0x35, 0xa4, 0x9d, 0x93, 0x3f, 0x4f, 0x8e, - 0x9c, 0x9c, 0x5c, 0xaa, 0xd6, 0xc7, 0xe1, 0x18, 0x76, 0xc1, 0xe3, 0x52, 0xdd, 0x61, 0x5a, 0x27, - 0x12, 0x46, 0xb1, 0x43, 0x49, 0xde, 0x01, 0xae, 0x30, 0x15, 0xc1, 0x76, 0x1b, 0xa4, 0xc6, 0x2c, - 0xbe, 0x54, 0xe6, 0x48, 0xdc, 0x45, 0x24, 0x7d, 0x6a, 0x48, 0x3c, 0x0c, 0xdb, 0x4e, 0xf8, 0x5c, - 0x66, 0xf0, 0x95, 0x98, 0x62, 0x85, 0x51, 0x44, 0x8a, 0x4d, 0x82, 0x9e, 0x92, 0xcc, 0xe2, 0xe2, - 0x56, 0xc8, 0x3c, 0x54, 0x5c, 0x56, 0x3e, 0x4b, 0x20, 0x6e, 0x12, 0x5e, 0x97, 0x27, 0xea, 0x44, - 0xe0, 0xbb, 0x40, 0x1f, 0xcf, 0x60, 0x90, 0x6f, 0x02, 0xb6, 0x31, 0x98, 0xa8, 0xb8, 0x63, 0x10, - 0x4d, 0x8f, 0x07, 0x72, 0x3d, 0xde, 0x34, 0x16, 0x30, 0x6e, 0x03, 0xbf, 0x1a, 0x9c, 0xc5, 0xcf, - 0x00, 0x9c, 0x26, 0x61, 0x86, 0x9c, 0x82, 0x69, 0xc0, 0x91, 0x6f, 0xaa, 0x34, 0xba, 0x1d, 0x07, - 0x6c, 0xe2, 0x0a, 0x64, 0xb4, 0x49, 0x6f, 0xec, 0xa3, 0x68, 0x61, 0x31, 0xc0, 0xe3, 0xf2, 0xb0, - 0xc5, 0x57, 0x55, 0x33, 0x7d, 0x7e, 0xa2, 0xa0, 0xbc, 0xe7, 0x66, 0xd3, 0x14, 0x76, 0x11, 0x76, - 0x0b, 0xcd, 0x1e, 0x49, 0xd3, 0xa4, 0xd2, 0x58, 0x45, 0xdc, 0x27, 0x49, 0x6b, 0xa9, 0xc2, 0x7e, - 0x4f, 0x90, 0x74, 0x33, 0x4d, 0xc6, 0x13, 0xc4, 0x55, 0x3d, 0x84, 0xbe, 0x3f, 0x53, 0x54, 0xbe, - 0x81, 0x7c, 0x9c, 0xa0, 0x78, 0x51, 0x0b, 0xcf, 0xe8, 0x84, 0xf6, 0x9c, 0xea, 0xcb, 0x6d, 0x09, - 0x0a, 0xd6, 0x3c, 0x04, 0x52, 0x2d, 0xe0, 0x03, 0x9d, 0x9c, 0xb6, 0xde, 0x50, 0x20, 0x82, 0xa3, - 0x5b, 0x73, 0xe6, 0x97, 0xff, 0x30, 0xe9, 0x2b, 0x04, 0x66, 0x60, 0x02, 0x9f, 0x66, 0x20, 0x7f, - 0x9f, 0x34, 0x8d, 0x0f, 0x31, 0xaa, 0x4f, 0x62, 0x5d, 0x1d, 0x86, 0x51, 0xb0, 0xa4, 0x44, 0xcf, - 0x31, 0x97, 0x37, 0x6e, 0xe6, 0x06, 0xbc, 0x1a, 0xc1, 0xa3, 0x40, 0x36, 0x3e, 0x3f, 0x84, 0xef, - 0xca, 0x9f, 0xf4, 0x72, 0x3a, 0x63, 0x1c, 0x6d, 0xd8, 0xc4, 0xf9, 0x1b, 0x78, 0x9b, 0x67, 0xdb, - 0xf4, 0xbf, 0x23, 0x7a, 0x9a, 0xb7, 0x35, 0x7c, 0x4f, 0xa1, 0x79, 0x27, 0x90, 0xf7, 0xe0, 0x7b, - 0xf0, 0xfd, 0x53, 0xc8, 0xfc, 0x07, 0x76, 0x76, 0x93, 0xea, 0x76, 0xb7, 0x97, 0xf0, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXOpenTabsIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x53, 0xf7, 0x29, - 0xba, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0b, 0xfc, 0xcb, 0x00, 0x00, - 0x03, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9a, 0xcb, 0x6b, 0x53, 0x41, 0x14, 0xc6, - 0x13, 0xab, 0xf8, 0x40, 0xeb, 0x03, 0xc4, 0x17, 0x5a, 0xc5, 0xfa, 0x40, 0x4a, 0xbb, 0x71, 0x55, - 0x50, 0xa4, 0x05, 0xa1, 0x6e, 0xdd, 0xd5, 0x22, 0x2e, 0xdc, 0xb8, 0xf3, 0x0f, 0x10, 0x77, 0x5d, - 0x09, 0x2e, 0x2c, 0x28, 0xb8, 0x75, 0x21, 0xba, 0xb3, 0x08, 0x42, 0xf1, 0x01, 0xae, 0x74, 0x21, - 0x56, 0xb1, 0x52, 0xad, 0x20, 0x54, 0xad, 0xf8, 0x02, 0x4b, 0x11, 0xd4, 0xda, 0xc6, 0xdf, 0xb9, - 0xcd, 0xa4, 0x5f, 0x6f, 0xd2, 0x90, 0xcc, 0xcd, 0xcd, 0x4d, 0x4a, 0x0e, 0x7c, 0xdc, 0x73, 0x26, - 0x33, 0xdf, 0x77, 0xce, 0x9d, 0xb9, 0x93, 0xe9, 0x4d, 0x53, 0xa9, 0x25, 0x62, 0xe9, 0x70, 0x1d, - 0x99, 0x4c, 0x66, 0x0d, 0x6d, 0x7d, 0xe0, 0x20, 0x68, 0x05, 0xdb, 0x41, 0x5e, 0x3f, 0xda, 0x2a, - 0x61, 0x53, 0x90, 0xbc, 0xcb, 0x62, 0x30, 0x9d, 0x4e, 0xbf, 0xae, 0x04, 0x69, 0x8a, 0x22, 0x4e, - 0x82, 0x71, 0x90, 0x84, 0x4d, 0x23, 0x7a, 0x19, 0xac, 0x8d, 0x54, 0x0c, 0x04, 0x9d, 0x60, 0x16, - 0x24, 0x6d, 0xd7, 0x7d, 0x0a, 0x09, 0x96, 0x0c, 0x99, 0x37, 0x31, 0xf8, 0x19, 0xe8, 0x10, 0x92, - 0xdf, 0xf8, 0xcf, 0xc1, 0x07, 0x90, 0x91, 0xf6, 0x4a, 0xba, 0x1b, 0x20, 0x6b, 0x07, 0xdb, 0x84, - 0xd4, 0xb4, 0x3a, 0x59, 0x66, 0x4f, 0xa4, 0xad, 0x34, 0x97, 0x42, 0xda, 0x43, 0xd3, 0xf0, 0x82, - 0xb8, 0xa5, 0xb4, 0xd1, 0xd1, 0x7a, 0xa1, 0xb3, 0x02, 0x5c, 0x0a, 0xe9, 0x5f, 0xf1, 0x62, 0x85, - 0xc4, 0x9e, 0x0d, 0xb5, 0xa3, 0x5e, 0x44, 0x9e, 0x83, 0x10, 0x6e, 0x02, 0xa3, 0x92, 0xc0, 0xbd, - 0x72, 0xa9, 0x96, 0x65, 0x07, 0xd8, 0xee, 0xe4, 0x6c, 0x16, 0xe7, 0xa9, 0x0b, 0xaa, 0x71, 0x65, - 0x19, 0xcd, 0xa0, 0xa3, 0x4b, 0x69, 0x5f, 0xb9, 0xba, 0xae, 0x90, 0x66, 0x19, 0x38, 0x05, 0xf1, - 0x1f, 0x89, 0xab, 0xe5, 0x7e, 0x13, 0x21, 0xcd, 0x47, 0x9a, 0x17, 0x77, 0x5d, 0x21, 0x8b, 0xf7, - 0xa8, 0x93, 0x4f, 0x96, 0x4c, 0x21, 0xcb, 0xa3, 0xdc, 0x70, 0x1e, 0xce, 0x75, 0x8c, 0xef, 0x06, - 0xf6, 0x8c, 0x19, 0x36, 0x02, 0x5f, 0xd3, 0xad, 0xbf, 0x19, 0xee, 0x5b, 0x42, 0x64, 0x5b, 0xf2, - 0x57, 0x60, 0xa7, 0x80, 0xb7, 0xe0, 0x3e, 0xcb, 0xff, 0x1f, 0xd7, 0x85, 0xc6, 0xa0, 0x7e, 0xd9, - 0x31, 0x7e, 0x2e, 0xfc, 0x34, 0x3f, 0xa2, 0x6f, 0x1a, 0xf4, 0x81, 0x09, 0x19, 0x57, 0x4d, 0x77, - 0x04, 0xb1, 0x2e, 0xcd, 0xcc, 0x77, 0x69, 0x9d, 0x83, 0xe4, 0x06, 0xd0, 0x2f, 0x32, 0xe5, 0x8d, - 0xdb, 0x3f, 0x84, 0xc0, 0x03, 0x8a, 0x39, 0xe6, 0x84, 0xca, 0x5e, 0x5a, 0x0c, 0xde, 0xc2, 0xe0, - 0x7e, 0x47, 0x90, 0xbd, 0xda, 0x96, 0x6d, 0x27, 0x80, 0xef, 0xa1, 0xf6, 0x4a, 0x85, 0x76, 0x02, - 0xd9, 0x0a, 0xec, 0x00, 0xab, 0x76, 0x95, 0x7c, 0x3a, 0x58, 0x66, 0xd3, 0x41, 0x23, 0x41, 0xc9, - 0x4b, 0x8b, 0xbe, 0xe7, 0x81, 0xda, 0x10, 0xc1, 0x0e, 0x65, 0x8f, 0xcb, 0x47, 0xa7, 0x0d, 0xbc, - 0x54, 0x71, 0xfc, 0xe3, 0xa6, 0xe7, 0xb3, 0xb4, 0xf4, 0xcb, 0xca, 0x8e, 0xe1, 0xbd, 0xdc, 0x91, - 0x4f, 0x71, 0x25, 0xaf, 0xbc, 0xe8, 0xbc, 0x22, 0x3e, 0xad, 0x6d, 0xf8, 0x41, 0x3e, 0x3e, 0x85, - 0xec, 0x17, 0xa2, 0x61, 0xc8, 0xe3, 0x5a, 0x4e, 0x22, 0x33, 0xef, 0xa2, 0x37, 0x4c, 0xf4, 0x63, - 0xbe, 0x25, 0x15, 0xe4, 0xe3, 0x53, 0xc8, 0x26, 0x21, 0xf9, 0x2c, 0x7e, 0x35, 0x5d, 0xd5, 0x0d, - 0xf2, 0xf1, 0x29, 0x44, 0x13, 0x8e, 0xeb, 0x78, 0xaf, 0x1a, 0x85, 0xfc, 0x3c, 0xdd, 0xa8, 0x85, - 0x14, 0x12, 0x49, 0xa4, 0xad, 0x51, 0x48, 0x22, 0xb7, 0xbd, 0x88, 0x68, 0x63, 0x46, 0x8a, 0xdc, - 0x9c, 0x44, 0x3e, 0x6a, 0xcc, 0x48, 0x22, 0xb7, 0xbd, 0x88, 0x68, 0x63, 0x46, 0x8a, 0xdc, 0x9c, - 0x44, 0x3e, 0x5a, 0x72, 0x33, 0x32, 0x77, 0x9e, 0x9f, 0xbb, 0x97, 0xab, 0x38, 0x1a, 0xc7, 0xf5, - 0xd2, 0x3a, 0xb6, 0xd9, 0x72, 0x33, 0xf2, 0x5e, 0x14, 0x56, 0xe2, 0xef, 0x96, 0xb8, 0x2e, 0x5c, - 0x57, 0xc8, 0x58, 0x28, 0xdb, 0x8b, 0xa1, 0xb8, 0xe6, 0x43, 0xf7, 0xa7, 0xee, 0x08, 0x99, 0x4e, - 0x82, 0xf5, 0xd9, 0x8c, 0xcf, 0xb0, 0xbc, 0xf6, 0xe2, 0xdf, 0x01, 0x1f, 0x81, 0x9e, 0x36, 0xa3, - 0xbc, 0x29, 0xc9, 0xd2, 0x57, 0xfe, 0x12, 0x14, 0xc2, 0x1f, 0x2b, 0x93, 0x24, 0x7e, 0x01, 0xfa, - 0x01, 0x91, 0x38, 0x82, 0x6f, 0xa8, 0x0b, 0x73, 0x4b, 0xcb, 0x92, 0xbd, 0x06, 0x6e, 0xd6, 0x45, - 0xd6, 0x05, 0x92, 0xcc, 0x15, 0xc2, 0xac, 0xcc, 0x80, 0x5e, 0xfa, 0x74, 0x81, 0x21, 0x30, 0x0e, - 0xec, 0xed, 0x48, 0x5d, 0x98, 0x7b, 0x46, 0x72, 0xc9, 0x52, 0xcc, 0x23, 0x02, 0x83, 0xfd, 0x14, - 0x67, 0x3b, 0x98, 0xbd, 0xfe, 0xd1, 0xed, 0xf8, 0x2e, 0x71, 0x1b, 0xa8, 0x29, 0xcb, 0x2b, 0x44, - 0xb3, 0xa3, 0x28, 0x7b, 0x2b, 0x6f, 0x33, 0x93, 0x33, 0x8a, 0xfb, 0x9b, 0x0b, 0x6a, 0xc8, 0xc9, - 0x2d, 0xad, 0x1a, 0xca, 0xc9, 0x2b, 0x15, 0x9f, 0x42, 0x74, 0x2b, 0x6e, 0xf2, 0x52, 0x8d, 0x3e, - 0x48, 0x75, 0x83, 0x7c, 0x7c, 0x0a, 0xd1, 0x57, 0x31, 0x2d, 0xd1, 0x73, 0xf2, 0x62, 0xd8, 0x25, - 0xa3, 0x82, 0x7c, 0x7c, 0x0a, 0xd1, 0x53, 0x40, 0x07, 0xcf, 0xcc, 0x01, 0x21, 0x8d, 0xdd, 0x45, - 0xaf, 0x07, 0x11, 0xfd, 0x2d, 0x5e, 0xf3, 0x29, 0x5d, 0x1f, 0xa2, 0xb3, 0x40, 0xed, 0x0d, 0x41, - 0x0f, 0x70, 0xa7, 0x82, 0xd2, 0xc9, 0xca, 0xe8, 0x09, 0xff, 0x66, 0x70, 0x0a, 0x7c, 0x01, 0x6a, - 0x9d, 0x46, 0xa3, 0xdb, 0x6a, 0x49, 0xb4, 0x30, 0xac, 0xa6, 0xa3, 0x1d, 0x69, 0xf6, 0x14, 0x18, - 0x90, 0xff, 0xe3, 0x4b, 0x81, 0x4e, 0x1e, 0x4d, 0x96, 0xa7, 0x3e, 0x17, 0x8e, 0xe2, 0x21, 0x3b, - 0x6b, 0xb7, 0x05, 0x65, 0x17, 0x62, 0x83, 0x28, 0xe6, 0x04, 0x97, 0x41, 0x50, 0x88, 0xdc, 0xba, - 0x54, 0xc3, 0x7e, 0x21, 0x72, 0x98, 0x42, 0x46, 0x23, 0x89, 0x51, 0x8c, 0xfd, 0x93, 0xc1, 0x63, - 0x90, 0x84, 0xdd, 0x46, 0x74, 0xa7, 0x16, 0xe0, 0x35, 0x23, 0x4a, 0x00, 0xa1, 0x2d, 0xb1, 0xd6, - 0x2c, 0xec, 0x5f, 0x32, 0xe2, 0x32, 0xf7, 0x1b, 0xe2, 0x18, 0xb3, 0x30, 0x11, 0x16, 0xf9, 0x0f, - 0xa4, 0x99, 0x6b, 0x25, 0x92, 0x4d, 0xbc, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, - 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXOpenTabsIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x48, 0x08, 0x06, 0x00, 0x00, 0x00, 0xbe, 0xda, 0x08, - 0x44, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4b, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xab, 0x1d, 0x6b, 0x00, 0x00, - 0x05, 0x20, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, 0x9c, 0x4d, 0x68, 0x15, 0x57, 0x14, 0xc7, - 0xf3, 0xaa, 0x6d, 0xb0, 0x9f, 0xba, 0x88, 0xa8, 0xad, 0xb6, 0x09, 0x7e, 0xa1, 0x50, 0x50, 0xbb, - 0xb1, 0x10, 0x25, 0xdd, 0x14, 0xd2, 0xd2, 0x2c, 0xda, 0x2e, 0x0a, 0x0d, 0x85, 0xfa, 0x81, 0x0a, - 0xe2, 0x22, 0x94, 0xe2, 0xc2, 0x4d, 0x05, 0x45, 0xe8, 0xa2, 0x50, 0xaa, 0x60, 0x57, 0x51, 0xdc, - 0xb8, 0x71, 0x91, 0xda, 0x95, 0xe9, 0xa6, 0x1f, 0xf4, 0x0b, 0x1a, 0xda, 0xb4, 0xd0, 0x54, 0xda, - 0x2e, 0x8c, 0x69, 0xd1, 0x95, 0x28, 0x56, 0xa2, 0x8d, 0xbf, 0x23, 0x93, 0x77, 0x6f, 0xee, 0x3b, - 0xf3, 0x6e, 0xe6, 0x71, 0x27, 0x99, 0xc9, 0xdc, 0x03, 0x7f, 0xe6, 0xde, 0x33, 0xe7, 0xde, 0x73, - 0xce, 0x7f, 0xe6, 0xde, 0x99, 0xb9, 0x6f, 0xe6, 0xb5, 0xb5, 0x45, 0x99, 0x35, 0x03, 0xb5, 0x59, - 0x5b, 0x62, 0x38, 0x35, 0x35, 0xd5, 0xc1, 0xe6, 0x19, 0xf0, 0x50, 0x96, 0x76, 0x39, 0xd9, 0x4e, - 0xd1, 0xef, 0xd5, 0x5a, 0xad, 0xf6, 0x4f, 0x4e, 0xfd, 0x37, 0x74, 0xdb, 0x94, 0x2c, 0xc8, 0x79, - 0x93, 0x16, 0xaf, 0x83, 0xb5, 0x09, 0x9e, 0x6a, 0xe8, 0x61, 0xfe, 0x15, 0x37, 0x09, 0xe1, 0x72, - 0x82, 0x21, 0xb6, 0x67, 0x21, 0x50, 0x88, 0x9c, 0x1b, 0x81, 0xa4, 0x4d, 0x60, 0x18, 0x94, 0x51, - 0xbe, 0x21, 0xe8, 0xad, 0x73, 0xc2, 0x14, 0x8e, 0xde, 0x02, 0x93, 0x65, 0x64, 0xc9, 0x8a, 0xf9, - 0x1e, 0xe5, 0x7d, 0xa1, 0x09, 0x9b, 0x31, 0x0c, 0x71, 0xb0, 0x0c, 0x07, 0xbf, 0x03, 0x99, 0x9b, - 0xca, 0x2e, 0x32, 0x3c, 0x37, 0x32, 0x24, 0xc7, 0x43, 0x25, 0xb2, 0xd8, 0xe9, 0xe8, 0x18, 0x75, - 0x1f, 0x51, 0xff, 0x63, 0x33, 0x77, 0x73, 0x82, 0x13, 0xa0, 0x55, 0x95, 0x03, 0xdd, 0xec, 0x42, - 0xf3, 0x38, 0xfb, 0x3f, 0x02, 0x32, 0xef, 0x86, 0x15, 0xce, 0xaa, 0x4e, 0x20, 0xa7, 0xaf, 0x26, - 0x32, 0x0f, 0xf4, 0x82, 0x67, 0x41, 0xb3, 0x00, 0xc3, 0x06, 0xd5, 0xa4, 0x37, 0xe2, 0xa8, 0x81, - 0xd5, 0xe0, 0x65, 0xf0, 0x05, 0x48, 0x93, 0x17, 0x9a, 0x74, 0xd3, 0xda, 0x2e, 0x3c, 0xbd, 0x96, - 0xe2, 0xed, 0x14, 0xfa, 0x19, 0xc3, 0xb5, 0x35, 0x0f, 0xf9, 0xb6, 0x22, 0xc6, 0xe3, 0x29, 0xf1, - 0xef, 0x0e, 0xee, 0x19, 0x47, 0x03, 0x8a, 0xb3, 0x09, 0x74, 0x4f, 0x06, 0x77, 0x96, 0x43, 0x87, - 0xc4, 0xd9, 0x0e, 0xc6, 0x94, 0x1c, 0x4e, 0x84, 0x72, 0x67, 0x0f, 0xa9, 0x75, 0x4a, 0xa7, 0x97, - 0x98, 0x20, 0x6f, 0x28, 0xfa, 0xc2, 0xa9, 0x88, 0xf3, 0x0e, 0x41, 0x7d, 0xa6, 0x04, 0xb6, 0x5e, - 0xd1, 0xb5, 0xa4, 0xb2, 0xc9, 0x92, 0x1b, 0x4f, 0x57, 0xc6, 0x5c, 0x45, 0xc1, 0xeb, 0x72, 0x25, - 0x77, 0x45, 0x3b, 0x09, 0x5c, 0x9b, 0x59, 0xd5, 0x6d, 0xb2, 0xe4, 0xea, 0xe1, 0xca, 0x35, 0x57, - 0x51, 0xf0, 0xfa, 0xbf, 0x4a, 0x7c, 0x8f, 0x29, 0xba, 0x96, 0x54, 0x36, 0x59, 0x2d, 0x75, 0x50, - 0xa5, 0x46, 0x91, 0xac, 0x0c, 0x47, 0x3b, 0x92, 0x15, 0xc9, 0xca, 0xc0, 0x40, 0x06, 0x53, 0xf7, - 0x71, 0x27, 0x43, 0x53, 0xbf, 0x29, 0xf7, 0x3c, 0xab, 0xb1, 0xb2, 0x97, 0x78, 0xe4, 0x8a, 0xbb, - 0x06, 0x2c, 0xf2, 0xb7, 0x6e, 0xc9, 0x42, 0xbb, 0x79, 0x7e, 0x8e, 0x38, 0xee, 0xa5, 0xf4, 0x26, - 0x6b, 0x61, 0xb2, 0xbc, 0xf3, 0x47, 0xb2, 0x1d, 0xe6, 0x16, 0xe4, 0x87, 0x14, 0xdb, 0xb6, 0x5c, - 0xc8, 0x22, 0xb8, 0x76, 0x1c, 0xbe, 0x07, 0x0e, 0x83, 0x47, 0xd3, 0x9c, 0xcf, 0xa1, 0x3e, 0x6d, - 0xba, 0x59, 0x45, 0x0c, 0x82, 0x1d, 0x49, 0x2c, 0x72, 0x4f, 0x7b, 0x86, 0xf2, 0xfb, 0x90, 0xd6, - 0x70, 0x65, 0x4d, 0xeb, 0x24, 0x69, 0x9b, 0x7d, 0x83, 0xb3, 0xcd, 0xb4, 0xfa, 0x0d, 0x1c, 0x05, - 0x45, 0x20, 0x2a, 0x4b, 0x12, 0x72, 0x66, 0xbe, 0x03, 0xe4, 0x49, 0xe0, 0x0d, 0xb7, 0x61, 0x50, - 0xb2, 0x70, 0x20, 0xce, 0x4e, 0x83, 0x2e, 0xd7, 0x51, 0xc9, 0xea, 0xf2, 0x88, 0xf7, 0x29, 0xf9, - 0x2c, 0xb7, 0xe3, 0x0e, 0x4a, 0x16, 0x1d, 0xbf, 0x0b, 0x5e, 0xb4, 0x1d, 0x94, 0xb8, 0xbc, 0x94, - 0xd8, 0x3f, 0xb4, 0xe3, 0x0f, 0x36, 0x67, 0x71, 0x14, 0x64, 0xc8, 0xa5, 0x3d, 0xb4, 0xca, 0xf3, - 0xe5, 0x49, 0xf0, 0x33, 0xf8, 0x13, 0x4c, 0x82, 0xf9, 0x16, 0x19, 0x05, 0x4f, 0x83, 0x0d, 0x60, - 0x0f, 0xd0, 0x1e, 0x8b, 0xfa, 0xc9, 0xeb, 0x13, 0xe6, 0xaf, 0xef, 0xd8, 0x6f, 0x04, 0xe5, 0xb7, - 0xc0, 0x95, 0x59, 0x2f, 0xcd, 0xd2, 0x70, 0xab, 0xdb, 0x38, 0xa9, 0x7f, 0xcf, 0x76, 0xa5, 0xf1, - 0x54, 0xbc, 0x12, 0xf1, 0xc9, 0x8a, 0xc5, 0xe9, 0x24, 0x5e, 0x77, 0x33, 0x30, 0x1d, 0x71, 0xc8, - 0x61, 0xa8, 0x1d, 0x99, 0xbb, 0x38, 0xda, 0xc5, 0x91, 0x99, 0x98, 0x76, 0x58, 0xc4, 0x2d, 0xf1, - 0xc9, 0x8a, 0xc5, 0x21, 0xf0, 0x97, 0x12, 0x5f, 0x3d, 0xaf, 0xbc, 0xc9, 0xfa, 0x9a, 0x40, 0x7e, - 0x51, 0x02, 0x28, 0x9c, 0x8a, 0x38, 0x6f, 0x13, 0xd4, 0xa0, 0x12, 0x58, 0x2e, 0x64, 0x69, 0xeb, - 0x46, 0x63, 0x8a, 0xf3, 0x22, 0xab, 0xb4, 0x78, 0xeb, 0x79, 0x85, 0x3c, 0xb3, 0xe4, 0x97, 0x21, - 0x57, 0xae, 0xb8, 0x8a, 0x82, 0xd7, 0xb5, 0x78, 0xeb, 0x79, 0x85, 0x24, 0x4b, 0xe3, 0x41, 0x7e, - 0x09, 0x2a, 0x93, 0x34, 0x8d, 0x37, 0x6f, 0xb2, 0xca, 0x44, 0x94, 0x37, 0xd6, 0x48, 0x96, 0x97, - 0x22, 0x63, 0x10, 0xc9, 0x32, 0x5c, 0x78, 0x4b, 0x91, 0x2c, 0x2f, 0x45, 0xc6, 0x20, 0x92, 0x65, - 0xb8, 0xf0, 0x96, 0x22, 0x59, 0x5e, 0x8a, 0x8c, 0x41, 0x24, 0xcb, 0x70, 0xe1, 0x2d, 0x45, 0xb2, - 0xbc, 0x14, 0x19, 0x83, 0x48, 0x96, 0xe1, 0xc2, 0x5b, 0x8a, 0x64, 0x79, 0x29, 0x32, 0x06, 0x91, - 0x2c, 0xc3, 0x85, 0xb7, 0x14, 0xc9, 0xf2, 0x52, 0x64, 0x0c, 0x22, 0x59, 0x86, 0x0b, 0x6f, 0x29, - 0x92, 0xe5, 0xa5, 0xc8, 0x18, 0x44, 0xb2, 0x0c, 0x17, 0xde, 0x52, 0x24, 0xcb, 0x4b, 0x91, 0x31, - 0xb0, 0xc9, 0xd2, 0x16, 0xbe, 0x1e, 0x31, 0xa6, 0xb1, 0x64, 0x93, 0x35, 0xae, 0xd0, 0xd1, 0xa5, - 0xe8, 0x2a, 0xab, 0xb2, 0xc9, 0x92, 0x37, 0x49, 0x5c, 0x79, 0xde, 0x55, 0x54, 0xb9, 0xee, 0x23, - 0xab, 0x87, 0x5f, 0x1c, 0x5f, 0xaa, 0x32, 0x41, 0x76, 0xee, 0x3e, 0xb2, 0xc4, 0x76, 0x10, 0xc2, - 0x7a, 0xed, 0x46, 0x55, 0x2d, 0xdb, 0xef, 0x3a, 0xfc, 0x08, 0x09, 0xf2, 0x1e, 0x42, 0x97, 0x43, - 0x86, 0x7c, 0x8c, 0x79, 0x11, 0xc2, 0x7e, 0x62, 0x2b, 0xaf, 0x12, 0xfd, 0x0d, 0xb4, 0x97, 0xc3, - 0xe4, 0x9d, 0x81, 0x05, 0x2d, 0x75, 0xb2, 0xf8, 0x45, 0xf6, 0x3f, 0x08, 0x39, 0x48, 0xb6, 0x17, - 0x53, 0x32, 0xde, 0x82, 0x5e, 0x50, 0x59, 0xb1, 0x87, 0x61, 0x1b, 0x84, 0x7d, 0x0e, 0x13, 0x17, - 0x2a, 0xcb, 0x86, 0x27, 0xf1, 0x19, 0x64, 0x25, 0xb6, 0x7b, 0xd9, 0x9e, 0xf3, 0xb4, 0xab, 0xe4, - 0xee, 0x06, 0xb2, 0x38, 0xbb, 0xae, 0x83, 0xb7, 0x61, 0xa3, 0x1b, 0x8c, 0x54, 0x92, 0x95, 0x94, - 0xa4, 0xeb, 0x73, 0x96, 0xbb, 0x1f, 0xc2, 0xbe, 0x62, 0x0e, 0xdb, 0x86, 0x5e, 0x26, 0xfc, 0xb5, - 0x16, 0x64, 0xc2, 0x6f, 0x20, 0x19, 0xdd, 0x76, 0xb0, 0x02, 0x2c, 0x58, 0x49, 0x25, 0x4b, 0x32, - 0x86, 0x30, 0x79, 0x04, 0xba, 0x9c, 0x40, 0x54, 0xa9, 0x02, 0xb1, 0x43, 0xec, 0x7c, 0x35, 0xd5, - 0x60, 0x01, 0xec, 0xd0, 0xce, 0x90, 0x05, 0x90, 0x56, 0x3e, 0x29, 0x44, 0xb2, 0x32, 0xf0, 0x1a, - 0xc9, 0x8a, 0x64, 0x65, 0x60, 0x20, 0x83, 0x69, 0xc8, 0x33, 0xeb, 0x96, 0xe2, 0x77, 0xc6, 0x4b, - 0xf7, 0xca, 0xfe, 0xa2, 0xa9, 0x3a, 0x94, 0x80, 0xea, 0x79, 0x85, 0x24, 0x4b, 0xae, 0x9a, 0xae, - 0x94, 0xed, 0x79, 0x51, 0x8b, 0xb7, 0x9e, 0x57, 0x48, 0xb2, 0xb4, 0x97, 0x57, 0xb7, 0x73, 0x4b, - 0x51, 0x8a, 0x7b, 0x2f, 0xe2, 0x94, 0x8f, 0x08, 0xfa, 0xdc, 0xa3, 0x4d, 0xbd, 0x9e, 0x57, 0x48, - 0xb2, 0xb4, 0xc5, 0xc3, 0x27, 0x70, 0xf6, 0x31, 0x81, 0xe4, 0xf5, 0xc9, 0x9c, 0x92, 0x5b, 0xcb, - 0xaa, 0x03, 0xb4, 0x94, 0x1b, 0x6b, 0x57, 0xb4, 0xbc, 0x5c, 0x9b, 0x6c, 0x75, 0x08, 0x59, 0x06, - 0x64, 0xe5, 0x42, 0x93, 0x11, 0x94, 0x7d, 0x40, 0xbe, 0xfd, 0x0b, 0x79, 0x80, 0xb2, 0x05, 0xe9, - 0x58, 0x13, 0x4b, 0x07, 0xe8, 0x06, 0xe7, 0x41, 0x9a, 0xbc, 0x32, 0xdd, 0x4c, 0x4e, 0xbd, 0x60, - 0x82, 0xb7, 0x0f, 0xe8, 0xec, 0x88, 0xa7, 0x43, 0x59, 0x0b, 0xd3, 0xd6, 0xc3, 0x3c, 0xcd, 0x82, - 0xef, 0x96, 0xdc, 0x1f, 0xf6, 0xf4, 0xfa, 0x25, 0xfb, 0x77, 0xf2, 0x24, 0xf3, 0xe0, 0xbf, 0x77, - 0x42, 0x93, 0xb5, 0x84, 0xce, 0x7f, 0x05, 0x9d, 0x9e, 0x20, 0xca, 0xb0, 0xfb, 0x2e, 0x41, 0x6e, - 0x81, 0xa8, 0xd1, 0xe9, 0x60, 0x83, 0x0e, 0x09, 0x3a, 0x96, 0x4f, 0x3a, 0xf6, 0x03, 0xf9, 0x16, - 0xa6, 0xec, 0x72, 0xcc, 0x26, 0x2a, 0xb7, 0x64, 0x18, 0x8e, 0x5d, 0x60, 0x28, 0x6d, 0x12, 0x28, - 0xb8, 0x7e, 0x94, 0xf8, 0x7a, 0x34, 0x72, 0x82, 0x0e, 0x43, 0xd7, 0x01, 0x4e, 0x65, 0x72, 0xec, - 0x07, 0xf2, 0xb1, 0x90, 0x2c, 0xf3, 0x14, 0xf1, 0x4f, 0x80, 0x64, 0x14, 0xc8, 0x6f, 0x0f, 0x72, - 0xd5, 0xbb, 0x04, 0x4e, 0x71, 0x46, 0xc9, 0x10, 0x6c, 0x90, 0x5c, 0xc9, 0x72, 0xbd, 0x41, 0x9e, - 0xdc, 0x21, 0xaf, 0x01, 0x45, 0xb9, 0x95, 0x90, 0xaf, 0xef, 0xaf, 0x40, 0x8e, 0x2c, 0x45, 0x79, - 0xe5, 0x3e, 0xde, 0xb6, 0x6e, 0x62, 0xf2, 0xf1, 0x89, 0x52, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXMoreIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x06, 0x00, 0x00, 0x00, 0x20, 0x4f, 0xee, - 0x6c, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x6b, 0xda, 0xa9, 0x4c, 0x00, 0x00, - 0x01, 0xc4, 0x49, 0x44, 0x41, 0x54, 0x48, 0x0d, 0xdd, 0x95, 0x4f, 0x2b, 0x44, 0x51, 0x18, 0xc6, - 0xe7, 0xfa, 0x5b, 0x14, 0x4d, 0xc4, 0x6a, 0xec, 0xd4, 0xa4, 0xd8, 0x68, 0x90, 0x1a, 0x5f, 0x60, - 0x0a, 0x65, 0xef, 0x23, 0x8c, 0x6c, 0x94, 0xad, 0x9d, 0x95, 0x2f, 0x80, 0xa5, 0x05, 0x45, 0x29, - 0x35, 0x62, 0x41, 0x4a, 0x22, 0xa9, 0x61, 0x35, 0x8c, 0x42, 0xca, 0x9f, 0xd8, 0xa9, 0x99, 0x05, - 0xe3, 0xf7, 0x4e, 0x33, 0x67, 0xee, 0x4c, 0xf7, 0x9c, 0x79, 0x6d, 0xbd, 0xf5, 0x73, 0xcf, 0x79, - 0xdf, 0xe7, 0x79, 0x8e, 0x3b, 0xdd, 0x99, 0x1b, 0x0a, 0xf9, 0xaa, 0x50, 0x28, 0x24, 0x60, 0x07, - 0x1e, 0xe1, 0x01, 0xb6, 0x21, 0xe1, 0x93, 0xa8, 0x97, 0xf8, 0xfa, 0x61, 0x1d, 0x6e, 0xe0, 0x1d, - 0x0e, 0x61, 0x0e, 0x1a, 0xd5, 0x21, 0x25, 0x21, 0x9e, 0x4e, 0x58, 0x86, 0x53, 0xf8, 0x84, 0x73, - 0x58, 0x81, 0xae, 0xaa, 0x2c, 0x1a, 0x1e, 0xac, 0x82, 0xad, 0xd6, 0x18, 0x78, 0x55, 0x26, 0xc7, - 0x06, 0xed, 0x2c, 0x7c, 0x59, 0xc2, 0xce, 0xe8, 0x77, 0x3b, 0xec, 0x55, 0x23, 0xb4, 0x31, 0x78, - 0xb2, 0x64, 0xbd, 0xd2, 0x9f, 0x30, 0x06, 0x36, 0x49, 0x8b, 0xd0, 0xdf, 0x4e, 0x1a, 0x83, 0x63, - 0x81, 0x61, 0x00, 0x72, 0x7e, 0x63, 0xc0, 0x7a, 0xd3, 0x11, 0x61, 0x46, 0xf8, 0xda, 0x21, 0x1b, - 0xe0, 0xf7, 0xb7, 0x9e, 0xd9, 0x84, 0x43, 0xfc, 0x69, 0x01, 0xdb, 0xa7, 0xe7, 0x37, 0x88, 0xa6, - 0xd9, 0x9c, 0x62, 0x59, 0xa0, 0x91, 0x47, 0x53, 0x53, 0x31, 0x4b, 0x84, 0x69, 0x13, 0xb2, 0xa0, - 0x09, 0x42, 0xb3, 0xd4, 0x80, 0x6b, 0x08, 0xda, 0x8c, 0xdb, 0xbe, 0x10, 0xcd, 0xa0, 0x7d, 0x6c, - 0x26, 0x63, 0x66, 0xe5, 0x5e, 0x8c, 0xb8, 0xc7, 0xc5, 0xa9, 0x36, 0x6b, 0x54, 0x6e, 0xa4, 0x4f, - 0x11, 0x58, 0x96, 0x44, 0xca, 0x8b, 0xa0, 0x2b, 0x9f, 0x4c, 0x2b, 0xfd, 0x9e, 0xa0, 0x59, 0x40, - 0x4f, 0x73, 0xae, 0x46, 0x23, 0xd1, 0x11, 0xb9, 0x91, 0xeb, 0x80, 0x43, 0x6c, 0x2d, 0xa7, 0xd6, - 0xf3, 0xbc, 0x3c, 0xc6, 0x8c, 0xcd, 0x5c, 0xd3, 0x4f, 0xd7, 0xec, 0x83, 0xb6, 0x1a, 0x8d, 0xf8, - 0xd2, 0x72, 0x23, 0x77, 0x90, 0x95, 0x5d, 0x9d, 0xca, 0xf0, 0x8f, 0xde, 0xd7, 0xd1, 0xc8, 0x78, - 0x5f, 0xa1, 0xc9, 0xa1, 0x39, 0x56, 0xe8, 0x34, 0x59, 0x12, 0x93, 0x2a, 0x66, 0xf1, 0x48, 0xc4, - 0xe1, 0x1b, 0x6c, 0x25, 0xb3, 0x71, 0xc5, 0xc1, 0xf2, 0xe3, 0xd1, 0x01, 0xf2, 0x0e, 0x72, 0xd5, - 0xbc, 0x26, 0x4b, 0x34, 0x84, 0xec, 0xb9, 0x82, 0x98, 0x1d, 0x40, 0xe5, 0xd5, 0xc0, 0x66, 0x06, - 0xde, 0xa0, 0xb6, 0x5e, 0x68, 0x4c, 0x6b, 0x0f, 0x2e, 0x1d, 0x1e, 0xc5, 0x73, 0x51, 0x1b, 0xc4, - 0x3e, 0x0f, 0x8b, 0x20, 0x4f, 0x82, 0xaa, 0xd0, 0x86, 0x61, 0x03, 0x82, 0x6a, 0x8b, 0x66, 0xf1, - 0xa5, 0x58, 0xb9, 0x13, 0x62, 0x69, 0xca, 0x8b, 0x6a, 0x0a, 0x86, 0xe1, 0x07, 0x2e, 0x61, 0x97, - 0x47, 0xea, 0x83, 0xeb, 0x9f, 0x8a, 0xac, 0x26, 0x0c, 0x93, 0x20, 0xbf, 0x4e, 0xbd, 0x70, 0x05, - 0x29, 0xb2, 0xb4, 0xdf, 0x21, 0xe4, 0x95, 0x22, 0x2f, 0xce, 0x4e, 0x88, 0xc2, 0x2d, 0x9c, 0x90, - 0x75, 0xc4, 0xf5, 0x7f, 0xd5, 0x2f, 0x30, 0x5e, 0xa3, 0xc0, 0xef, 0xd7, 0xce, 0x11, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXMoreIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x00, 0x12, 0x08, 0x06, 0x00, 0x00, 0x00, 0x13, 0xcf, 0x23, - 0xd5, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4b, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0xb1, 0x08, 0xca, 0x01, 0x00, 0x00, - 0x02, 0xc6, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x98, 0x3d, 0x68, 0x15, 0x41, 0x14, 0x85, - 0xb3, 0x2f, 0xd1, 0x48, 0x10, 0x02, 0xa2, 0x21, 0x85, 0x76, 0x16, 0x16, 0x1a, 0x34, 0x2f, 0xa0, - 0xd8, 0xd8, 0x99, 0x68, 0x11, 0x14, 0xb4, 0x10, 0x24, 0xa8, 0x85, 0xd6, 0x5a, 0x06, 0xd4, 0xc6, - 0x46, 0x14, 0x0b, 0x8b, 0x34, 0x4a, 0x8a, 0xa0, 0x36, 0xa9, 0xd2, 0xaa, 0x8d, 0x8d, 0x29, 0x12, - 0x83, 0x29, 0xb4, 0x12, 0x9b, 0x88, 0x8a, 0x81, 0x60, 0x63, 0xfc, 0x21, 0xc9, 0xf3, 0xbb, 0x92, - 0x59, 0x76, 0x33, 0x33, 0x99, 0xbd, 0xf7, 0x3d, 0xbb, 0x5c, 0x38, 0xec, 0xcc, 0xfd, 0x39, 0x67, - 0x77, 0x76, 0x77, 0x66, 0x76, 0xb3, 0xb6, 0x80, 0x35, 0x1a, 0x8d, 0xfd, 0xb8, 0xcf, 0x83, 0x01, - 0x50, 0x07, 0x6b, 0xe0, 0x0d, 0x98, 0x03, 0x93, 0x59, 0x96, 0x7d, 0xe0, 0xd8, 0x52, 0x43, 0xf3, - 0x20, 0x84, 0x67, 0x81, 0x68, 0xf6, 0x83, 0x65, 0xe0, 0x34, 0x9f, 0xa2, 0xf9, 0x85, 0x7e, 0x4b, - 0x0d, 0xcd, 0xe3, 0x10, 0x9e, 0x02, 0x72, 0x8d, 0x47, 0xc0, 0x12, 0x70, 0x9a, 0x13, 0x68, 0x4a, - 0x3f, 0x6c, 0x14, 0xd7, 0xc0, 0x75, 0xb0, 0x0c, 0x62, 0x26, 0xb1, 0x1b, 0xa0, 0x16, 0x66, 0xd1, - 0x79, 0xe1, 0xe9, 0x00, 0x37, 0xc1, 0x1f, 0x10, 0xb3, 0x25, 0x02, 0x17, 0x75, 0xcc, 0xf1, 0x6c, - 0xb8, 0x76, 0x82, 0x31, 0xb0, 0x06, 0x62, 0xf6, 0x95, 0xc0, 0x99, 0x20, 0x0b, 0x81, 0x76, 0xf0, - 0x22, 0x56, 0x19, 0xf0, 0xbf, 0x94, 0x9a, 0x20, 0x59, 0x45, 0x27, 0xf5, 0x9d, 0x60, 0x3a, 0xc0, - 0x1d, 0x73, 0x3d, 0xae, 0x48, 0x1d, 0x4d, 0x83, 0xb8, 0x17, 0x7c, 0x8c, 0x09, 0x04, 0xfc, 0xf7, - 0x3d, 0x32, 0x92, 0x46, 0x03, 0x89, 0x29, 0xd7, 0xa8, 0x47, 0xa4, 0x70, 0x40, 0x7e, 0x37, 0x25, - 0x10, 0x88, 0x9f, 0x53, 0x48, 0x78, 0xa9, 0xf0, 0x4d, 0x05, 0x38, 0x53, 0xae, 0x93, 0x39, 0x11, - 0x99, 0x7d, 0xe0, 0x77, 0xaa, 0x22, 0x10, 0x97, 0x9a, 0x43, 0x39, 0x91, 0xa2, 0x41, 0xdd, 0x31, - 0xb0, 0x12, 0xe0, 0x4c, 0xb9, 0xbe, 0x91, 0xb0, 0x5b, 0x21, 0x95, 0xa7, 0x52, 0x37, 0x92, 0x22, - 0x8f, 0xc4, 0x17, 0xf0, 0x77, 0xbb, 0x79, 0xe7, 0x12, 0x8c, 0xdb, 0x73, 0xd6, 0xea, 0x0d, 0xa9, - 0x19, 0xa9, 0x9e, 0x5e, 0xca, 0xbc, 0x42, 0xcf, 0xf2, 0x1a, 0xef, 0xa1, 0x6e, 0xb8, 0xc4, 0x54, - 0xbd, 0x73, 0xb5, 0x7a, 0x6a, 0x29, 0x73, 0x2f, 0xbd, 0x41, 0x37, 0x58, 0xb2, 0x02, 0x59, 0x4d, - 0x56, 0x12, 0x8b, 0x59, 0xeb, 0x44, 0x4b, 0x5d, 0xcb, 0x93, 0x21, 0x37, 0x46, 0x56, 0x3c, 0xab, - 0xd5, 0x65, 0xf5, 0x93, 0x01, 0x6b, 0x86, 0xa4, 0x1f, 0x8e, 0x4c, 0x73, 0x06, 0xe4, 0x77, 0x92, - 0x6f, 0x7a, 0x7d, 0xd7, 0x75, 0x64, 0x6b, 0xa1, 0xb5, 0x03, 0x14, 0x74, 0x69, 0x8b, 0x0a, 0xf9, - 0x75, 0x19, 0x28, 0xb9, 0x50, 0xf7, 0x84, 0x15, 0x62, 0x95, 0x9b, 0x96, 0x5a, 0xd1, 0x54, 0x0d, - 0xf0, 0x86, 0xb3, 0xb1, 0x68, 0x5a, 0x5e, 0xf9, 0xa2, 0x6c, 0xad, 0xc6, 0xc6, 0x6b, 0x15, 0xcf, - 0xdb, 0xa2, 0x57, 0xd9, 0x9e, 0x83, 0xa3, 0xa1, 0xa9, 0x21, 0xff, 0x17, 0xf9, 0xef, 0x34, 0x35, - 0x1b, 0x72, 0x65, 0xe3, 0xa8, 0xb5, 0xf7, 0x14, 0xfc, 0xd4, 0x16, 0x15, 0xf2, 0x67, 0xdd, 0x1d, - 0x9a, 0x2d, 0x38, 0xb5, 0x4d, 0x6b, 0xad, 0xe5, 0x82, 0xdd, 0xb9, 0xa9, 0x35, 0xb9, 0x41, 0x2b, - 0x14, 0xcf, 0x3b, 0x02, 0xc3, 0x71, 0xe6, 0x5f, 0x0d, 0x73, 0xc8, 0x00, 0xb0, 0x2c, 0xe3, 0xb2, - 0xeb, 0x3e, 0x6c, 0x10, 0x6e, 0xa3, 0xee, 0x04, 0xd8, 0x6c, 0x07, 0x4d, 0x38, 0x68, 0x8b, 0x78, - 0x7b, 0x8c, 0x9a, 0xd7, 0x82, 0x8c, 0x69, 0xe7, 0x27, 0x52, 0xba, 0x73, 0x4d, 0x3a, 0x77, 0xd2, - 0x35, 0x5e, 0xc6, 0xad, 0x9c, 0xc0, 0xd0, 0x80, 0xed, 0xa1, 0xc7, 0x98, 0x76, 0xc8, 0x37, 0xab, - 0xc9, 0xa0, 0xce, 0xc0, 0xf3, 0xb4, 0x84, 0x97, 0x31, 0x54, 0x12, 0x24, 0xbc, 0x0d, 0xbc, 0xf6, - 0xd2, 0xe2, 0x8e, 0x57, 0x84, 0x3a, 0x4a, 0x24, 0xca, 0x0e, 0xf5, 0x5d, 0x60, 0x3e, 0x2e, 0xe1, - 0x45, 0xc6, 0x95, 0x12, 0x5e, 0x3a, 0x8c, 0xfb, 0xc0, 0x67, 0x8f, 0x39, 0xee, 0x78, 0xe0, 0x91, - 0x88, 0x83, 0x7c, 0x19, 0xb0, 0xdb, 0x60, 0xb3, 0x8f, 0x5a, 0xd9, 0xb5, 0xcb, 0xa7, 0x51, 0x53, - 0x03, 0xe5, 0x4e, 0x00, 0x9e, 0x1d, 0xe0, 0x1e, 0x58, 0x05, 0x31, 0xfb, 0x4e, 0xe0, 0xb2, 0xab, - 0x69, 0xf6, 0x08, 0xd7, 0x2e, 0xf0, 0x24, 0x26, 0xb6, 0xee, 0x97, 0xd7, 0xbd, 0xf4, 0x14, 0x07, - 0x97, 0x6f, 0x92, 0xfa, 0x38, 0xa1, 0x0b, 0xc0, 0xfd, 0x2e, 0x71, 0xbf, 0x68, 0x64, 0x52, 0x7e, - 0xc6, 0x64, 0xd9, 0xcc, 0x4a, 0x16, 0xbc, 0x56, 0x34, 0x8f, 0x12, 0x90, 0xef, 0x3e, 0xa7, 0xf9, - 0x83, 0xb6, 0xe8, 0xc9, 0x64, 0x3e, 0x8e, 0xe6, 0x02, 0xc7, 0x96, 0x1a, 0x9a, 0x83, 0x10, 0x9e, - 0x06, 0xb2, 0xc9, 0x95, 0xb9, 0x57, 0x7e, 0xc9, 0x88, 0x9e, 0xe0, 0x11, 0x9a, 0x8b, 0x1c, 0xb7, - 0x6c, 0x6b, 0x04, 0xfe, 0xf3, 0x08, 0xfc, 0x05, 0x85, 0x24, 0x43, 0xa4, 0x3d, 0xeb, 0x6a, 0x6e, - 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXGearIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x57, 0x02, 0xf9, - 0x87, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x37, 0x6c, 0x0c, 0x00, 0x00, - 0x06, 0x6a, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xd5, 0x98, 0x7b, 0x88, 0x55, 0x55, 0x14, 0x87, - 0x67, 0xd4, 0xd1, 0xc9, 0x4c, 0x2d, 0xcb, 0x34, 0x8a, 0x91, 0x1c, 0x2b, 0x31, 0xc9, 0x71, 0x8a, - 0x4c, 0x1c, 0x2a, 0xc8, 0x30, 0xc5, 0xcc, 0xc2, 0x12, 0x13, 0x24, 0xe9, 0x45, 0xd0, 0x04, 0xa6, - 0xf5, 0xc7, 0x64, 0x91, 0x14, 0x61, 0x6f, 0xb4, 0x18, 0x2a, 0x04, 0x4b, 0x7b, 0x3f, 0xa0, 0x07, - 0x21, 0xf6, 0x18, 0x32, 0x8a, 0x2c, 0x19, 0x4b, 0x53, 0x62, 0x6a, 0xd0, 0x2c, 0x1b, 0xf3, 0x91, - 0x39, 0x96, 0xe9, 0xa4, 0x4d, 0xdf, 0x6f, 0xe6, 0x9e, 0x7b, 0xd7, 0xdd, 0x77, 0xdf, 0x73, 0xcf, - 0x9e, 0x07, 0x53, 0x0b, 0xbe, 0x7b, 0xd6, 0x5a, 0x7b, 0xad, 0xb5, 0xf7, 0x3d, 0x8f, 0xbd, 0xf7, - 0x39, 0x45, 0x45, 0x5d, 0x28, 0xad, 0xad, 0xad, 0x63, 0xa0, 0xcc, 0x57, 0x12, 0x7f, 0x29, 0x54, - 0x41, 0x89, 0xaf, 0xbd, 0xc7, 0x7d, 0x0c, 0xac, 0x02, 0x24, 0xcd, 0x30, 0xc2, 0x1d, 0x10, 0xbe, - 0x57, 0xd5, 0x88, 0xd4, 0xba, 0x6d, 0xff, 0x09, 0x9b, 0x81, 0xdd, 0xde, 0x36, 0xbc, 0xf6, 0x9f, - 0xe7, 0xed, 0xa0, 0x70, 0x4d, 0x30, 0x6d, 0x5b, 0x6c, 0x5b, 0x67, 0xf5, 0x3e, 0x21, 0x05, 0x18, - 0xc4, 0x60, 0xe2, 0x1f, 0x85, 0xaf, 0x8b, 0x8b, 0x8b, 0x9f, 0x72, 0x72, 0xcb, 0x8d, 0x3d, 0x97, - 0xd8, 0xed, 0xd8, 0xbd, 0xa0, 0x05, 0x66, 0x40, 0x24, 0x67, 0xd2, 0x46, 0x7a, 0x71, 0x6b, 0xe4, - 0xc0, 0x3e, 0x0f, 0x7d, 0x11, 0xac, 0xc6, 0xbf, 0x26, 0xf2, 0x77, 0xf9, 0x91, 0x8e, 0xe6, 0x43, - 0x24, 0x2b, 0x50, 0xfa, 0xc0, 0x28, 0x58, 0x02, 0xbb, 0x21, 0xa9, 0xbc, 0x4c, 0xe0, 0x15, 0xa0, - 0xfc, 0xc9, 0xa0, 0xdb, 0x4e, 0xf2, 0x55, 0x97, 0x0f, 0xda, 0x16, 0xa4, 0x03, 0x75, 0x66, 0x65, - 0xa7, 0x35, 0x3a, 0xa0, 0xff, 0x4a, 0x4e, 0x8b, 0xc9, 0x7b, 0xcb, 0xf6, 0x97, 0x44, 0xd7, 0x25, - 0x0e, 0x91, 0x0d, 0x4e, 0xf0, 0x69, 0x8e, 0x6d, 0xcd, 0x63, 0x18, 0x4d, 0xd0, 0x6c, 0x9d, 0x8e, - 0x3e, 0x14, 0xdb, 0xce, 0x4a, 0xc1, 0x57, 0x20, 0xe8, 0x19, 0xa0, 0xb3, 0x8b, 0x41, 0x03, 0xeb, - 0x0d, 0xae, 0xd4, 0xe3, 0x78, 0x09, 0x3e, 0x83, 0x9f, 0xa1, 0x89, 0xfb, 0x59, 0xb1, 0x45, 0x9c, - 0xe1, 0xe3, 0x38, 0x0c, 0x87, 0x0b, 0x61, 0x1a, 0x4c, 0x81, 0x21, 0xe0, 0x4a, 0x25, 0xb1, 0xa5, - 0xe4, 0x1d, 0x76, 0x1b, 0x82, 0x6c, 0x8a, 0x94, 0x80, 0xa6, 0xbd, 0x35, 0x30, 0x07, 0x34, 0x87, - 0xd7, 0xc0, 0x3f, 0xe0, 0x4a, 0x03, 0x8e, 0xb3, 0x42, 0x3a, 0x20, 0xbe, 0x37, 0xcc, 0x83, 0x46, - 0x70, 0x65, 0x3d, 0x8e, 0xe1, 0x30, 0x0e, 0x6a, 0xe1, 0x0b, 0xb8, 0x28, 0xa4, 0xbe, 0xce, 0xd8, - 0x78, 0xb0, 0xf2, 0xa7, 0x35, 0x3c, 0xfa, 0xc4, 0xa0, 0x0e, 0x52, 0xc1, 0xd4, 0xd1, 0x89, 0xaa, - 0x86, 0xc3, 0x4e, 0xcd, 0x43, 0x8e, 0xfd, 0x5c, 0x50, 0x7d, 0x92, 0x7b, 0xc1, 0x97, 0x4e, 0x11, - 0x6b, 0x2e, 0xc6, 0x78, 0xdb, 0x38, 0x36, 0xa0, 0x87, 0x3e, 0x4f, 0xe9, 0x31, 0x91, 0x7b, 0x3e, - 0x6c, 0x37, 0xf5, 0xac, 0x7a, 0x0c, 0x43, 0xb7, 0x5e, 0x98, 0x90, 0xa4, 0x4b, 0xf8, 0xb7, 0xad, - 0x84, 0xae, 0x5b, 0xa8, 0x5a, 0x95, 0x38, 0x6a, 0x3e, 0xb7, 0x67, 0xee, 0xc6, 0xb0, 0x1e, 0xb2, - 0xa3, 0xa9, 0x75, 0x32, 0x6c, 0x05, 0x57, 0xdc, 0xf5, 0x26, 0x3b, 0x31, 0x9f, 0x45, 0x95, 0x41, - 0xf0, 0x9b, 0x53, 0xed, 0x26, 0x1b, 0x4f, 0xdb, 0x03, 0xa6, 0x5d, 0xeb, 0xc0, 0x20, 0xdb, 0x1e, - 0xaa, 0x93, 0x5f, 0x06, 0xbf, 0x80, 0x95, 0x9b, 0x43, 0xeb, 0xb4, 0xc5, 0x53, 0xe1, 0x11, 0x5b, - 0x05, 0xfd, 0x75, 0xb7, 0x10, 0xbe, 0xfe, 0xb0, 0xc3, 0xc4, 0x3d, 0xe1, 0xc6, 0x84, 0xda, 0xd4, - 0xd2, 0x4c, 0x64, 0xaf, 0x7c, 0x13, 0xf6, 0x80, 0x82, 0x75, 0x08, 0x3a, 0x15, 0xa6, 0xc2, 0xa5, - 0x30, 0x05, 0x8e, 0x40, 0x24, 0x7b, 0x51, 0x34, 0x67, 0xe7, 0x08, 0xfe, 0xeb, 0xa2, 0x20, 0x8e, - 0xea, 0x78, 0x74, 0x4e, 0x50, 0xa0, 0x83, 0x1a, 0x8f, 0x99, 0x9a, 0x52, 0x97, 0x41, 0x15, 0x68, - 0x5c, 0x17, 0x78, 0xcb, 0xd1, 0xb0, 0x0d, 0xf2, 0xc9, 0xf5, 0xde, 0xa4, 0x94, 0x93, 0xa4, 0x3a, - 0x93, 0xb8, 0x36, 0x2e, 0x36, 0x49, 0x1b, 0xb5, 0x4e, 0x80, 0xb8, 0x55, 0x5e, 0xeb, 0x48, 0xb6, - 0x90, 0xb0, 0xc9, 0x0c, 0xc2, 0xaa, 0x2a, 0x14, 0x3b, 0xc3, 0xd0, 0x3e, 0x16, 0x8e, 0x9a, 0xa4, - 0xab, 0xb2, 0xab, 0x87, 0x5b, 0xd4, 0x5a, 0x64, 0xea, 0x59, 0x55, 0xb3, 0xd2, 0xa4, 0x9c, 0x8a, - 0x38, 0x35, 0x0b, 0xd4, 0x81, 0x2b, 0x0f, 0xe7, 0x04, 0x7b, 0x1c, 0x24, 0x2d, 0x37, 0x89, 0x8d, - 0xe8, 0xfd, 0xc0, 0xb7, 0x62, 0x7b, 0xb2, 0x73, 0x5d, 0xe4, 0x6a, 0x31, 0xb3, 0x27, 0x05, 0xb3, - 0xf5, 0x77, 0xd0, 0x4a, 0xee, 0x17, 0x1a, 0xb5, 0x3b, 0xfc, 0x1c, 0xac, 0x8c, 0xf5, 0x47, 0x67, - 0x7b, 0x49, 0x38, 0x11, 0xf6, 0x98, 0xc4, 0xfd, 0xe8, 0x9a, 0x76, 0x77, 0xc1, 0x6b, 0x70, 0x6e, - 0x76, 0x46, 0x61, 0x8b, 0x9c, 0xf7, 0xc1, 0x4a, 0x45, 0xc1, 0x2c, 0xa2, 0xeb, 0x4d, 0xc6, 0xf7, - 0x05, 0x13, 0x4c, 0x00, 0x79, 0x0b, 0x4c, 0xae, 0xab, 0xea, 0x01, 0x9f, 0x69, 0xc2, 0x0b, 0xaa, - 0xc4, 0xdf, 0xe5, 0x14, 0xc9, 0x59, 0xf1, 0xb3, 0xee, 0x6d, 0x82, 0x75, 0xc9, 0xed, 0x2c, 0xf2, - 0x43, 0xc1, 0x5e, 0x52, 0x01, 0xe4, 0xaa, 0xd6, 0xac, 0x98, 0x78, 0x6d, 0x1c, 0xb5, 0xbf, 0x1a, - 0x13, 0x13, 0xe3, 0x36, 0x6d, 0x76, 0x1c, 0x39, 0x77, 0x43, 0xfa, 0x0f, 0x50, 0x58, 0x5b, 0xe3, - 0x05, 0x50, 0x6a, 0x92, 0x7e, 0x32, 0x7a, 0x21, 0x55, 0x8b, 0xdc, 0x84, 0x54, 0xd0, 0x21, 0x8e, - 0xf3, 0x41, 0x53, 0xaf, 0x36, 0x62, 0x1b, 0x41, 0xa2, 0xad, 0xf3, 0x83, 0xf4, 0x35, 0x20, 0x09, - 0xc4, 0x6e, 0x53, 0x92, 0x91, 0xd9, 0xe4, 0x4d, 0x84, 0xf4, 0xb8, 0xb5, 0x25, 0xd0, 0xbd, 0xbb, - 0x16, 0x7c, 0x3b, 0xcd, 0x7b, 0x4c, 0x72, 0xac, 0x4a, 0xfe, 0x9b, 0x10, 0x89, 0x5e, 0x0f, 0xd3, - 0x82, 0xf3, 0x0c, 0xd0, 0xec, 0xd1, 0x55, 0xa2, 0xd5, 0x7a, 0xba, 0x3a, 0xd0, 0x3f, 0xd1, 0x59, - 0x9b, 0x0c, 0xc5, 0xe0, 0xca, 0x5e, 0xd7, 0x11, 0x63, 0x9f, 0x6d, 0xda, 0xd6, 0x1b, 0xbd, 0x88, - 0xfd, 0xbd, 0xae, 0xe4, 0x2e, 0xeb, 0xeb, 0xa4, 0xae, 0x77, 0x8b, 0xb6, 0x6d, 0x8d, 0xfe, 0x40, - 0x1d, 0x3c, 0x0e, 0xbb, 0xc1, 0x95, 0x61, 0xae, 0x23, 0xc6, 0xfe, 0xce, 0xb4, 0x55, 0x19, 0x5d, - 0x57, 0x79, 0x24, 0xb6, 0x3a, 0x95, 0xe8, 0x65, 0x7e, 0x4f, 0x42, 0x7c, 0x27, 0xf0, 0x28, 0xb9, - 0x1f, 0xc2, 0x7d, 0x90, 0x11, 0x3a, 0xd1, 0x16, 0x5a, 0x5b, 0x09, 0x2b, 0x2b, 0x32, 0x11, 0xf1, - 0x1a, 0x49, 0x37, 0x98, 0xc4, 0xbf, 0xd0, 0x6f, 0x83, 0xd3, 0x41, 0x5b, 0x93, 0x6f, 0x21, 0x92, - 0xac, 0x4f, 0x2e, 0x71, 0x55, 0x49, 0xd0, 0x8e, 0xd7, 0xca, 0x2b, 0x18, 0x27, 0xc5, 0xe5, 0xe8, - 0x6c, 0x1d, 0x30, 0x19, 0x1f, 0xc4, 0x06, 0x9b, 0x46, 0x72, 0x8a, 0xe1, 0x63, 0x93, 0xeb, 0x53, - 0xf5, 0x62, 0xa4, 0xab, 0x91, 0x48, 0x88, 0x9d, 0xe1, 0x14, 0x99, 0xe7, 0x26, 0x66, 0x9e, 0xe6, - 0x4c, 0xcb, 0xd6, 0x8c, 0x5a, 0x74, 0x0e, 0x05, 0x7c, 0xcf, 0x86, 0x09, 0x69, 0x57, 0xb9, 0xcf, - 0x75, 0x6b, 0xac, 0xcb, 0x69, 0xc8, 0x38, 0x8e, 0xa0, 0xce, 0x24, 0xae, 0x31, 0xe3, 0x2a, 0xa8, - 0xb9, 0xd3, 0xe6, 0xa6, 0xd8, 0x0c, 0x06, 0x3b, 0x04, 0x36, 0x3b, 0xff, 0x7a, 0x52, 0x6c, 0x52, - 0xaa, 0x91, 0x9c, 0x11, 0x60, 0x5f, 0x05, 0xf5, 0xc9, 0x44, 0x8b, 0xd7, 0x8f, 0xf0, 0x02, 0x94, - 0x27, 0xa9, 0x63, 0x63, 0xc8, 0xf9, 0x14, 0xac, 0xe4, 0xdf, 0x63, 0x11, 0xa5, 0x37, 0xb0, 0xed, - 0x36, 0x3a, 0xa5, 0x3f, 0x63, 0x8b, 0xe6, 0xd3, 0x89, 0x7d, 0xc7, 0xe4, 0xea, 0x24, 0x68, 0xe1, - 0xea, 0xb0, 0x90, 0x5f, 0x6e, 0xea, 0x45, 0xaa, 0xa6, 0xe2, 0x1a, 0x6f, 0x51, 0x1a, 0xf2, 0x6d, - 0x5f, 0xf5, 0x56, 0xd6, 0xd7, 0x9b, 0x94, 0x72, 0xd2, 0xee, 0xde, 0xab, 0x59, 0xb3, 0x50, 0x5c, - 0x6e, 0xbe, 0x36, 0x6a, 0xda, 0xb7, 0x3d, 0xcc, 0x2c, 0xb9, 0x32, 0x27, 0x8f, 0x66, 0xbd, 0x98, - 0xe7, 0x93, 0xbb, 0x73, 0x12, 0x52, 0x0e, 0x12, 0xfa, 0x83, 0xbd, 0x72, 0x2b, 0xf3, 0xc5, 0x26, - 0xf5, 0x53, 0x6f, 0x18, 0xd8, 0xc9, 0x04, 0x33, 0x2d, 0xda, 0xa1, 0x46, 0x2b, 0x7e, 0xa6, 0x24, - 0x4e, 0x7d, 0xab, 0xd1, 0xb4, 0xa5, 0x37, 0x33, 0x4d, 0x7f, 0xda, 0x4d, 0x46, 0xa2, 0x69, 0xd1, - 0xfb, 0xed, 0x07, 0xff, 0x43, 0x51, 0x10, 0x47, 0x5d, 0xad, 0x53, 0x32, 0x55, 0x3b, 0xa6, 0x51, - 0x63, 0x95, 0xa9, 0x29, 0xb5, 0x1a, 0xb4, 0x63, 0x28, 0xd3, 0x31, 0x51, 0x55, 0x02, 0xef, 0x04, - 0x2b, 0xeb, 0x30, 0xb2, 0x66, 0x24, 0xec, 0xd1, 0xd0, 0x62, 0x82, 0x6e, 0x4d, 0x54, 0x3c, 0x26, - 0x88, 0x5a, 0xd3, 0x4c, 0x3d, 0xa9, 0x5b, 0x20, 0xfc, 0x79, 0x22, 0xa9, 0x2f, 0xec, 0x03, 0x2b, - 0x5a, 0xb1, 0xd3, 0x42, 0x43, 0x9d, 0x69, 0xd4, 0x17, 0x35, 0xdf, 0xb4, 0x9c, 0x8e, 0x2f, 0xa4, - 0x90, 0x5f, 0x09, 0x7f, 0x98, 0x9a, 0x52, 0x67, 0x17, 0xca, 0xf3, 0xb6, 0x93, 0x38, 0xdd, 0x29, - 0x14, 0x99, 0xb5, 0x28, 0x5a, 0xb4, 0xe6, 0x46, 0x0e, 0x8e, 0x9a, 0x1d, 0xc6, 0x7b, 0x0b, 0x25, - 0x74, 0x92, 0xaf, 0xab, 0xa9, 0x97, 0x1f, 0x57, 0xde, 0x4b, 0x58, 0x22, 0x13, 0x46, 0x85, 0x52, - 0xb0, 0x0f, 0xa6, 0x5b, 0xf4, 0x45, 0x1c, 0xb6, 0xb3, 0xe5, 0x99, 0xec, 0x70, 0x8d, 0x5a, 0xb3, - 0xa0, 0xd9, 0xed, 0xc4, 0xd8, 0x57, 0x07, 0x55, 0x25, 0xb1, 0xc2, 0x24, 0x4b, 0xfd, 0x06, 0x7c, - 0xdb, 0x6d, 0xb5, 0xe9, 0xbb, 0x4d, 0x87, 0x3e, 0x68, 0x91, 0x37, 0x14, 0x9e, 0x06, 0x57, 0x1a, - 0x70, 0x68, 0xdb, 0x11, 0xc9, 0xb3, 0xa1, 0x7f, 0x40, 0xb7, 0xc8, 0xfd, 0xf0, 0x24, 0x8c, 0x53, - 0x32, 0x47, 0xcd, 0xf5, 0x07, 0xc1, 0x95, 0x8d, 0x38, 0xd4, 0x16, 0xbb, 0x56, 0xd8, 0x01, 0x10, - 0xab, 0x69, 0x52, 0xb3, 0x97, 0x7b, 0xbf, 0xe3, 0x6a, 0x5d, 0x0d, 0xba, 0x03, 0x06, 0x83, 0x66, - 0x9f, 0x95, 0x90, 0x77, 0x15, 0xcf, 0x9a, 0x55, 0x6c, 0x27, 0x3e, 0x9d, 0x42, 0xda, 0x9b, 0xd4, - 0x83, 0x6f, 0x56, 0xd8, 0x8f, 0xff, 0x0d, 0xd0, 0xbb, 0x80, 0xf6, 0xff, 0x62, 0x27, 0x1c, 0x0f, - 0xda, 0x96, 0x0b, 0xcd, 0xdf, 0x53, 0xa1, 0x12, 0x7c, 0x7d, 0x2f, 0x63, 0xaf, 0x74, 0x07, 0x6d, - 0xdd, 0x23, 0xfc, 0x01, 0x7d, 0xea, 0xe8, 0x4e, 0x59, 0x12, 0x3a, 0xf2, 0xd0, 0x69, 0xcf, 0xfd, - 0xac, 0xf7, 0x11, 0x1d, 0x1e, 0x08, 0xed, 0x34, 0x15, 0xaf, 0xdd, 0xeb, 0x27, 0xb0, 0xcf, 0xe4, - 0xbb, 0xf5, 0x4d, 0x93, 0x5f, 0x0d, 0xfd, 0x03, 0x03, 0x53, 0x65, 0xd4, 0xf9, 0x42, 0x2e, 0xf7, - 0x65, 0x1c, 0x75, 0x6b, 0x5c, 0x0b, 0x0d, 0x90, 0x54, 0x16, 0x13, 0x58, 0x46, 0xfe, 0x25, 0x1c, - 0xb5, 0xdb, 0xdd, 0x01, 0x92, 0xa8, 0x7e, 0xbb, 0xd5, 0xd5, 0xbf, 0xdc, 0x3b, 0x25, 0xb0, 0x10, - 0x2e, 0x77, 0x6b, 0xe3, 0xb3, 0x5f, 0xb3, 0xb5, 0xad, 0xd6, 0xd4, 0x38, 0x07, 0xae, 0x81, 0x77, - 0x21, 0x92, 0x83, 0x9e, 0x5c, 0x3d, 0xd4, 0x35, 0xe0, 0xee, 0xff, 0xdd, 0xd0, 0xee, 0xb3, 0xe9, - 0xfc, 0x96, 0x68, 0x84, 0x1c, 0x97, 0xda, 0x9e, 0xb0, 0x47, 0x81, 0xde, 0x0d, 0x24, 0xd1, 0x27, - 0x16, 0x1b, 0xd2, 0xf3, 0x3a, 0x03, 0x1b, 0x09, 0x9a, 0x16, 0xb5, 0x00, 0xe6, 0x6c, 0xb8, 0xf0, - 0x2d, 0x05, 0xc9, 0xbd, 0x3d, 0x3f, 0xda, 0x3c, 0x23, 0x60, 0x70, 0x03, 0xa1, 0x5f, 0x9e, 0x66, - 0xad, 0x25, 0x9d, 0xde, 0xa9, 0xe6, 0xab, 0xfd, 0xbf, 0xf5, 0xff, 0x0b, 0x9a, 0x0a, 0x94, 0x47, - 0x1c, 0x29, 0x6a, 0x39, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXGearIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x48, 0x08, 0x06, 0x00, 0x00, 0x00, 0x55, 0xed, 0xb3, - 0x47, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0x90, 0x31, 0x46, 0xef, 0x00, 0x00, - 0x0a, 0x22, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, 0x9a, 0x7b, 0xf0, 0x55, 0x55, 0x15, 0xc7, - 0xf9, 0xf9, 0x00, 0xd1, 0x02, 0x05, 0x8c, 0x50, 0x12, 0x30, 0x34, 0x53, 0xb0, 0x86, 0x81, 0xc6, - 0x47, 0x45, 0x8e, 0x8a, 0xf9, 0x47, 0x93, 0x4d, 0x5a, 0x99, 0x3d, 0x06, 0x7b, 0xd1, 0x64, 0x8d, - 0x8e, 0x36, 0x9a, 0x5a, 0x43, 0x9a, 0xce, 0x68, 0x35, 0x66, 0x52, 0x3e, 0xd2, 0x8a, 0x64, 0x1c, - 0x99, 0xd2, 0x9e, 0x0a, 0x3d, 0xc8, 0x34, 0x67, 0x22, 0x29, 0x41, 0x14, 0xc9, 0xc9, 0xfa, 0xa5, - 0xf8, 0xa0, 0xa2, 0xd4, 0xd1, 0x44, 0x25, 0xa4, 0xcf, 0xf7, 0xfe, 0xee, 0xb9, 0xb3, 0x7f, 0xeb, - 0xae, 0xbd, 0xcf, 0x3e, 0xf7, 0x9c, 0x7e, 0x3c, 0x86, 0x35, 0xf3, 0xbd, 0x7b, 0xef, 0xb5, 0xd7, - 0xeb, 0xec, 0x73, 0xce, 0x7e, 0xac, 0x73, 0x87, 0x0d, 0xdb, 0x49, 0xdb, 0xce, 0x08, 0x6c, 0xd9, - 0xb2, 0x65, 0x24, 0xf8, 0x3e, 0x78, 0x04, 0x5c, 0x58, 0x16, 0x19, 0x32, 0x1f, 0x03, 0x7f, 0x01, - 0x4b, 0xc1, 0xb8, 0x32, 0xf9, 0xed, 0xbe, 0x9f, 0x8b, 0xfc, 0x28, 0x08, 0xe9, 0xed, 0xb1, 0x8b, - 0x42, 0x68, 0x3a, 0xd8, 0x1c, 0x08, 0xcf, 0x8f, 0xc9, 0xee, 0x30, 0x7c, 0x2e, 0xf6, 0xba, 0xe0, - 0x82, 0x55, 0xbd, 0x17, 0xf4, 0x79, 0x17, 0x08, 0xff, 0x27, 0x12, 0x08, 0x68, 0x89, 0x27, 0xb7, - 0xdd, 0xf0, 0xb8, 0x90, 0xdd, 0xca, 0x82, 0x45, 0xe6, 0xd7, 0xc1, 0x05, 0x17, 0xd5, 0xf7, 0x5a, - 0x3d, 0x3a, 0x8e, 0x2a, 0x3a, 0x83, 0xf2, 0xcf, 0x56, 0xce, 0xb6, 0x91, 0x1d, 0x6e, 0x79, 0xdb, - 0x44, 0x9b, 0xc0, 0x2e, 0x03, 0x1b, 0xc1, 0x0a, 0xf0, 0xfa, 0x58, 0x50, 0xf4, 0xad, 0x03, 0x96, - 0x9e, 0x84, 0xa1, 0x39, 0xe6, 0xb7, 0xe0, 0x6e, 0xf0, 0x0b, 0xf0, 0x57, 0x60, 0x69, 0x13, 0x0c, - 0xf7, 0x26, 0xc0, 0xdf, 0x1f, 0x2c, 0x03, 0x92, 0x59, 0x08, 0x76, 0x89, 0xc5, 0x30, 0xe4, 0x7c, - 0x82, 0x19, 0x0d, 0x42, 0xfa, 0x37, 0x8d, 0x37, 0x87, 0x81, 0xd0, 0xd6, 0x7c, 0x72, 0x39, 0x78, - 0x19, 0xd4, 0xa1, 0x05, 0x28, 0xcf, 0x30, 0xb6, 0x0f, 0x85, 0xf7, 0xa8, 0x31, 0x3a, 0x3d, 0x94, - 0xa9, 0x53, 0x77, 0xdf, 0xff, 0x2a, 0x06, 0x09, 0x6c, 0x34, 0xf2, 0x4f, 0x1b, 0x9d, 0x17, 0x68, - 0xcf, 0x03, 0x63, 0xc0, 0x87, 0xc0, 0x1b, 0x41, 0x93, 0xb4, 0x16, 0x63, 0x8b, 0xc0, 0x9f, 0xc0, - 0xf5, 0x60, 0x1f, 0x10, 0xd2, 0xb4, 0xbe, 0xbe, 0xbe, 0x35, 0x21, 0xa3, 0xd7, 0x7a, 0xed, 0x01, - 0x92, 0x63, 0x06, 0x49, 0xf3, 0xc3, 0xd4, 0x5e, 0x83, 0x68, 0x58, 0xef, 0x79, 0xec, 0x8d, 0x62, - 0x80, 0x36, 0x37, 0x61, 0xb7, 0xa9, 0x77, 0x75, 0x45, 0x13, 0xc1, 0x34, 0x64, 0x63, 0x65, 0x53, - 0x83, 0xa3, 0x78, 0xdc, 0x49, 0xaf, 0x87, 0x40, 0xef, 0x43, 0xe7, 0xd4, 0x0a, 0x7a, 0x7a, 0x25, - 0xfb, 0xc1, 0x63, 0x60, 0x5d, 0xbb, 0x54, 0x7d, 0x13, 0x78, 0x75, 0x80, 0x09, 0xd4, 0xdf, 0x04, - 0xf6, 0x06, 0xb9, 0xa4, 0x58, 0xb6, 0x1d, 0xe2, 0xf5, 0x3a, 0x0e, 0x68, 0x62, 0x2e, 0xa3, 0xa7, - 0x10, 0xb8, 0x01, 0x1c, 0x0b, 0x76, 0xcd, 0xbd, 0x02, 0x64, 0x77, 0x03, 0x6f, 0x05, 0x5a, 0x29, - 0xef, 0x07, 0x65, 0xa4, 0xd5, 0xb4, 0xca, 0xcd, 0xca, 0x0d, 0xc5, 0x97, 0xc3, 0xd9, 0x04, 0x70, - 0x23, 0xb8, 0x09, 0x9c, 0x02, 0x76, 0x2f, 0x24, 0xa9, 0x7f, 0x1a, 0xfc, 0x17, 0xa4, 0xe8, 0x1e, - 0x3a, 0x4f, 0x02, 0x23, 0x0a, 0xbd, 0x3a, 0x25, 0x76, 0xde, 0x00, 0x7e, 0x04, 0xca, 0xe8, 0x12, - 0x04, 0x5a, 0x73, 0x2c, 0xe5, 0x2e, 0xe0, 0x44, 0xa0, 0x2d, 0x80, 0x8e, 0x3a, 0x07, 0xd5, 0x89, - 0x61, 0x90, 0x2e, 0xc6, 0x6e, 0x03, 0x21, 0xad, 0xa7, 0x71, 0x29, 0xb8, 0x3e, 0x64, 0x26, 0xea, - 0x3a, 0x4b, 0x35, 0x32, 0x38, 0x61, 0x60, 0xd8, 0x9c, 0x09, 0x96, 0x24, 0xfc, 0xaa, 0x4b, 0x03, - 0x79, 0x3e, 0xe8, 0x07, 0x21, 0xad, 0x0e, 0x6d, 0xd5, 0xaa, 0x63, 0x75, 0x79, 0x68, 0xb9, 0xc7, - 0xfa, 0x05, 0xb5, 0x82, 0x48, 0x28, 0x13, 0xcf, 0x3b, 0x80, 0x5e, 0xdf, 0x2a, 0xf4, 0x78, 0xc2, - 0x64, 0xb5, 0x2e, 0xbc, 0x9e, 0x56, 0xc1, 0xb3, 0x76, 0xc0, 0x27, 0x83, 0xf0, 0x90, 0x29, 0xf5, - 0xe7, 0xc0, 0xc4, 0x6a, 0x9e, 0xf3, 0xa5, 0xb1, 0x7d, 0x20, 0x58, 0x09, 0x72, 0xe9, 0xbc, 0x7c, - 0xeb, 0x19, 0x92, 0x78, 0xd5, 0xf6, 0xbf, 0x8c, 0xd6, 0x20, 0xb0, 0x9f, 0xcc, 0x51, 0x5e, 0xeb, - 0x08, 0xdf, 0x94, 0xe1, 0xaa, 0x67, 0x11, 0xfc, 0x29, 0x95, 0xa2, 0x39, 0xa6, 0x8c, 0x56, 0x23, - 0xd0, 0x99, 0x47, 0x7b, 0x76, 0x18, 0x2a, 0x62, 0xf0, 0xb5, 0xe0, 0xf9, 0x84, 0xe7, 0x3f, 0xd0, - 0x37, 0xb6, 0xd0, 0xa1, 0x3e, 0x0e, 0x78, 0x2b, 0xdb, 0xa0, 0x23, 0x48, 0x21, 0xdf, 0x54, 0x89, - 0xcf, 0x3e, 0xa0, 0x05, 0x25, 0x46, 0x3a, 0xea, 0x1c, 0xd9, 0x94, 0xbf, 0x8e, 0x1d, 0x8c, 0x6a, - 0x15, 0x58, 0x1b, 0xf1, 0x7a, 0x17, 0xfc, 0x51, 0x1d, 0xe1, 0x76, 0x05, 0xde, 0x19, 0x8e, 0xbc, - 0xd2, 0x1b, 0x4d, 0x6d, 0x4e, 0xad, 0xcb, 0x56, 0x1b, 0xfb, 0xbb, 0x83, 0x5f, 0x3a, 0xbe, 0xc5, - 0xda, 0x00, 0xf6, 0x72, 0x15, 0xeb, 0x30, 0x31, 0xaa, 0xcc, 0x9e, 0x47, 0xff, 0x80, 0xe9, 0x66, - 0xfa, 0xe0, 0xef, 0x0a, 0xee, 0x73, 0x94, 0x3e, 0x51, 0x27, 0x96, 0x1c, 0x5d, 0x7c, 0x8e, 0x02, - 0xab, 0x1c, 0xdf, 0x62, 0x5d, 0x94, 0x63, 0x23, 0x5b, 0x06, 0x83, 0xaf, 0x04, 0x5a, 0xda, 0x3d, - 0x7a, 0x4f, 0xca, 0x10, 0x0a, 0xb3, 0x1d, 0xa5, 0x7f, 0xc2, 0xb3, 0x87, 0xcb, 0x94, 0x99, 0x9e, - 0xfa, 0xf0, 0x31, 0x09, 0xfc, 0x07, 0x58, 0xd2, 0x54, 0xd1, 0xdc, 0x82, 0x81, 0x31, 0xed, 0x79, - 0x3c, 0xba, 0x25, 0x27, 0x72, 0x14, 0x6f, 0x76, 0x94, 0xbf, 0x9e, 0xa3, 0x5b, 0x57, 0x06, 0xbf, - 0xda, 0x03, 0x79, 0x74, 0x63, 0x65, 0xdb, 0x58, 0xd9, 0x13, 0xfc, 0x18, 0x3c, 0x0d, 0xf4, 0xea, - 0xf4, 0x83, 0x07, 0xc0, 0x8b, 0xc0, 0xd2, 0xbf, 0x60, 0x8c, 0xcf, 0x71, 0x82, 0xdc, 0x44, 0xa0, - 0x65, 0x3e, 0x24, 0x25, 0xb6, 0xa6, 0xe5, 0xe8, 0xd7, 0x91, 0xc1, 0xc7, 0x70, 0xf0, 0x50, 0xe8, - 0xb8, 0x5d, 0xd7, 0x64, 0xad, 0x63, 0x8b, 0xb6, 0x25, 0x7f, 0x07, 0xcf, 0x80, 0x3b, 0xc0, 0xab, - 0xa2, 0xfe, 0xe8, 0x3c, 0x13, 0xe4, 0xd2, 0xdc, 0xa8, 0x21, 0xa7, 0x03, 0xa3, 0xde, 0x9d, 0x5c, - 0xe6, 0x88, 0x36, 0xce, 0xc2, 0xf7, 0x9c, 0xdc, 0x8b, 0x42, 0xee, 0xab, 0xd1, 0x00, 0xe8, 0x8c, - 0x4d, 0xc4, 0xd6, 0xbe, 0x9e, 0x9e, 0x4a, 0xb9, 0x5f, 0xe4, 0x47, 0x80, 0x87, 0xad, 0x21, 0xda, - 0xef, 0x8e, 0x06, 0xd4, 0x60, 0x07, 0x7e, 0x72, 0x4f, 0x03, 0xf3, 0xa3, 0x6e, 0x31, 0xa2, 0x3d, - 0x44, 0xce, 0x46, 0xeb, 0x9b, 0x51, 0x23, 0x89, 0x0e, 0x6c, 0xeb, 0x48, 0x60, 0xa9, 0x1f, 0xc6, - 0x1e, 0x09, 0xb5, 0x46, 0xba, 0xf0, 0x31, 0xcf, 0x3a, 0x76, 0xda, 0x3a, 0xd7, 0x95, 0x9f, 0x19, - 0x11, 0x3a, 0x1b, 0xa4, 0x4e, 0xe8, 0x3d, 0x6f, 0xb4, 0xb0, 0x7b, 0x3b, 0xb0, 0xf4, 0x05, 0x8d, - 0x02, 0xcc, 0xbd, 0xc0, 0xff, 0x65, 0x8f, 0x84, 0xdd, 0xbd, 0xc1, 0x0b, 0x20, 0x46, 0x5a, 0x88, - 0xf2, 0x7d, 0x23, 0x7c, 0x3c, 0xb0, 0xe7, 0x29, 0x19, 0x2f, 0xfd, 0xf4, 0x92, 0xba, 0xe5, 0xe8, - 0x1f, 0x0c, 0xec, 0xa4, 0xaf, 0xc0, 0xb5, 0xf4, 0x8b, 0x54, 0xd7, 0xe4, 0xf9, 0x6d, 0xf0, 0xba, - 0x94, 0xad, 0xaa, 0x7d, 0xd8, 0x5b, 0x0c, 0x3c, 0x3a, 0xad, 0xaa, 0x2d, 0xdd, 0xcd, 0x7d, 0x3d, - 0x4b, 0xf0, 0x5a, 0x77, 0xbb, 0xb2, 0xc1, 0x40, 0x01, 0x1b, 0x97, 0x45, 0x6c, 0x5b, 0xb6, 0x9e, - 0xe2, 0x6b, 0x41, 0x23, 0xe7, 0x26, 0xec, 0x9c, 0x62, 0x1d, 0xb4, 0xdb, 0xb3, 0x82, 0xf0, 0xf2, - 0xaa, 0x28, 0x1e, 0x13, 0x31, 0xd6, 0xf3, 0xeb, 0x55, 0x78, 0xc6, 0xee, 0x58, 0x90, 0x7a, 0x85, - 0xad, 0xeb, 0x1f, 0xc0, 0xa8, 0x9d, 0x1a, 0xc6, 0x86, 0x9e, 0x5e, 0x8f, 0x4e, 0x2f, 0x62, 0xf3, - 0xca, 0xd8, 0x7b, 0x77, 0x98, 0x27, 0x0c, 0xef, 0x91, 0x08, 0xbf, 0x0a, 0xfb, 0x2c, 0x84, 0xb3, - 0x53, 0xae, 0xc8, 0x6a, 0xa5, 0xbb, 0xa2, 0x8a, 0x83, 0x88, 0xec, 0xc3, 0xf0, 0x37, 0x3a, 0x7d, - 0x87, 0x3b, 0xbc, 0x34, 0x8b, 0x61, 0xbe, 0xc6, 0x19, 0xea, 0x97, 0xe0, 0xc5, 0x06, 0x34, 0x6d, - 0xb0, 0xdd, 0x8b, 0xfe, 0x0c, 0xa0, 0x4d, 0xa2, 0xa5, 0x75, 0x30, 0x16, 0x01, 0x9d, 0xc4, 0xff, - 0x66, 0x3b, 0x69, 0x4b, 0xe7, 0xe0, 0x2c, 0x27, 0x09, 0x21, 0x6c, 0x28, 0xeb, 0x60, 0x29, 0x6f, - 0x3f, 0x86, 0x96, 0x96, 0xf9, 0x23, 0x80, 0xe6, 0x08, 0x9d, 0x7a, 0x2d, 0xe9, 0x2b, 0x44, 0x2d, - 0xc2, 0xe0, 0x32, 0x6b, 0x94, 0xf6, 0xd5, 0xa0, 0xb3, 0xd4, 0x53, 0x1f, 0x0e, 0xae, 0x00, 0x96, - 0x94, 0x4b, 0x1e, 0x53, 0x13, 0xde, 0xb1, 0x47, 0x67, 0xb3, 0x05, 0xe0, 0x58, 0xd0, 0xfd, 0x2a, - 0xc3, 0xd4, 0xa9, 0xfb, 0x73, 0xe0, 0x09, 0x90, 0xa2, 0x3b, 0xeb, 0x8c, 0x0e, 0x86, 0xe5, 0xc7, - 0x1e, 0x39, 0x7e, 0x07, 0xaf, 0xeb, 0xa9, 0x84, 0xa7, 0x9b, 0x75, 0x27, 0x18, 0x6a, 0xd2, 0x26, - 0xf8, 0x72, 0x30, 0xb2, 0xb8, 0x56, 0x05, 0xa7, 0x4f, 0x24, 0x97, 0x82, 0x09, 0x05, 0x33, 0x52, - 0xea, 0xfb, 0x55, 0x1d, 0x3a, 0x04, 0x65, 0x9b, 0x8b, 0xb9, 0x99, 0x8f, 0x7c, 0x2f, 0x5b, 0xa3, - 0xf0, 0xb6, 0xc0, 0x5b, 0x6c, 0xf9, 0x43, 0xd0, 0xd6, 0xa7, 0xf2, 0xcf, 0x82, 0x33, 0x0b, 0x5f, - 0x1a, 0x20, 0x31, 0x73, 0xc8, 0x9b, 0xe0, 0x72, 0xf4, 0x0a, 0x19, 0xef, 0x20, 0xb8, 0xa1, 0xe8, - 0x74, 0xca, 0x54, 0x9f, 0x23, 0xde, 0x28, 0xab, 0x33, 0x26, 0x1a, 0xa0, 0x45, 0xe0, 0xf6, 0x0c, - 0xf3, 0xaf, 0xc9, 0x90, 0x49, 0x89, 0xac, 0x72, 0x3a, 0x8f, 0x76, 0x78, 0x05, 0xab, 0xf6, 0x96, - 0xa2, 0x30, 0x54, 0xb1, 0x5c, 0x8e, 0xfc, 0x55, 0x85, 0x4e, 0xeb, 0xc3, 0x9a, 0x1a, 0xbc, 0x77, - 0x53, 0x29, 0xde, 0x05, 0x4e, 0x02, 0x0a, 0xae, 0xd3, 0x47, 0x5d, 0xb4, 0x96, 0x47, 0xff, 0xd0, - 0x81, 0x6a, 0x6f, 0xbf, 0xf8, 0xd0, 0x4e, 0x5c, 0x7e, 0x0a, 0xda, 0x44, 0xe5, 0x68, 0xec, 0x0e, - 0xfa, 0xb6, 0x8f, 0x9c, 0x96, 0xde, 0x7b, 0x40, 0x78, 0x36, 0xd2, 0xbf, 0x35, 0xbe, 0x0c, 0xea, - 0xd0, 0x5c, 0x94, 0x67, 0x3b, 0x06, 0x56, 0xc3, 0xfb, 0x21, 0xb8, 0x95, 0x58, 0x54, 0x4f, 0x13, - 0x01, 0x6a, 0xb9, 0xb5, 0xf4, 0x6c, 0x5a, 0xab, 0xbc, 0x17, 0x83, 0x3a, 0xe7, 0x59, 0x52, 0xd6, - 0xef, 0x3c, 0x70, 0x78, 0x1b, 0xe7, 0x50, 0x3e, 0x0b, 0x2c, 0xe9, 0xc6, 0xd5, 0x22, 0x0c, 0xde, - 0x61, 0x8d, 0xd2, 0xd6, 0x13, 0x53, 0x8d, 0x50, 0x3a, 0xd7, 0x31, 0x24, 0x56, 0xad, 0x54, 0x29, - 0xfa, 0x4a, 0xfe, 0x6b, 0xe5, 0xaa, 0x4a, 0x7f, 0xac, 0x76, 0x05, 0xbe, 0x34, 0x4e, 0xbd, 0xed, - 0xcb, 0x75, 0xbe, 0xf4, 0x00, 0xb7, 0x6b, 0x89, 0x6d, 0x0b, 0x3f, 0x10, 0x51, 0x3a, 0x20, 0xc2, - 0xcf, 0x62, 0xf3, 0xf8, 0x6a, 0xc5, 0x3a, 0x1d, 0x68, 0x95, 0xca, 0x25, 0x4d, 0xd6, 0x1f, 0xc8, - 0x15, 0x8e, 0xc9, 0x31, 0x38, 0x5a, 0xa5, 0xc7, 0x3a, 0xfd, 0xc9, 0x57, 0xaa, 0xea, 0x00, 0x1d, - 0xe1, 0x38, 0xa8, 0xca, 0xd2, 0xe1, 0xd0, 0xce, 0x6f, 0x31, 0x1b, 0xcf, 0xd0, 0x31, 0x87, 0x81, - 0xd5, 0x3f, 0xca, 0xea, 0x52, 0xec, 0x6f, 0x79, 0x3d, 0x0d, 0x90, 0xee, 0x70, 0xd7, 0xfe, 0x04, - 0x5e, 0xad, 0x3b, 0xc9, 0x5d, 0xd4, 0x2b, 0x9a, 0x33, 0xd1, 0x6a, 0xf2, 0x56, 0x62, 0xee, 0x10, - 0x06, 0x67, 0x25, 0x65, 0x13, 0x74, 0x42, 0xc4, 0x88, 0x7c, 0xe5, 0x13, 0x17, 0x31, 0x1b, 0x28, - 0x91, 0xed, 0x91, 0x92, 0xdd, 0x53, 0xf2, 0xad, 0x0d, 0x96, 0x44, 0x57, 0xc7, 0x0a, 0x4b, 0x3a, - 0x7e, 0xcc, 0x05, 0xf3, 0x81, 0xf2, 0xe2, 0x27, 0x00, 0xfd, 0x89, 0xaa, 0x31, 0xc2, 0x9e, 0xfe, - 0x63, 0xb4, 0x1e, 0x78, 0xa4, 0x05, 0x41, 0x07, 0xe2, 0x72, 0x42, 0xf0, 0x0c, 0xe0, 0x1d, 0x26, - 0x43, 0xc3, 0x17, 0x96, 0x5b, 0xea, 0x96, 0xc0, 0xc0, 0x2c, 0x60, 0x93, 0x70, 0x4a, 0x90, 0x35, - 0xf7, 0x5f, 0x9d, 0x6e, 0xb7, 0x2d, 0x0e, 0x3e, 0xbc, 0x74, 0x2f, 0xec, 0x41, 0x74, 0x49, 0x44, - 0x7d, 0x80, 0x8d, 0xa8, 0xee, 0x5c, 0x0e, 0x3d, 0x94, 0x34, 0xe4, 0x74, 0x62, 0x54, 0xab, 0x97, - 0x77, 0x92, 0xfe, 0xa2, 0x23, 0xde, 0x38, 0x0b, 0xdf, 0xb7, 0xe4, 0x5c, 0x18, 0x32, 0x1f, 0x89, - 0x3a, 0xa7, 0x53, 0x7b, 0x91, 0x5c, 0xf2, 0x36, 0x5b, 0x29, 0xdb, 0x7a, 0x32, 0x2d, 0xe9, 0x2b, - 0x47, 0xe7, 0x14, 0x1f, 0x55, 0xae, 0xd9, 0x81, 0x8f, 0x03, 0x81, 0x4d, 0xf3, 0xda, 0x58, 0x8a, - 0xf6, 0xd5, 0x51, 0x77, 0x48, 0x4c, 0x01, 0xde, 0x3f, 0x32, 0x0a, 0xe5, 0xb0, 0x5c, 0x43, 0x23, - 0xeb, 0xd3, 0x0f, 0x72, 0xe3, 0x81, 0x3e, 0x46, 0x5a, 0x3a, 0x31, 0x1a, 0x4c, 0x83, 0x1d, 0x38, - 0xfd, 0x99, 0x75, 0x1c, 0x69, 0x6f, 0x84, 0x9f, 0x4e, 0xbf, 0x22, 0x30, 0x02, 0xcc, 0x04, 0xd3, - 0xc1, 0x24, 0xa0, 0xfc, 0x4b, 0x2c, 0xd9, 0x7d, 0x71, 0xce, 0x75, 0xa0, 0xaf, 0x44, 0x98, 0xa5, - 0xac, 0xcf, 0xd6, 0x39, 0xf6, 0x53, 0x32, 0x38, 0x7d, 0xa7, 0x75, 0xdc, 0x6e, 0xdf, 0x4d, 0xb9, - 0x0f, 0x38, 0x00, 0x1c, 0x06, 0x34, 0x3f, 0xbe, 0x22, 0x65, 0x2b, 0xda, 0x87, 0xe2, 0x64, 0xa0, - 0xc9, 0xd4, 0x92, 0x32, 0x8c, 0xc9, 0x74, 0x25, 0xfd, 0xc7, 0x58, 0x25, 0xda, 0xca, 0x09, 0x4d, - 0x8c, 0x3a, 0x6c, 0xa8, 0x03, 0x1f, 0x23, 0x41, 0x3f, 0xb0, 0xa4, 0x95, 0x78, 0x66, 0x43, 0x6e, - 0x06, 0xcc, 0x60, 0x50, 0x59, 0x46, 0x8f, 0x34, 0xf1, 0xba, 0xf9, 0x65, 0xf8, 0xca, 0x0c, 0xae, - 0x75, 0x94, 0xce, 0x69, 0x34, 0xb8, 0x88, 0x31, 0xfc, 0x7e, 0xc7, 0xf1, 0x2d, 0xd6, 0xc2, 0x88, - 0x4a, 0xef, 0x6c, 0x8c, 0x8e, 0x06, 0xfa, 0x43, 0x83, 0x47, 0x0b, 0x60, 0x76, 0xed, 0x8c, 0xe1, - 0x29, 0x4b, 0x69, 0xe9, 0x7e, 0x18, 0xdd, 0x69, 0xcd, 0xde, 0x43, 0x73, 0x35, 0xf1, 0x71, 0xb1, - 0x75, 0xdc, 0x6e, 0xeb, 0xe9, 0xdd, 0xdf, 0x55, 0xaa, 0xc3, 0xc4, 0xe8, 0x58, 0x50, 0x7c, 0xdc, - 0x6b, 0xfb, 0x1a, 0x54, 0x7c, 0x8b, 0x56, 0xe7, 0xd8, 0x42, 0x7d, 0x12, 0xd0, 0x29, 0xdd, 0xd2, - 0x5b, 0xea, 0xc4, 0x91, 0xa3, 0x8b, 0xc3, 0x8f, 0x5b, 0xa7, 0x41, 0x5b, 0x31, 0x4d, 0xce, 0xb1, - 0x53, 0x49, 0x06, 0xa3, 0x1a, 0x80, 0x32, 0xd2, 0x64, 0xdc, 0x7a, 0x3a, 0x28, 0xf5, 0x37, 0x1a, - 0x4b, 0xdf, 0xad, 0xe4, 0xb4, 0x07, 0x61, 0x1c, 0x7e, 0x10, 0x94, 0x7d, 0x73, 0x5b, 0xd2, 0x83, - 0xe9, 0xb8, 0x0a, 0x0e, 0x8f, 0x04, 0x9a, 0xd8, 0x72, 0xe8, 0x56, 0x84, 0x4e, 0x76, 0x04, 0xb5, - 0x7d, 0xd8, 0x37, 0xee, 0xa5, 0x5e, 0x0f, 0xb6, 0xf5, 0xbf, 0xc4, 0xab, 0x1c, 0xbf, 0x31, 0xd6, - 0xfb, 0xea, 0x79, 0x0c, 0xb4, 0xf1, 0x70, 0x5b, 0xcc, 0x4b, 0x84, 0xef, 0x0d, 0xe6, 0xbc, 0xc0, - 0x64, 0xa3, 0x55, 0x62, 0x98, 0x08, 0xaa, 0xe6, 0x98, 0x94, 0x9d, 0x6c, 0x86, 0x70, 0xbe, 0xc2, - 0x19, 0x08, 0xed, 0x23, 0xee, 0x75, 0xf8, 0x1e, 0xeb, 0xf7, 0x30, 0x3b, 0xf3, 0x53, 0x33, 0x51, - 0xb5, 0x52, 0xc4, 0x7b, 0x60, 0xf7, 0x2c, 0xb0, 0xc1, 0x73, 0xda, 0xe6, 0x69, 0xb7, 0xbe, 0x14, - 0xd8, 0x9b, 0xb6, 0xbe, 0xa9, 0x38, 0x94, 0xab, 0x9e, 0x0d, 0x9e, 0x04, 0x9a, 0xa4, 0xaf, 0x01, - 0xad, 0xbd, 0x0f, 0xa5, 0xf6, 0x19, 0x8b, 0x41, 0x19, 0x5d, 0x89, 0x80, 0x97, 0xa8, 0xea, 0x29, - 0x46, 0x6c, 0x69, 0xfb, 0xf0, 0x29, 0xf0, 0x38, 0x48, 0x91, 0xb2, 0x04, 0x63, 0xe4, 0x84, 0x72, - 0x2a, 0xf8, 0x0a, 0x90, 0xce, 0x53, 0x20, 0xef, 0xf4, 0xde, 0x53, 0x84, 0x46, 0x09, 0x67, 0x9f, - 0x07, 0xf6, 0x0e, 0xc1, 0x1a, 0x44, 0xda, 0x54, 0xfe, 0x14, 0x9c, 0x0a, 0xf6, 0x34, 0x26, 0x4a, - 0x9b, 0xe8, 0x68, 0x50, 0x8e, 0x03, 0xfa, 0xe2, 0xba, 0x0e, 0x94, 0xd1, 0x37, 0x10, 0x68, 0x64, - 0x3b, 0xd1, 0xb5, 0x7f, 0x29, 0x8d, 0xd6, 0x11, 0x20, 0x98, 0x2f, 0xc1, 0xbe, 0xc0, 0xe9, 0xf2, - 0x58, 0xcf, 0xc1, 0xfc, 0x15, 0xe8, 0x07, 0xfa, 0x18, 0xf9, 0x68, 0xbb, 0x54, 0x5d, 0xc9, 0xab, - 0xf1, 0x40, 0xf9, 0x20, 0x41, 0x69, 0xd2, 0xa3, 0xc0, 0xf1, 0x20, 0xf7, 0x28, 0xf0, 0x3d, 0x92, - 0x6c, 0x1f, 0x46, 0xbe, 0x11, 0x6a, 0x64, 0x94, 0x89, 0xa4, 0xca, 0x0a, 0xa5, 0x0b, 0xad, 0xfd, - 0x85, 0x22, 0x71, 0xf5, 0x55, 0x62, 0x49, 0x98, 0x19, 0xe8, 0x6a, 0x6a, 0xf2, 0x9c, 0x55, 0xea, - 0x69, 0xe8, 0x04, 0x1a, 0x8d, 0xa5, 0xf6, 0x00, 0xf1, 0x7a, 0x29, 0xa7, 0x33, 0xcd, 0xb9, 0xfe, - 0x1b, 0xe0, 0xe9, 0x63, 0xdc, 0x4b, 0x4e, 0x5f, 0x5d, 0xd6, 0x66, 0x0c, 0x2c, 0x05, 0x5f, 0x03, - 0xca, 0x9f, 0x87, 0x34, 0x8e, 0x98, 0x26, 0x87, 0x8c, 0xad, 0x5a, 0x27, 0x18, 0x05, 0x14, 0x92, - 0x26, 0xec, 0xb3, 0x8b, 0xa0, 0xa8, 0x2b, 0x65, 0xf2, 0x49, 0x50, 0x75, 0xaf, 0x82, 0x4a, 0x17, - 0x69, 0xcb, 0xf1, 0x19, 0xd0, 0xf9, 0xce, 0x4f, 0xfd, 0xfd, 0x40, 0x8b, 0x40, 0x48, 0x33, 0x0a, - 0xff, 0x5b, 0xbd, 0x24, 0x2a, 0xa5, 0x53, 0xef, 0x6a, 0x47, 0xa7, 0xa4, 0x53, 0xf4, 0xcb, 0x07, - 0x7d, 0xde, 0x9e, 0x45, 0x39, 0xf0, 0x30, 0x9d, 0xf2, 0x22, 0x6d, 0x7b, 0xc1, 0xb0, 0x5a, 0x2b, - 0x65, 0xe7, 0x6f, 0x29, 0xe1, 0x85, 0xd3, 0x37, 0x07, 0x14, 0x49, 0xb9, 0x07, 0xa9, 0xdb, 0x7f, - 0x91, 0x84, 0xe2, 0x43, 0x5f, 0x27, 0x20, 0xed, 0x89, 0xde, 0x06, 0xb4, 0xea, 0x44, 0x89, 0xfe, - 0xe5, 0xc0, 0xd2, 0xb9, 0x52, 0x80, 0xa9, 0xa5, 0xbc, 0x95, 0x82, 0xa5, 0xd4, 0x76, 0xc0, 0xd2, - 0x63, 0x51, 0xc3, 0x03, 0xfa, 0x4a, 0x80, 0x69, 0x2b, 0x30, 0x2a, 0x25, 0xb7, 0x4d, 0xf7, 0x11, - 0xbc, 0xfd, 0xe6, 0xff, 0x04, 0xbc, 0xae, 0xa7, 0x02, 0x5e, 0x1f, 0x58, 0x05, 0x42, 0xfa, 0xcd, - 0xd6, 0xb8, 0xb8, 0xda, 0x93, 0x74, 0xc5, 0xa0, 0x1f, 0x34, 0xf2, 0x17, 0xb1, 0x67, 0xd9, 0x68, - 0x78, 0xc3, 0xe0, 0x69, 0xe2, 0x3d, 0xdf, 0xf0, 0xad, 0xae, 0xe9, 0xde, 0x01, 0x9a, 0x3c, 0x0e, - 0xfb, 0x01, 0x3d, 0x35, 0xa2, 0x9f, 0x83, 0xe4, 0x3e, 0x8c, 0xfe, 0x85, 0x12, 0x84, 0xf4, 0xd7, - 0x38, 0x6f, 0xa5, 0xdc, 0x01, 0x46, 0xc5, 0x5c, 0x02, 0x17, 0xaa, 0xf9, 0xea, 0x20, 0xe0, 0xa6, - 0x6a, 0x43, 0x71, 0x64, 0xf4, 0xaa, 0x4d, 0x01, 0xa3, 0x43, 0xfe, 0xce, 0xfa, 0xce, 0x11, 0xd8, - 0x7e, 0x46, 0xe0, 0x7f, 0xd1, 0xc6, 0xfb, 0xa0, 0x6e, 0xf6, 0xa7, 0x73, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCircleDownArrowIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x2e, 0x08, 0x06, 0x00, 0x00, 0x00, 0x57, 0xb9, 0x2b, - 0x37, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x52, 0x92, 0x24, 0x04, 0x00, 0x00, - 0x05, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xe5, 0x99, 0x5d, 0x88, 0x55, 0x55, 0x14, 0xc7, - 0xbd, 0xe6, 0x4c, 0x90, 0xa9, 0x59, 0xca, 0x64, 0x56, 0x68, 0x18, 0x0a, 0x21, 0x44, 0x90, 0x41, - 0x06, 0xe5, 0x54, 0x50, 0xbd, 0x54, 0xcf, 0x9a, 0x45, 0x11, 0x69, 0x61, 0xd6, 0x93, 0x0f, 0x41, - 0xa4, 0x49, 0x5a, 0xa2, 0x11, 0x46, 0x14, 0xf4, 0x52, 0x50, 0x4f, 0x81, 0x31, 0x84, 0x4a, 0xa6, - 0x06, 0x95, 0x58, 0xf4, 0x01, 0x8a, 0x7d, 0x3a, 0xf6, 0x92, 0x5f, 0xf9, 0x11, 0x15, 0x36, 0x39, - 0x3a, 0x4e, 0xbf, 0xff, 0xf1, 0xae, 0x3b, 0xeb, 0xec, 0x7b, 0xce, 0xb9, 0xfb, 0x5c, 0xef, 0xcc, - 0x1d, 0x68, 0xc1, 0x9f, 0xbd, 0xbe, 0xd7, 0x3a, 0xe7, 0x9e, 0x7d, 0xce, 0xde, 0xfb, 0x56, 0xc6, - 0xb4, 0x88, 0x06, 0x07, 0x07, 0xc7, 0x92, 0x6a, 0x2a, 0xb8, 0x0a, 0x4c, 0x07, 0x57, 0x82, 0x53, - 0xe0, 0x20, 0x38, 0x24, 0x54, 0x2a, 0x95, 0x7f, 0x18, 0xdb, 0x4f, 0x34, 0x3b, 0x15, 0x3c, 0x06, - 0x3e, 0x02, 0x7d, 0xa0, 0x11, 0xfd, 0x8c, 0xc3, 0x2b, 0xe0, 0x56, 0xa0, 0x0b, 0x1d, 0x59, 0xa2, - 0xe8, 0x9d, 0x60, 0x27, 0x18, 0x00, 0xcd, 0xd2, 0x61, 0x02, 0xd7, 0x80, 0x49, 0xc3, 0xde, 0x3d, - 0x45, 0xe6, 0x82, 0x2d, 0xa0, 0x95, 0x74, 0x9c, 0x64, 0xcf, 0x80, 0xce, 0x32, 0x17, 0x50, 0x89, - 0x71, 0x26, 0x69, 0x07, 0x7e, 0x1b, 0xc0, 0x93, 0x20, 0xeb, 0x27, 0x3e, 0x87, 0x7e, 0x17, 0xf8, - 0x0a, 0x24, 0xcf, 0x33, 0xe3, 0x51, 0x30, 0x1e, 0xe8, 0x99, 0x9f, 0x06, 0xae, 0x03, 0xf7, 0x00, - 0xcd, 0x83, 0x2c, 0x3a, 0x80, 0x72, 0x21, 0xf3, 0x60, 0x77, 0x96, 0xb1, 0xb4, 0x8e, 0xa6, 0xa7, - 0x80, 0x4f, 0x41, 0x16, 0x7d, 0x82, 0xf2, 0x51, 0x90, 0xd7, 0x4c, 0xaa, 0x1e, 0x7e, 0x63, 0xc1, - 0x7c, 0xb0, 0x0e, 0x9c, 0x04, 0x21, 0xfd, 0x8b, 0xe2, 0xa1, 0x54, 0x50, 0x33, 0x02, 0x49, 0x6e, - 0x00, 0x07, 0xc2, 0xec, 0xc8, 0x5f, 0x83, 0xee, 0x66, 0x72, 0x5a, 0x0c, 0xf1, 0x93, 0x81, 0x26, - 0x6a, 0xd6, 0xa4, 0x7e, 0x19, 0x7d, 0xd6, 0x2f, 0x6b, 0xe1, 0xf9, 0x23, 0x81, 0xb3, 0xc0, 0x09, - 0xe0, 0x49, 0x45, 0x74, 0x87, 0xa3, 0x1e, 0xb1, 0xfc, 0xec, 0x43, 0x16, 0x72, 0x5d, 0x03, 0xb2, - 0x7e, 0xd1, 0xd7, 0x87, 0xbc, 0x22, 0x39, 0x12, 0x4d, 0x02, 0x3f, 0x00, 0x4f, 0x87, 0x10, 0xe6, - 0x45, 0xa6, 0x28, 0xe5, 0x46, 0xde, 0x0e, 0xf0, 0xa6, 0x2f, 0x56, 0xe5, 0x97, 0x44, 0x27, 0x22, - 0xe0, 0x22, 0xb0, 0x39, 0x48, 0xb2, 0x0f, 0x59, 0x1f, 0x95, 0x61, 0x25, 0x6a, 0xe8, 0xed, 0xe2, - 0xe9, 0x0c, 0xc2, 0x82, 0xa8, 0xa2, 0x38, 0x3e, 0xe7, 0x23, 0xe1, 0xf5, 0xba, 0xd2, 0x1b, 0x61, - 0x44, 0x88, 0x5a, 0xeb, 0x33, 0xea, 0x5f, 0x5e, 0x58, 0x9c, 0x80, 0x2e, 0xf0, 0xb7, 0x0b, 0x8c, - 0xbf, 0x62, 0x97, 0x99, 0x78, 0x4d, 0xbc, 0x65, 0x20, 0xee, 0x6e, 0xa5, 0x63, 0xf5, 0x8b, 0x6f, - 0x01, 0x9e, 0xd6, 0x3b, 0x97, 0x7a, 0x16, 0xcf, 0x37, 0xbc, 0x37, 0xfc, 0xf3, 0xf5, 0x5e, 0x8d, - 0x35, 0xc4, 0xbd, 0xe3, 0xf2, 0xcc, 0x6e, 0x1c, 0x91, 0xf6, 0x20, 0xf6, 0x32, 0xf0, 0xbb, 0xcb, - 0x71, 0x1a, 0x7e, 0x46, 0xda, 0xab, 0x2a, 0x61, 0x98, 0x0d, 0x74, 0x87, 0x8d, 0x34, 0x19, 0x2f, - 0xc9, 0x74, 0x6e, 0xa0, 0x24, 0xee, 0x27, 0x4b, 0xc2, 0xb8, 0xb8, 0x81, 0x7b, 0xa6, 0x99, 0x38, - 0xfd, 0x62, 0x9e, 0xde, 0xcf, 0x73, 0x7c, 0xcd, 0x7b, 0xc1, 0xc7, 0xcf, 0xe8, 0x20, 0x23, 0xb1, - 0x5a, 0x4c, 0x19, 0x3d, 0x1c, 0x98, 0xa3, 0x44, 0x82, 0x3b, 0x41, 0xaf, 0x25, 0x61, 0xd4, 0xba, - 0xa8, 0xcb, 0x82, 0xfd, 0x4b, 0xfe, 0x01, 0x53, 0x32, 0xea, 0xb3, 0xfd, 0xb6, 0x93, 0x47, 0x9c, - 0xe5, 0xd3, 0xdf, 0x4f, 0xd1, 0x35, 0xae, 0xb0, 0x7a, 0xbd, 0xdf, 0xe4, 0xa4, 0x71, 0xae, 0xe4, - 0x26, 0x14, 0xd7, 0x9a, 0x92, 0xb1, 0x87, 0xc0, 0xb3, 0x4e, 0x6e, 0x17, 0xfb, 0x21, 0x85, 0x07, - 0x5c, 0xf1, 0x07, 0x8d, 0xb7, 0x3b, 0x5e, 0x53, 0x54, 0x0d, 0x3d, 0xe6, 0xd0, 0xce, 0x91, 0x9b, - 0x77, 0x9c, 0xfa, 0x5f, 0xb8, 0x1e, 0xba, 0xb9, 0xc9, 0x13, 0x25, 0x5b, 0xe3, 0xf3, 0x9d, 0x51, - 0xbb, 0x96, 0x1d, 0x4e, 0x6e, 0x37, 0xeb, 0x6f, 0x62, 0x27, 0xcd, 0xdc, 0xac, 0x86, 0xac, 0x71, - 0x2d, 0x3d, 0x8d, 0x7a, 0xb9, 0xd2, 0xd3, 0x26, 0x8c, 0x82, 0x71, 0x5f, 0xd0, 0x43, 0xd2, 0xab, - 0x35, 0xee, 0x3f, 0xe7, 0x9a, 0x98, 0xa3, 0x89, 0xc2, 0x7e, 0x92, 0x5e, 0xb5, 0x3e, 0x9e, 0x40, - 0x97, 0x97, 0xba, 0x4e, 0x0f, 0x3b, 0x7e, 0x34, 0xb0, 0x61, 0xe3, 0xb5, 0x3b, 0x3e, 0x25, 0xe8, - 0xee, 0x44, 0x20, 0xb7, 0x5b, 0x3c, 0x49, 0x03, 0x83, 0xae, 0x89, 0x2b, 0xc4, 0xeb, 0x51, 0x39, - 0xe6, 0x94, 0x62, 0x13, 0x43, 0xa0, 0xab, 0x13, 0xf9, 0xa5, 0xb4, 0x18, 0xd2, 0xd2, 0xf7, 0xf1, - 0x3a, 0x63, 0x81, 0x02, 0xff, 0x69, 0xe0, 0x03, 0xf0, 0x1d, 0xb8, 0xa5, 0xc0, 0xd5, 0x4c, 0x5a, - 0x60, 0xf9, 0xf5, 0xbf, 0xde, 0x34, 0xe7, 0x89, 0x04, 0x7f, 0x01, 0xa3, 0xad, 0xa6, 0xcf, 0x1b, - 0x71, 0x54, 0x71, 0x4f, 0x2b, 0xbc, 0x2f, 0x06, 0xbf, 0x96, 0x5f, 0x64, 0x36, 0xf4, 0x5a, 0xc4, - 0x79, 0xdb, 0xbb, 0x66, 0xcb, 0x1b, 0xf1, 0x9f, 0x0b, 0x3c, 0x25, 0xb5, 0x6c, 0x72, 0xfa, 0xe7, - 0x48, 0x1b, 0xdb, 0x42, 0xe2, 0xad, 0xa3, 0x79, 0xb0, 0xd7, 0x39, 0xad, 0x25, 0xb3, 0x6f, 0xbe, - 0xcf, 0xd9, 0x12, 0x1e, 0xbb, 0xf6, 0xa5, 0xdb, 0xc1, 0x1c, 0x67, 0xdb, 0xe6, 0xf8, 0x3c, 0x36, - 0xec, 0x67, 0xa8, 0x57, 0x92, 0x6e, 0x77, 0x97, 0x74, 0x0a, 0xfe, 0xe2, 0xbc, 0x2c, 0xa6, 0xc7, - 0x47, 0x5b, 0x2e, 0xbf, 0x96, 0x50, 0x0a, 0x9d, 0x02, 0x8c, 0x61, 0xfc, 0x5c, 0x42, 0x95, 0xee, - 0x65, 0x1c, 0x0f, 0xbe, 0x35, 0x45, 0x75, 0x5c, 0x6d, 0xb9, 0x8a, 0x46, 0x7c, 0x9f, 0x0d, 0xe2, - 0xba, 0x6b, 0xfe, 0x18, 0x56, 0x06, 0xc6, 0xfb, 0x6a, 0xc6, 0x02, 0x86, 0x18, 0x35, 0xbf, 0xdf, - 0xc5, 0x6a, 0x75, 0x79, 0x17, 0xf8, 0xd8, 0xe9, 0x16, 0xc0, 0x6f, 0x72, 0xb2, 0xd8, 0xa8, 0xa6, - 0x55, 0x1a, 0xdf, 0x1d, 0x2e, 0x56, 0xcb, 0x5b, 0xbd, 0x05, 0xcf, 0x13, 0xc2, 0x8d, 0xce, 0x28, - 0xf6, 0x2d, 0xb3, 0x35, 0x1a, 0xf1, 0xbd, 0x1a, 0xf8, 0xe6, 0xff, 0x40, 0xde, 0x03, 0x8c, 0xfc, - 0x45, 0x48, 0xf7, 0x62, 0xa3, 0x9c, 0x66, 0xc7, 0x57, 0x1b, 0x12, 0xbf, 0xd4, 0xde, 0x6c, 0xb6, - 0xda, 0x88, 0xc3, 0xaf, 0xc0, 0x48, 0xc7, 0x63, 0x3a, 0x04, 0x8a, 0x22, 0x7c, 0xd5, 0xfc, 0x2f, - 0x16, 0x5c, 0x30, 0xae, 0x8a, 0x4a, 0x58, 0x75, 0x22, 0xcf, 0x23, 0x41, 0xae, 0xfa, 0x37, 0x18, - 0x0e, 0xaf, 0x06, 0x4e, 0x4f, 0x95, 0x2c, 0xd2, 0xa8, 0xf9, 0x95, 0x25, 0xf3, 0x8d, 0xa3, 0x1f, - 0xbf, 0xae, 0x1f, 0x40, 0xee, 0xaa, 0xcb, 0x81, 0x52, 0xe7, 0x28, 0xfd, 0xc0, 0xe8, 0x08, 0x8c, - 0xff, 0xa2, 0xd6, 0xc5, 0x84, 0x0a, 0xfc, 0xa7, 0x83, 0xac, 0x3b, 0x5f, 0xaa, 0x69, 0xe5, 0x25, - 0xcf, 0x52, 0xe0, 0xe9, 0xbd, 0xb0, 0x5e, 0x4d, 0xc6, 0x6b, 0xa3, 0xf7, 0x84, 0x2f, 0xf5, 0xd3, - 0x56, 0x0b, 0xaa, 0x79, 0x7f, 0xa7, 0x5e, 0xa8, 0x15, 0x88, 0x64, 0x88, 0x9f, 0x08, 0x74, 0xe3, - 0x8c, 0x74, 0x34, 0x37, 0x23, 0x37, 0x1c, 0xa3, 0xce, 0xbb, 0xff, 0x34, 0x6f, 0xc6, 0xb3, 0xe0, - 0xee, 0xdc, 0x80, 0x1c, 0x03, 0x31, 0x7a, 0xfd, 0x2d, 0x07, 0x7e, 0xb9, 0x9c, 0xe3, 0x9d, 0x56, - 0x13, 0xa3, 0xf5, 0x93, 0xce, 0xdb, 0x3d, 0x15, 0xef, 0xf2, 0x95, 0x02, 0xef, 0x15, 0x3e, 0x02, - 0x5e, 0x87, 0x93, 0xd7, 0xa7, 0xd3, 0x0f, 0x9f, 0x44, 0x2d, 0x9d, 0x1b, 0x7a, 0x3a, 0x86, 0xa0, - 0xcf, 0x7e, 0x31, 0xe1, 0xa4, 0x2b, 0xee, 0xf1, 0x91, 0xf0, 0x3f, 0x02, 0xbf, 0xb5, 0x2b, 0x4e, - 0xd2, 0xa4, 0x95, 0x1a, 0x4f, 0x07, 0x75, 0x35, 0xe7, 0xee, 0x88, 0x4e, 0x87, 0xf3, 0x04, 0xb0, - 0x37, 0x48, 0x72, 0x14, 0xb9, 0xf4, 0x4f, 0x1f, 0x53, 0x94, 0xbc, 0x7a, 0x83, 0x84, 0x67, 0x3a, - 0x2a, 0xff, 0x44, 0x4c, 0x7c, 0xca, 0x87, 0xa0, 0x99, 0x40, 0x3f, 0x93, 0x27, 0x7d, 0xb9, 0x34, - 0xdb, 0x6d, 0x8d, 0x93, 0x8a, 0x69, 0x46, 0x20, 0x97, 0xbe, 0xbe, 0x3b, 0x41, 0x48, 0x1b, 0x9b, - 0xc9, 0x97, 0xc4, 0x90, 0x49, 0x87, 0x44, 0xfe, 0x0d, 0x61, 0xc9, 0xf5, 0x65, 0x8c, 0x5a, 0x16, - 0xe4, 0x15, 0x27, 0x5e, 0x5f, 0xc5, 0x75, 0xa0, 0x0f, 0x84, 0xa4, 0xff, 0x86, 0x2e, 0xec, 0xe6, - 0x90, 0x40, 0x05, 0xb6, 0x85, 0x99, 0xab, 0xf2, 0x67, 0x8c, 0x4b, 0x40, 0xb2, 0x9d, 0xca, 0x6b, - 0xd2, 0xf4, 0xf8, 0xe9, 0x5c, 0xf0, 0x76, 0xb0, 0x01, 0x68, 0x69, 0x10, 0x92, 0x2e, 0x62, 0xa1, - 0xf9, 0x17, 0x8d, 0x7e, 0x81, 0x9e, 0xeb, 0x47, 0xb2, 0x71, 0x18, 0xd7, 0x82, 0xe5, 0x40, 0x7c, - 0x48, 0xda, 0xa1, 0x7c, 0x03, 0x76, 0x03, 0x2d, 0x3b, 0xb5, 0xec, 0x3d, 0x02, 0xf4, 0x1f, 0x90, - 0x96, 0xa5, 0xda, 0x6e, 0xcd, 0x04, 0x7a, 0xb5, 0xe6, 0x6d, 0x54, 0x7a, 0xb1, 0xe9, 0x3f, 0xa0, - 0x2f, 0x19, 0x5b, 0x4b, 0x5c, 0xc0, 0x1c, 0xb0, 0x09, 0xb4, 0x92, 0x34, 0x8f, 0x74, 0x4e, 0xd8, - 0xd1, 0xda, 0x6e, 0x33, 0xb2, 0x51, 0xe4, 0x36, 0xb0, 0x15, 0xf8, 0x25, 0x02, 0x62, 0x29, 0xfa, - 0x0d, 0xef, 0xd5, 0x20, 0x39, 0xe0, 0xc9, 0x28, 0x33, 0x7c, 0x2a, 0x8a, 0xea, 0x38, 0x78, 0x11, - 0xd0, 0x1e, 0xd2, 0x6f, 0xff, 0x10, 0xeb, 0xe8, 0x1c, 0x9a, 0xef, 0xc1, 0x4b, 0x60, 0x1e, 0x88, - 0x7a, 0x4c, 0xf3, 0xba, 0xbf, 0xa0, 0xe0, 0x30, 0x29, 0xcd, 0x4c, 0x46, 0xa7, 0xe7, 0x59, 0xd0, - 0xb3, 0xad, 0x53, 0x31, 0x3d, 0xf3, 0xc9, 0x73, 0xcf, 0xf3, 0xdb, 0x0f, 0xff, 0xff, 0xa6, 0xff, - 0x00, 0x60, 0x58, 0x79, 0x12, 0xc5, 0x84, 0x2f, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCircleDownArrowIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x45, 0x08, 0x06, 0x00, 0x00, 0x00, 0x1c, 0x8d, 0x2b, - 0x29, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x00, 0x7a, 0x1f, 0x21, 0x4c, 0x00, 0x00, - 0x08, 0x52, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, 0x9b, 0x79, 0xa8, 0x55, 0x55, 0x14, 0xc6, - 0x7d, 0x6a, 0x5a, 0x62, 0xe5, 0xac, 0x95, 0x60, 0x65, 0x96, 0x59, 0x96, 0x69, 0xda, 0x68, 0x96, - 0x46, 0x36, 0xa1, 0x26, 0x92, 0xd1, 0x3f, 0x15, 0x41, 0xa2, 0x66, 0x11, 0x12, 0x25, 0x28, 0x99, - 0x95, 0x15, 0x44, 0x54, 0x52, 0x50, 0x34, 0x10, 0x1a, 0x0d, 0xfa, 0x87, 0x65, 0xa5, 0x26, 0xa4, - 0xbe, 0x22, 0xad, 0x88, 0xca, 0x92, 0xb4, 0x14, 0x9b, 0x54, 0x34, 0x4d, 0x71, 0x2e, 0xa7, 0x7e, - 0xdf, 0xeb, 0xee, 0xcb, 0x79, 0xe7, 0xae, 0x7d, 0xcf, 0xf8, 0xee, 0xf3, 0x8a, 0x0b, 0x3e, 0xf7, - 0x39, 0x6b, 0xaf, 0xf5, 0xad, 0xb5, 0xd7, 0x3b, 0xc3, 0x3e, 0x7b, 0x5f, 0x9b, 0x34, 0x69, 0x64, - 0x39, 0x7c, 0xf8, 0x70, 0x4b, 0xd0, 0x15, 0xb4, 0x6e, 0xe4, 0x54, 0x8a, 0xe1, 0x6b, 0x8a, 0x47, - 0x0d, 0x78, 0xa0, 0x81, 0x43, 0x3f, 0x04, 0x5c, 0x0a, 0x4e, 0x05, 0xa7, 0x15, 0x5a, 0x1d, 0xb7, - 0x07, 0x2e, 0x8f, 0x1d, 0x1c, 0x6f, 0x28, 0x60, 0x7d, 0xa1, 0xfd, 0x91, 0xf6, 0xa3, 0x9a, 0x9a, - 0x9a, 0x6d, 0xb4, 0xd5, 0x2d, 0x14, 0xe2, 0x24, 0x70, 0x1b, 0x78, 0x17, 0xec, 0x00, 0x59, 0x64, - 0x3f, 0xce, 0x8b, 0xc0, 0x78, 0xd0, 0xb5, 0xea, 0x2a, 0x43, 0xd2, 0xc3, 0xc0, 0x7c, 0xf0, 0x0f, - 0x68, 0x08, 0x39, 0x04, 0xe9, 0x57, 0xe0, 0x5e, 0xd0, 0xe2, 0x88, 0x2e, 0x10, 0x09, 0x0e, 0x00, - 0x4b, 0x41, 0x25, 0x65, 0x2d, 0xc1, 0x46, 0x03, 0x77, 0xfb, 0x1d, 0x19, 0x35, 0x22, 0xa1, 0xee, - 0x40, 0xb7, 0x48, 0x63, 0x8a, 0xae, 0x9c, 0x41, 0x79, 0x55, 0x24, 0x75, 0x85, 0x49, 0x42, 0x97, - 0xee, 0x74, 0x30, 0x01, 0xc4, 0xbd, 0x8c, 0x0f, 0x61, 0xbb, 0x06, 0x6c, 0x04, 0x1b, 0x02, 0xed, - 0x5f, 0x1c, 0x9f, 0x0c, 0xf4, 0xe0, 0x15, 0x4e, 0x29, 0xb4, 0x67, 0xd2, 0x9e, 0x00, 0xe2, 0xca, - 0x87, 0x18, 0xde, 0xc3, 0x43, 0x59, 0xfc, 0x95, 0x15, 0x0a, 0xd2, 0x11, 0xd4, 0x82, 0x38, 0xb2, - 0x1b, 0xa3, 0xb9, 0xe0, 0x2e, 0xd0, 0x21, 0x49, 0xa6, 0xd8, 0xb7, 0x02, 0xc3, 0xc1, 0xeb, 0x60, - 0x33, 0x88, 0x23, 0x7f, 0x62, 0xd4, 0x2f, 0x49, 0x9c, 0xcc, 0xb6, 0x04, 0xec, 0x0d, 0xd6, 0x81, - 0x28, 0xf9, 0x18, 0x03, 0x3d, 0x74, 0x93, 0xfc, 0xa5, 0xbd, 0xf9, 0xc1, 0xd3, 0x14, 0x5c, 0x09, - 0x5e, 0x01, 0x7a, 0x1b, 0x95, 0x93, 0x3d, 0x74, 0x8e, 0xf6, 0x92, 0xe5, 0xd9, 0x41, 0x20, 0x0d, - 0x72, 0x67, 0xb9, 0x6c, 0xe8, 0xfb, 0x1a, 0x5c, 0x93, 0x67, 0xdc, 0x30, 0x17, 0xfc, 0x67, 0x83, - 0x39, 0x20, 0x4a, 0xa6, 0x61, 0x90, 0xfa, 0x11, 0x11, 0x8e, 0x5b, 0x72, 0x0e, 0xf9, 0xfd, 0xe0, - 0x60, 0x99, 0x2c, 0xd6, 0xd0, 0x57, 0xd1, 0x37, 0x01, 0xf1, 0x2e, 0x01, 0x51, 0x6f, 0xbc, 0xd9, - 0xd8, 0x34, 0x2f, 0x19, 0x50, 0x56, 0x05, 0xa4, 0x23, 0x81, 0xe6, 0x07, 0x3e, 0x99, 0x45, 0xc7, - 0xf1, 0x59, 0xe3, 0xa4, 0xf5, 0x27, 0xf6, 0x44, 0x50, 0xee, 0x0f, 0x36, 0x23, 0x2d, 0xb7, 0xe9, - 0x47, 0xb0, 0x0b, 0xc1, 0x2e, 0x60, 0x89, 0x0a, 0x35, 0xc9, 0x74, 0xac, 0xb0, 0x92, 0x3c, 0x6e, - 0x00, 0xdb, 0xad, 0x24, 0x0b, 0xba, 0x31, 0xb9, 0xa4, 0x04, 0x59, 0x27, 0xf0, 0x9b, 0x27, 0x90, - 0x9e, 0x2d, 0xc3, 0x73, 0x09, 0x94, 0x13, 0x09, 0xf9, 0xf4, 0x04, 0x3f, 0x7b, 0xf2, 0xfd, 0x17, - 0xfd, 0xd5, 0x99, 0x42, 0x41, 0xd0, 0x02, 0x7c, 0xee, 0x09, 0xa0, 0x6f, 0x99, 0x3e, 0x99, 0x02, - 0x34, 0x90, 0x33, 0x79, 0xb5, 0x05, 0xdf, 0x79, 0xf2, 0xde, 0x82, 0x5e, 0x73, 0x9f, 0x74, 0x82, - 0xf3, 0x0c, 0x0f, 0xb1, 0xee, 0xdd, 0x9b, 0xd3, 0xb1, 0x56, 0xc6, 0x8b, 0xfc, 0xba, 0x81, 0x4d, - 0xc0, 0x92, 0x1f, 0x50, 0x26, 0x7f, 0xf0, 0xe2, 0xd4, 0x0b, 0x1c, 0xb0, 0x18, 0xd1, 0x3d, 0x5c, - 0x99, 0xa1, 0x65, 0x8b, 0x42, 0x9e, 0x9a, 0xd3, 0xf8, 0x3e, 0x4a, 0xc7, 0x27, 0x66, 0x87, 0xec, - 0x03, 0x60, 0xc9, 0x5b, 0x89, 0xc9, 0xca, 0x38, 0x10, 0xa0, 0x39, 0xb8, 0x13, 0x2c, 0x04, 0x53, - 0x40, 0xa7, 0x32, 0xe6, 0x89, 0xbb, 0xe0, 0xbb, 0x1b, 0x58, 0xa2, 0xd9, 0xf1, 0x89, 0xb1, 0x09, - 0x31, 0xbe, 0xca, 0x62, 0x41, 0xb7, 0x0a, 0xe4, 0xfa, 0xda, 0x85, 0x4f, 0xeb, 0x2d, 0x41, 0x79, - 0x33, 0x76, 0xa2, 0x31, 0x0d, 0x21, 0x7f, 0x2d, 0x18, 0x20, 0x70, 0xfc, 0x78, 0x2c, 0x0a, 0x1c, - 0x6a, 0xc0, 0x97, 0x01, 0xc7, 0xe0, 0xe1, 0xc8, 0x58, 0x24, 0x09, 0x8c, 0x20, 0xff, 0x28, 0x18, - 0x80, 0x63, 0x4d, 0xcf, 0xb5, 0x4a, 0x97, 0x9b, 0xc0, 0xd7, 0x05, 0x58, 0x53, 0x0a, 0x7d, 0x93, - 0xe9, 0xe3, 0xb3, 0xbc, 0x60, 0x74, 0x2b, 0xb0, 0x64, 0x59, 0x79, 0xcf, 0x74, 0xbd, 0x04, 0x5a, - 0x66, 0x04, 0x3b, 0x29, 0x1d, 0x9b, 0xdf, 0x8b, 0x18, 0x9a, 0xee, 0x5b, 0xf2, 0xaa, 0xdf, 0xab, - 0xd0, 0x83, 0xd7, 0x17, 0x96, 0x27, 0xba, 0xab, 0x22, 0x9d, 0x53, 0x18, 0xc0, 0x5b, 0xa9, 0xa2, - 0x9c, 0x48, 0x2c, 0xeb, 0x2b, 0x5b, 0x1f, 0x96, 0x6d, 0xc3, 0xa9, 0x37, 0x75, 0x0a, 0x3a, 0xbb, - 0x70, 0xac, 0x85, 0xe5, 0xb0, 0x68, 0xd1, 0xb8, 0x36, 0xac, 0xac, 0xa6, 0x73, 0xf2, 0xdf, 0x49, - 0xbe, 0xd3, 0x8c, 0x9c, 0xf5, 0x6a, 0x2e, 0x99, 0x5e, 0x14, 0x8b, 0x42, 0xa7, 0x66, 0xa7, 0xd6, - 0x17, 0xe5, 0xf3, 0x06, 0x59, 0x35, 0xaa, 0x74, 0xab, 0xec, 0x36, 0x12, 0x1f, 0x11, 0xd6, 0x05, - 0x8b, 0x52, 0xd2, 0x89, 0xb1, 0xb6, 0x1c, 0x96, 0x84, 0x9d, 0xaa, 0xf1, 0x9c, 0xab, 0x65, 0x1f, - 0x79, 0x2f, 0x34, 0x72, 0xbf, 0x9e, 0xbb, 0xa4, 0xde, 0x9a, 0x4f, 0x5d, 0x51, 0x50, 0xea, 0xe1, - 0x36, 0xd8, 0x70, 0x98, 0x0f, 0xd9, 0x7e, 0x43, 0x5f, 0xad, 0xaa, 0xf7, 0x8d, 0xc4, 0x5b, 0xa1, - 0xbb, 0x2e, 0xa8, 0x77, 0x57, 0xca, 0x8d, 0x28, 0xad, 0x75, 0x56, 0x8b, 0x24, 0xe8, 0x5f, 0x6d, - 0xc7, 0x5a, 0xc3, 0x3d, 0x68, 0x24, 0x5d, 0xef, 0x2e, 0x71, 0x45, 0xb1, 0xde, 0x2e, 0x07, 0x70, - 0x9e, 0x6f, 0x10, 0x54, 0xad, 0x8a, 0xab, 0xfe, 0x6f, 0x92, 0xff, 0xcc, 0x18, 0x40, 0xbd, 0xf1, - 0xbb, 0xa2, 0x68, 0x1b, 0x33, 0x2c, 0x2b, 0x20, 0xd9, 0x1e, 0x56, 0x1e, 0x05, 0xe7, 0xb5, 0xc6, - 0x18, 0xea, 0x8d, 0xbf, 0x5c, 0x51, 0xb4, 0x05, 0x71, 0x34, 0x8a, 0xf6, 0xa8, 0xc3, 0xa2, 0x4d, - 0x7e, 0xed, 0x69, 0xd7, 0x89, 0x2b, 0x8a, 0x35, 0xdd, 0x3d, 0x5a, 0x8b, 0xe2, 0x1b, 0x57, 0xb1, - 0x06, 0xda, 0x36, 0x68, 0x46, 0x79, 0xac, 0xaf, 0xd3, 0xca, 0x6f, 0x28, 0x15, 0xfe, 0x52, 0x0d, - 0xdc, 0x44, 0x17, 0x85, 0x04, 0x3a, 0x03, 0x15, 0x26, 0x2c, 0x3e, 0xe7, 0xb0, 0x5d, 0xb5, 0x9d, - 0x5b, 0xb7, 0x8f, 0xc6, 0x50, 0x7c, 0xae, 0xe8, 0xf6, 0xd1, 0x16, 0xa5, 0x25, 0x9b, 0x2c, 0xe5, - 0x51, 0xa0, 0xd3, 0x16, 0xad, 0xb6, 0x6f, 0xc3, 0xa2, 0xcf, 0x9c, 0x3a, 0x51, 0x51, 0x76, 0x15, - 0x8e, 0xc3, 0x4d, 0xea, 0x5f, 0x16, 0x71, 0x4b, 0x9e, 0x0c, 0x6e, 0x07, 0xbd, 0xc3, 0xa4, 0x59, - 0xce, 0xe1, 0xd3, 0xa2, 0xd4, 0xcd, 0xa0, 0x7b, 0x06, 0x1e, 0xcd, 0x5e, 0xdd, 0xb3, 0x34, 0x48, - 0x53, 0xac, 0x83, 0x3a, 0x7d, 0x97, 0x93, 0xef, 0x0a, 0x0a, 0x12, 0x95, 0x1c, 0x93, 0xf0, 0x65, - 0x28, 0x75, 0xeb, 0x69, 0x95, 0x4e, 0x0b, 0xc8, 0x0f, 0x94, 0x18, 0xa5, 0x50, 0xc0, 0xa3, 0x8f, - 0xd5, 0x5f, 0xc1, 0x3c, 0xf0, 0x0b, 0xe7, 0x93, 0x69, 0xd3, 0x88, 0x6f, 0x5c, 0xc5, 0xc7, 0x45, - 0x53, 0xe6, 0x22, 0xaa, 0x90, 0xbe, 0x22, 0xc3, 0x52, 0x7c, 0x1a, 0x87, 0x3b, 0x22, 0xce, 0xc7, - 0xd1, 0xaf, 0xa9, 0xb3, 0x44, 0x45, 0x7f, 0x96, 0x01, 0x4c, 0xac, 0x3b, 0x2b, 0xfd, 0xc7, 0xba, - 0x8c, 0x4b, 0x74, 0xf8, 0xf7, 0xc7, 0x75, 0x01, 0x70, 0xf7, 0xbd, 0x3e, 0x5c, 0xb5, 0x63, 0xd9, - 0xa2, 0x94, 0x32, 0x52, 0x13, 0x5d, 0x94, 0x02, 0x45, 0xb1, 0x4a, 0x01, 0x4a, 0x9f, 0x73, 0xc0, - 0xc4, 0x3c, 0xdc, 0x6a, 0x68, 0x9f, 0xf1, 0x14, 0x66, 0xaf, 0x61, 0x5b, 0x4f, 0x87, 0x5f, 0x3f, - 0x6c, 0x3e, 0x01, 0xfa, 0xa9, 0x46, 0x50, 0xf4, 0x87, 0xdc, 0x1f, 0x54, 0xc4, 0x3c, 0xf6, 0x8d, - 0xab, 0x78, 0xc7, 0xb8, 0x7b, 0xab, 0xa8, 0x08, 0x10, 0xfb, 0x9c, 0x03, 0x26, 0xe6, 0xe1, 0xcb, - 0x68, 0xf7, 0x18, 0x3d, 0x56, 0x61, 0xc2, 0x76, 0xfb, 0xb9, 0x72, 0x8b, 0xdf, 0x26, 0x14, 0xa4, - 0x0f, 0x3c, 0x2a, 0x48, 0x1b, 0x83, 0xef, 0x39, 0x6c, 0x0f, 0x1b, 0xfa, 0x28, 0x95, 0x35, 0x2e, - 0xf1, 0xd4, 0x9f, 0x82, 0x10, 0x7c, 0x26, 0x08, 0xcb, 0x46, 0x14, 0xd6, 0xfa, 0x4a, 0x54, 0xd0, - 0x26, 0xf8, 0x0d, 0x06, 0x5a, 0x03, 0xb5, 0x64, 0xac, 0x23, 0xa0, 0xf3, 0x9d, 0x90, 0x41, 0xf1, - 0xb3, 0x02, 0x7d, 0x0f, 0xa0, 0xcd, 0x2b, 0x4b, 0x9e, 0x74, 0x1c, 0x49, 0x5b, 0xc8, 0x5e, 0x32, - 0x08, 0xf5, 0x46, 0xaa, 0x2f, 0x18, 0x4d, 0x36, 0x0c, 0xa5, 0xd2, 0xbd, 0x9c, 0x4a, 0xf0, 0xbd, - 0x06, 0x58, 0x85, 0xd1, 0x12, 0xe0, 0xb5, 0x22, 0xa5, 0x7d, 0x03, 0x04, 0xa5, 0xee, 0x36, 0x46, - 0xd1, 0x06, 0x68, 0xf7, 0xc0, 0x92, 0xe9, 0xa9, 0x12, 0x2a, 0x38, 0x41, 0xf8, 0xbb, 0x41, 0x5a, - 0xfa, 0x91, 0x88, 0xd1, 0x05, 0x86, 0xa1, 0x54, 0x8f, 0x65, 0x4c, 0xc0, 0x57, 0x98, 0x6d, 0x70, - 0xeb, 0x37, 0x26, 0x2f, 0x2a, 0x48, 0x40, 0xd6, 0x72, 0xac, 0xd7, 0xee, 0xa2, 0x80, 0x2e, 0x78, - 0xf8, 0x44, 0xc6, 0x7c, 0xfa, 0x06, 0xc9, 0x02, 0xc7, 0x0f, 0x9a, 0xbc, 0x18, 0x28, 0xa1, 0xb0, - 0xac, 0x30, 0x8d, 0x13, 0x28, 0x21, 0xbc, 0x1a, 0x58, 0x57, 0xcc, 0x6a, 0xf4, 0xaf, 0x86, 0x02, - 0x6a, 0x4b, 0x33, 0x5c, 0x28, 0x67, 0x92, 0xa9, 0x20, 0x4a, 0x19, 0xa2, 0xa9, 0x8e, 0x2c, 0xd4, - 0xf6, 0x30, 0x87, 0x84, 0x91, 0x1e, 0x84, 0x96, 0x9c, 0x61, 0x3a, 0x24, 0x50, 0x42, 0x3a, 0x08, - 0x58, 0x7b, 0x2f, 0x07, 0x42, 0x01, 0xf5, 0xcb, 0x00, 0x4b, 0xe2, 0x6d, 0x5c, 0x45, 0xe4, 0x04, - 0xf1, 0xb7, 0x06, 0xf9, 0x4a, 0xaf, 0x1b, 0xc6, 0x57, 0x1a, 0x0e, 0x52, 0x4d, 0xf2, 0x3a, 0x25, - 0xe8, 0x80, 0x67, 0x10, 0xb0, 0x0a, 0x83, 0xba, 0xac, 0x64, 0xba, 0x85, 0x5d, 0x8a, 0x44, 0xd0, - 0xcf, 0x34, 0x2c, 0xf1, 0x17, 0x1c, 0x6b, 0x7d, 0x31, 0x5b, 0x3b, 0xf5, 0x5b, 0xd1, 0x5b, 0xaf, - 0x44, 0x17, 0x2f, 0x76, 0x0b, 0x8f, 0xb6, 0x64, 0x93, 0x14, 0x26, 0x97, 0x82, 0x28, 0x41, 0xe2, - 0xce, 0x01, 0x96, 0x5c, 0x5c, 0x76, 0x00, 0x78, 0xbc, 0x60, 0x79, 0xa1, 0x7b, 0xaa, 0xac, 0x63, - 0x82, 0x4e, 0xb8, 0xe2, 0x16, 0x66, 0x5a, 0x02, 0xda, 0xb2, 0xa6, 0xc4, 0xd4, 0x6f, 0xe3, 0x2c, - 0x59, 0x5d, 0xd6, 0x51, 0x9d, 0x78, 0x69, 0xdf, 0x55, 0xbf, 0x50, 0x0a, 0x8b, 0xf6, 0x78, 0xdd, - 0x14, 0x3b, 0x92, 0x27, 0xca, 0x00, 0xae, 0x81, 0xc0, 0x8a, 0xe3, 0xe2, 0x3e, 0x1a, 0xc5, 0x91, - 0xa4, 0x1f, 0xd2, 0x25, 0x8e, 0x38, 0xd4, 0x8e, 0x8a, 0xc5, 0x83, 0xd3, 0x23, 0x21, 0x47, 0x77, - 0x1a, 0xbd, 0xef, 0x1a, 0x2b, 0xc2, 0xff, 0x46, 0x90, 0xfa, 0x0a, 0x33, 0x35, 0x01, 0x4d, 0xa4, - 0x29, 0x71, 0x6e, 0x72, 0x03, 0x08, 0xb5, 0xcb, 0x23, 0x9d, 0x9d, 0x01, 0x8e, 0xad, 0x81, 0x66, - 0xb3, 0x61, 0x39, 0x88, 0x62, 0xa8, 0xb3, 0xcb, 0xa3, 0x85, 0xef, 0x0a, 0xe0, 0x9e, 0x63, 0xe2, - 0x7f, 0x28, 0x0f, 0x5e, 0xc7, 0x01, 0x5f, 0x07, 0xb0, 0x0e, 0x58, 0x32, 0xd0, 0xd9, 0xc5, 0x6a, - 0x61, 0x18, 0x63, 0xb1, 0xa0, 0xd3, 0xa4, 0xeb, 0x9c, 0x58, 0x24, 0x31, 0x8d, 0xe0, 0x53, 0xe2, - 0xa3, 0xc0, 0xb9, 0x31, 0x5d, 0x62, 0x99, 0xc1, 0x77, 0x1c, 0x58, 0x0a, 0x2c, 0x49, 0xbe, 0x9f, - 0x05, 0x8b, 0x66, 0x95, 0x3f, 0x59, 0x6c, 0xe8, 0x34, 0xe9, 0xca, 0xe5, 0x6d, 0x14, 0x6b, 0x74, - 0x29, 0x8d, 0xc8, 0xf1, 0x15, 0x4f, 0xfe, 0x9a, 0x1b, 0xf5, 0x4c, 0x45, 0x8b, 0xe3, 0x00, 0xb0, - 0xd7, 0x43, 0xbc, 0x00, 0x7d, 0xb3, 0x54, 0xc4, 0x15, 0x70, 0x22, 0xb7, 0x09, 0x9e, 0xbc, 0xa5, - 0xce, 0x76, 0x8b, 0x42, 0xa0, 0x25, 0x45, 0x9f, 0xbc, 0x47, 0x87, 0x96, 0xf6, 0x8e, 0x28, 0x21, - 0xa7, 0xb1, 0x20, 0x3c, 0x53, 0x76, 0x63, 0x98, 0x99, 0x4b, 0xb2, 0xb0, 0x4d, 0x77, 0x8c, 0x46, - 0xfb, 0x0d, 0xba, 0xae, 0xb9, 0x04, 0xca, 0x48, 0x42, 0x1e, 0xba, 0xe5, 0xad, 0x65, 0x01, 0x97, - 0xf6, 0x72, 0x0e, 0x5a, 0x66, 0x0c, 0xf3, 0xbf, 0x3b, 0x44, 0xfa, 0x1d, 0xdc, 0x5c, 0xc7, 0x6c, - 0xb4, 0x7a, 0x53, 0x69, 0xfd, 0xb4, 0xd1, 0x84, 0xf8, 0xed, 0xc1, 0x62, 0xe0, 0x93, 0x3f, 0xe8, - 0x28, 0xae, 0xd6, 0xe7, 0x92, 0x28, 0x84, 0x7a, 0x4d, 0x7f, 0xef, 0x8b, 0x88, 0x7e, 0x1f, 0xd0, - 0x9a, 0xe9, 0x71, 0xb9, 0x04, 0x4c, 0x40, 0x42, 0xcc, 0x21, 0x60, 0x2d, 0xf0, 0x89, 0xbe, 0xd0, - 0xfb, 0x26, 0xa0, 0x8c, 0x6f, 0x0a, 0x71, 0x3b, 0xf0, 0xa9, 0x2f, 0x72, 0x41, 0xbf, 0x86, 0x76, - 0x34, 0x48, 0xb5, 0x62, 0x17, 0x3f, 0x9b, 0xba, 0xd9, 0x77, 0x1f, 0xe2, 0xe8, 0x81, 0x5f, 0x4e, - 0xd6, 0xd3, 0x99, 0x7a, 0xa1, 0x2c, 0x56, 0x3e, 0x04, 0x88, 0xba, 0x6f, 0x5d, 0x82, 0xfa, 0x8f, - 0x50, 0x83, 0x63, 0x91, 0x26, 0x34, 0x82, 0xf7, 0x74, 0x30, 0x0b, 0x1c, 0x02, 0xe5, 0x44, 0x39, - 0xa4, 0xdd, 0x91, 0x48, 0x98, 0x15, 0xe6, 0x04, 0x1b, 0x07, 0xb4, 0xac, 0x18, 0x25, 0xab, 0x30, - 0x78, 0x1a, 0x5c, 0x0e, 0xdc, 0x22, 0x79, 0xe2, 0x80, 0xf8, 0x9e, 0x05, 0x26, 0x02, 0x4d, 0xc6, - 0x7c, 0x6f, 0x16, 0xba, 0x8a, 0xf2, 0x36, 0x47, 0xa9, 0xdf, 0x8c, 0xa9, 0x2f, 0x73, 0x82, 0xea, - 0x4a, 0x98, 0x0d, 0xda, 0xc5, 0x1c, 0xe5, 0x66, 0xec, 0xe6, 0x81, 0x65, 0x40, 0x6b, 0xb1, 0x1b, - 0x0b, 0xed, 0x16, 0x56, 0xe5, 0xeb, 0xf6, 0x7a, 0xe0, 0x74, 0xff, 0xe3, 0x54, 0x2b, 0xee, 0xfa, - 0x2b, 0x9f, 0x07, 0x86, 0x81, 0x5e, 0x20, 0x8e, 0x68, 0x55, 0x7e, 0x0a, 0x7c, 0x99, 0x57, 0xe9, - 0xe2, 0x04, 0x33, 0x6d, 0x18, 0x44, 0x47, 0xa0, 0xe5, 0x06, 0xdf, 0x8a, 0x19, 0x5d, 0x91, 0xa2, - 0x2b, 0x6e, 0x03, 0xb0, 0x96, 0x2c, 0x23, 0x9d, 0x03, 0x06, 0x8b, 0x38, 0xbe, 0xc8, 0x4c, 0xb4, - 0x31, 0x94, 0x24, 0xa3, 0xcb, 0x5b, 0x93, 0xb9, 0xc6, 0x10, 0xbd, 0x15, 0x87, 0x36, 0xc6, 0xb8, - 0x63, 0xc5, 0x24, 0x39, 0x2d, 0xe6, 0xd4, 0x56, 0xa8, 0x32, 0xda, 0xaa, 0xb8, 0x03, 0xa4, 0x7e, - 0x56, 0xf9, 0x06, 0x95, 0xfa, 0x99, 0xe2, 0x23, 0x94, 0x9e, 0x44, 0xcf, 0xa7, 0xb9, 0x05, 0x8c, - 0x00, 0x79, 0xce, 0x11, 0xd6, 0xc3, 0x37, 0xb7, 0x80, 0xa5, 0x3c, 0x3b, 0xd2, 0x6c, 0x9b, 0xe2, - 0xde, 0xc8, 0x42, 0x81, 0xba, 0x81, 0xfb, 0xc0, 0x62, 0xe0, 0xfb, 0xc0, 0xa4, 0xcb, 0x14, 0xad, - 0xb1, 0xac, 0x04, 0xfa, 0xd4, 0xe8, 0x0f, 0x1a, 0xe4, 0x8f, 0x18, 0x2e, 0x51, 0x45, 0x82, 0x04, - 0x83, 0x32, 0xb0, 0xf6, 0x9c, 0xeb, 0xcd, 0xe2, 0xa0, 0x65, 0xce, 0xce, 0x60, 0x3b, 0xd0, 0x5b, - 0xc9, 0x41, 0x57, 0xc5, 0x26, 0xae, 0x86, 0xe2, 0xde, 0x32, 0xe7, 0xc7, 0xe4, 0x58, 0x05, 0x8e, - 0xa0, 0x0a, 0xfc, 0x07, 0x9a, 0x90, 0xb7, 0xcb, 0x6c, 0x98, 0xf8, 0x98, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - - -#pragma mark - Content Type Icons - -static const u_int8_t FLEXJSONIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, - 0x32, 0x32, 0x3a, 0x30, 0x32, 0x3a, 0x32, 0x33, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, - 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, - 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, - 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, - 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, - 0x61, 0x3e, 0x0a, 0x03, 0x64, 0xa2, 0xe8, 0x00, 0x00, 0x06, 0x37, 0x49, 0x44, 0x41, 0x54, 0x68, - 0x05, 0xed, 0x59, 0x7b, 0x48, 0x57, 0x57, 0x1c, 0x3f, 0xc7, 0x47, 0x3e, 0xf2, 0x31, 0xc9, 0x50, - 0xdb, 0x56, 0x13, 0x73, 0x59, 0x3e, 0x57, 0x46, 0x66, 0xe2, 0x28, 0x1b, 0x51, 0x6a, 0x2a, 0xb1, - 0xcd, 0x6a, 0x43, 0xaa, 0x8d, 0x06, 0xe5, 0xa0, 0xac, 0x86, 0x8c, 0xcd, 0xbf, 0x4c, 0xb3, 0x65, - 0x81, 0xb4, 0xd2, 0xa6, 0x11, 0xe8, 0x60, 0xb4, 0x2d, 0x96, 0x2e, 0xb6, 0x08, 0x35, 0x62, 0x15, - 0x3e, 0x96, 0xda, 0x16, 0xe1, 0x7c, 0xe2, 0x62, 0x51, 0x12, 0xe5, 0x2f, 0xcd, 0xf7, 0xdd, 0xe7, - 0xfe, 0xce, 0xe5, 0x78, 0xfb, 0xa9, 0xf7, 0xfe, 0x7e, 0xbf, 0x7b, 0xf6, 0x08, 0x7e, 0x87, 0xb8, - 0x7c, 0xcf, 0xf7, 0x7c, 0xce, 0xf7, 0x7d, 0xbe, 0xe7, 0xf4, 0x93, 0x4a, 0x92, 0x44, 0x5e, 0xe4, - 0xe1, 0xf4, 0x22, 0x1b, 0x2f, 0xdb, 0xee, 0x70, 0xe0, 0xbf, 0xce, 0xa0, 0x23, 0x03, 0x8e, 0x0c, - 0x18, 0x8c, 0x80, 0xa3, 0x84, 0x0c, 0x06, 0xd0, 0xf0, 0x76, 0x17, 0xc3, 0x12, 0x14, 0x01, 0xb5, - 0xbf, 0x93, 0xeb, 0x7f, 0x48, 0xa3, 0xe3, 0xf2, 0x34, 0x29, 0x9c, 0xbe, 0xb9, 0xd4, 0x52, 0xf0, - 0xe7, 0xdf, 0x2a, 0x37, 0x66, 0xd0, 0x4b, 0xf4, 0x9d, 0x38, 0x32, 0xcf, 0xcb, 0x12, 0x60, 0xdf, - 0x5c, 0x8c, 0x03, 0x39, 0x55, 0x52, 0x45, 0xfd, 0xd4, 0x8d, 0xee, 0xe5, 0x3e, 0x83, 0x03, 0x25, - 0x3f, 0x73, 0x80, 0xf4, 0xc5, 0x8f, 0xf4, 0xa7, 0x4f, 0x68, 0x68, 0xa0, 0x7d, 0x36, 0x3f, 0xb7, - 0x4b, 0xc0, 0x19, 0x68, 0xe8, 0x24, 0x6a, 0xeb, 0x9f, 0x13, 0x3f, 0xcb, 0xe4, 0xd1, 0x53, 0x29, - 0xf7, 0x1b, 0xee, 0xcf, 0x2c, 0x20, 0xeb, 0xd8, 0x02, 0x32, 0x00, 0x07, 0xf8, 0x28, 0xc8, 0x74, - 0x7a, 0x2b, 0x82, 0xcc, 0xf3, 0xe6, 0x8c, 0x29, 0xe2, 0xd7, 0xc3, 0x4e, 0x4f, 0x86, 0xc8, 0xc7, - 0xe7, 0xa4, 0xdb, 0x7d, 0xb2, 0xe9, 0x0d, 0x1d, 0x53, 0x4b, 0x46, 0x28, 0x01, 0x0e, 0x98, 0x9e, - 0x29, 0xb1, 0xf4, 0xf5, 0xa4, 0x1f, 0x25, 0xcd, 0x6a, 0x4c, 0xf0, 0x7c, 0x79, 0x69, 0x6b, 0x3c, - 0xbd, 0x6d, 0x8e, 0xbd, 0x69, 0x18, 0xbb, 0xe8, 0xac, 0x68, 0xab, 0x17, 0x04, 0x94, 0x10, 0xd7, - 0xe5, 0x31, 0x87, 0x93, 0xb3, 0x12, 0xee, 0xae, 0xb3, 0x2e, 0xd9, 0xb7, 0x20, 0xd2, 0x01, 0xfb, - 0x2c, 0x30, 0xb8, 0xcb, 0xe1, 0x00, 0x21, 0x8f, 0x06, 0x95, 0x20, 0xba, 0x3a, 0xeb, 0x47, 0x53, - 0x8d, 0x79, 0x3c, 0xa4, 0x8f, 0xd7, 0x45, 0x18, 0xcd, 0xc0, 0xfd, 0x27, 0xa4, 0xe6, 0x96, 0xa2, - 0x65, 0x49, 0x90, 0xae, 0x3a, 0xb2, 0x64, 0xc1, 0x14, 0xa6, 0xac, 0x76, 0x8a, 0xb6, 0x9b, 0x32, - 0xe4, 0x40, 0xf1, 0x25, 0xb2, 0xea, 0x33, 0xe9, 0xfe, 0x63, 0xb9, 0x0b, 0x79, 0xcc, 0xa1, 0x39, - 0xc9, 0xfa, 0x5d, 0x25, 0x36, 0x98, 0x6c, 0x8c, 0x56, 0x60, 0x05, 0x3f, 0x4c, 0xae, 0xcb, 0x97, - 0x7a, 0xfb, 0xed, 0x36, 0x5e, 0xde, 0x68, 0xc8, 0x81, 0xe6, 0x6e, 0x69, 0xc0, 0xdc, 0x43, 0xfd, - 0xbd, 0x69, 0xd9, 0x07, 0x34, 0x6e, 0xb1, 0xbe, 0x29, 0x94, 0x92, 0xb2, 0x0f, 0xe9, 0xa6, 0x18, - 0xc5, 0x87, 0x5b, 0x3d, 0xd2, 0xa3, 0xa7, 0xfa, 0xbb, 0x34, 0x10, 0x86, 0x1c, 0x48, 0x8f, 0xa5, - 0xe1, 0xaf, 0xc8, 0xa6, 0xf4, 0x9b, 0xa4, 0xf7, 0xbf, 0x9c, 0xfc, 0xae, 0x41, 0x43, 0x91, 0xb2, - 0x34, 0x3c, 0x46, 0x36, 0x16, 0x4a, 0x97, 0x5a, 0xe4, 0xa4, 0xb9, 0xb9, 0xd2, 0xf7, 0x12, 0xe8, - 0x02, 0x3f, 0xfd, 0x5d, 0x1a, 0x08, 0x43, 0x0e, 0xbc, 0xbd, 0x8a, 0xd4, 0x7e, 0x4a, 0x23, 0x5f, - 0x55, 0xc2, 0x79, 0xa6, 0x4e, 0xb9, 0xd1, 0x34, 0xf4, 0x5d, 0x6f, 0x27, 0xbf, 0xfd, 0xa9, 0xc0, - 0x4a, 0x77, 0xd1, 0x92, 0x2c, 0x1a, 0xe0, 0xab, 0x01, 0xd7, 0x5f, 0x32, 0xe4, 0x00, 0xc4, 0xcf, - 0x71, 0x21, 0x49, 0x11, 0x8a, 0x1a, 0x6b, 0xaa, 0x59, 0x8d, 0xd9, 0x14, 0xa3, 0x6f, 0x9f, 0x2e, - 0xc2, 0xa8, 0x03, 0xb2, 0x0f, 0x56, 0x74, 0xcf, 0x19, 0xed, 0x50, 0xb7, 0xd4, 0x19, 0x01, 0xd6, - 0x30, 0x05, 0x38, 0x60, 0x8d, 0x9a, 0x7f, 0x0e, 0xe3, 0x70, 0x40, 0x15, 0x5b, 0xd3, 0x33, 0x32, - 0xa9, 0x77, 0x8c, 0x85, 0xdc, 0xbe, 0x2a, 0x9d, 0x44, 0xc0, 0x73, 0x7a, 0xbe, 0x0f, 0xba, 0x90, - 0x6c, 0xf8, 0xe0, 0x88, 0x94, 0x7d, 0x8e, 0xac, 0x5b, 0x86, 0xde, 0x4a, 0xc2, 0x54, 0x37, 0x2e, - 0xd3, 0xf7, 0x7d, 0x23, 0x19, 0x78, 0x46, 0xca, 0x6a, 0x15, 0x17, 0xcd, 0xbb, 0xd4, 0x96, 0xd8, - 0x49, 0x0b, 0x70, 0x20, 0x71, 0x29, 0x71, 0x71, 0xa6, 0xe3, 0x13, 0xb2, 0x65, 0x5f, 0xff, 0x22, - 0xe1, 0x5f, 0x6e, 0x9a, 0xd3, 0x74, 0x07, 0x76, 0x95, 0x4d, 0xaa, 0x6d, 0x4c, 0x0a, 0x57, 0xcf, - 0xec, 0xa7, 0x05, 0x9c, 0x81, 0xd7, 0x03, 0x49, 0xd1, 0x56, 0x8a, 0x5b, 0xc9, 0x7a, 0x2b, 0xde, - 0x78, 0x8d, 0x1e, 0x7e, 0xd7, 0x06, 0xbc, 0x86, 0x64, 0x2a, 0xea, 0xe7, 0xf5, 0xbf, 0x1e, 0x93, - 0xe6, 0x6e, 0xc2, 0x7e, 0x95, 0x58, 0xf6, 0xf2, 0x0c, 0x25, 0x74, 0xa1, 0x49, 0x31, 0x03, 0x37, - 0xd7, 0xea, 0xc5, 0x04, 0x6f, 0x0a, 0x21, 0x43, 0x98, 0x03, 0x42, 0xac, 0xb1, 0x43, 0x88, 0x80, - 0x12, 0xb2, 0x43, 0xab, 0xc0, 0x2d, 0x0e, 0x07, 0x04, 0x06, 0xd3, 0x2e, 0x51, 0x8e, 0x0c, 0xd8, - 0x15, 0x36, 0x81, 0x9b, 0x6c, 0xcb, 0xc0, 0x57, 0xe6, 0x21, 0x50, 0xbd, 0x71, 0x51, 0x36, 0xb4, - 0xd1, 0x91, 0x91, 0x11, 0x4f, 0x4f, 0x4f, 0x67, 0x67, 0xe7, 0xa1, 0xa1, 0x21, 0x17, 0x17, 0x01, - 0x57, 0xb8, 0x71, 0xeb, 0x21, 0xc1, 0x36, 0x3b, 0x7c, 0x7d, 0x7d, 0x3d, 0x3c, 0x3c, 0xfe, 0x3f, - 0xd6, 0xc3, 0x01, 0x1b, 0x32, 0x00, 0xf4, 0xe4, 0xa4, 0xfc, 0x9e, 0x71, 0x72, 0xd2, 0x2f, 0x3c, - 0x20, 0xad, 0x81, 0x41, 0x9a, 0xc1, 0xa1, 0x6f, 0xca, 0xb5, 0x6b, 0xd7, 0xd6, 0xae, 0x5d, 0xbb, - 0xca, 0x3c, 0x56, 0x9b, 0xc7, 0xb1, 0x63, 0xc7, 0x2c, 0xb4, 0x56, 0x57, 0x57, 0x67, 0x65, 0x65, - 0x05, 0x04, 0x04, 0xa0, 0xc6, 0x56, 0xae, 0x5c, 0x19, 0x15, 0x15, 0xb5, 0x79, 0xf3, 0x66, 0x35, - 0xe6, 0xde, 0xbd, 0x7b, 0x3b, 0x76, 0xec, 0x08, 0x0b, 0x0b, 0xf3, 0xf2, 0xf2, 0x8a, 0x89, 0x89, - 0x39, 0x74, 0xe8, 0xd0, 0xe0, 0xa0, 0xf2, 0x7b, 0xd8, 0xd9, 0xb3, 0x67, 0xe3, 0xe3, 0xe3, 0xe3, - 0xe2, 0xe2, 0xea, 0xeb, 0xeb, 0x33, 0x33, 0x33, 0xfd, 0xfc, 0xfc, 0x16, 0x2e, 0x5c, 0x58, 0x5a, - 0x5a, 0xaa, 0xde, 0xae, 0x45, 0xe3, 0x2d, 0xa4, 0x3d, 0xf2, 0xf3, 0xf3, 0x2d, 0xf6, 0x6f, 0xdb, - 0xb6, 0x4d, 0xbd, 0xe5, 0xca, 0x95, 0x2b, 0x0c, 0xb0, 0x61, 0xc3, 0x86, 0xf5, 0xeb, 0xd7, 0x53, - 0xf3, 0x2b, 0x07, 0xb6, 0x72, 0x4c, 0x73, 0x73, 0xb3, 0x8f, 0x8f, 0x8f, 0x85, 0x90, 0xe0, 0xe0, - 0xe0, 0xfe, 0xfe, 0x7e, 0x60, 0x52, 0x52, 0x52, 0xd8, 0x12, 0x4c, 0xe7, 0x18, 0x08, 0xb9, 0x73, - 0xe7, 0x0e, 0x97, 0xa0, 0x41, 0x10, 0x8d, 0x35, 0xb6, 0x84, 0x23, 0x7b, 0xf9, 0xf2, 0xe5, 0x0b, - 0xe6, 0xb1, 0x65, 0xcb, 0x16, 0xe8, 0xb0, 0x70, 0xe0, 0xe0, 0xc1, 0x83, 0x60, 0x86, 0x87, 0x87, - 0x33, 0x7c, 0x77, 0x77, 0xf7, 0xce, 0x9d, 0x3b, 0x91, 0x10, 0x36, 0x1d, 0x1b, 0x1b, 0x8b, 0x88, - 0x90, 0xff, 0xdb, 0x1f, 0x14, 0x14, 0x74, 0xf2, 0xe4, 0xc9, 0x8e, 0x8e, 0x8e, 0xbc, 0xbc, 0x3c, - 0x1c, 0x24, 0x2e, 0xe7, 0xc1, 0x83, 0x07, 0xc8, 0x2b, 0xa6, 0xee, 0xee, 0xee, 0xe5, 0xe5, 0xe5, - 0xc8, 0x83, 0xbf, 0xbf, 0x3f, 0xa6, 0x47, 0x8f, 0x1e, 0x65, 0x12, 0xb4, 0xbf, 0xfa, 0x0e, 0xa8, - 0xf7, 0xe7, 0xe6, 0xe6, 0x72, 0xc5, 0x9c, 0x7f, 0xfe, 0xfc, 0x79, 0x30, 0x31, 0x50, 0x39, 0xd9, - 0xd9, 0xd9, 0x15, 0x15, 0x15, 0x5d, 0x5d, 0x5d, 0x7c, 0xb5, 0xad, 0xad, 0x8d, 0xad, 0x16, 0x17, - 0x17, 0x73, 0xe6, 0xf6, 0xed, 0xdb, 0xc1, 0x84, 0xc5, 0xe3, 0xe3, 0xe3, 0x60, 0x66, 0x64, 0x64, - 0x60, 0x9a, 0x9c, 0x9c, 0xcc, 0x00, 0xa9, 0xa9, 0xa9, 0x98, 0xee, 0xdb, 0xb7, 0x8f, 0xe3, 0x35, - 0x08, 0xfd, 0x33, 0xc0, 0xd4, 0x6b, 0x7c, 0xd3, 0xd3, 0xd3, 0x13, 0x12, 0x12, 0x00, 0x80, 0xad, - 0x25, 0x25, 0x25, 0x08, 0x7f, 0x48, 0x48, 0xc8, 0x9e, 0x3d, 0x7b, 0xd8, 0x96, 0xbb, 0x77, 0xef, - 0x32, 0x22, 0x2d, 0x2d, 0x8d, 0x0b, 0x61, 0xf4, 0xf0, 0xf0, 0x70, 0x4f, 0x4f, 0x0f, 0x67, 0xae, - 0x58, 0xb1, 0x82, 0xd1, 0x8b, 0x16, 0x2d, 0x02, 0x81, 0x55, 0xbe, 0xa4, 0x41, 0x08, 0x70, 0x00, - 0x5d, 0x15, 0x35, 0xd6, 0xda, 0xda, 0x8a, 0xa3, 0x99, 0x98, 0x98, 0xe8, 0xea, 0xea, 0x8a, 0x80, - 0x9d, 0x3a, 0x75, 0x0a, 0xb5, 0x04, 0xc5, 0xa8, 0x1c, 0xa6, 0xbe, 0xb1, 0xb1, 0x91, 0xdb, 0xc1, - 0x68, 0x14, 0x7a, 0x60, 0xe0, 0xd4, 0x1f, 0xfa, 0x78, 0xd7, 0x62, 0xa7, 0x88, 0x83, 0xb5, 0x09, - 0x01, 0x0e, 0xa0, 0x36, 0xd0, 0x37, 0x70, 0x54, 0x8e, 0x1c, 0x39, 0x72, 0xf5, 0xea, 0xd5, 0xce, - 0xce, 0x4e, 0xd4, 0x06, 0x7c, 0xa8, 0xab, 0xab, 0x83, 0x6e, 0xd4, 0x95, 0xb7, 0xb7, 0xfc, 0x37, - 0x33, 0x24, 0xa7, 0xaf, 0xaf, 0x0f, 0x44, 0x4b, 0x4b, 0x4b, 0x55, 0x55, 0x15, 0x08, 0xb4, 0xa3, - 0xb9, 0x73, 0xe7, 0x82, 0x00, 0x18, 0x5f, 0xd6, 0xa3, 0x39, 0xc1, 0x98, 0x98, 0xea, 0x0c, 0xe0, - 0xac, 0x1f, 0x33, 0x9e, 0x81, 0xbd, 0x7b, 0xf7, 0x42, 0x87, 0x9b, 0x9b, 0x1b, 0xaa, 0xb6, 0xb2, - 0xb2, 0xf2, 0xc0, 0x81, 0x03, 0x98, 0x22, 0x9c, 0xa8, 0x28, 0x26, 0xf9, 0xf4, 0xe9, 0xd3, 0xcc, - 0x08, 0xe4, 0x2a, 0x3a, 0x3a, 0x9a, 0xd1, 0xb8, 0xd1, 0x6f, 0xdc, 0xb8, 0x01, 0xc0, 0xfe, 0xfd, - 0xfb, 0x39, 0x07, 0x87, 0xb8, 0xa8, 0xa8, 0x88, 0xa5, 0x02, 0x79, 0x28, 0x2c, 0x2c, 0xd4, 0xb5, - 0xcd, 0xb6, 0x9b, 0x78, 0xc6, 0xba, 0x44, 0x8b, 0x84, 0x32, 0x18, 0x77, 0xfc, 0xf8, 0x71, 0x66, - 0x0a, 0xda, 0x48, 0x41, 0x41, 0x41, 0x64, 0x64, 0x24, 0x9b, 0xee, 0xde, 0xbd, 0x1b, 0x18, 0x38, - 0xdf, 0xdb, 0xdb, 0x8b, 0x4a, 0x03, 0x13, 0xe5, 0x7e, 0xe2, 0xc4, 0x09, 0xf4, 0x7e, 0xd0, 0xf0, - 0x04, 0x63, 0x62, 0x62, 0x02, 0xb5, 0x07, 0x39, 0xb0, 0x1e, 0xa2, 0x46, 0x47, 0x47, 0xf1, 0xb5, - 0xaa, 0x96, 0x74, 0x5d, 0x54, 0x03, 0x58, 0xbb, 0xc8, 0xc9, 0xc9, 0x51, 0x33, 0x4d, 0x26, 0x13, - 0x9a, 0x23, 0xfa, 0x49, 0x7b, 0x7b, 0xfb, 0xcd, 0x9b, 0x37, 0xf1, 0xc5, 0xab, 0x49, 0x0d, 0xe0, - 0xf4, 0xc3, 0x87, 0x0f, 0x91, 0x96, 0x81, 0x81, 0x01, 0xce, 0x31, 0x4e, 0xe8, 0x67, 0xe0, 0xe2, - 0xc5, 0x8b, 0x4d, 0x4d, 0x4d, 0xb8, 0x65, 0x1b, 0x1a, 0x1a, 0x6a, 0x6a, 0x6a, 0x10, 0xb3, 0x35, - 0x6b, 0xd6, 0xb0, 0xd0, 0xb2, 0x2f, 0x2e, 0x57, 0x0c, 0xd0, 0xa1, 0xa1, 0xa1, 0x6a, 0xfe, 0x74, - 0x1a, 0x99, 0xc1, 0x98, 0xce, 0x37, 0xc4, 0xd1, 0x8d, 0x81, 0xc5, 0xa3, 0x80, 0xdf, 0x50, 0xba, - 0x1b, 0xff, 0x1d, 0x80, 0xfe, 0x63, 0x0e, 0x37, 0x25, 0xfa, 0x09, 0x1a, 0x36, 0xae, 0xfa, 0xd8, - 0xd8, 0xd8, 0xe5, 0xcb, 0x97, 0x1b, 0x0a, 0x98, 0xe8, 0xcd, 0xfa, 0x0e, 0x88, 0xd6, 0x28, 0x58, - 0x9e, 0x80, 0x7b, 0x40, 0xb0, 0x45, 0x36, 0x8a, 0x73, 0x38, 0x60, 0x63, 0xc0, 0x84, 0xc3, 0x1d, - 0x19, 0x10, 0x1e, 0x52, 0x1b, 0x05, 0x3a, 0x32, 0x60, 0x63, 0xc0, 0x84, 0xc3, 0x5f, 0xf8, 0x0c, - 0xfc, 0x0d, 0x80, 0x98, 0xbd, 0xed, 0xf7, 0x50, 0xda, 0x08, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXJSONIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0d, 0x5c, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x09, 0x8c, 0x15, 0x49, 0xf5, 0x71, 0x0c, 0x37, 0x3b, 0x80, 0x9c, 0x4b, 0x80, 0xe1, 0x0a, - 0xe0, 0x22, 0x20, 0xb7, 0x24, 0x72, 0x0c, 0x12, 0xc3, 0x21, 0x4e, 0xb2, 0x8b, 0x60, 0x88, 0x44, - 0x19, 0x96, 0x51, 0x20, 0x30, 0x84, 0x05, 0x51, 0x43, 0x42, 0x96, 0x71, 0x81, 0x44, 0x10, 0xd8, - 0x48, 0xb2, 0x86, 0x63, 0xb3, 0xdc, 0xe7, 0x42, 0x60, 0xc1, 0x15, 0x44, 0x09, 0x67, 0x04, 0x16, - 0x11, 0x59, 0x40, 0x58, 0x1c, 0x21, 0x1c, 0x0e, 0xa7, 0xb3, 0xc8, 0xb5, 0x40, 0xfb, 0x5e, 0x35, - 0x55, 0x5d, 0xdd, 0x5d, 0xfd, 0xbb, 0x7b, 0xaa, 0xff, 0xff, 0x0d, 0xf3, 0x2b, 0xf9, 0xbf, 0x5f, - 0xbd, 0xbb, 0x5e, 0x75, 0x57, 0x5f, 0xf5, 0xaa, 0x2b, 0x18, 0x58, 0x20, 0x44, 0xa9, 0x18, 0x82, - 0x97, 0xb1, 0x2a, 0x05, 0xea, 0xbc, 0x65, 0xaa, 0xe1, 0x5b, 0x9b, 0x52, 0x72, 0xc9, 0xab, 0x5c, - 0xbd, 0xed, 0xa6, 0x80, 0x13, 0x95, 0xfd, 0xa6, 0x1d, 0xe3, 0xac, 0xbb, 0x04, 0x64, 0x76, 0x95, - 0x05, 0x65, 0x1b, 0x8a, 0xd6, 0x99, 0x5e, 0xaf, 0xf8, 0xd4, 0xe6, 0x3d, 0xab, 0x54, 0x20, 0x8d, - 0x6e, 0xb4, 0x37, 0x46, 0x69, 0xc1, 0x9b, 0x1d, 0xc0, 0x26, 0x50, 0xa1, 0x42, 0x05, 0xd3, 0x2c, - 0x6e, 0x6b, 0xd5, 0xaa, 0xa5, 0x94, 0xab, 0xcc, 0xb1, 0x8f, 0x1f, 0x3f, 0xe6, 0x20, 0x05, 0x42, - 0xc0, 0x4e, 0x20, 0x74, 0x1b, 0x42, 0x0b, 0xd8, 0xda, 0xe0, 0x34, 0xaf, 0xaa, 0xbb, 0x04, 0xc6, - 0xfc, 0xc6, 0x62, 0xfb, 0xcf, 0x3d, 0x0b, 0x16, 0x90, 0xdc, 0xb3, 0x04, 0xcb, 0xbb, 0x82, 0x0c, - 0x73, 0x3e, 0x97, 0x85, 0x82, 0x21, 0x42, 0x17, 0x34, 0xac, 0x63, 0xc1, 0x1c, 0x72, 0x09, 0x7c, - 0xb0, 0x8b, 0x93, 0x00, 0x4a, 0x14, 0x2e, 0xb9, 0xa2, 0xf4, 0xe4, 0x29, 0x40, 0x15, 0xd1, 0x3b, - 0x96, 0x30, 0x87, 0x5c, 0x02, 0x9c, 0xe0, 0xb5, 0x75, 0xb9, 0xe4, 0xc5, 0xc8, 0xf1, 0x2e, 0x81, - 0x96, 0x2d, 0x5b, 0xc2, 0x90, 0x21, 0x66, 0xcb, 0x69, 0xdf, 0xe2, 0x3f, 0x2e, 0x20, 0x0e, 0xa0, - 0x71, 0xe3, 0xc6, 0xf1, 0xc8, 0x25, 0xdc, 0x86, 0x6e, 0x43, 0x68, 0x01, 0xe1, 0x5a, 0x40, 0xc0, - 0xd5, 0xe6, 0x80, 0x72, 0x81, 0xd9, 0x02, 0x19, 0x50, 0x8d, 0x7f, 0xd3, 0x97, 0x03, 0xa8, 0xf0, - 0x4e, 0xcb, 0x81, 0x0c, 0x38, 0x85, 0xa8, 0x3e, 0xff, 0x27, 0x2a, 0xac, 0x1b, 0x57, 0x66, 0x03, - 0x37, 0x14, 0xbb, 0xbd, 0x5b, 0xbd, 0x63, 0x0c, 0x53, 0x31, 0x70, 0xdc, 0xb8, 0xc5, 0x1c, 0x32, - 0xb7, 0x9d, 0x7e, 0x66, 0xaf, 0x7b, 0xd5, 0xd2, 0xb7, 0x17, 0xd5, 0xac, 0x59, 0xd3, 0xcb, 0xa9, - 0x50, 0x78, 0x65, 0x1f, 0x0c, 0x1b, 0x36, 0x0c, 0x1e, 0x3c, 0x78, 0x20, 0x14, 0xf5, 0xee, 0xdd, - 0x1b, 0x8e, 0x1f, 0x3f, 0x0e, 0x27, 0x4e, 0x9c, 0x80, 0x7b, 0xf7, 0xee, 0xb1, 0xc3, 0x75, 0xec, - 0xd8, 0xb1, 0x50, 0xbd, 0x7a, 0x75, 0xb8, 0x7f, 0xff, 0x3e, 0xab, 0x17, 0x14, 0x14, 0x40, 0xdb, - 0xb6, 0x6d, 0x85, 0x8c, 0x00, 0xbc, 0x8e, 0x5b, 0x64, 0x10, 0x24, 0x82, 0xe9, 0xb7, 0x76, 0xed, - 0x5a, 0x86, 0xe3, 0xf5, 0xdd, 0xbb, 0x77, 0x1b, 0x1b, 0x37, 0x6e, 0x64, 0xb4, 0xbc, 0xbc, 0x3c, - 0xb6, 0x15, 0x42, 0x2f, 0x80, 0xf4, 0xf5, 0x01, 0x7a, 0x19, 0x49, 0x79, 0xf9, 0x5b, 0xa0, 0xdc, - 0x8b, 0x22, 0x89, 0xcd, 0x0b, 0x25, 0xf1, 0x30, 0x40, 0xa3, 0x66, 0xbd, 0x1f, 0x58, 0xed, 0xa2, - 0x7a, 0x90, 0x91, 0x94, 0x24, 0x7c, 0x5b, 0xd0, 0xf0, 0x87, 0xa6, 0xe2, 0x3b, 0x1b, 0x2d, 0x03, - 0xf7, 0x36, 0x5b, 0xb0, 0x1f, 0xe4, 0x6b, 0xe0, 0xc9, 0x57, 0x7e, 0x2a, 0x12, 0xd3, 0x7d, 0x0d, - 0x90, 0x78, 0x8d, 0xaa, 0x6a, 0x25, 0x7b, 0x4f, 0xaa, 0xf1, 0x36, 0xac, 0xf3, 0xd0, 0x96, 0xeb, - 0x7b, 0x3e, 0xb3, 0x5f, 0x5c, 0xc9, 0x34, 0xba, 0xa4, 0x56, 0x5d, 0x6c, 0xc9, 0x3c, 0x04, 0x5b, - 0x03, 0x8e, 0x93, 0xf2, 0xa2, 0x4e, 0x4a, 0x54, 0x8a, 0x08, 0x57, 0xfa, 0xc0, 0x43, 0x48, 0x42, - 0x07, 0x0a, 0x91, 0xad, 0xc9, 0x52, 0xa5, 0x76, 0x75, 0xa9, 0xe2, 0x01, 0xfa, 0x1a, 0xf8, 0x7a, - 0x73, 0x53, 0xf2, 0xbd, 0x0d, 0x96, 0x06, 0x7e, 0x23, 0x61, 0x61, 0xbc, 0x21, 0x5f, 0x03, 0x87, - 0x17, 0x02, 0xfc, 0x62, 0xa4, 0x5b, 0xc1, 0xda, 0x9f, 0xbb, 0x71, 0x2a, 0xcc, 0x2b, 0x3a, 0xd8, - 0x6d, 0xde, 0x1c, 0xe2, 0x50, 0x55, 0xc5, 0x45, 0xc2, 0xa5, 0x3e, 0x44, 0x74, 0x32, 0xa7, 0x93, - 0xfe, 0xbc, 0x79, 0xf3, 0x98, 0x1f, 0xf2, 0xfd, 0x1e, 0x21, 0xa8, 0xbe, 0x74, 0xe9, 0x52, 0xb6, - 0xa5, 0x7a, 0xbd, 0x7a, 0xf5, 0xd8, 0x7d, 0x20, 0xe7, 0x23, 0x9c, 0xad, 0x48, 0xc7, 0x84, 0x0d, - 0x9c, 0x3b, 0x77, 0x2e, 0xab, 0x5f, 0xbf, 0x7e, 0x9d, 0x9d, 0xcc, 0x51, 0x88, 0xd5, 0xf9, 0x76, - 0xfe, 0xfc, 0xf9, 0xc6, 0x99, 0x33, 0x67, 0x8c, 0x3e, 0x7d, 0xfa, 0xd8, 0xf0, 0x36, 0x25, 0x58, - 0xf1, 0x3c, 0x92, 0xb9, 0x01, 0x52, 0xc8, 0x7f, 0x24, 0x8c, 0x97, 0x26, 0xb6, 0x3a, 0xa7, 0xd1, - 0x76, 0xf8, 0xf0, 0xe1, 0x4e, 0xfd, 0x6e, 0x03, 0x3d, 0x7a, 0xf4, 0x30, 0xaa, 0x56, 0xad, 0x6a, - 0x3c, 0x7a, 0xf4, 0xc8, 0xc5, 0x5c, 0x16, 0x44, 0xea, 0x3b, 0x19, 0x9b, 0x1a, 0x69, 0xf1, 0x1d, - 0x2a, 0x74, 0xad, 0x25, 0x3d, 0x44, 0xba, 0x0e, 0xfa, 0xc9, 0x27, 0x3d, 0x42, 0x7e, 0x0e, 0xe8, - 0xd2, 0x33, 0x0d, 0xd0, 0x8d, 0xa0, 0xae, 0x7c, 0x82, 0xe7, 0x36, 0xc1, 0x55, 0xcf, 0xc1, 0x27, - 0x89, 0x0b, 0xb6, 0x58, 0xfc, 0x15, 0xb1, 0x5f, 0xe5, 0xcb, 0x4c, 0x4e, 0x71, 0x5e, 0xcb, 0x86, - 0xb9, 0xfc, 0xe4, 0x3a, 0x9c, 0xdb, 0x48, 0x0e, 0x62, 0xd9, 0x31, 0x3f, 0xa7, 0xae, 0xde, 0x06, - 0x78, 0xa3, 0xc0, 0x74, 0xc3, 0x8f, 0xd7, 0xe9, 0xac, 0xaa, 0x9e, 0xf2, 0x63, 0xe0, 0xc5, 0xb3, - 0x56, 0x95, 0x2f, 0x65, 0xc2, 0x69, 0x35, 0xa0, 0xb8, 0x04, 0xa0, 0xd9, 0x8f, 0x2c, 0xbb, 0x1f, - 0xcf, 0xb2, 0x60, 0x2f, 0xe8, 0xf5, 0x7a, 0x74, 0xc5, 0x60, 0x52, 0xa9, 0xe7, 0xa6, 0xfe, 0xde, - 0x8b, 0x33, 0x18, 0x5e, 0xab, 0x01, 0x39, 0x0d, 0x01, 0x36, 0xfc, 0xd2, 0x32, 0xf4, 0xfe, 0x0e, - 0x0b, 0x4e, 0x04, 0xf1, 0x07, 0xd7, 0x5f, 0x7b, 0x0d, 0xe0, 0xb7, 0xe3, 0x13, 0x71, 0xfa, 0xd3, - 0xb4, 0x1a, 0x40, 0xea, 0xfb, 0x74, 0xb0, 0x8c, 0xec, 0xfb, 0x9b, 0x05, 0x7b, 0x41, 0xd7, 0xee, - 0x58, 0x94, 0x2f, 0x56, 0x58, 0x70, 0x59, 0x21, 0xed, 0x06, 0x84, 0x35, 0xfc, 0xbf, 0x47, 0x61, - 0x25, 0x12, 0xf3, 0x47, 0x32, 0x0a, 0xdd, 0xb8, 0x0b, 0xd0, 0xfe, 0x6d, 0xcb, 0x50, 0x90, 0x61, - 0x94, 0x1e, 0xe9, 0xff, 0x73, 0x99, 0x25, 0x53, 0x56, 0x28, 0x92, 0x06, 0x94, 0xd5, 0x78, 0x14, - 0x72, 0x29, 0xdf, 0x85, 0xa2, 0x70, 0x5a, 0xd6, 0x51, 0xbe, 0x1a, 0x90, 0x9f, 0x9f, 0x2f, 0xee, - 0xf6, 0xe4, 0x28, 0xa4, 0x15, 0x0e, 0x72, 0x9f, 0x85, 0x0e, 0x8a, 0x1b, 0x3d, 0x82, 0x17, 0x2f, - 0x5e, 0x6c, 0x13, 0x5b, 0xb0, 0x60, 0x81, 0x8d, 0x4e, 0x3c, 0xa7, 0x4e, 0x9d, 0x12, 0x3c, 0x25, - 0x25, 0x25, 0x46, 0xc5, 0x8a, 0x15, 0x05, 0xcf, 0xa0, 0x41, 0x83, 0x04, 0xed, 0xf4, 0xe9, 0xd3, - 0x02, 0x9f, 0x9b, 0x9b, 0x2b, 0x60, 0x7c, 0x56, 0x2e, 0x78, 0x12, 0x01, 0x9e, 0x77, 0xad, 0x5e, - 0x42, 0xe4, 0x1c, 0xbf, 0xa3, 0xe5, 0x3c, 0xbc, 0x81, 0x8d, 0x1b, 0x37, 0x36, 0xa6, 0x4e, 0x9d, - 0x6a, 0x5c, 0xbd, 0x7a, 0x95, 0x93, 0x8c, 0x6e, 0xdd, 0xba, 0x31, 0xa7, 0x9e, 0x3d, 0x7b, 0x26, - 0x70, 0xa3, 0x46, 0x8d, 0x62, 0x38, 0x7c, 0x2d, 0xcb, 0x70, 0x74, 0x6b, 0x4d, 0x3a, 0x78, 0xe1, - 0xfa, 0x78, 0x3d, 0xd1, 0x36, 0x92, 0xab, 0x51, 0x34, 0xc8, 0xde, 0x2e, 0xd0, 0xdb, 0x03, 0x2a, - 0xfc, 0x21, 0x02, 0x1a, 0x86, 0xa1, 0x43, 0x87, 0xb2, 0xb7, 0x0c, 0xb4, 0xfb, 0xad, 0x5c, 0xb9, - 0x92, 0xd1, 0xd7, 0xaf, 0x5f, 0xcf, 0xb6, 0x55, 0xaa, 0x54, 0x61, 0x5b, 0xad, 0xbf, 0x44, 0xad, - 0x73, 0xd2, 0x28, 0x8a, 0x68, 0xcc, 0x58, 0xb5, 0x6a, 0x95, 0x8d, 0x44, 0x6f, 0x25, 0xe8, 0x31, - 0xc0, 0xae, 0x5d, 0xbb, 0x8c, 0xfd, 0xfb, 0xf7, 0xdb, 0x68, 0x72, 0xe5, 0xc0, 0x81, 0x03, 0xc6, - 0x95, 0x2b, 0x57, 0x64, 0x94, 0x36, 0xec, 0x7b, 0x1e, 0x78, 0xf8, 0xf0, 0x21, 0xd4, 0xa8, 0x51, - 0x83, 0x05, 0xa9, 0x72, 0xe5, 0xca, 0x70, 0xf2, 0xe4, 0x49, 0xe8, 0xd8, 0xb1, 0xa3, 0x56, 0xd0, - 0xa2, 0x14, 0xf6, 0x6d, 0x40, 0x94, 0xc6, 0x92, 0xa1, 0xab, 0x7c, 0x9d, 0x07, 0x92, 0x11, 0x41, - 0x5d, 0x9d, 0x99, 0x5d, 0x48, 0x37, 0x82, 0xba, 0xf2, 0x99, 0x63, 0x40, 0x37, 0x82, 0xba, 0xf2, - 0x99, 0x1e, 0xd0, 0x8d, 0xa0, 0xae, 0x7c, 0xa6, 0x07, 0x74, 0x23, 0xa8, 0x2b, 0x1f, 0xc9, 0xd5, - 0xa8, 0xf3, 0xa6, 0x5e, 0xf5, 0xc8, 0x50, 0x7e, 0xfc, 0x98, 0xf7, 0x2d, 0x80, 0x0f, 0xa7, 0xe9, - 0xba, 0x6e, 0xca, 0x47, 0xb2, 0x0b, 0xc9, 0x4f, 0x24, 0x82, 0xb8, 0xb5, 0xed, 0x08, 0x80, 0xfc, - 0x76, 0x38, 0x88, 0x8c, 0x17, 0x4f, 0x24, 0x0d, 0xe0, 0xca, 0x7f, 0x3a, 0x14, 0x40, 0x15, 0x7d, - 0xa2, 0x13, 0x5e, 0xa6, 0x2d, 0xd9, 0xce, 0xa5, 0xf4, 0xb6, 0xda, 0x0d, 0x78, 0xfe, 0xdc, 0x72, - 0xa0, 0x30, 0xcf, 0x82, 0xfd, 0xa0, 0x47, 0x4f, 0xfc, 0x38, 0x82, 0xd1, 0xb5, 0x1b, 0x20, 0x9b, - 0xe1, 0x0f, 0x6d, 0x65, 0x5c, 0xb2, 0xe1, 0x48, 0x1b, 0x90, 0x6c, 0x67, 0x55, 0xfa, 0xb5, 0x1b, - 0xb0, 0x47, 0x9a, 0x1a, 0xd3, 0x30, 0x5b, 0x65, 0xc2, 0x8e, 0xab, 0xee, 0x31, 0xc5, 0xc6, 0xce, - 0x15, 0xbc, 0xa6, 0xd5, 0x00, 0x7a, 0xb6, 0x3f, 0x72, 0xae, 0x69, 0x8c, 0x9e, 0x87, 0x06, 0xd9, - 0x85, 0x56, 0xbd, 0x63, 0x39, 0xd7, 0x7c, 0x0c, 0xc0, 0xa5, 0x1b, 0x56, 0xbd, 0x2c, 0x90, 0x56, - 0x03, 0x56, 0xfe, 0xd1, 0x34, 0xd9, 0xa8, 0x2e, 0xc0, 0xe7, 0x1f, 0x04, 0x33, 0xff, 0x9d, 0x6f, - 0x02, 0x8c, 0x1f, 0x6c, 0xf2, 0x96, 0xe2, 0x34, 0xc9, 0x73, 0x57, 0x82, 0xc9, 0x79, 0x71, 0x69, - 0xdf, 0xd0, 0xb4, 0xc2, 0x19, 0xb7, 0x77, 0xbe, 0x34, 0xd5, 0xcb, 0xc3, 0xa4, 0x97, 0xc1, 0xbc, - 0x77, 0x01, 0xfe, 0xf2, 0x77, 0x93, 0xfa, 0x87, 0x22, 0x80, 0xde, 0xed, 0xbd, 0x38, 0x83, 0xe1, - 0xb5, 0x7a, 0x80, 0x4c, 0x7c, 0xf6, 0xbe, 0x65, 0x48, 0x39, 0xcf, 0xde, 0x22, 0x33, 0x88, 0x3b, - 0x4f, 0x15, 0x5d, 0xe7, 0x49, 0x87, 0x76, 0x03, 0x5e, 0x33, 0x9f, 0xb8, 0x90, 0xae, 0xb4, 0x14, - 0xed, 0x06, 0xa4, 0xc5, 0x6b, 0xc9, 0x68, 0xa4, 0x0d, 0x88, 0xfa, 0xf5, 0x91, 0xe4, 0xa7, 0x27, - 0xa8, 0xdd, 0x00, 0x1a, 0x3e, 0x79, 0xe9, 0x55, 0x08, 0xe0, 0x35, 0x6d, 0x8f, 0xf0, 0xf9, 0x8b, - 0x38, 0x27, 0xc0, 0x37, 0x72, 0x2c, 0x58, 0x07, 0xd2, 0x1e, 0x85, 0xc8, 0x78, 0x9b, 0x7c, 0x80, - 0x5b, 0xff, 0xb5, 0xdc, 0x50, 0x8d, 0x46, 0xf2, 0xe5, 0x34, 0x71, 0xd2, 0xfb, 0x31, 0x55, 0xea, - 0x8b, 0xa5, 0x25, 0x18, 0x14, 0xc9, 0xfd, 0xc0, 0x45, 0xcc, 0x8e, 0xf8, 0xe4, 0x18, 0xc0, 0xc9, - 0x8b, 0xde, 0x46, 0xdf, 0x79, 0xd3, 0xa4, 0x55, 0xc9, 0xc2, 0x97, 0xdb, 0x78, 0xd1, 0x97, 0x15, - 0x89, 0x65, 0x3c, 0x79, 0xd2, 0xe3, 0x61, 0x6f, 0xb3, 0xf1, 0xa7, 0x48, 0x7b, 0x70, 0xfc, 0x9d, - 0x55, 0x79, 0x98, 0x69, 0x80, 0x2a, 0x2a, 0xa9, 0xc4, 0x95, 0xaf, 0x1e, 0xc8, 0xce, 0xce, 0x86, - 0x2d, 0x5b, 0xa4, 0xa9, 0x59, 0xa9, 0x0c, 0xb5, 0x87, 0xad, 0x50, 0x3d, 0x50, 0x5a, 0x5a, 0x0a, - 0x87, 0x0f, 0x1f, 0xf6, 0x50, 0x95, 0x1e, 0x74, 0xa8, 0xd1, 0x38, 0x8e, 0x23, 0xae, 0x6f, 0x0f, - 0x4c, 0x99, 0x32, 0x85, 0xbd, 0x36, 0xa5, 0x57, 0xa7, 0xfc, 0xe7, 0x8c, 0x35, 0xcd, 0xd1, 0xe6, - 0x34, 0x7a, 0x11, 0xc8, 0x5f, 0xb3, 0x72, 0xbe, 0xf1, 0xe3, 0xc7, 0x0b, 0x3a, 0xd1, 0xce, 0x9e, - 0x3d, 0xcb, 0x49, 0x40, 0xd9, 0x65, 0x84, 0x3b, 0x78, 0xf0, 0xa0, 0xe0, 0xc1, 0xf7, 0xc8, 0x82, - 0xee, 0x0b, 0xf8, 0xbd, 0xe7, 0x3c, 0x74, 0xe8, 0x90, 0x81, 0xef, 0x7a, 0xd9, 0xaf, 0x4e, 0x9d, - 0x3a, 0xb6, 0x17, 0xd2, 0x24, 0x3b, 0x70, 0xe0, 0x40, 0x86, 0xe3, 0x2f, 0xb2, 0xfb, 0xf6, 0xed, - 0x6b, 0xe3, 0x69, 0xd1, 0xa2, 0x05, 0xab, 0x0f, 0x1e, 0x3c, 0xd8, 0x58, 0xbe, 0x7c, 0xb9, 0x78, - 0x63, 0xcf, 0xdf, 0xe4, 0xcf, 0x98, 0x31, 0x83, 0xd1, 0xd1, 0x51, 0x63, 0xd2, 0xa4, 0x49, 0x46, - 0xb5, 0x6a, 0xd5, 0x6c, 0xf2, 0x7e, 0xfe, 0x59, 0xaf, 0xc7, 0xfd, 0x38, 0x91, 0xde, 0xb3, 0x67, - 0x4f, 0x97, 0x72, 0x9e, 0xad, 0x46, 0x0e, 0xd0, 0x14, 0x02, 0x7c, 0x89, 0x6d, 0xd3, 0x44, 0xf8, - 0x76, 0xed, 0xda, 0xb9, 0x70, 0x59, 0x59, 0x59, 0x02, 0x47, 0x3c, 0xfd, 0xfa, 0xf5, 0x63, 0x75, - 0x3e, 0xf5, 0x40, 0x7e, 0xdb, 0x2f, 0x18, 0x15, 0x80, 0x76, 0x03, 0x48, 0xe7, 0xc4, 0x89, 0x13, - 0x45, 0x14, 0xc9, 0x19, 0xfa, 0x51, 0xe1, 0x2f, 0xc6, 0x47, 0x8c, 0x18, 0xc1, 0xea, 0xfc, 0x4f, - 0xe6, 0x21, 0x1c, 0xd5, 0x67, 0xcf, 0x9e, 0xcd, 0xc8, 0xf4, 0x22, 0x9c, 0xea, 0x97, 0x2e, 0x5d, - 0xe2, 0xec, 0x09, 0xb7, 0xbe, 0xc7, 0x00, 0x2a, 0x4b, 0x58, 0x68, 0x2a, 0x01, 0x46, 0x8d, 0x3c, - 0x66, 0xbf, 0xe9, 0xd3, 0xa7, 0x33, 0x7e, 0x4c, 0x3d, 0x00, 0x9c, 0xe0, 0xc1, 0xe0, 0x4d, 0x9b, - 0x36, 0xc1, 0x93, 0x27, 0xe6, 0xa3, 0xb8, 0x85, 0x0b, 0x31, 0xb3, 0x05, 0x0b, 0xcf, 0x4b, 0x66, - 0x15, 0x9d, 0xbf, 0x84, 0xcd, 0x73, 0x10, 0xbb, 0x77, 0xef, 0x2e, 0xa2, 0xcb, 0x49, 0xad, 0x5a, - 0xb5, 0x62, 0x38, 0xf4, 0xc1, 0xc0, 0x37, 0xfa, 0x02, 0xe6, 0xf4, 0x73, 0xe7, 0xce, 0x09, 0x1c, - 0xf1, 0xd0, 0x0f, 0x0f, 0x7a, 0x4e, 0xb6, 0xd1, 0xee, 0xde, 0xbd, 0x6b, 0xab, 0x0b, 0xa6, 0x04, - 0x80, 0xd9, 0xd7, 0x09, 0x18, 0x64, 0x12, 0x9e, 0xc8, 0x98, 0x01, 0x19, 0x47, 0x5d, 0x4e, 0xb3, - 0x4e, 0x30, 0x6d, 0x94, 0x65, 0x71, 0x7a, 0x75, 0x3d, 0x4d, 0xb9, 0xd9, 0xbb, 0x77, 0xaf, 0xf1, - 0xfc, 0xf9, 0x73, 0x59, 0x5c, 0x1b, 0xf6, 0xbd, 0x9c, 0x1e, 0x39, 0x72, 0x24, 0xd0, 0x6a, 0x05, - 0x34, 0xd4, 0x6d, 0xdb, 0xb6, 0x0d, 0xda, 0xb4, 0x69, 0x03, 0x17, 0x2e, 0x5c, 0xd0, 0xe9, 0xf4, - 0x68, 0x65, 0xfd, 0x42, 0x40, 0x23, 0x0b, 0xef, 0x7a, 0xdc, 0x6f, 0xfd, 0xd8, 0x53, 0x4e, 0xf7, - 0xed, 0x81, 0x68, 0xc3, 0x15, 0xbd, 0x36, 0xed, 0x51, 0x28, 0x7a, 0x97, 0xc2, 0x69, 0xcc, 0x34, - 0x20, 0x5c, 0xbc, 0xa2, 0xe7, 0xce, 0xf4, 0x40, 0xf4, 0x31, 0x0d, 0xa7, 0xf1, 0xa5, 0x1f, 0x85, - 0xc2, 0x35, 0x37, 0x7e, 0xdc, 0x2f, 0xfd, 0x21, 0x10, 0xbf, 0x90, 0x86, 0xf3, 0x28, 0xd3, 0x01, - 0xe1, 0xe2, 0x15, 0x39, 0x77, 0xa6, 0x03, 0x22, 0x0f, 0x69, 0x38, 0x85, 0x99, 0x0e, 0x08, 0x17, - 0xaf, 0xc8, 0xb9, 0x33, 0x1d, 0x10, 0x79, 0x48, 0xc3, 0x29, 0xcc, 0x74, 0x40, 0xb8, 0x78, 0x45, - 0xce, 0x1d, 0xea, 0xb1, 0x74, 0xe4, 0xd6, 0x3d, 0x14, 0x52, 0xb6, 0xf4, 0x99, 0x7f, 0x03, 0x7c, - 0xf5, 0xcc, 0x62, 0xa0, 0xd4, 0xdd, 0x21, 0x3d, 0xac, 0x7a, 0x22, 0x88, 0x5e, 0x95, 0xca, 0x25, - 0xab, 0x12, 0x40, 0xc7, 0x1c, 0x00, 0xca, 0x01, 0x8e, 0x5b, 0x89, 0xcd, 0x7d, 0xc0, 0x43, 0x7c, - 0xe2, 0x98, 0x3b, 0x13, 0xe0, 0xec, 0x65, 0x75, 0x88, 0xbc, 0x12, 0x4b, 0x55, 0xdc, 0xce, 0x97, - 0xe9, 0x32, 0x0f, 0x75, 0xc4, 0xde, 0xf7, 0x00, 0xaa, 0x45, 0x90, 0x38, 0x25, 0xeb, 0x2d, 0x2b, - 0x1c, 0x9b, 0x23, 0xe0, 0x7b, 0xb3, 0xd5, 0xc1, 0x6f, 0xf3, 0x3a, 0x40, 0x4e, 0x23, 0x9c, 0x0e, - 0xf4, 0x22, 0x7b, 0x3d, 0x48, 0x43, 0x69, 0x32, 0x18, 0x95, 0x7f, 0xe1, 0x2c, 0xb6, 0x2f, 0xae, - 0x9b, 0x30, 0xff, 0xff, 0x47, 0x31, 0xc0, 0xf7, 0xdf, 0x05, 0xf8, 0xb4, 0x88, 0x63, 0xd2, 0xbb, - 0x8d, 0xc5, 0x11, 0x40, 0x53, 0x66, 0xe5, 0x55, 0xd4, 0x78, 0x48, 0x68, 0x65, 0x29, 0xbe, 0x7c, - 0x15, 0xc7, 0x85, 0xdd, 0x9e, 0x2e, 0x06, 0xf8, 0xb6, 0x34, 0xbd, 0x90, 0xcb, 0xab, 0xa6, 0xa1, - 0x70, 0x5a, 0x2a, 0xb7, 0xb1, 0x3e, 0x09, 0xd3, 0x52, 0x07, 0xba, 0x25, 0x0a, 0x1d, 0xba, 0x3e, - 0x24, 0x92, 0x8f, 0x75, 0x07, 0x24, 0x72, 0xfc, 0x55, 0xa1, 0xc5, 0xa2, 0x03, 0x4a, 0x1f, 0xaa, - 0xc3, 0x19, 0x62, 0xd8, 0x57, 0x2b, 0x40, 0xac, 0x97, 0x8e, 0x2f, 0x3d, 0x6c, 0x7a, 0x2a, 0x4a, - 0x12, 0x21, 0xed, 0x1d, 0x70, 0x13, 0xa7, 0x07, 0xd2, 0xd5, 0x8f, 0xb3, 0xf4, 0x6c, 0x17, 0xcd, - 0x34, 0xc0, 0x26, 0x78, 0xe9, 0xd9, 0x4d, 0xb1, 0x10, 0x6d, 0xff, 0x19, 0x00, 0xb7, 0x4b, 0x9d, - 0x56, 0x53, 0x5f, 0x4f, 0xdb, 0x49, 0x98, 0xd6, 0xe0, 0x7c, 0xeb, 0xd7, 0xee, 0x06, 0xbf, 0xd1, - 0x02, 0xe0, 0x57, 0x38, 0xb9, 0x23, 0xe8, 0x35, 0xbf, 0x5b, 0x83, 0x1a, 0xb3, 0xf3, 0xaf, 0x98, - 0x69, 0x84, 0xb9, 0xfb, 0x9f, 0x5f, 0x76, 0xd3, 0x69, 0xb9, 0xc8, 0xa8, 0xed, 0xb9, 0xad, 0xa8, - 0x31, 0x69, 0x3b, 0x02, 0xea, 0xe3, 0x09, 0xb6, 0x43, 0x73, 0xb7, 0x53, 0x74, 0x03, 0x36, 0xe1, - 0x77, 0xfa, 0x89, 0x10, 0xb2, 0xe6, 0x8b, 0xd7, 0x00, 0x26, 0xa1, 0x4e, 0x55, 0xf0, 0xc9, 0x87, - 0x28, 0x26, 0xdc, 0xca, 0xf6, 0xc2, 0xc0, 0x69, 0x3b, 0x02, 0x64, 0x27, 0xb7, 0xe1, 0xa4, 0xb5, - 0x1f, 0x9b, 0x53, 0x3e, 0x04, 0xba, 0x16, 0xae, 0x48, 0x71, 0xe5, 0xa3, 0x60, 0x59, 0x2c, 0x42, - 0x48, 0x01, 0x3c, 0xc3, 0x4b, 0x5c, 0x5a, 0x35, 0xeb, 0x81, 0xf5, 0x25, 0x04, 0xc6, 0xf5, 0x11, - 0x4e, 0x41, 0x19, 0xde, 0x4b, 0x21, 0x90, 0x62, 0x54, 0xda, 0x8e, 0x00, 0xb9, 0x9d, 0xc3, 0x7b, - 0xcb, 0x35, 0x13, 0xbe, 0x8f, 0x27, 0xc9, 0x12, 0x69, 0xfa, 0xb8, 0x9b, 0x23, 0x18, 0x86, 0x72, - 0x48, 0x9c, 0xc1, 0x27, 0xc9, 0x38, 0x04, 0x9f, 0xfc, 0x88, 0x45, 0x07, 0x90, 0x23, 0xe5, 0xb5, - 0x64, 0x3a, 0x20, 0xcd, 0x3d, 0x1f, 0x8b, 0x0e, 0xc0, 0x79, 0x5f, 0x38, 0x17, 0xd0, 0x1d, 0x89, - 0xad, 0x87, 0xdc, 0xb8, 0xb0, 0x98, 0x2d, 0x07, 0xdd, 0x12, 0x95, 0xf0, 0xe9, 0x68, 0x5c, 0x4a, - 0x2c, 0x4e, 0xc2, 0x14, 0x8c, 0x42, 0xcc, 0xba, 0xfc, 0x70, 0x8f, 0x77, 0x58, 0xa2, 0x7a, 0x1a, - 0x4a, 0x16, 0xf2, 0xbf, 0x8b, 0x2b, 0xa1, 0xbe, 0xed, 0x6d, 0x2b, 0x95, 0x14, 0xc5, 0x7e, 0x97, - 0x4a, 0xf3, 0x96, 0xad, 0x45, 0x05, 0x00, 0x7f, 0x9a, 0x8b, 0xb9, 0x5b, 0xf8, 0xf4, 0x33, 0x59, - 0xa5, 0x6d, 0x53, 0x80, 0x3f, 0xcf, 0x8f, 0x4f, 0xf0, 0xa9, 0x9d, 0xb1, 0x39, 0x02, 0x92, 0x15, - 0xf4, 0xb8, 0xeb, 0x8d, 0xcd, 0x11, 0x10, 0xf7, 0x40, 0x25, 0xcb, 0xbf, 0x4c, 0x07, 0x24, 0x2b, - 0xb2, 0x01, 0xf5, 0x66, 0x3a, 0x20, 0x60, 0xa0, 0x92, 0xc5, 0x96, 0xe9, 0x80, 0x64, 0x45, 0x36, - 0xa0, 0xde, 0xa4, 0x76, 0x00, 0x25, 0x77, 0xe0, 0x4a, 0x9d, 0x01, 0x5d, 0x29, 0x9f, 0x6c, 0x49, - 0xeb, 0x00, 0x4a, 0x30, 0xc4, 0xbc, 0x3b, 0xf6, 0x95, 0xb8, 0x69, 0xd3, 0xa6, 0x95, 0xcf, 0xe8, - 0x06, 0x68, 0x75, 0xd2, 0x3a, 0x80, 0x32, 0xe0, 0x72, 0x72, 0x72, 0x00, 0x13, 0xc9, 0x60, 0xc0, - 0x80, 0x01, 0x01, 0x5c, 0x29, 0x9f, 0x2c, 0x91, 0xdd, 0x07, 0x50, 0x6a, 0xe1, 0xcd, 0x9b, 0x37, - 0x95, 0x51, 0xac, 0x84, 0xf7, 0xfe, 0x98, 0xf0, 0x09, 0x94, 0x8a, 0x9b, 0xa8, 0xd0, 0xf7, 0x14, - 0x71, 0x51, 0x61, 0xc0, 0xe4, 0x39, 0xf6, 0xad, 0x45, 0x4a, 0xe3, 0x25, 0x39, 0xfc, 0xfe, 0x10, - 0x6c, 0xdd, 0xba, 0x15, 0x30, 0x93, 0x0f, 0x30, 0xa3, 0x95, 0xe5, 0xac, 0x79, 0xe9, 0x21, 0x1e, - 0xcc, 0x0e, 0x84, 0xf3, 0xe7, 0xcf, 0xb3, 0xe1, 0x8f, 0xe4, 0xdb, 0xb7, 0x6f, 0x0f, 0x4d, 0x9a, - 0x34, 0xf1, 0x12, 0x61, 0x79, 0x70, 0x94, 0xfb, 0x86, 0x49, 0x78, 0xec, 0x88, 0xa5, 0x6f, 0x39, - 0x12, 0x8c, 0x5f, 0x63, 0x82, 0xa3, 0x47, 0x8f, 0x32, 0xb8, 0x4b, 0x97, 0x2e, 0xd0, 0xab, 0x57, - 0x12, 0x9e, 0x5f, 0x47, 0x91, 0x98, 0xc6, 0x53, 0x84, 0xb1, 0x85, 0x22, 0x27, 0xce, 0x09, 0x3b, - 0xd7, 0xd2, 0x96, 0xed, 0xd2, 0x2a, 0xcf, 0x32, 0x7f, 0xdd, 0xba, 0x75, 0x8d, 0xfe, 0xfd, 0xfb, - 0x1b, 0x1d, 0x3a, 0x74, 0x30, 0x30, 0x41, 0xd0, 0x46, 0xa3, 0x6c, 0x45, 0x67, 0xc1, 0x2c, 0x78, - 0x83, 0xa7, 0x32, 0xcb, 0x7a, 0x9c, 0x30, 0x65, 0xf8, 0x2e, 0x5b, 0xb6, 0xcc, 0x26, 0x4e, 0xd9, - 0xc1, 0x4e, 0xbe, 0x46, 0x8d, 0x1a, 0xb9, 0x70, 0x9c, 0x07, 0x73, 0x55, 0x6d, 0xf2, 0xba, 0x95, - 0x50, 0xa9, 0x9e, 0x61, 0x8d, 0xf1, 0xf4, 0x68, 0x72, 0x3e, 0x51, 0x07, 0xc8, 0xf9, 0xae, 0x04, - 0x53, 0xca, 0xb3, 0x5c, 0x28, 0x3d, 0x74, 0xc3, 0x86, 0x0d, 0xc6, 0xa2, 0x45, 0x8b, 0x5c, 0xa9, - 0xa2, 0x93, 0x27, 0x4f, 0xb6, 0x05, 0xab, 0xa8, 0xa8, 0x48, 0x16, 0x65, 0x30, 0x2d, 0xd7, 0x2d, - 0x77, 0x24, 0xff, 0xc6, 0x98, 0xcc, 0xc8, 0x17, 0x47, 0x27, 0x5f, 0x69, 0x15, 0xf8, 0xcb, 0x97, - 0x2f, 0x0b, 0xf2, 0x8a, 0x15, 0x2b, 0x84, 0x0d, 0x3c, 0x9a, 0x8d, 0xa7, 0x4f, 0x9f, 0x0a, 0x9a, - 0x2e, 0x10, 0x8b, 0x0e, 0xc0, 0xe1, 0xc2, 0xe0, 0x79, 0xbc, 0x7c, 0x4f, 0x73, 0x6e, 0xa9, 0xe1, - 0xa3, 0x47, 0x8f, 0x36, 0x6e, 0xdd, 0xba, 0x25, 0xda, 0x8c, 0x19, 0xd4, 0x06, 0x2e, 0xce, 0x2e, - 0x82, 0x33, 0x66, 0xcc, 0x18, 0x41, 0x73, 0x02, 0x4b, 0x96, 0x2c, 0x11, 0x7c, 0xa4, 0x9b, 0x72, - 0x83, 0xe5, 0x22, 0x77, 0xc0, 0xac, 0x59, 0xb3, 0x64, 0x12, 0xeb, 0x0c, 0xd9, 0x1f, 0xaf, 0x7c, - 0x62, 0x9b, 0x50, 0xc0, 0x4a, 0xd2, 0x4e, 0xc2, 0xe8, 0x70, 0xe0, 0x52, 0xbb, 0x76, 0x6d, 0x58, - 0xbd, 0x7a, 0x35, 0x1b, 0x6b, 0xd1, 0x6f, 0xb8, 0x76, 0xed, 0x1a, 0xe0, 0x50, 0x03, 0x73, 0xe6, - 0xcc, 0x81, 0xdc, 0xdc, 0x5c, 0xa6, 0x07, 0x73, 0xef, 0x61, 0xcd, 0x9a, 0x35, 0xd0, 0xa0, 0x41, - 0x03, 0xf6, 0xed, 0x5d, 0x42, 0xe2, 0x90, 0x02, 0x98, 0x41, 0x2e, 0xec, 0x90, 0x8c, 0xfc, 0xfd, - 0x5e, 0x41, 0x40, 0x60, 0xfb, 0xf6, 0xed, 0xa2, 0x4a, 0xeb, 0xc4, 0x77, 0xee, 0xdc, 0x59, 0xd4, - 0x9d, 0x00, 0x9d, 0xb3, 0xe4, 0x42, 0x79, 0xd2, 0x49, 0x2b, 0x01, 0x3b, 0xaa, 0x4c, 0x6c, 0x41, - 0x87, 0xa0, 0xd6, 0xad, 0x5b, 0x8b, 0xbd, 0x93, 0x60, 0x5c, 0x1f, 0xc0, 0xc0, 0x13, 0x3a, 0xb3, - 0x59, 0x5c, 0x5c, 0x2c, 0x96, 0xa5, 0xc0, 0x20, 0x18, 0x78, 0x32, 0xb5, 0xf9, 0x42, 0x5f, 0x04, - 0xc0, 0x60, 0x0a, 0x79, 0xe2, 0xc1, 0x93, 0xae, 0x51, 0x58, 0x58, 0x68, 0xcc, 0x9c, 0x39, 0x93, - 0x7d, 0xd2, 0x90, 0x70, 0xfc, 0x47, 0xa9, 0xfa, 0xf2, 0xf0, 0x42, 0x76, 0x28, 0x9f, 0x9b, 0xce, - 0x0f, 0x9c, 0x87, 0xce, 0x27, 0xb4, 0x7c, 0x05, 0x95, 0x9d, 0x3b, 0x77, 0xb2, 0x73, 0x11, 0xa7, - 0xd1, 0x96, 0x56, 0x90, 0xc0, 0x0e, 0xb5, 0xf9, 0x51, 0xd6, 0x4a, 0x52, 0x87, 0x20, 0xf9, 0xf3, - 0x8b, 0xf8, 0x91, 0x49, 0x4f, 0x1f, 0xe9, 0x84, 0x4b, 0x0d, 0xc3, 0xbd, 0xdb, 0x36, 0xa4, 0xc8, - 0x8d, 0xee, 0xd4, 0xa9, 0x13, 0xeb, 0x18, 0x2f, 0x25, 0xb4, 0xe4, 0x00, 0xd9, 0xa8, 0x5f, 0xbf, - 0xbe, 0x08, 0x24, 0x97, 0xc7, 0x85, 0x4d, 0x8c, 0x09, 0x13, 0x26, 0x18, 0xb7, 0x6f, 0xe3, 0x27, - 0x63, 0x1d, 0x05, 0x8f, 0x36, 0xa3, 0x6b, 0xd7, 0xae, 0xb6, 0x73, 0x04, 0xad, 0x1b, 0x42, 0x1f, - 0xd0, 0xa0, 0xb2, 0x6e, 0xdd, 0x3a, 0xa3, 0x69, 0xd3, 0xa6, 0x36, 0x9d, 0xb4, 0x13, 0x38, 0x3f, - 0x0f, 0xe1, 0x50, 0x1b, 0xb8, 0x9a, 0xb4, 0x0e, 0xd8, 0xb1, 0x63, 0x87, 0xcd, 0xe9, 0x63, 0xc7, - 0x8e, 0x05, 0x76, 0xaa, 0x3c, 0x31, 0x26, 0xbe, 0x30, 0xc7, 0x5d, 0xc8, 0xaf, 0x1c, 0x39, 0x72, - 0x04, 0xf0, 0x04, 0xe6, 0xc9, 0x46, 0xcb, 0x8e, 0xec, 0xdb, 0xb7, 0xcf, 0x36, 0x56, 0x7b, 0x32, - 0x97, 0x43, 0x42, 0x64, 0x37, 0x62, 0xb8, 0xa2, 0x08, 0xbb, 0x81, 0xa2, 0x8f, 0xa1, 0xe0, 0x21, - 0x0b, 0xcd, 0x9a, 0x35, 0xf3, 0xbd, 0xf1, 0x2a, 0x87, 0xf1, 0x76, 0x35, 0x39, 0xb2, 0x0e, 0x70, - 0x69, 0xce, 0x20, 0x02, 0x45, 0x20, 0x16, 0x97, 0xa1, 0x81, 0x3c, 0x7d, 0x45, 0x99, 0x32, 0x1d, - 0x90, 0xe6, 0x8e, 0xcd, 0x74, 0x40, 0xa6, 0x03, 0xd2, 0x1c, 0x81, 0x34, 0x9b, 0xcf, 0x1c, 0x01, - 0x69, 0xee, 0x80, 0xff, 0x03, 0x75, 0x4b, 0xcb, 0x8b, 0xae, 0x16, 0xbd, 0x22, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXTextPlainIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, - 0x32, 0x32, 0x3a, 0x30, 0x32, 0x3a, 0x34, 0x33, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, - 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, - 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, - 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, - 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, - 0x61, 0x3e, 0x0a, 0x04, 0xa5, 0xd6, 0xff, 0x00, 0x00, 0x05, 0x7b, 0x49, 0x44, 0x41, 0x54, 0x68, - 0x05, 0xed, 0x58, 0x5b, 0x48, 0x23, 0x57, 0x18, 0xce, 0x24, 0x31, 0xf1, 0x52, 0xad, 0x31, 0x78, - 0xdf, 0xd6, 0x2a, 0xb6, 0x52, 0xad, 0x28, 0x8a, 0xe8, 0x82, 0x62, 0xe9, 0x45, 0xa5, 0x45, 0xf0, - 0x82, 0x58, 0x41, 0xb4, 0xed, 0x83, 0x0f, 0xe2, 0x83, 0x6f, 0x8a, 0x20, 0xb8, 0x3e, 0x28, 0x05, - 0x45, 0x7d, 0x12, 0x84, 0x82, 0x8a, 0x88, 0x22, 0x0a, 0xbe, 0x54, 0xb4, 0xc2, 0x3e, 0xe9, 0x82, - 0x37, 0x50, 0x1a, 0x45, 0x2a, 0x5e, 0x8a, 0xdd, 0x20, 0x58, 0x35, 0xb1, 0x8a, 0x49, 0x4c, 0xd2, - 0x2f, 0x7b, 0xe2, 0x38, 0x3b, 0xc6, 0x89, 0x33, 0x39, 0xac, 0x2b, 0x9d, 0xf3, 0x30, 0xfc, 0xe7, - 0xfc, 0xdf, 0x7f, 0xff, 0xcf, 0x3f, 0x93, 0x30, 0x4e, 0xa7, 0x53, 0xf1, 0x94, 0x97, 0xf2, 0x29, - 0x3b, 0xef, 0xf2, 0x5d, 0x0e, 0xe0, 0xb1, 0x2b, 0x28, 0x57, 0x40, 0xae, 0x80, 0x8f, 0x19, 0x90, - 0x5b, 0xc8, 0xc7, 0x04, 0xfa, 0x2c, 0x2e, 0x57, 0xc0, 0xe7, 0x14, 0xfa, 0xa8, 0x40, 0xae, 0x80, - 0x8f, 0x09, 0xf4, 0x59, 0x5c, 0xed, 0xb3, 0x06, 0x97, 0x02, 0xa7, 0x43, 0xf1, 0x7a, 0xc3, 0x61, - 0x32, 0x3a, 0x9d, 0x0e, 0x2f, 0x9f, 0x86, 0x8c, 0x92, 0xf9, 0x30, 0x86, 0x89, 0x49, 0x55, 0x32, - 0x94, 0x6a, 0x4f, 0x27, 0x80, 0xfd, 0x57, 0xf6, 0xdf, 0x5e, 0x58, 0x1e, 0x9e, 0x8b, 0xef, 0x5e, - 0x68, 0xe3, 0x9f, 0xab, 0x1e, 0x8e, 0x17, 0x40, 0xd2, 0xc9, 0x83, 0xf9, 0xc8, 0x4b, 0xe2, 0x79, - 0x1e, 0x98, 0x8d, 0xe2, 0xf0, 0x3c, 0x71, 0xee, 0x96, 0x4e, 0x05, 0x6c, 0x57, 0x6e, 0x9d, 0xfe, - 0x21, 0x4c, 0xa0, 0x8e, 0xc1, 0xc6, 0xf2, 0xaf, 0xf3, 0xe2, 0x1f, 0xb7, 0x97, 0x41, 0x7a, 0xa5, - 0xf6, 0x03, 0x17, 0xe0, 0xf2, 0xd4, 0x79, 0x65, 0x76, 0x1d, 0x5e, 0x8b, 0xa8, 0x96, 0x4b, 0x50, - 0x60, 0xd1, 0x09, 0xc0, 0x6e, 0x71, 0xfb, 0xfa, 0xc5, 0xf7, 0xea, 0xec, 0x9f, 0xfc, 0x60, 0x6f, - 0x73, 0xc6, 0xfe, 0xb2, 0xc7, 0xed, 0x66, 0xf6, 0x8f, 0x7e, 0x9f, 0x17, 0xba, 0x1a, 0xe6, 0xd5, - 0xaf, 0xb6, 0xb5, 0x71, 0x1b, 0x88, 0xeb, 0x1b, 0xbc, 0x80, 0x67, 0x0f, 0x64, 0xd1, 0x69, 0xa1, - 0x6b, 0xab, 0xdb, 0x9c, 0x4a, 0xe3, 0x4a, 0xff, 0x7d, 0x4b, 0xe5, 0x0a, 0xcd, 0xb5, 0xec, 0x37, - 0x78, 0xb2, 0xf5, 0xe5, 0x49, 0x29, 0x80, 0x9b, 0x96, 0x60, 0x5d, 0xf4, 0xe8, 0x93, 0x5a, 0xeb, - 0x0e, 0x8f, 0x0d, 0xd8, 0x23, 0x4c, 0xd4, 0x21, 0x9d, 0x00, 0x74, 0x1f, 0xb9, 0x3d, 0x0b, 0x89, - 0x12, 0xaa, 0x80, 0x3e, 0xc1, 0x6d, 0x2e, 0xf4, 0x99, 0x10, 0x4c, 0x54, 0x00, 0x74, 0xee, 0x40, - 0xd2, 0x37, 0x6a, 0xcb, 0x85, 0x42, 0xa9, 0x52, 0x7c, 0x22, 0x38, 0x1c, 0x9f, 0xa5, 0x29, 0x9f, - 0xff, 0xac, 0xb9, 0xb6, 0x3a, 0x93, 0xbe, 0xa6, 0x63, 0x17, 0xa1, 0xd2, 0x51, 0xa4, 0x0d, 0x56, - 0x64, 0x55, 0x7b, 0x57, 0xa5, 0xd2, 0x28, 0x32, 0x7e, 0xf0, 0x0e, 0x13, 0x55, 0x01, 0x3a, 0x2d, - 0x24, 0xca, 0x24, 0x5d, 0xb0, 0x1c, 0x00, 0xdd, 0x7c, 0x8a, 0xd7, 0xf6, 0xe4, 0x2b, 0x40, 0xf9, - 0x4a, 0x59, 0xce, 0x15, 0x27, 0x7f, 0x39, 0x90, 0x47, 0xd3, 0x6b, 0xd7, 0x93, 0x2c, 0xd3, 0xdf, - 0x0e, 0xa3, 0x81, 0xc1, 0xe0, 0xd4, 0x7d, 0xac, 0xc4, 0x75, 0xa7, 0xbb, 0x18, 0x8a, 0xff, 0x8d, - 0xfe, 0xf9, 0xd2, 0xfe, 0xfb, 0x2f, 0x56, 0x81, 0x2f, 0x6a, 0x7c, 0x4b, 0x7f, 0xdb, 0xac, 0xf9, - 0xf4, 0x4b, 0x3a, 0xdf, 0xa1, 0x24, 0x11, 0x34, 0x5b, 0xc8, 0x68, 0x70, 0x08, 0x78, 0x0f, 0x7b, - 0xe0, 0x1a, 0xff, 0xb8, 0xad, 0x0c, 0x95, 0x52, 0xd0, 0x0c, 0xe0, 0xb3, 0xaf, 0x54, 0xfa, 0x78, - 0x21, 0x85, 0xe0, 0x02, 0x43, 0xc5, 0x6f, 0x56, 0x09, 0xcd, 0x16, 0x62, 0x95, 0xbe, 0x4b, 0x42, - 0x28, 0x61, 0xef, 0xd2, 0x0f, 0xc9, 0xb6, 0xe4, 0x00, 0x24, 0xa7, 0x8e, 0x92, 0xa0, 0x5c, 0x01, - 0x4a, 0x89, 0x94, 0xac, 0xe6, 0xff, 0x5d, 0x81, 0xeb, 0x37, 0xcb, 0xe1, 0x90, 0xfe, 0x6e, 0x5a, - 0x5d, 0x5d, 0x6d, 0x6f, 0x6f, 0x3f, 0x3a, 0x3a, 0x92, 0x5c, 0x01, 0x05, 0x3e, 0x25, 0x24, 0xac, - 0x9d, 0x9d, 0x9d, 0xb0, 0xb0, 0x30, 0x62, 0x35, 0x34, 0x34, 0x54, 0x82, 0x06, 0x22, 0x52, 0x55, - 0x55, 0x05, 0x25, 0xc3, 0xc3, 0xc3, 0x92, 0x35, 0x48, 0x6c, 0xa1, 0xe0, 0xe0, 0xe0, 0xa4, 0xa4, - 0xa4, 0x98, 0x98, 0x18, 0x98, 0xbf, 0xb8, 0xb8, 0x90, 0x9c, 0x3f, 0xe8, 0x51, 0xa9, 0x54, 0x91, - 0x91, 0x91, 0x92, 0x35, 0x48, 0xac, 0x00, 0x49, 0xd8, 0xca, 0xca, 0x0a, 0x0c, 0xfb, 0xf9, 0xf9, - 0x09, 0xe7, 0x0f, 0x3d, 0x26, 0x00, 0xb0, 0x5a, 0xad, 0x02, 0x5c, 0xaf, 0x2c, 0x0f, 0x15, 0x68, - 0x6d, 0x6d, 0xcd, 0xce, 0xce, 0x2e, 0x28, 0x28, 0x58, 0x5a, 0x5a, 0xca, 0xc9, 0xc9, 0x09, 0x0c, - 0x0c, 0x4c, 0x4d, 0x4d, 0xed, 0xea, 0xea, 0x12, 0xd5, 0xeb, 0x5b, 0x5b, 0x5b, 0xb5, 0xb5, 0xb5, - 0x59, 0x59, 0x59, 0xc8, 0x31, 0x34, 0xa4, 0xa7, 0xa7, 0x4f, 0x4f, 0x4f, 0x73, 0xd3, 0x3c, 0x37, - 0x37, 0x97, 0x9f, 0x9f, 0x0f, 0x43, 0xb9, 0xb9, 0xb9, 0xbd, 0xbd, 0xbd, 0x5c, 0xd6, 0xe9, 0xe9, - 0x69, 0x49, 0x49, 0x09, 0x58, 0xf5, 0xf5, 0xf5, 0x93, 0x93, 0x93, 0xb0, 0x1e, 0x14, 0x14, 0x54, - 0x54, 0x54, 0x64, 0x34, 0x1a, 0xb9, 0x30, 0x37, 0x7d, 0x37, 0xc4, 0xf8, 0xf8, 0x78, 0xc2, 0x83, - 0x18, 0x57, 0xa0, 0xba, 0xba, 0x9a, 0x07, 0x16, 0xa8, 0x00, 0x22, 0x87, 0x2c, 0xc3, 0x30, 0x88, - 0x21, 0x22, 0x22, 0x02, 0xb4, 0x56, 0xab, 0xdd, 0xdf, 0xdf, 0x67, 0x35, 0x34, 0x37, 0x37, 0xb3, - 0xca, 0x11, 0x2a, 0x7b, 0x0e, 0x82, 0xa8, 0x05, 0x17, 0xc1, 0xab, 0xd5, 0xb7, 0xbf, 0x58, 0x2a, - 0x2b, 0x2b, 0xb9, 0x30, 0x42, 0x7b, 0x68, 0xa1, 0xdd, 0xdd, 0x5d, 0xd2, 0x94, 0x3a, 0x9d, 0x6e, - 0x60, 0x60, 0x60, 0x63, 0x63, 0xa3, 0xb4, 0xb4, 0x94, 0x18, 0x9b, 0x9f, 0x9f, 0xe7, 0xaa, 0x10, - 0x08, 0x60, 0x6a, 0x6a, 0xaa, 0xbb, 0xbb, 0xfb, 0xf0, 0xf0, 0x10, 0x78, 0x8b, 0xc5, 0x42, 0x62, - 0xe0, 0x5e, 0xd6, 0xf3, 0xf3, 0xf3, 0x99, 0x99, 0x19, 0xa2, 0x99, 0x17, 0x00, 0x44, 0x46, 0x46, - 0x46, 0x88, 0xc5, 0xc2, 0xc2, 0x42, 0x58, 0xa9, 0xab, 0xab, 0xc3, 0x16, 0x09, 0xe5, 0x5a, 0x27, - 0xb4, 0x87, 0x00, 0xc0, 0x48, 0x48, 0x48, 0x80, 0x00, 0x2a, 0x48, 0x40, 0xc7, 0xc7, 0xc7, 0xb8, - 0x6a, 0x38, 0x69, 0x6a, 0x6a, 0xe2, 0xaa, 0x10, 0x08, 0x00, 0x30, 0x44, 0xdb, 0xd1, 0xd1, 0xd1, - 0xd8, 0xd8, 0xd8, 0xd6, 0xd6, 0x96, 0x96, 0x96, 0x06, 0xf1, 0xce, 0xce, 0x4e, 0xae, 0x38, 0x68, - 0x28, 0xc4, 0xf9, 0xdd, 0x00, 0xd6, 0xd7, 0xd7, 0x71, 0x8e, 0xb5, 0xbc, 0xbc, 0x0c, 0x18, 0xa6, - 0x2d, 0xd9, 0x9a, 0x4c, 0x26, 0x9e, 0x86, 0xdb, 0x02, 0x11, 0x04, 0xf7, 0x89, 0x1e, 0x25, 0x5b, - 0xbd, 0x5e, 0x9f, 0x92, 0x92, 0x82, 0x52, 0x20, 0xa3, 0x5c, 0xc0, 0x7d, 0xb4, 0xcd, 0x66, 0x2b, - 0x2e, 0x2e, 0x9e, 0x9d, 0x9d, 0x05, 0x40, 0xa3, 0xd1, 0xa0, 0x91, 0x50, 0x04, 0xd0, 0x76, 0xbb, - 0xfd, 0x3e, 0x91, 0xfb, 0xce, 0x33, 0x33, 0x33, 0xc1, 0x8a, 0x8b, 0x8b, 0x23, 0x80, 0xab, 0xab, - 0xab, 0x90, 0x90, 0x10, 0x2e, 0xd8, 0xc3, 0x25, 0x66, 0xd9, 0x0b, 0x0b, 0x0b, 0x84, 0xc6, 0xad, - 0xda, 0xdc, 0xdc, 0x04, 0xcd, 0x5e, 0x0f, 0x16, 0xe3, 0x91, 0x40, 0x03, 0x10, 0xef, 0x27, 0x26, - 0x26, 0x90, 0xb3, 0xcb, 0xcb, 0xcb, 0xb2, 0xb2, 0x32, 0x8f, 0x48, 0xaf, 0x87, 0x08, 0x1e, 0x18, - 0xf2, 0xf4, 0x08, 0x16, 0x0a, 0x60, 0x74, 0x74, 0x74, 0x6c, 0x6c, 0x6c, 0x6f, 0x6f, 0xaf, 0xa1, - 0xa1, 0x01, 0xef, 0x5c, 0xc8, 0xa3, 0x23, 0x59, 0x2d, 0x38, 0x61, 0x33, 0xca, 0xa5, 0x01, 0xc0, - 0x08, 0xc2, 0x33, 0x3c, 0x3c, 0x1c, 0x2d, 0xee, 0xef, 0xef, 0x8f, 0x41, 0x79, 0x72, 0x72, 0x82, - 0x13, 0x54, 0x9f, 0x15, 0x07, 0x0d, 0x29, 0x32, 0xd9, 0xb8, 0x34, 0x01, 0xb0, 0x48, 0x42, 0xb0, - 0x03, 0x90, 0x3d, 0x67, 0xf5, 0x08, 0xdd, 0x81, 0x5b, 0xd0, 0x1b, 0xaa, 0xa6, 0xa6, 0x06, 0xf2, - 0x58, 0x66, 0xb3, 0x39, 0x36, 0x36, 0x96, 0xc7, 0xc5, 0x16, 0x93, 0x97, 0x00, 0x06, 0x07, 0x07, - 0x09, 0x37, 0x23, 0x23, 0xa3, 0xa2, 0xa2, 0x82, 0x05, 0xe3, 0x8d, 0x31, 0x34, 0x34, 0x04, 0x0c, - 0x2a, 0x13, 0x10, 0x10, 0xc0, 0xd3, 0x80, 0x66, 0xeb, 0xef, 0xef, 0x07, 0xf7, 0xe0, 0xe0, 0x00, - 0xf3, 0x83, 0x70, 0x13, 0x13, 0x13, 0xcf, 0xce, 0xce, 0xa2, 0xa3, 0xa3, 0xc9, 0x16, 0xd3, 0x05, - 0xd6, 0x89, 0x15, 0xf2, 0x14, 0xaa, 0x40, 0x4b, 0x4b, 0x4b, 0x5e, 0x5e, 0x5e, 0x54, 0x54, 0x14, - 0x66, 0x62, 0x4f, 0x4f, 0x0f, 0xeb, 0x16, 0x74, 0x91, 0x3b, 0xcd, 0xf3, 0x80, 0x2d, 0x34, 0x06, - 0x2e, 0x8a, 0x86, 0xc9, 0xb3, 0xb6, 0xb6, 0x06, 0x5f, 0xd1, 0xc1, 0x7d, 0x7d, 0x7d, 0xe8, 0x5d, - 0x48, 0x91, 0x4a, 0x42, 0x50, 0xa9, 0xe4, 0x9b, 0x66, 0xc5, 0xc1, 0x45, 0x30, 0x44, 0x39, 0x86, - 0x2f, 0xd2, 0xcf, 0xdd, 0xc2, 0xef, 0xb7, 0xec, 0x72, 0xa3, 0x61, 0x69, 0x32, 0x85, 0x16, 0x17, - 0x17, 0xd9, 0x13, 0x09, 0x04, 0x1a, 0xcc, 0x60, 0x30, 0xdc, 0x9d, 0x1b, 0x12, 0x54, 0x09, 0x88, - 0xf0, 0xa7, 0x10, 0xec, 0xe1, 0xe5, 0x87, 0x27, 0xa2, 0x1c, 0x1f, 0x1f, 0xdf, 0xde, 0xde, 0x2e, - 0x2f, 0x2f, 0xc7, 0x0b, 0xe5, 0xad, 0xa0, 0x1f, 0xb6, 0x41, 0x8e, 0x93, 0x93, 0x93, 0x1f, 0x86, - 0xf5, 0x01, 0xc5, 0x0b, 0x0e, 0x6f, 0x2e, 0x9e, 0x32, 0x74, 0x0e, 0x0f, 0xf3, 0x5e, 0x6d, 0xf9, - 0x15, 0xc0, 0x47, 0x08, 0xbe, 0x2e, 0xf1, 0x9a, 0x24, 0x61, 0xa0, 0x71, 0x31, 0xd1, 0x79, 0x21, - 0xbd, 0x57, 0x5b, 0xf9, 0x7f, 0xa1, 0xc7, 0x2e, 0x07, 0x7f, 0x96, 0x3d, 0xb6, 0x3f, 0xa2, 0xed, - 0xcb, 0x01, 0x88, 0x4e, 0x19, 0x65, 0x01, 0xb9, 0x02, 0x94, 0x13, 0x2a, 0x5a, 0x9d, 0x5c, 0x01, - 0xd1, 0x29, 0xa3, 0x2c, 0xf0, 0x1f, 0x15, 0xdc, 0xd7, 0x70, 0xbb, 0x15, 0xe8, 0x4c, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXTextPlainIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0e, 0xc4, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x09, 0x90, 0x54, 0xc5, 0xf5, 0xcd, 0xcc, 0x9e, 0xdc, 0x57, 0x40, 0x2e, 0x5d, 0xee, 0xfb, - 0x08, 0x2b, 0x22, 0x87, 0x58, 0x12, 0xce, 0x70, 0xc7, 0x14, 0x10, 0x81, 0x18, 0x52, 0x21, 0x72, - 0x05, 0x39, 0xb6, 0x8c, 0x86, 0xaa, 0x68, 0x82, 0x40, 0x15, 0x1a, 0x20, 0x80, 0x28, 0x90, 0x18, - 0x24, 0xa6, 0x8a, 0x32, 0x51, 0x63, 0x89, 0x21, 0x01, 0x53, 0x50, 0x04, 0x10, 0xb1, 0x90, 0x02, - 0x42, 0x20, 0xc5, 0xa9, 0x72, 0x83, 0xe1, 0x5a, 0x98, 0xdd, 0xd9, 0x99, 0xfd, 0x79, 0xaf, 0x67, - 0xbb, 0xa7, 0xff, 0x39, 0xff, 0xff, 0x9d, 0xf9, 0xb3, 0x8b, 0xbf, 0xab, 0x66, 0xba, 0xfb, 0xf5, - 0xbb, 0xfa, 0xbd, 0xee, 0xfe, 0xdd, 0xff, 0x77, 0xff, 0x1f, 0x50, 0x30, 0x80, 0x83, 0x10, 0x74, - 0x80, 0xcb, 0x50, 0x53, 0x4b, 0xf0, 0xc2, 0xd0, 0x7b, 0xb0, 0x76, 0x76, 0x89, 0x4a, 0x89, 0xa4, - 0x12, 0xe6, 0xbc, 0x96, 0xa7, 0x22, 0x00, 0xaa, 0xb4, 0x1c, 0x9e, 0x1f, 0x72, 0x57, 0xa1, 0x1f, - 0x85, 0x33, 0x87, 0x63, 0x22, 0xcd, 0x71, 0x02, 0x94, 0x50, 0xb3, 0xb0, 0xce, 0x25, 0x55, 0x49, - 0x4b, 0xae, 0x23, 0x08, 0x04, 0x02, 0x5a, 0x1c, 0x55, 0x5e, 0x45, 0xf0, 0xe5, 0x97, 0x5f, 0x8a, - 0xc2, 0x8d, 0x1b, 0x37, 0xb2, 0x74, 0x61, 0x61, 0xa1, 0x80, 0xb1, 0x04, 0xaf, 0xcc, 0xec, 0xd9, - 0xb3, 0x79, 0xd2, 0x32, 0x76, 0x5c, 0x69, 0xc7, 0x04, 0xaa, 0x3a, 0xa8, 0x95, 0x35, 0xce, 0x39, - 0x26, 0xc8, 0x92, 0xf9, 0x50, 0xdb, 0xe1, 0xa1, 0x5d, 0x61, 0x08, 0x6e, 0x5d, 0x53, 0x60, 0xd2, - 0x0b, 0xb9, 0xd0, 0xb4, 0x8d, 0x64, 0x6a, 0xad, 0x49, 0x78, 0xb3, 0x20, 0xf8, 0xe5, 0xb3, 0xe5, - 0xda, 0x62, 0x45, 0xa5, 0xd2, 0x1b, 0xf3, 0x4a, 0x99, 0x80, 0x97, 0xc6, 0x85, 0x59, 0xbc, 0xea, - 0xa7, 0x61, 0x90, 0xa5, 0x12, 0xb0, 0x0a, 0x5a, 0x89, 0xd5, 0x81, 0x1a, 0xdc, 0xd2, 0xa5, 0x4b, - 0x99, 0xde, 0x4c, 0x4f, 0xcc, 0xcb, 0x8d, 0xb0, 0x7f, 0xff, 0xfe, 0x22, 0xcf, 0xea, 0x40, 0x85, - 0x68, 0x0e, 0x41, 0x60, 0x95, 0x60, 0x12, 0xec, 0x22, 0x33, 0xe9, 0x64, 0x68, 0x2b, 0x8e, 0x95, - 0x2d, 0x53, 0xf9, 0xad, 0xb2, 0xcc, 0x8c, 0xe8, 0x55, 0x4d, 0x4f, 0x8b, 0xa0, 0x6d, 0x14, 0x54, - 0xbe, 0x6c, 0x7b, 0x0d, 0x86, 0x46, 0x65, 0xf3, 0x36, 0xe4, 0x43, 0x93, 0x02, 0xa9, 0x59, 0x6a, - 0x19, 0x60, 0xde, 0xb2, 0x06, 0xfd, 0xc7, 0x67, 0x0b, 0x86, 0xc4, 0x78, 0xc4, 0x4f, 0x72, 0x18, - 0x8b, 0xf7, 0x56, 0x46, 0x58, 0xfc, 0xe1, 0xba, 0x08, 0xfc, 0xf1, 0xa5, 0x08, 0x14, 0xdf, 0x30, - 0xe0, 0xcc, 0x41, 0xe4, 0x83, 0x64, 0x41, 0xee, 0x1f, 0x1c, 0x97, 0x60, 0x5b, 0x96, 0x95, 0xb2, - 0xec, 0xe6, 0x5f, 0xc6, 0x63, 0x5e, 0x26, 0xc7, 0x8e, 0xbb, 0x02, 0x57, 0xcc, 0x6e, 0x6c, 0x69, - 0x22, 0xbb, 0x4c, 0xac, 0xf0, 0x92, 0x0a, 0xd8, 0xb9, 0x73, 0xa7, 0x15, 0x3d, 0x0c, 0x1b, 0x36, - 0xcc, 0xb2, 0x5c, 0x75, 0xa9, 0x42, 0x4c, 0xe5, 0x99, 0x67, 0x9e, 0xa1, 0x7e, 0x21, 0xcc, 0x28, - 0xa7, 0x6b, 0xd6, 0xac, 0xa9, 0x94, 0x96, 0x96, 0xaa, 0xca, 0xeb, 0xd4, 0xa9, 0x23, 0x70, 0xeb, - 0xd7, 0xaf, 0xaf, 0x10, 0x8e, 0x4c, 0x93, 0xe0, 0x84, 0x68, 0x54, 0xc0, 0x7f, 0x44, 0xc5, 0xd3, - 0x9c, 0x40, 0xce, 0xdf, 0xb8, 0x71, 0xc3, 0xb2, 0x7c, 0xcc, 0x98, 0x31, 0x4c, 0x70, 0xf5, 0x77, - 0x72, 0xf5, 0xaf, 0x41, 0xd2, 0x66, 0x8a, 0x8e, 0xad, 0x54, 0xa8, 0xfe, 0x02, 0x4c, 0x87, 0x6b, - 0xa3, 0xa1, 0x9a, 0x6c, 0x25, 0x0f, 0xd7, 0x3c, 0x6d, 0x65, 0x43, 0x4b, 0x13, 0xc9, 0x0c, 0xe4, - 0x34, 0x9f, 0xea, 0x52, 0xfc, 0xfa, 0xb3, 0xf1, 0xc9, 0x85, 0x99, 0x10, 0x53, 0x01, 0x7d, 0x46, - 0x65, 0xeb, 0x68, 0xba, 0x0c, 0x88, 0x57, 0xb8, 0xee, 0xb7, 0xe2, 0x64, 0x14, 0x37, 0x68, 0x6a, - 0x7d, 0xc1, 0x51, 0x0d, 0x15, 0xac, 0x6f, 0x6b, 0xfe, 0x68, 0xdc, 0x37, 0xbb, 0x1e, 0x68, 0x50, - 0x0d, 0xb3, 0xa6, 0x35, 0xd0, 0xa9, 0x6f, 0x02, 0x28, 0x8f, 0x81, 0xa5, 0x99, 0x2c, 0x7b, 0xb2, - 0xd6, 0xd1, 0xb2, 0x1f, 0xe4, 0xb2, 0x99, 0xbf, 0xcd, 0x83, 0x07, 0x3b, 0x19, 0xeb, 0x6a, 0x29, - 0xc0, 0x44, 0x69, 0x47, 0x60, 0x63, 0xb1, 0x8e, 0x58, 0x58, 0x23, 0xdf, 0xe7, 0x02, 0xe8, 0x7a, - 0x7c, 0xe5, 0xca, 0x15, 0x4b, 0x1b, 0x74, 0xeb, 0xd6, 0xcd, 0xb2, 0x3c, 0x69, 0x3f, 0x18, 0x3e, - 0x7c, 0xb8, 0x61, 0xfb, 0xb6, 0x0b, 0x14, 0x3e, 0x58, 0xb7, 0x6e, 0x1d, 0x9b, 0x73, 0x2f, 0x5e, - 0xbc, 0x58, 0xcc, 0xbd, 0xb5, 0xaa, 0xcd, 0x9b, 0x37, 0x0f, 0x96, 0x2f, 0x5f, 0x0e, 0x7b, 0xf6, - 0xec, 0x61, 0x45, 0x53, 0xa7, 0x4e, 0x15, 0xb8, 0xc5, 0xc5, 0xc5, 0x2c, 0x8d, 0x93, 0x06, 0x68, - 0xd7, 0xae, 0x5d, 0x82, 0x54, 0xd6, 0xe4, 0xb1, 0xc7, 0x1e, 0x63, 0x59, 0x2c, 0x15, 0x60, 0x5e, - 0x83, 0xd3, 0xa7, 0x4f, 0x2b, 0x8d, 0x1b, 0x37, 0x56, 0x56, 0xaf, 0x5e, 0xad, 0xe0, 0xe2, 0x40, - 0x94, 0xcb, 0xb8, 0x3c, 0xcd, 0x63, 0x42, 0x4a, 0x70, 0xc2, 0x4c, 0xed, 0xda, 0xb5, 0xd9, 0x4c, - 0xe1, 0xc8, 0x91, 0x23, 0x8c, 0x01, 0x21, 0xf2, 0xdf, 0xb5, 0x6b, 0xb8, 0x08, 0x93, 0xf2, 0x8c, - 0x58, 0xca, 0xbf, 0xf3, 0xce, 0x3b, 0xac, 0x7c, 0xdc, 0xb8, 0x71, 0x2c, 0x66, 0x0c, 0xf0, 0x4f, - 0x0c, 0xd7, 0x33, 0x67, 0xce, 0x84, 0x26, 0x4d, 0x9a, 0xc0, 0xed, 0xdb, 0xb7, 0x91, 0x4f, 0x3c, - 0x60, 0x39, 0x4f, 0xb2, 0xd8, 0x69, 0x9e, 0x88, 0xfc, 0x9e, 0xac, 0x32, 0xa1, 0x51, 0x26, 0xed, - 0x26, 0x32, 0x12, 0x9a, 0x4a, 0x98, 0xe8, 0x67, 0xa9, 0x64, 0xea, 0x25, 0x2f, 0xbf, 0x02, 0x5e, - 0x5a, 0xdb, 0x48, 0x96, 0x18, 0x87, 0x8c, 0x0a, 0xcd, 0x60, 0xf2, 0x6c, 0xc2, 0x0c, 0x87, 0xc3, - 0xe5, 0x59, 0x08, 0xc1, 0x38, 0xed, 0x8b, 0xef, 0xd7, 0x80, 0xbc, 0x9a, 0x1c, 0xcb, 0x7d, 0x5c, - 0xa9, 0x26, 0x34, 0x7f, 0x63, 0x3e, 0xd0, 0x4f, 0x0e, 0x46, 0x30, 0xb9, 0x9c, 0xa7, 0xe9, 0xee, - 0x5b, 0x2a, 0x82, 0x2b, 0x0f, 0x70, 0xc1, 0x8d, 0x1f, 0xd2, 0x4f, 0x79, 0x8d, 0x60, 0xa7, 0x3e, - 0x2f, 0x87, 0xdf, 0x3f, 0xaf, 0xbe, 0xed, 0x4c, 0x37, 0xf7, 0xe4, 0x90, 0x57, 0x33, 0x00, 0x2f, - 0xbe, 0xaf, 0x36, 0x86, 0x5c, 0x6e, 0x96, 0x4e, 0xc9, 0x30, 0xca, 0x9b, 0x05, 0x09, 0xd1, 0x36, - 0x19, 0xad, 0x60, 0x8e, 0x6b, 0xe7, 0x26, 0x93, 0x96, 0xd6, 0x28, 0x5f, 0xa9, 0x26, 0x64, 0xc4, - 0xd0, 0x2e, 0xac, 0xf4, 0x5e, 0x6a, 0x9a, 0x90, 0x6b, 0x0f, 0xfc, 0xf9, 0x95, 0x08, 0x7c, 0xbe, - 0x23, 0x6a, 0xaa, 0xef, 0x03, 0xad, 0x82, 0xf0, 0xec, 0x7a, 0xcd, 0xc3, 0x07, 0xc4, 0xe6, 0x1e, - 0x30, 0x23, 0x4c, 0xe6, 0x41, 0x2d, 0x9d, 0xeb, 0x0a, 0x68, 0x19, 0x39, 0xcd, 0xdf, 0xbd, 0x05, - 0xf0, 0xdf, 0x03, 0x31, 0x68, 0xd8, 0x2c, 0x00, 0x2d, 0x71, 0x4d, 0x14, 0x74, 0xd9, 0x16, 0x32, - 0x56, 0x01, 0xa7, 0x15, 0x36, 0xc3, 0x77, 0x59, 0x6f, 0x33, 0x76, 0xde, 0xc3, 0xfd, 0x0a, 0x78, - 0x6f, 0x73, 0xb5, 0x44, 0xd7, 0x1e, 0x98, 0x3f, 0x7f, 0x3e, 0x5b, 0xe5, 0xd1, 0x03, 0x99, 0x11, - 0x23, 0x46, 0xa8, 0xb9, 0x3a, 0xc8, 0x11, 0xbd, 0xfc, 0xc4, 0xc7, 0x01, 0x69, 0x1c, 0x95, 0x2f, - 0xce, 0xe4, 0xb8, 0x45, 0x8b, 0x16, 0x6c, 0xe1, 0xb6, 0x63, 0xc7, 0x0e, 0x16, 0x23, 0x26, 0x5b, - 0x10, 0x96, 0x97, 0xeb, 0x9f, 0xa5, 0x51, 0x19, 0x5f, 0x79, 0xca, 0x3c, 0x66, 0xcc, 0x98, 0x21, - 0x68, 0x09, 0xa7, 0x7b, 0xf7, 0xee, 0x72, 0x31, 0x4b, 0x13, 0x9c, 0xff, 0xe4, 0xc2, 0xa3, 0x47, - 0x8f, 0x0a, 0xf8, 0xa0, 0x41, 0x83, 0x44, 0xfa, 0xde, 0xbd, 0x7b, 0x32, 0x5a, 0x9c, 0x87, 0x0e, - 0x52, 0x01, 0x20, 0xc6, 0x6d, 0xdb, 0xb6, 0x15, 0xc5, 0xf4, 0x08, 0x95, 0x60, 0xb4, 0x7a, 0x95, - 0x03, 0xc1, 0x8c, 0x2a, 0x40, 0x37, 0xe5, 0xe7, 0xcc, 0x99, 0xa3, 0xd0, 0x52, 0x7b, 0xfa, 0xf4, - 0xe9, 0x8c, 0x76, 0xd9, 0xb2, 0x65, 0x32, 0x29, 0x4b, 0xf7, 0xea, 0xd5, 0x8b, 0x95, 0x69, 0x0b, - 0xfa, 0xf5, 0xeb, 0xa7, 0x82, 0x1b, 0x55, 0x94, 0x68, 0x54, 0xcb, 0x6e, 0x99, 0x09, 0x27, 0x38, - 0x77, 0xee, 0x9c, 0x42, 0x35, 0xe7, 0x79, 0x19, 0x87, 0x31, 0x30, 0xa8, 0x00, 0x29, 0x4e, 0xf8, - 0x67, 0xce, 0x9c, 0x61, 0xe8, 0xfc, 0xc6, 0xbf, 0x7c, 0x3f, 0x80, 0xf3, 0x49, 0x6b, 0x05, 0x70, - 0xa9, 0xcf, 0xe5, 0xb8, 0x8a, 0xb7, 0x6f, 0xdf, 0xae, 0x5c, 0xbd, 0x7a, 0xd5, 0x15, 0xad, 0x5d, - 0x22, 0xc3, 0x0b, 0x99, 0xb6, 0x53, 0x21, 0x33, 0x34, 0x68, 0xd5, 0x0c, 0x86, 0xd3, 0xe9, 0xaa, - 0xac, 0xb0, 0xd6, 0x8c, 0xae, 0x87, 0x51, 0x2d, 0xa3, 0x4c, 0xe5, 0xab, 0x7d, 0x05, 0x0c, 0xfb, - 0x40, 0xa6, 0xac, 0xe9, 0x46, 0x6e, 0xb5, 0xf7, 0x80, 0x5f, 0x01, 0x37, 0x6e, 0x4f, 0x25, 0x8d, - 0xef, 0x81, 0x54, 0x5a, 0xd3, 0x0d, 0x2f, 0xdf, 0x03, 0x6e, 0xac, 0x96, 0x4a, 0x1a, 0xcf, 0x3d, - 0x40, 0x77, 0x23, 0x52, 0x19, 0x0c, 0xe7, 0x42, 0x56, 0x02, 0xce, 0xfd, 0xbb, 0x1c, 0xd6, 0x2f, - 0x50, 0xdf, 0x26, 0x34, 0xc3, 0x1f, 0x33, 0x3b, 0x07, 0xfa, 0x8e, 0x4d, 0x88, 0xd8, 0x58, 0x54, - 0x0a, 0x67, 0x8e, 0xc4, 0xd8, 0x0a, 0x6c, 0xe9, 0x3f, 0x9c, 0xdf, 0x46, 0x34, 0x92, 0xe3, 0xd8, - 0x03, 0x27, 0x3e, 0xc5, 0x27, 0xe8, 0x36, 0xc3, 0x7f, 0xf6, 0xa9, 0x71, 0x6f, 0x56, 0xdc, 0xd0, - 0x4d, 0xe5, 0x64, 0x31, 0x61, 0x1e, 0x9b, 0x4a, 0xdd, 0xbb, 0x1d, 0x9f, 0x5a, 0x77, 0x7c, 0x24, - 0x04, 0x23, 0xa6, 0xe7, 0x40, 0xa4, 0x44, 0x81, 0xd7, 0x7e, 0x16, 0xf7, 0xc8, 0x84, 0x9f, 0xe7, - 0x42, 0xf3, 0xb6, 0x41, 0xf8, 0xec, 0xef, 0x51, 0xd8, 0xf3, 0x6e, 0x19, 0x84, 0x8b, 0xd3, 0x3f, - 0x0d, 0x77, 0x5e, 0x81, 0x3b, 0xf1, 0x9a, 0xd6, 0x6b, 0x1c, 0x04, 0xba, 0x13, 0x1d, 0x09, 0x27, - 0xee, 0x50, 0x37, 0x78, 0x20, 0xc0, 0x60, 0x8d, 0x5a, 0xc4, 0x61, 0xe1, 0xe2, 0x38, 0xee, 0x67, - 0xdb, 0x62, 0xf0, 0xe9, 0x47, 0x65, 0x70, 0xfb, 0x7a, 0xa2, 0x42, 0x7c, 0xe7, 0x08, 0x61, 0x34, - 0x6c, 0x16, 0x84, 0x1f, 0x2c, 0x8a, 0x6f, 0x00, 0x8c, 0x53, 0xd8, 0xff, 0x77, 0x5c, 0x81, 0x58, - 0x24, 0xae, 0x44, 0xae, 0xc5, 0xc3, 0x89, 0x5a, 0x75, 0xe3, 0x15, 0x88, 0xc6, 0x37, 0x23, 0xc2, - 0x7b, 0x2b, 0xf5, 0x5b, 0x5b, 0x2e, 0x9c, 0x2c, 0x17, 0x5a, 0x52, 0xda, 0xb3, 0x0a, 0x3c, 0xb9, - 0x30, 0x17, 0x36, 0x14, 0x95, 0xc0, 0x90, 0xa7, 0xf5, 0xdb, 0x66, 0xb8, 0x46, 0x5d, 0x06, 0x84, - 0x80, 0x6e, 0xee, 0x7e, 0xbf, 0x28, 0x6e, 0xd5, 0x1f, 0x2f, 0xcb, 0x83, 0xfd, 0x1f, 0x46, 0xe1, - 0xd4, 0xe7, 0x31, 0xd6, 0xe4, 0x08, 0xaf, 0x73, 0xbf, 0x84, 0xed, 0x3a, 0xf4, 0x76, 0xdc, 0x15, - 0xb9, 0xa8, 0xca, 0x3f, 0x89, 0x8e, 0xe0, 0x73, 0x8a, 0x17, 0xc7, 0xc6, 0xf7, 0x3e, 0xcf, 0x58, - 0x99, 0x07, 0x0f, 0x75, 0x31, 0x57, 0xe6, 0x95, 0xa7, 0x4b, 0xe0, 0x7f, 0x97, 0xe2, 0x96, 0x77, - 0x7a, 0x17, 0x5a, 0x68, 0xac, 0x49, 0x98, 0x4b, 0xd3, 0x20, 0x56, 0xd5, 0xac, 0xa7, 0x15, 0xc0, - 0x9b, 0x70, 0x29, 0x0f, 0x9e, 0x56, 0x20, 0xaf, 0x96, 0xb1, 0xfe, 0x74, 0xbd, 0x78, 0x69, 0x6c, - 0x18, 0x2e, 0x9e, 0x4a, 0x8c, 0x52, 0xc6, 0x98, 0x7a, 0xa8, 0xeb, 0x25, 0xa5, 0x9b, 0x27, 0x2d, - 0x7b, 0xdf, 0x8f, 0xc2, 0xd6, 0xd7, 0x2b, 0x86, 0x26, 0xbd, 0x2e, 0xd0, 0xb4, 0x75, 0x10, 0xe6, - 0xbe, 0xa1, 0x7f, 0xaa, 0x63, 0x80, 0x2a, 0x40, 0x69, 0xf3, 0x40, 0xb4, 0x4c, 0xc8, 0x10, 0x89, - 0xfe, 0xe3, 0xb3, 0xa0, 0x7e, 0x13, 0x63, 0x91, 0x4d, 0x1e, 0x72, 0xae, 0x3c, 0x31, 0x76, 0xed, - 0x01, 0xa1, 0x95, 0xcb, 0xc4, 0x17, 0xc7, 0xca, 0x71, 0x97, 0xba, 0x82, 0xa7, 0x34, 0x6c, 0xec, - 0x50, 0xb4, 0x90, 0x91, 0xb1, 0x0a, 0x58, 0xe8, 0xe4, 0xa8, 0xc8, 0xd8, 0x9f, 0x8e, 0x58, 0x64, - 0x16, 0xd9, 0xaf, 0x40, 0x66, 0xed, 0x9f, 0xe4, 0xc8, 0x48, 0xa6, 0x95, 0xb3, 0x23, 0xdf, 0x6f, - 0x42, 0x76, 0xac, 0x94, 0x4e, 0x9c, 0x6a, 0xef, 0x81, 0xc4, 0xa4, 0xdc, 0xa1, 0x99, 0xf0, 0xd9, - 0x19, 0x9c, 0x3d, 0x7b, 0x96, 0x51, 0x3d, 0xf1, 0xc4, 0x13, 0x0e, 0xa9, 0x13, 0xe8, 0xf4, 0x34, - 0x28, 0x1a, 0x8d, 0x42, 0x28, 0x14, 0x4a, 0x00, 0x1d, 0xa4, 0x5c, 0x5f, 0xc8, 0xe4, 0xc7, 0x50, - 0x6e, 0x17, 0xe9, 0xf8, 0xf0, 0x0f, 0x1a, 0x34, 0x68, 0x00, 0x17, 0x2e, 0x5c, 0x80, 0x66, 0xcd, - 0x9a, 0x39, 0x50, 0x3b, 0x81, 0xea, 0xba, 0x09, 0x91, 0xd2, 0x0b, 0x16, 0x2c, 0x48, 0x70, 0x72, - 0x91, 0xc2, 0x33, 0x50, 0xf4, 0x94, 0xd4, 0xb5, 0xf2, 0x24, 0x52, 0x57, 0x01, 0x72, 0x27, 0x59, - 0x97, 0x7e, 0x43, 0x87, 0x0e, 0x15, 0x69, 0xda, 0xbf, 0x6d, 0x37, 0xdc, 0xbd, 0x7b, 0x17, 0xb2, - 0xb3, 0xb3, 0x05, 0x2d, 0xf1, 0x3a, 0x74, 0xe8, 0x90, 0x8a, 0xfc, 0xa9, 0xa7, 0x9e, 0x12, 0xe5, - 0xeb, 0xd7, 0xaf, 0x57, 0x95, 0xe1, 0xc1, 0x2e, 0x56, 0x46, 0xfb, 0xc0, 0xb9, 0x2e, 0x93, 0x26, - 0x4d, 0x52, 0xe1, 0x88, 0x0c, 0x5a, 0x40, 0x17, 0xe8, 0x01, 0x37, 0x22, 0x28, 0xc1, 0x60, 0x50, - 0xd9, 0xbc, 0x79, 0xb3, 0x82, 0x6e, 0x66, 0xf9, 0xb7, 0xde, 0x7a, 0x4b, 0x85, 0x8b, 0x1e, 0x60, - 0x70, 0x15, 0x10, 0x33, 0x1f, 0x7f, 0xfc, 0xb1, 0xd2, 0xb2, 0x65, 0x4b, 0x16, 0xe3, 0xc6, 0x73, - 0x86, 0x43, 0xfc, 0xe4, 0x40, 0x8f, 0x60, 0x47, 0x8e, 0x1c, 0xc9, 0xca, 0x56, 0xae, 0x5c, 0x29, - 0x17, 0x29, 0xcf, 0x3d, 0xf7, 0x9c, 0xa0, 0xa1, 0x67, 0xce, 0x79, 0x79, 0x79, 0x86, 0x72, 0x88, - 0x48, 0xcd, 0xb5, 0x82, 0xcd, 0xc2, 0x85, 0x0b, 0x75, 0x04, 0xa4, 0x80, 0x56, 0x09, 0xb3, 0x0a, - 0x10, 0x9b, 0xb7, 0xdf, 0x7e, 0x5b, 0xa1, 0xbd, 0xe6, 0xf4, 0x14, 0xbf, 0xa0, 0xa0, 0x40, 0x47, - 0x5b, 0x21, 0x8a, 0xc1, 0xb5, 0x15, 0xa0, 0x32, 0x92, 0xf5, 0xf8, 0xe3, 0x8f, 0x33, 0x34, 0xbe, - 0xf5, 0x00, 0xfb, 0x0a, 0xcb, 0xcb, 0x7f, 0xba, 0x26, 0x84, 0x84, 0x95, 0x0e, 0xf5, 0xea, 0xd5, - 0x83, 0x29, 0x53, 0xa6, 0x40, 0xa3, 0x46, 0x8d, 0x00, 0xf7, 0x4c, 0xb0, 0x66, 0xe0, 0x86, 0x29, - 0x1f, 0xdd, 0x88, 0x1f, 0x05, 0xdc, 0xbe, 0xa0, 0x63, 0x63, 0x59, 0x81, 0x47, 0x1f, 0x7d, 0x94, - 0x11, 0x90, 0x12, 0x14, 0x66, 0xcd, 0x9a, 0xc5, 0xe2, 0x64, 0x7f, 0xb7, 0x6e, 0xdd, 0xc2, 0x2d, - 0x64, 0x41, 0xa0, 0x33, 0xec, 0x63, 0xc7, 0x8e, 0x85, 0xba, 0x75, 0xeb, 0x26, 0x23, 0x71, 0x5f, - 0x2e, 0xbb, 0x83, 0xa7, 0x79, 0x13, 0x42, 0xae, 0xcc, 0x95, 0x14, 0xe3, 0x71, 0x10, 0x5e, 0xac, - 0xa0, 0x42, 0x02, 0x2e, 0xe3, 0xe0, 0x01, 0x7c, 0x86, 0xd3, 0xb4, 0x69, 0x53, 0x55, 0x39, 0x6f, - 0xc3, 0x84, 0x4b, 0x61, 0xdf, 0xbe, 0x7d, 0xaa, 0x72, 0xce, 0xa3, 0x4d, 0x9b, 0x36, 0xac, 0x9c, - 0xe7, 0x29, 0xe6, 0xfb, 0x2c, 0x38, 0x8c, 0x21, 0x48, 0x7f, 0x96, 0x17, 0x32, 0xc4, 0x43, 0x3a, - 0x7d, 0xb8, 0x79, 0xf3, 0xa6, 0x1e, 0x28, 0x41, 0x2e, 0x5e, 0xbc, 0xc8, 0x2e, 0x72, 0xe7, 0xcf, - 0x9f, 0x07, 0xdc, 0xad, 0x22, 0x95, 0xc4, 0x93, 0x7d, 0xfb, 0xf6, 0x65, 0xc3, 0xa7, 0xae, 0xa0, - 0x02, 0xa0, 0x95, 0xab, 0xcd, 0xab, 0xe8, 0xa4, 0xca, 0xb0, 0x24, 0x1e, 0xce, 0x51, 0x3a, 0x76, - 0xec, 0xc8, 0x2c, 0x84, 0x43, 0x97, 0xb2, 0x77, 0xef, 0x5e, 0x2d, 0x4a, 0x95, 0xca, 0xeb, 0x46, - 0xa1, 0x21, 0x43, 0x86, 0xa8, 0xdc, 0x3b, 0x7e, 0xfc, 0xf8, 0x2a, 0xa5, 0xb0, 0x56, 0x19, 0xd7, - 0x53, 0x09, 0x95, 0x1b, 0x33, 0x98, 0xb1, 0x1c, 0x85, 0x32, 0xa8, 0x97, 0x6d, 0xd1, 0x7e, 0x05, - 0x6c, 0x9b, 0x2a, 0x4d, 0x88, 0xbe, 0x07, 0xd2, 0x64, 0x58, 0xdb, 0x6c, 0xab, 0xfd, 0x28, 0x64, - 0xbb, 0xa6, 0x55, 0x14, 0xb1, 0xda, 0x77, 0x81, 0x2a, 0x6a, 0x57, 0xdb, 0x6a, 0xf9, 0x0e, 0xb0, - 0x6d, 0xaa, 0xf4, 0x20, 0xfa, 0x0e, 0x48, 0x8f, 0x5d, 0x6d, 0x73, 0xf5, 0x1d, 0x60, 0xdb, 0x54, - 0xe9, 0x41, 0xf4, 0x1d, 0x90, 0x1e, 0xbb, 0xda, 0xe6, 0xea, 0x3b, 0xc0, 0xb6, 0xa9, 0xd2, 0x83, - 0xe8, 0x3b, 0x20, 0x3d, 0x76, 0xb5, 0xcd, 0xd5, 0xf2, 0x86, 0x96, 0x6d, 0x2e, 0x36, 0x10, 0x2f, - 0x9d, 0x56, 0xe0, 0xfa, 0x85, 0x72, 0x30, 0xda, 0x3b, 0x61, 0x83, 0x5c, 0x85, 0x12, 0xc4, 0x87, - 0x38, 0x75, 0x1b, 0x05, 0xa0, 0xa0, 0xab, 0x75, 0xfb, 0x39, 0x79, 0xb0, 0x1c, 0xfe, 0xb6, 0x21, - 0x02, 0xf8, 0x0e, 0x49, 0xa8, 0x5d, 0x3f, 0x00, 0x7d, 0x46, 0x67, 0xc3, 0x77, 0xa6, 0x78, 0x56, - 0x65, 0x95, 0xce, 0x66, 0x19, 0x4f, 0x16, 0x62, 0x7b, 0xde, 0x8d, 0xc2, 0x47, 0xeb, 0xcd, 0x77, - 0xd7, 0x98, 0x29, 0x97, 0x0c, 0xde, 0x73, 0x50, 0x16, 0x4c, 0x7c, 0xde, 0x7c, 0x93, 0xe3, 0x6f, - 0xa6, 0x95, 0x30, 0xa7, 0xcb, 0x7c, 0xe6, 0xff, 0x2e, 0x1f, 0x1a, 0x3f, 0x98, 0x86, 0x0d, 0x57, - 0xb2, 0x10, 0x07, 0x69, 0xeb, 0x26, 0xe4, 0x80, 0x91, 0x15, 0xea, 0x8d, 0x2b, 0xc6, 0xb7, 0x86, - 0xad, 0x68, 0xec, 0x94, 0x25, 0xe3, 0x5b, 0x9e, 0xd8, 0xcf, 0x29, 0xd8, 0x29, 0x06, 0x30, 0x51, - 0x98, 0x81, 0x84, 0x27, 0xfd, 0x91, 0xef, 0x51, 0xe6, 0xf5, 0x7b, 0x78, 0x58, 0x16, 0x3c, 0xb9, - 0x30, 0xd1, 0x72, 0xe5, 0xfd, 0x9a, 0x1c, 0x87, 0x62, 0xed, 0xde, 0xcd, 0x7d, 0x7f, 0x8d, 0x02, - 0xbd, 0xc7, 0x93, 0x87, 0xf0, 0x9d, 0xf4, 0x38, 0x96, 0xf3, 0xf7, 0x22, 0xf6, 0xc4, 0x01, 0x5a, - 0x43, 0xd1, 0x9b, 0x3b, 0xdc, 0x84, 0xbc, 0x1a, 0x6a, 0x3a, 0x79, 0x43, 0x79, 0x18, 0xf7, 0x71, - 0x2f, 0x99, 0x10, 0x86, 0x58, 0xcc, 0xda, 0x29, 0xda, 0xb7, 0x88, 0x68, 0xf5, 0xe8, 0xd0, 0x3b, - 0x04, 0x3f, 0x5a, 0x92, 0xab, 0x05, 0xa7, 0x2d, 0xef, 0xc9, 0x10, 0xd4, 0xe6, 0xdb, 0xea, 0xad, - 0x0f, 0xad, 0x7b, 0xba, 0x13, 0xdb, 0xac, 0x9d, 0x9a, 0xae, 0x75, 0xf7, 0x04, 0xdf, 0x2c, 0xec, - 0x50, 0xa1, 0x44, 0xa7, 0x72, 0x6d, 0x30, 0xb7, 0x8d, 0xc3, 0xad, 0x40, 0x4f, 0x2e, 0xc2, 0xc9, - 0x94, 0xb3, 0x3b, 0x04, 0x25, 0xe3, 0xa3, 0x2d, 0x97, 0xb7, 0x97, 0xf3, 0xb2, 0x54, 0xbd, 0x86, - 0x86, 0xf3, 0xab, 0x6c, 0xac, 0x6e, 0x52, 0x95, 0xe5, 0xe6, 0xd3, 0x3b, 0xb6, 0x80, 0xef, 0x00, - 0xc7, 0x26, 0x4b, 0x2d, 0xc1, 0x7d, 0xed, 0x80, 0x6c, 0x83, 0x6b, 0xc2, 0xf5, 0xf3, 0xc9, 0xe7, - 0xa1, 0x26, 0x1b, 0x2a, 0x52, 0x6b, 0xf9, 0x0a, 0x6e, 0x9e, 0xcc, 0x82, 0x64, 0xcd, 0x69, 0x25, - 0x4c, 0x1b, 0xed, 0xe9, 0x00, 0x63, 0x19, 0x7b, 0x81, 0x38, 0x40, 0xcc, 0xe4, 0xbd, 0x56, 0x9f, - 0x6e, 0x8d, 0xc2, 0xf1, 0xfd, 0xf1, 0x99, 0x0f, 0x6d, 0x61, 0x6c, 0xd1, 0x21, 0x08, 0xad, 0x7b, - 0x84, 0x20, 0x37, 0xfe, 0xfa, 0x7a, 0x99, 0xad, 0x61, 0xba, 0x51, 0xcb, 0x20, 0x5c, 0xf9, 0x42, - 0x6d, 0xf0, 0x3f, 0x2d, 0x8e, 0xc0, 0xc3, 0xc3, 0x43, 0xd0, 0xa9, 0x6f, 0x08, 0xdf, 0x6a, 0x17, - 0x80, 0x1b, 0x97, 0x15, 0x38, 0x7b, 0x34, 0x06, 0xc7, 0xf6, 0xc6, 0x40, 0x3b, 0x5b, 0xeb, 0xd4, - 0x37, 0x0b, 0x7e, 0xf8, 0x2b, 0x03, 0x2f, 0x1a, 0x4a, 0x73, 0x07, 0xf4, 0xfc, 0x22, 0xfc, 0xeb, - 0xef, 0x85, 0x2b, 0x7d, 0x1e, 0xb1, 0x68, 0x53, 0x3e, 0x7b, 0x11, 0x57, 0xb2, 0x2a, 0x97, 0xe1, - 0x6e, 0xae, 0xe5, 0x53, 0xc3, 0x50, 0x7c, 0xd3, 0x7a, 0x6a, 0x6a, 0xc4, 0x27, 0x18, 0x0c, 0xc0, - 0xa4, 0x5f, 0xe4, 0x40, 0xb7, 0x81, 0x89, 0x99, 0x96, 0x11, 0x5e, 0x65, 0x61, 0x9e, 0x3b, 0x80, - 0xde, 0xf0, 0xf7, 0xaf, 0xbf, 0x94, 0xc1, 0xd9, 0x23, 0xd8, 0x03, 0x2a, 0x8e, 0x30, 0xda, 0xa9, - 0x44, 0x30, 0x14, 0x80, 0x16, 0xed, 0x83, 0x50, 0x38, 0x2c, 0x04, 0x8f, 0x7c, 0xd7, 0x59, 0xc7, - 0x8d, 0xe0, 0xb9, 0xd4, 0xed, 0x7f, 0x28, 0x83, 0x43, 0xff, 0x8c, 0x82, 0x76, 0x51, 0xc8, 0x65, - 0xd7, 0xac, 0x13, 0x80, 0x8e, 0xd8, 0x2b, 0xba, 0xf6, 0x0f, 0x41, 0x7b, 0x5c, 0x0b, 0xd0, 0xfd, - 0x26, 0x2f, 0x82, 0xe7, 0x0e, 0xf0, 0xa2, 0x52, 0xd5, 0x49, 0xc6, 0x7d, 0x7d, 0x11, 0xae, 0x0e, - 0x8e, 0xf0, 0x1d, 0x90, 0x61, 0x2f, 0xf9, 0x0e, 0xf0, 0x1d, 0x90, 0x61, 0x0b, 0x64, 0x58, 0xbc, - 0xdf, 0x03, 0x7c, 0x07, 0x64, 0xd8, 0x02, 0x19, 0x16, 0xef, 0xf7, 0x00, 0xdf, 0x01, 0x19, 0xb6, - 0x00, 0x8a, 0x4f, 0x76, 0x6a, 0x26, 0x9d, 0x1a, 0x7a, 0xde, 0x03, 0xd6, 0xae, 0x5d, 0x2b, 0x0e, - 0x10, 0xf2, 0x83, 0x84, 0x14, 0xd3, 0x81, 0x2c, 0xaf, 0xc3, 0x9d, 0x3b, 0x77, 0x98, 0x2e, 0x74, - 0x6a, 0x93, 0x74, 0xa0, 0xe3, 0x49, 0x5e, 0x07, 0x67, 0x6b, 0xfa, 0x14, 0x68, 0x37, 0x7a, 0xf4, - 0x68, 0xa0, 0xf3, 0x57, 0xf8, 0xf1, 0x1d, 0x38, 0x7c, 0xf8, 0x30, 0x9c, 0x3c, 0x79, 0x92, 0x71, - 0x8d, 0x44, 0x12, 0xcf, 0x7a, 0x53, 0x20, 0xc6, 0x16, 0x0b, 0xfc, 0x76, 0x0f, 0xe0, 0x79, 0x48, - 0xd8, 0xbd, 0x7b, 0x37, 0xf4, 0xee, 0xdd, 0x9b, 0x7d, 0x6a, 0xc7, 0x16, 0x61, 0x0a, 0x91, 0x6c, - 0xdf, 0x8a, 0xc0, 0x77, 0x4a, 0x33, 0x63, 0xd1, 0x79, 0x45, 0x3c, 0x79, 0x07, 0xed, 0xdb, 0xb7, - 0x07, 0x82, 0x1d, 0x3b, 0x76, 0x0c, 0x0e, 0x1c, 0x38, 0x00, 0x64, 0xc0, 0xae, 0x5d, 0xbb, 0x42, - 0x8f, 0x1e, 0x3d, 0x00, 0xbf, 0x8b, 0x68, 0x4b, 0x45, 0x3c, 0x11, 0x08, 0x2b, 0x56, 0xac, 0x60, - 0xb8, 0x78, 0x28, 0x14, 0xb6, 0x6d, 0xdb, 0x66, 0x8b, 0x8e, 0x3e, 0xbd, 0x84, 0xe7, 0xd7, 0x00, - 0xdf, 0x9a, 0xcc, 0x86, 0x0f, 0x3a, 0x22, 0xdc, 0xbc, 0x79, 0x73, 0xc0, 0x93, 0x7e, 0x30, 0x70, - 0xe0, 0x40, 0x5b, 0x67, 0x33, 0xbf, 0xfa, 0xea, 0x2b, 0xa0, 0x03, 0xd7, 0x3c, 0x64, 0x65, 0x65, - 0x41, 0x87, 0x0e, 0x1d, 0x2c, 0x4f, 0x8e, 0x53, 0xdd, 0xa9, 0xc1, 0x50, 0xbd, 0xf3, 0xf3, 0xf3, - 0xd9, 0x67, 0x9f, 0xb8, 0x0d, 0xf6, 0xef, 0xdf, 0xcf, 0xe0, 0x3d, 0x7b, 0xf6, 0x84, 0x3e, 0x7d, - 0xfa, 0x70, 0xb6, 0xc9, 0x63, 0xed, 0xb9, 0x31, 0xa3, 0xfc, 0xa5, 0x4b, 0x97, 0x14, 0xec, 0xa2, - 0x74, 0x4b, 0x51, 0xfc, 0xe8, 0xe3, 0x93, 0x72, 0x5e, 0x9b, 0x9e, 0x30, 0x61, 0x82, 0x11, 0x2b, - 0x15, 0x8c, 0x9f, 0xd6, 0x25, 0x5a, 0xa3, 0x77, 0x6b, 0xab, 0x90, 0x31, 0xb3, 0x6a, 0xd5, 0x2a, - 0x9d, 0x4c, 0xfa, 0x02, 0x15, 0xff, 0xf0, 0x25, 0xd7, 0xa1, 0x4b, 0x97, 0x2e, 0x0a, 0x36, 0x08, - 0x2d, 0xb9, 0xc8, 0x77, 0xee, 0xdc, 0x59, 0xc7, 0x87, 0x68, 0x8d, 0x4e, 0xfd, 0x72, 0xa2, 0x2d, - 0x5b, 0xb6, 0xe8, 0x68, 0xf0, 0xe3, 0x54, 0x3a, 0x18, 0xd7, 0x01, 0x1b, 0x16, 0x27, 0xb5, 0x8c, - 0x75, 0x07, 0x0d, 0xad, 0xb0, 0xb5, 0x67, 0x58, 0xdf, 0x7c, 0xf3, 0x4d, 0x15, 0xfa, 0xa9, 0x53, - 0xa7, 0x94, 0x1a, 0x35, 0x6a, 0x08, 0xa5, 0xe8, 0xcc, 0xb6, 0x55, 0x70, 0xea, 0x00, 0xe2, 0x15, - 0x0e, 0x87, 0x15, 0x6c, 0x75, 0x3a, 0xb6, 0x64, 0x70, 0x3c, 0x55, 0x2c, 0x64, 0x6f, 0xda, 0xb4, - 0x49, 0x87, 0x63, 0x04, 0xe0, 0xef, 0x15, 0x4f, 0xe6, 0x00, 0x4e, 0xcb, 0x5f, 0x98, 0x4e, 0xf8, - 0x74, 0x9e, 0x9d, 0x9f, 0xcf, 0xa5, 0x72, 0xb2, 0x07, 0x77, 0x00, 0xbe, 0x83, 0x41, 0xc1, 0x9e, - 0xc9, 0xc9, 0x4c, 0x63, 0xd7, 0x17, 0x61, 0xba, 0x68, 0x4e, 0x9b, 0x36, 0x0d, 0xe5, 0x25, 0x02, - 0x0d, 0x01, 0x7c, 0x48, 0x21, 0x28, 0x75, 0x73, 0x1a, 0x2a, 0x52, 0x15, 0x76, 0xed, 0xda, 0x05, - 0xad, 0x5a, 0xb5, 0x62, 0x27, 0xa9, 0xe5, 0x0b, 0x38, 0xa5, 0x73, 0x72, 0x72, 0x54, 0xb3, 0x19, - 0x2f, 0x2e, 0xa8, 0x8b, 0x16, 0x2d, 0x02, 0x6c, 0x64, 0xa2, 0x7a, 0x83, 0x07, 0x0f, 0x16, 0xe9, - 0x58, 0x2c, 0x06, 0xf2, 0xd7, 0xcb, 0x45, 0x81, 0x26, 0xe1, 0xda, 0x01, 0xf8, 0xc6, 0x01, 0x9d, - 0x00, 0x74, 0x33, 0x3b, 0x62, 0xce, 0x65, 0xd0, 0xb5, 0x80, 0x3e, 0x6f, 0x9d, 0x8a, 0x80, 0x5f, - 0xca, 0x03, 0x3a, 0x3f, 0x7f, 0xf9, 0xf2, 0x65, 0xc6, 0xee, 0xf8, 0xf1, 0xe3, 0xec, 0xc0, 0x34, - 0xc9, 0xe4, 0x3f, 0xba, 0x8e, 0x78, 0x19, 0xb4, 0x6f, 0x1a, 0xa1, 0x86, 0xe0, 0x38, 0x98, 0xf6, - 0x0d, 0x83, 0x02, 0xed, 0x10, 0x84, 0xc2, 0x58, 0x97, 0xa3, 0x8f, 0x41, 0xe0, 0x3b, 0x2e, 0x44, - 0xf7, 0x23, 0x38, 0x5e, 0x14, 0x15, 0x3c, 0xf7, 0xaf, 0xe2, 0xb2, 0x64, 0xc9, 0x12, 0xa5, 0x53, - 0xa7, 0x4e, 0x0a, 0xe1, 0xd3, 0xaf, 0x56, 0xad, 0x5a, 0x82, 0x86, 0x8e, 0xd4, 0x73, 0x38, 0x1d, - 0x9b, 0xa7, 0xef, 0x29, 0xc8, 0x61, 0xcd, 0x9a, 0x35, 0x02, 0x97, 0xf8, 0x17, 0x16, 0x16, 0x2a, - 0xaf, 0xbe, 0xfa, 0xaa, 0x82, 0xef, 0xcb, 0x50, 0xe6, 0xce, 0x9d, 0xab, 0x1a, 0x7e, 0xa8, 0xbc, - 0x61, 0xc3, 0x86, 0x4a, 0x51, 0x51, 0x91, 0xcc, 0x82, 0x7d, 0x44, 0x99, 0xae, 0x4d, 0xd8, 0x8b, - 0x84, 0x2c, 0x59, 0x6f, 0x1a, 0xc2, 0xb8, 0x0e, 0xf4, 0x31, 0x0a, 0x7c, 0xcf, 0x87, 0xa0, 0xa7, - 0x6f, 0x42, 0xd0, 0x39, 0x70, 0x2d, 0x3e, 0xbd, 0xd2, 0x82, 0xc2, 0xd6, 0xad, 0x5b, 0x59, 0xdd, - 0xb8, 0x4d, 0x28, 0xc6, 0x8b, 0xba, 0xf2, 0xc1, 0x07, 0x1f, 0x08, 0x1e, 0x46, 0x09, 0xd7, 0xd3, - 0x50, 0xfa, 0x42, 0xe2, 0xc4, 0x89, 0x13, 0x81, 0x5e, 0x46, 0x72, 0xe2, 0xc4, 0x09, 0x36, 0x33, - 0x42, 0xa5, 0x01, 0xc7, 0x48, 0x40, 0xa5, 0x20, 0x37, 0x57, 0xbf, 0xbb, 0xec, 0xeb, 0xaf, 0xbf, - 0x66, 0x53, 0x50, 0x9a, 0x7f, 0x6b, 0x43, 0x49, 0x49, 0x09, 0x2b, 0x23, 0x38, 0x0d, 0x27, 0x78, - 0xe1, 0x57, 0xa1, 0x10, 0xcf, 0x01, 0x03, 0x06, 0xb0, 0x97, 0x3e, 0x7c, 0xf2, 0xc9, 0x27, 0x70, - 0xf0, 0xe0, 0x41, 0xf6, 0x23, 0xa4, 0x82, 0x82, 0x02, 0x78, 0xf9, 0xe5, 0x97, 0x61, 0xf2, 0xe4, - 0xc9, 0x30, 0x6a, 0xd4, 0x28, 0xc0, 0xf7, 0x21, 0x00, 0x7e, 0x8f, 0x82, 0x0d, 0x81, 0x32, 0x13, - 0x9a, 0xb1, 0xd0, 0xd0, 0x44, 0x43, 0x23, 0xcd, 0x9c, 0xb4, 0x81, 0x16, 0x64, 0x7c, 0x51, 0x46, - 0x2f, 0x4e, 0x21, 0x7d, 0x79, 0x28, 0x2b, 0x2b, 0x63, 0x79, 0x99, 0x8e, 0x74, 0xbe, 0x7e, 0xfd, - 0x3a, 0x43, 0xa1, 0x3a, 0xc9, 0x5f, 0x8b, 0x24, 0x20, 0xe5, 0xb5, 0x30, 0xce, 0x4f, 0xc4, 0x46, - 0x5e, 0x31, 0x83, 0xc9, 0x3d, 0xa0, 0xb2, 0xdf, 0xad, 0x30, 0x93, 0xf1, 0x4d, 0x83, 0xdb, 0x5a, - 0x07, 0xd0, 0x67, 0x4e, 0x71, 0x86, 0x23, 0x9c, 0xa6, 0x4d, 0x50, 0xcb, 0xa7, 0x45, 0x95, 0x1f, - 0x9c, 0x5b, 0xc0, 0x96, 0x03, 0xf8, 0x62, 0xc3, 0xa8, 0x3b, 0xd1, 0x32, 0x1e, 0xc7, 0x75, 0x5b, - 0x8b, 0x1f, 0xe7, 0xea, 0xdd, 0xff, 0x14, 0xb6, 0x1c, 0x70, 0xff, 0x9b, 0x21, 0x73, 0x35, 0x74, - 0x3d, 0x0d, 0xcd, 0x9c, 0xca, 0xf7, 0x97, 0x64, 0xdf, 0x01, 0x19, 0xf6, 0xa7, 0xef, 0x00, 0xdf, - 0x01, 0x19, 0xb6, 0x40, 0x86, 0xc5, 0xfb, 0x3d, 0x20, 0xc3, 0x0e, 0xf8, 0x3f, 0xb8, 0x3e, 0x1b, - 0x7a, 0x52, 0x1b, 0x0a, 0x83, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, - 0x82 -}; - -static const u_int8_t FLEXHTMLIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa8, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, 0x2d, 0x30, 0x39, 0x54, - 0x32, 0x33, 0x3a, 0x30, 0x32, 0x3a, 0x39, 0x35, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, - 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, - 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, - 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, - 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, - 0x70, 0x61, 0x63, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, - 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, - 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, - 0x3a, 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, - 0x61, 0x3e, 0x0a, 0x3c, 0x50, 0x22, 0x3f, 0x00, 0x00, 0x05, 0xe7, 0x49, 0x44, 0x41, 0x54, 0x68, - 0x05, 0xed, 0x59, 0x6b, 0x4c, 0x5b, 0x55, 0x1c, 0xa7, 0xa5, 0xe5, 0xe5, 0x78, 0xb5, 0x94, 0xf2, - 0x4a, 0x00, 0x91, 0x47, 0xd8, 0x32, 0x51, 0x24, 0x7c, 0x70, 0x20, 0xf2, 0x34, 0x31, 0x13, 0x1f, - 0x0c, 0x30, 0x2c, 0xbc, 0x24, 0xca, 0xc6, 0x07, 0x1e, 0x09, 0x1f, 0xf8, 0x60, 0x42, 0x4c, 0xd0, - 0x84, 0x98, 0x98, 0xf1, 0xc5, 0x69, 0x54, 0x60, 0x3a, 0x82, 0x3a, 0x5d, 0x98, 0x24, 0xdb, 0x88, - 0x01, 0x24, 0x3a, 0x32, 0xca, 0x63, 0x4c, 0x26, 0x8f, 0x05, 0x48, 0x86, 0x06, 0x28, 0x14, 0x4a, - 0x5b, 0x1e, 0x85, 0xb6, 0xf8, 0x83, 0xa3, 0xd7, 0x6b, 0xcb, 0x6e, 0x6f, 0x7b, 0xe9, 0x08, 0xc9, - 0x3d, 0x69, 0x2e, 0xff, 0xf3, 0x3b, 0xff, 0xf7, 0xff, 0x7f, 0xce, 0x69, 0x2f, 0x82, 0xdd, 0xdd, - 0x5d, 0xa7, 0xe3, 0x3c, 0x84, 0xc7, 0xd9, 0xf9, 0x3d, 0xdf, 0xf9, 0x00, 0x8e, 0xba, 0x82, 0x7c, - 0x05, 0xf8, 0x0a, 0x70, 0xcc, 0x00, 0xdf, 0x42, 0x1c, 0x13, 0xc8, 0x59, 0x9c, 0xaf, 0x00, 0xe7, - 0x14, 0x72, 0x54, 0xc0, 0x57, 0x80, 0x63, 0x02, 0x39, 0x8b, 0xf3, 0x15, 0x38, 0x28, 0x85, 0xab, - 0x86, 0x15, 0x4b, 0x78, 0xdd, 0xa4, 0x33, 0x39, 0x99, 0x2c, 0x71, 0x8e, 0xc8, 0x21, 0x57, 0xe0, - 0xc1, 0xc6, 0x68, 0xed, 0xec, 0xc5, 0x94, 0xfb, 0xcf, 0x5b, 0xba, 0x35, 0xa0, 0xbd, 0x93, 0x3c, - 0xfa, 0xec, 0x67, 0x0b, 0x97, 0x34, 0x46, 0xb5, 0xe5, 0xaa, 0xdd, 0x88, 0xe0, 0x50, 0x7e, 0x0f, - 0x20, 0xb5, 0xb7, 0x57, 0x7f, 0x6a, 0x5e, 0xb8, 0xac, 0xd0, 0xf6, 0xc3, 0x15, 0x57, 0xa1, 0xdb, - 0xc4, 0x0b, 0x0b, 0x66, 0x3e, 0xf5, 0xac, 0x75, 0x95, 0x4e, 0xe6, 0x02, 0x74, 0x77, 0xf6, 0x78, - 0x53, 0x9a, 0x57, 0x1c, 0x50, 0xfe, 0x8c, 0x5b, 0xb4, 0x19, 0x8f, 0x1d, 0x53, 0x91, 0x1d, 0x32, - 0x74, 0x91, 0x35, 0xa3, 0xba, 0x7d, 0xa9, 0xf5, 0xeb, 0xc5, 0x2f, 0xfe, 0xd2, 0xcf, 0xd1, 0x71, - 0x06, 0x7a, 0xd3, 0xb8, 0x71, 0x55, 0xd9, 0x8c, 0xcf, 0x19, 0xef, 0x94, 0x12, 0xf9, 0x85, 0x54, - 0x9f, 0x2c, 0x06, 0x66, 0xab, 0x4b, 0xf6, 0x07, 0xf0, 0x70, 0x73, 0xa2, 0x65, 0xf1, 0xf2, 0x75, - 0xd5, 0x77, 0x70, 0x88, 0x6e, 0xc6, 0xdf, 0x25, 0xe0, 0x9c, 0x5f, 0x01, 0x1d, 0x21, 0x74, 0x8c, - 0xfb, 0xc9, 0x37, 0xfc, 0xf2, 0x6e, 0xae, 0xdc, 0xd8, 0x32, 0x6d, 0x12, 0xe4, 0xd7, 0xb5, 0x5e, - 0x7c, 0xc2, 0xdc, 0x9e, 0x2e, 0x94, 0xbf, 0x7b, 0x4e, 0x56, 0x70, 0x42, 0xe8, 0x69, 0x29, 0x65, - 0x15, 0xb1, 0xb9, 0x85, 0x76, 0x9d, 0x76, 0x7b, 0xd4, 0x5d, 0xcd, 0x8b, 0x9f, 0xc2, 0x36, 0x5d, - 0xbb, 0x58, 0x28, 0x4e, 0xf5, 0x79, 0x25, 0xd7, 0xef, 0x7c, 0x8a, 0x4f, 0x86, 0xf0, 0xf1, 0xbf, - 0x93, 0xb4, 0xc6, 0xb5, 0x0e, 0xd5, 0xb5, 0xf6, 0xa5, 0x2b, 0x0f, 0xd6, 0x47, 0xe9, 0xe2, 0x27, - 0x9c, 0x3d, 0x11, 0x43, 0x91, 0xfc, 0xbd, 0x50, 0xd7, 0x70, 0x3a, 0x6e, 0x95, 0xb6, 0x39, 0x80, - 0xe2, 0xa9, 0x9c, 0x5f, 0xd4, 0x3f, 0xd3, 0xf5, 0x46, 0x7b, 0xc4, 0xe6, 0xca, 0xce, 0xbf, 0x2e, - 0xcd, 0x93, 0x88, 0xa4, 0x74, 0x9c, 0x99, 0xfe, 0x63, 0xe3, 0x3e, 0xc2, 0x40, 0x30, 0x1a, 0xc3, - 0x7f, 0x7b, 0x5a, 0x20, 0x10, 0x7c, 0x14, 0x76, 0x29, 0x4f, 0x56, 0xc8, 0x2c, 0x4b, 0x5f, 0xb5, - 0xf9, 0x14, 0x5a, 0x35, 0xa8, 0x28, 0xf9, 0x2c, 0xc9, 0xd9, 0x8e, 0x93, 0x3d, 0xb7, 0x4e, 0xdd, - 0x29, 0x95, 0x5f, 0xb4, 0xc9, 0x7b, 0x68, 0x88, 0xf5, 0x38, 0xfd, 0x41, 0xe8, 0xc7, 0x03, 0xcf, - 0x4d, 0x7c, 0x12, 0xf1, 0x79, 0xb8, 0x5b, 0x04, 0xd1, 0x89, 0x13, 0x45, 0x65, 0x58, 0xa6, 0xf4, - 0xb3, 0x21, 0xec, 0xdf, 0x03, 0xd0, 0xde, 0xad, 0xbe, 0x85, 0x6e, 0x79, 0xdb, 0xbf, 0x38, 0xc9, - 0xeb, 0x65, 0x36, 0xc6, 0xcc, 0x78, 0xf4, 0xbb, 0x5b, 0x9d, 0xaa, 0xeb, 0xdf, 0x2e, 0x5d, 0x99, - 0xdd, 0x9a, 0x36, 0x5b, 0x62, 0x3f, 0xb5, 0x39, 0x80, 0x7c, 0x59, 0x91, 0x6a, 0x67, 0x99, 0x9c, - 0x39, 0x3b, 0xa6, 0x9d, 0x9b, 0x2b, 0x1d, 0xf8, 0x84, 0xb8, 0x86, 0xe6, 0xcb, 0x0a, 0xd1, 0xc4, - 0xfe, 0xe2, 0x00, 0x36, 0xb6, 0xff, 0xed, 0x9f, 0xef, 0x35, 0x86, 0x35, 0x3a, 0x7f, 0xa2, 0xd7, - 0x8b, 0x67, 0x6c, 0xcc, 0x85, 0xcd, 0x7b, 0x00, 0xf6, 0xcc, 0x4e, 0x7d, 0xca, 0x03, 0x91, 0x40, - 0x84, 0x33, 0x31, 0xdf, 0xbf, 0xe8, 0x25, 0xef, 0xf4, 0x03, 0xf7, 0xb1, 0xce, 0xa4, 0xbd, 0xa1, - 0xfa, 0xa1, 0x5d, 0xd9, 0xf2, 0xfb, 0xfa, 0x3d, 0x4a, 0x0a, 0x84, 0x8b, 0xd0, 0xe5, 0x35, 0x69, - 0x4e, 0x89, 0xbc, 0x1c, 0x7d, 0x45, 0xc7, 0xd9, 0xd0, 0xf6, 0x04, 0x40, 0xe9, 0x1d, 0xdb, 0xb8, - 0x87, 0xcb, 0xab, 0x73, 0xe5, 0xc7, 0x6d, 0xd3, 0x36, 0x05, 0x82, 0x08, 0x75, 0x0b, 0xef, 0x3d, - 0x3d, 0x42, 0x47, 0x40, 0x8f, 0xe8, 0x14, 0x05, 0x93, 0xd9, 0x66, 0x67, 0xae, 0x4c, 0xec, 0x5f, - 0x20, 0x7f, 0xa7, 0xc0, 0xbf, 0xd4, 0x4f, 0x24, 0x33, 0xe3, 0x67, 0x39, 0xe5, 0x14, 0x00, 0xb1, - 0xb1, 0xbc, 0xa3, 0xbc, 0xaa, 0xfc, 0xea, 0x1b, 0xe5, 0x97, 0xcb, 0x3b, 0x4b, 0x04, 0x61, 0xbe, - 0x89, 0x09, 0xcf, 0xa9, 0xa7, 0xe2, 0x4a, 0x02, 0xca, 0xcf, 0x4a, 0xde, 0x12, 0x0b, 0xc4, 0x2c, - 0x7d, 0x3d, 0x98, 0x0d, 0x1b, 0xff, 0x50, 0x86, 0xde, 0xa4, 0xbf, 0xb6, 0xd4, 0xf6, 0xea, 0x58, - 0x72, 0xd8, 0x5d, 0xef, 0x68, 0x85, 0xdc, 0x52, 0x67, 0xb7, 0xfa, 0x36, 0x96, 0x22, 0x06, 0x24, - 0x17, 0x1e, 0x16, 0xe2, 0x7b, 0x91, 0x25, 0x83, 0x7d, 0x88, 0x93, 0x7d, 0x62, 0x0c, 0x52, 0x77, - 0x35, 0xbf, 0x55, 0x4e, 0x97, 0x59, 0x32, 0x00, 0xff, 0xf0, 0xd1, 0xfb, 0x7f, 0xea, 0x1f, 0x59, - 0x2e, 0x71, 0x41, 0x0e, 0xa1, 0x85, 0x0e, 0xae, 0xec, 0x93, 0x42, 0x6d, 0xbe, 0xc8, 0x9e, 0x94, - 0x63, 0x6c, 0xed, 0xf0, 0x01, 0xb0, 0xcd, 0x94, 0xa3, 0xf8, 0xf8, 0x0a, 0x38, 0x2a, 0xb3, 0x6c, - 0xf5, 0xf2, 0x15, 0x60, 0x9b, 0x29, 0x47, 0xf1, 0x1d, 0xfb, 0x0a, 0xb0, 0xfa, 0x3a, 0x8d, 0x9b, - 0xd2, 0x68, 0x34, 0x0a, 0xf7, 0x87, 0xa3, 0x32, 0xb9, 0xaf, 0xd7, 0x60, 0x30, 0xe0, 0xaf, 0x4d, - 0x86, 0xac, 0x57, 0x60, 0x7c, 0x7c, 0x5c, 0x2a, 0x95, 0x8a, 0xc5, 0x62, 0x99, 0x8c, 0xe9, 0x0b, - 0x23, 0x6c, 0xf7, 0xf4, 0xf4, 0xcc, 0xcf, 0xcf, 0xdb, 0x17, 0xe1, 0xf4, 0xf4, 0x34, 0xb1, 0x02, - 0x43, 0x20, 0xd8, 0x2b, 0xb1, 0x1e, 0x80, 0x97, 0x97, 0x57, 0x48, 0x48, 0x08, 0x34, 0x6a, 0x34, - 0x1a, 0x06, 0xbd, 0x5d, 0x5d, 0x5d, 0xa9, 0xa9, 0xa9, 0x65, 0x65, 0x65, 0x0c, 0x3c, 0x0c, 0x4b, - 0x9e, 0x9e, 0x9e, 0xd1, 0xd1, 0xd1, 0x41, 0x41, 0x41, 0xe0, 0x59, 0x5f, 0x5f, 0x67, 0xe0, 0x34, - 0x5f, 0x62, 0xf3, 0x45, 0x6a, 0x68, 0x68, 0x08, 0x62, 0x22, 0x91, 0x88, 0x81, 0xb9, 0xa5, 0xa5, - 0x05, 0x3c, 0x09, 0x09, 0x09, 0x0c, 0x3c, 0x56, 0x97, 0x06, 0x07, 0x07, 0xa1, 0x04, 0x45, 0xb0, - 0xca, 0x49, 0x31, 0x58, 0xaf, 0x00, 0x34, 0x52, 0xa3, 0xad, 0xad, 0x2d, 0x32, 0x32, 0x12, 0xd9, - 0xca, 0xce, 0xce, 0x56, 0x2a, 0x95, 0x14, 0x8e, 0x36, 0x9b, 0x98, 0x98, 0xc0, 0x54, 0xab, 0xd5, - 0xf6, 0xee, 0x8f, 0x81, 0x81, 0x01, 0xd2, 0xd0, 0xd8, 0x3c, 0x39, 0x39, 0x39, 0x89, 0x89, 0x89, - 0x8d, 0x8d, 0x8d, 0xe9, 0xe9, 0xe9, 0x90, 0xad, 0xac, 0xac, 0xac, 0xad, 0xad, 0x95, 0x48, 0x24, - 0x59, 0x59, 0x59, 0xfd, 0xfd, 0x7b, 0x6f, 0xf2, 0x38, 0x0d, 0x2a, 0x14, 0x06, 0x82, 0x54, 0x00, - 0x66, 0x9c, 0x9d, 0x9d, 0x29, 0x63, 0x75, 0x75, 0x75, 0x44, 0x64, 0x78, 0x78, 0x98, 0x02, 0xe9, - 0x44, 0x43, 0x43, 0x03, 0x18, 0x96, 0x97, 0x99, 0xde, 0x32, 0x44, 0x45, 0x45, 0xd1, 0xed, 0x3a, - 0xbc, 0x02, 0x19, 0x19, 0x19, 0xc8, 0x74, 0x4d, 0x4d, 0x0d, 0x1c, 0xed, 0xec, 0xec, 0x24, 0xee, - 0x62, 0x87, 0x24, 0x25, 0x25, 0xc9, 0xe5, 0x72, 0x4c, 0x5d, 0x5d, 0x5d, 0x51, 0x22, 0x8c, 0xb8, - 0xb8, 0x38, 0xb4, 0x13, 0x10, 0xec, 0xc8, 0xf6, 0xf6, 0x76, 0x10, 0x38, 0x5b, 0xc6, 0xc6, 0xc6, - 0xd2, 0xd2, 0xd2, 0x40, 0x27, 0x27, 0x27, 0x4f, 0x4d, 0x4d, 0x01, 0xc1, 0x53, 0xaf, 0xd7, 0x03, - 0xb1, 0x7f, 0xd0, 0x13, 0xf0, 0x38, 0x9a, 0xaa, 0x00, 0x32, 0x04, 0x1e, 0x85, 0x42, 0x41, 0xec, - 0xad, 0xae, 0xae, 0x52, 0x22, 0x0c, 0x7b, 0x60, 0x64, 0x64, 0xef, 0xf7, 0x71, 0x4c, 0x4c, 0x0c, - 0x98, 0xab, 0xab, 0xab, 0x41, 0xd7, 0xd7, 0xd7, 0x83, 0x0e, 0x0c, 0x0c, 0x04, 0xbd, 0xb0, 0xb0, - 0x40, 0x29, 0x71, 0x6c, 0x05, 0xb0, 0x89, 0xe3, 0xe3, 0xe3, 0x61, 0x92, 0x1c, 0x4a, 0x20, 0xb6, - 0xb7, 0xff, 0xf7, 0x5b, 0x1e, 0x08, 0xc3, 0xf0, 0xf0, 0xf0, 0xc0, 0x2a, 0xde, 0xbd, 0xe1, 0x49, - 0xa7, 0x4d, 0x26, 0x4e, 0xff, 0x34, 0xb0, 0x6d, 0x13, 0x13, 0xff, 0x88, 0x13, 0x66, 0xbe, 0xa2, - 0x1f, 0x80, 0xe8, 0x74, 0x3a, 0x33, 0xdc, 0xd1, 0x53, 0x56, 0x01, 0xa0, 0xc4, 0x74, 0x3f, 0xa8, - 0x29, 0x45, 0x60, 0xd5, 0xdb, 0xdb, 0x1b, 0x4f, 0xf4, 0xf4, 0xec, 0xec, 0x2c, 0xda, 0xba, 0xbb, - 0xbb, 0xbb, 0xa2, 0xa2, 0xa2, 0xb5, 0xb5, 0x15, 0x20, 0x61, 0xa3, 0x33, 0xd3, 0x69, 0x4a, 0x33, - 0x4e, 0x2d, 0x1c, 0x59, 0x64, 0x4a, 0xa7, 0x29, 0x86, 0x83, 0x09, 0xe8, 0x62, 0x1e, 0x33, 0x33, - 0x33, 0xbe, 0xbe, 0xbe, 0x44, 0x38, 0x36, 0x36, 0x56, 0xad, 0x56, 0x93, 0xde, 0x05, 0x02, 0x02, - 0xb7, 0x1b, 0x11, 0x9f, 0x9c, 0x9c, 0x24, 0x3c, 0x28, 0x85, 0xbb, 0xbb, 0x3b, 0xa1, 0x33, 0x33, - 0x33, 0x37, 0x37, 0x37, 0x03, 0x02, 0xfe, 0x79, 0x5d, 0x57, 0x55, 0x55, 0x45, 0x0e, 0x00, 0xec, - 0xf5, 0xbe, 0xbe, 0x3e, 0x72, 0x6d, 0x61, 0x6f, 0x40, 0x49, 0x70, 0x70, 0x30, 0x11, 0xa1, 0x3f, - 0x21, 0xce, 0xec, 0x1b, 0x56, 0xad, 0x57, 0x00, 0x3d, 0x8a, 0xee, 0x27, 0x7a, 0xc9, 0x5d, 0x86, - 0x8b, 0x86, 0x4c, 0xc9, 0x8d, 0x43, 0x68, 0x1c, 0x88, 0x4d, 0x4d, 0x4d, 0x38, 0xe6, 0xc1, 0x8f, - 0x0a, 0xc0, 0x2d, 0xdc, 0xca, 0xcd, 0xcd, 0xcd, 0xb0, 0x41, 0xc4, 0xd1, 0x78, 0x88, 0x0d, 0xf7, - 0x3a, 0xf8, 0x81, 0x80, 0x0d, 0xcc, 0xa0, 0xc9, 0xd1, 0x4c, 0x3f, 0xa0, 0x89, 0x42, 0x3c, 0x0f, - 0xec, 0x55, 0x6a, 0x95, 0x10, 0x87, 0xfc, 0x56, 0x02, 0xee, 0xce, 0xcd, 0xcd, 0xa1, 0x62, 0xc4, - 0x39, 0x33, 0x63, 0x8e, 0x98, 0x1e, 0x72, 0x00, 0x8e, 0x70, 0x91, 0x59, 0xa7, 0xf5, 0x16, 0x62, - 0x96, 0x3f, 0xf2, 0x55, 0x3e, 0x80, 0xa3, 0x2e, 0x01, 0x5f, 0x01, 0xbe, 0x02, 0x1c, 0x33, 0xc0, - 0xb7, 0x10, 0xc7, 0x04, 0x72, 0x16, 0xe7, 0x2b, 0xc0, 0x39, 0x85, 0x1c, 0x15, 0x1c, 0xfb, 0x0a, - 0xfc, 0x0d, 0x0a, 0x08, 0x48, 0x44, 0xec, 0xf6, 0xcb, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHTMLIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0f, 0x8d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x09, 0x54, 0x14, 0x47, 0xf6, 0x73, 0x05, 0x10, 0xd4, 0x78, 0x24, 0x28, 0x8a, 0x46, 0xc1, - 0xdd, 0x28, 0xde, 0x06, 0x41, 0x8d, 0x26, 0xae, 0xc7, 0xaa, 0xf1, 0x40, 0xa3, 0x59, 0x45, 0x4d, - 0x5c, 0x13, 0x37, 0xe6, 0x78, 0x66, 0xf1, 0x4e, 0x36, 0x51, 0xdc, 0xd5, 0x98, 0xb7, 0x3e, 0xcf, - 0x68, 0xa2, 0x79, 0x26, 0xcf, 0xac, 0x67, 0x36, 0xc7, 0x4b, 0xc4, 0xe8, 0x86, 0x55, 0x14, 0x41, - 0x41, 0xf1, 0x8a, 0x1b, 0x09, 0x04, 0x0f, 0x44, 0x14, 0x41, 0x10, 0x05, 0xe5, 0x86, 0xde, 0xfa, - 0x85, 0x5d, 0x74, 0xcf, 0x74, 0xcf, 0x74, 0x4f, 0x77, 0xcf, 0x60, 0xd2, 0xf5, 0x5e, 0x4f, 0xff, - 0xfa, 0xff, 0xd7, 0x3f, 0xea, 0x57, 0x55, 0xd7, 0x74, 0x77, 0x55, 0xbb, 0x71, 0x24, 0x81, 0x8a, - 0xe4, 0xae, 0x82, 0x97, 0xb2, 0x6a, 0x2f, 0xf0, 0x87, 0xa3, 0x61, 0x54, 0x52, 0x69, 0xcd, 0x7d, - 0x7a, 0xe6, 0xf3, 0xcc, 0x12, 0xf4, 0x81, 0x4f, 0x83, 0x13, 0x9e, 0xe2, 0x41, 0x4e, 0x0e, 0x06, - 0xc6, 0xf1, 0x00, 0xb8, 0x51, 0x96, 0x63, 0x89, 0x12, 0xe5, 0xdd, 0x30, 0xc7, 0xd4, 0x29, 0x00, - 0xb4, 0x3b, 0x2d, 0xa5, 0xc4, 0xcd, 0xcd, 0x8d, 0xa1, 0x6d, 0x6a, 0x10, 0x32, 0xf2, 0x25, 0x8c, - 0xf7, 0xc1, 0x78, 0x0d, 0x36, 0x9d, 0xe6, 0x1d, 0x15, 0x9e, 0x45, 0x05, 0x2e, 0xdd, 0xcf, 0x84, - 0xe2, 0xea, 0xbb, 0x94, 0x3e, 0x35, 0x35, 0x12, 0x46, 0x24, 0x0d, 0x10, 0xf2, 0xd6, 0xc1, 0x7c, - 0xdc, 0x47, 0x1f, 0x7b, 0x96, 0x07, 0x45, 0xe7, 0x6f, 0xae, 0x7f, 0x21, 0xca, 0x5b, 0xb5, 0x25, - 0xa4, 0xf2, 0x0d, 0x6f, 0x62, 0xca, 0x08, 0x11, 0x33, 0x66, 0x9c, 0x58, 0x4b, 0x7c, 0x33, 0x98, - 0x3b, 0x77, 0xae, 0xb5, 0xa3, 0x02, 0x8c, 0xa8, 0x96, 0xf8, 0x42, 0x48, 0x1f, 0x3d, 0x7a, 0x34, - 0xec, 0xd9, 0xb3, 0x47, 0xc0, 0x5a, 0x07, 0x1a, 0xef, 0x83, 0x6a, 0x0d, 0x56, 0x36, 0xda, 0x41, - 0x88, 0x7c, 0xb6, 0xc3, 0xeb, 0x10, 0xd9, 0x21, 0x05, 0x56, 0x43, 0x9b, 0x2d, 0xd5, 0x56, 0x4d, - 0xeb, 0x01, 0x02, 0x5b, 0xdf, 0xcb, 0xa7, 0x26, 0x5b, 0x91, 0xf9, 0x56, 0x29, 0x24, 0x20, 0x6e, - 0xf3, 0xe5, 0xf5, 0x42, 0x14, 0x83, 0x25, 0x9b, 0x36, 0x4f, 0xc5, 0x82, 0xe3, 0x93, 0x87, 0xf1, - 0x59, 0xd6, 0xe4, 0x19, 0x82, 0x00, 0xc8, 0x13, 0x93, 0xb6, 0x48, 0x88, 0x12, 0xc1, 0x36, 0x15, - 0x08, 0x39, 0x5f, 0x4c, 0x7d, 0x9e, 0xbb, 0x53, 0x59, 0x24, 0x44, 0x29, 0x82, 0x5d, 0xd3, 0x8a, - 0x0e, 0x1f, 0x3e, 0x6c, 0x2b, 0x6c, 0x92, 0x34, 0xd9, 0x32, 0x52, 0x7e, 0x12, 0x09, 0xdc, 0x96, - 0x2d, 0x5b, 0xf0, 0x8a, 0x44, 0xc9, 0x78, 0xe6, 0x8f, 0x73, 0xe7, 0xce, 0x31, 0xb8, 0x5b, 0xb7, - 0x6e, 0xac, 0x38, 0xcf, 0xcb, 0x10, 0x0f, 0x00, 0xc9, 0x18, 0x20, 0xf3, 0xfd, 0xfb, 0xf7, 0x99, - 0x82, 0xf2, 0xf2, 0x72, 0x26, 0x74, 0xda, 0xb4, 0x69, 0x0c, 0xde, 0xbd, 0x7b, 0x37, 0xe7, 0xe9, - 0xe9, 0xc9, 0xf2, 0x52, 0x4a, 0x5c, 0x13, 0x03, 0x62, 0x89, 0x6e, 0xe9, 0xe1, 0xf7, 0xc0, 0xa1, - 0xb1, 0x48, 0x4d, 0xfd, 0xfd, 0x06, 0x15, 0x5c, 0x28, 0x3e, 0x0f, 0xef, 0xa7, 0xbf, 0xa7, 0xbc, - 0x96, 0x2c, 0x7b, 0x9e, 0x30, 0x8f, 0x23, 0x25, 0x19, 0xfb, 0x85, 0x28, 0x36, 0xa2, 0x56, 0xd6, - 0x56, 0x50, 0x38, 0xf5, 0x76, 0x8a, 0x88, 0x6e, 0x99, 0x91, 0xec, 0xc9, 0x5f, 0xe6, 0xec, 0x62, - 0x82, 0x2c, 0x0b, 0x0c, 0x3d, 0x1a, 0x2e, 0x42, 0xcd, 0x3b, 0xff, 0xba, 0x2c, 0x2f, 0x32, 0x4a, - 0x2a, 0x40, 0xcb, 0xb7, 0x5e, 0xd9, 0x24, 0x12, 0x84, 0x19, 0xc4, 0x4b, 0x25, 0xc4, 0x0f, 0x4b, - 0x8c, 0x90, 0x22, 0x49, 0x2b, 0x40, 0xce, 0x0f, 0x2f, 0xae, 0xb2, 0x12, 0x68, 0xa9, 0x60, 0xfa, - 0xc9, 0x09, 0x56, 0x3c, 0x96, 0x5a, 0x24, 0x3d, 0x10, 0x32, 0x0d, 0x4f, 0xec, 0x47, 0xb3, 0x52, - 0x16, 0xa6, 0x97, 0x5c, 0x10, 0xb2, 0x4a, 0xc2, 0x76, 0x15, 0xf0, 0xa5, 0x2c, 0xad, 0xe7, 0xf1, - 0xf6, 0xce, 0xe6, 0x58, 0x64, 0xb7, 0xc3, 0x59, 0x8d, 0x45, 0x85, 0x85, 0x85, 0x50, 0x56, 0x56, - 0x66, 0xb7, 0xa0, 0x90, 0x01, 0xaf, 0xc7, 0x79, 0x79, 0x79, 0x42, 0x54, 0x3d, 0x2c, 0x15, 0xa4, - 0x95, 0x2b, 0x57, 0x8a, 0xd0, 0x84, 0x5b, 0x94, 0x97, 0xca, 0x8c, 0x18, 0x61, 0xfd, 0xf7, 0x00, - 0xf9, 0x24, 0x4b, 0xa2, 0xc0, 0x16, 0x2d, 0x5a, 0x50, 0x39, 0x08, 0xf3, 0x07, 0x2d, 0x40, 0xf2, - 0x1f, 0x7c, 0xf0, 0x01, 0x17, 0x12, 0x12, 0x42, 0xf1, 0x94, 0x89, 0xfc, 0xa8, 0x52, 0x80, 0x1e, - 0x5c, 0xbc, 0x78, 0x91, 0xbb, 0x7c, 0xf9, 0x32, 0x53, 0xc2, 0x0b, 0xe2, 0xbd, 0x39, 0x7b, 0xf6, - 0xac, 0x63, 0x0a, 0x78, 0x6b, 0xf9, 0x33, 0x0a, 0xe6, 0xe1, 0x51, 0xa3, 0x46, 0x51, 0xf8, 0xf6, - 0xed, 0xdb, 0x0c, 0x27, 0xa4, 0xf3, 0xca, 0x79, 0x63, 0xf0, 0x6c, 0xf6, 0x03, 0x52, 0x2b, 0xb6, - 0x93, 0x55, 0x3f, 0xb0, 0xcd, 0xae, 0x9e, 0x6a, 0x78, 0x0c, 0xd4, 0x9b, 0xa4, 0xae, 0x84, 0xe1, - 0x35, 0xa4, 0xce, 0x1c, 0xf5, 0xdc, 0xa6, 0x03, 0xea, 0xeb, 0x4c, 0xdf, 0x12, 0x4e, 0x8b, 0xc0, - 0xcd, 0xf2, 0x1b, 0xfa, 0x5a, 0xfe, 0x40, 0x9a, 0x66, 0x07, 0x96, 0xa7, 0xbf, 0x0b, 0xf6, 0x6e, - 0x5b, 0x90, 0xe9, 0x14, 0x44, 0x9d, 0x1c, 0x27, 0x72, 0x00, 0xcb, 0x44, 0x9f, 0x9f, 0x2d, 0xc2, - 0x39, 0x92, 0x71, 0x68, 0x14, 0x9a, 0x72, 0x72, 0x0c, 0xe4, 0x95, 0xdf, 0xa4, 0xfa, 0xde, 0x0a, - 0x59, 0x08, 0xe3, 0x02, 0x27, 0xc9, 0xea, 0x46, 0xc3, 0xb1, 0xf6, 0xbf, 0x1f, 0x90, 0x00, 0xbe, - 0x1e, 0x8d, 0x44, 0x7c, 0x49, 0x85, 0x47, 0x60, 0xc9, 0x85, 0x05, 0x14, 0xe7, 0xef, 0xd9, 0x18, - 0xf6, 0xf6, 0x8f, 0x17, 0xd1, 0x95, 0x64, 0x14, 0x3b, 0x30, 0x34, 0x31, 0x1c, 0x6a, 0xb9, 0x5a, - 0x2a, 0xf3, 0xab, 0x88, 0xff, 0x40, 0xf3, 0x47, 0x5a, 0xd8, 0x95, 0xff, 0x8f, 0xf4, 0xbf, 0xc1, - 0xe1, 0xfc, 0x38, 0xf8, 0xb0, 0xe7, 0xa7, 0x10, 0xda, 0xa4, 0xbb, 0x4d, 0xfe, 0xb2, 0x9a, 0x52, - 0x18, 0x7b, 0x7c, 0x08, 0xd4, 0x70, 0xd5, 0x94, 0x2f, 0x7e, 0x50, 0xaa, 0x4d, 0x7e, 0x46, 0x14, - 0x5e, 0x98, 0xed, 0xc1, 0x69, 0xc5, 0xff, 0xa3, 0xd3, 0x74, 0x9c, 0x00, 0xe3, 0x71, 0xf9, 0xfe, - 0x45, 0xd9, 0x22, 0x78, 0xaf, 0x15, 0x79, 0x76, 0x5f, 0xfb, 0x5c, 0x96, 0x07, 0x09, 0xb7, 0x2a, - 0xf2, 0x45, 0x32, 0x93, 0x0a, 0x8e, 0xd8, 0xe4, 0xb7, 0x24, 0x2a, 0x8e, 0x00, 0xf3, 0x58, 0x00, - 0x4c, 0x26, 0x4d, 0x29, 0xff, 0x41, 0x53, 0x5a, 0xd7, 0xe3, 0x13, 0xe8, 0xde, 0xb4, 0x17, 0xa5, - 0xfe, 0x72, 0x2f, 0x1d, 0x66, 0x9f, 0x99, 0x0e, 0xfd, 0x5b, 0x0c, 0x82, 0xe5, 0xa1, 0xab, 0x05, - 0x25, 0xea, 0xc0, 0xc2, 0xca, 0x02, 0x98, 0x94, 0x32, 0x92, 0x66, 0xfc, 0x3d, 0xfd, 0xe1, 0xdb, - 0xfe, 0x07, 0xc1, 0x1d, 0x3c, 0xac, 0xf8, 0x94, 0x20, 0x34, 0x39, 0x20, 0xa5, 0xa0, 0xa2, 0xb6, - 0x02, 0x46, 0x26, 0x3d, 0x4d, 0x9a, 0x58, 0x4b, 0xf8, 0x2a, 0xe2, 0x80, 0x14, 0x8b, 0xae, 0x38, - 0xdd, 0x1d, 0x40, 0xeb, 0x12, 0x0a, 0x0e, 0xc1, 0x33, 0x2d, 0x87, 0xe8, 0x6a, 0xa8, 0x9c, 0x30, - 0x43, 0x1c, 0x90, 0x53, 0x66, 0x04, 0x5e, 0xf3, 0x75, 0xc0, 0x08, 0xa3, 0xd4, 0xc8, 0xfc, 0x6d, - 0x38, 0x80, 0x4f, 0x67, 0xf0, 0x20, 0xff, 0xf6, 0x64, 0x2b, 0x27, 0x21, 0x21, 0x01, 0xbc, 0xbc, - 0xbc, 0x64, 0xe9, 0xf6, 0x08, 0xd1, 0xd1, 0xd1, 0x54, 0x07, 0xea, 0x19, 0x39, 0xb2, 0x6e, 0x84, - 0xb2, 0x57, 0x06, 0xe9, 0x8a, 0x22, 0x40, 0xc6, 0x5e, 0x2a, 0xab, 0xa8, 0xa8, 0x88, 0x29, 0x99, - 0x39, 0x73, 0x26, 0x93, 0x7f, 0xf0, 0xe0, 0x41, 0x58, 0xba, 0x74, 0x29, 0x54, 0x57, 0x57, 0xc3, - 0xda, 0xb5, 0x6b, 0xe9, 0x91, 0x98, 0x98, 0x48, 0xe9, 0xe8, 0x34, 0x1a, 0x35, 0x7f, 0xfe, 0x7c, - 0x7a, 0x6e, 0xd2, 0xa4, 0x09, 0x90, 0xbf, 0xc4, 0x14, 0x1e, 0x3f, 0x7e, 0x3c, 0x93, 0x81, 0xe5, - 0x78, 0x3d, 0x0c, 0xa9, 0x04, 0xb0, 0xbc, 0x30, 0xc8, 0xe5, 0x89, 0x2c, 0x6e, 0xf0, 0xe0, 0xc1, - 0x94, 0x7c, 0xe6, 0xcc, 0x19, 0xfa, 0xaf, 0xf5, 0xca, 0x95, 0x2b, 0x8c, 0x9d, 0xd4, 0x20, 0xc5, - 0x31, 0x84, 0x00, 0xc0, 0xb2, 0x43, 0x87, 0x0e, 0xa5, 0x18, 0x84, 0x53, 0x52, 0x52, 0x38, 0xbc, - 0x8f, 0x8e, 0xb0, 0x65, 0x42, 0x9c, 0xdc, 0x7f, 0x78, 0x4b, 0x5e, 0xcc, 0x2b, 0x8a, 0x00, 0x11, - 0x4a, 0xd3, 0xf0, 0xe1, 0xc3, 0xe9, 0x19, 0x6b, 0x11, 0x13, 0x29, 0x4f, 0xcf, 0xf8, 0xd3, 0xb8, - 0x71, 0x63, 0x0a, 0x5f, 0xbd, 0x7a, 0x95, 0x9e, 0x57, 0xad, 0x5a, 0x05, 0xc2, 0x28, 0x79, 0x7b, - 0x7b, 0x53, 0x3c, 0xfe, 0x08, 0x61, 0x86, 0x74, 0x10, 0xd0, 0x7d, 0x18, 0xcd, 0xcc, 0xcc, 0xa4, - 0xa6, 0x74, 0xea, 0xd4, 0xc9, 0x41, 0x93, 0xd4, 0x15, 0xd3, 0xdd, 0x01, 0x75, 0xea, 0xb5, 0x73, - 0xab, 0x6a, 0x42, 0xda, 0xd5, 0xe9, 0x2f, 0xc1, 0x74, 0x40, 0xff, 0x3a, 0x55, 0x27, 0xd1, 0xec, - 0x03, 0xea, 0xea, 0x4b, 0x7f, 0x6e, 0xb3, 0x0f, 0xe8, 0x5f, 0xa7, 0xea, 0x24, 0x9a, 0x11, 0x50, - 0x57, 0x5f, 0xfa, 0x73, 0x9b, 0x11, 0xd0, 0xbf, 0x4e, 0xd5, 0x49, 0x34, 0x23, 0xa0, 0xa4, 0xbe, - 0x32, 0xef, 0x65, 0x28, 0x61, 0x73, 0x88, 0xc7, 0x29, 0x57, 0x62, 0xfe, 0xe6, 0xaf, 0xe2, 0xdb, - 0x85, 0x2a, 0x5c, 0xd1, 0xd4, 0x84, 0x8a, 0xaa, 0x0a, 0xe9, 0x9d, 0xe9, 0x4f, 0xb3, 0x3e, 0x96, - 0x55, 0x99, 0x57, 0x91, 0x4b, 0x69, 0xdd, 0x9a, 0xf6, 0x64, 0x3c, 0x87, 0x6e, 0xfd, 0x40, 0xcb, - 0x65, 0x97, 0x65, 0x31, 0x9c, 0xa3, 0x80, 0xa7, 0xa3, 0x05, 0xdf, 0x3c, 0x37, 0x13, 0xc8, 0xbd, - 0x52, 0x5a, 0xfc, 0x4e, 0xd5, 0x6d, 0x59, 0x31, 0xaf, 0x9c, 0x8e, 0xa2, 0xb4, 0xb5, 0x3d, 0xb6, - 0x30, 0x9e, 0x6b, 0xa5, 0x75, 0xff, 0xda, 0x66, 0xa4, 0x4e, 0x82, 0x36, 0xbe, 0x41, 0xb0, 0x3d, - 0xec, 0x1b, 0x46, 0x53, 0x0b, 0xa8, 0x6e, 0x42, 0xc7, 0x6f, 0x1f, 0x85, 0x77, 0x7f, 0x9a, 0x47, - 0xf5, 0xe0, 0x2d, 0xf1, 0xef, 0xfa, 0x1f, 0x02, 0x72, 0xcf, 0x42, 0x52, 0x6f, 0x2d, 0xd4, 0x02, - 0x79, 0x0b, 0x05, 0xfc, 0xc8, 0xfd, 0xcf, 0xd8, 0xfe, 0x87, 0xad, 0x78, 0x84, 0xb7, 0xe9, 0xa3, - 0x3b, 0xbd, 0x0d, 0x63, 0x5a, 0x4f, 0xb0, 0xe2, 0xb1, 0x87, 0x50, 0xec, 0x00, 0x1a, 0x33, 0xe6, - 0xd8, 0x60, 0xc0, 0xdb, 0xe0, 0x98, 0x36, 0xf4, 0xdc, 0x0a, 0x5d, 0x9b, 0xf4, 0xb0, 0x29, 0x7f, - 0xce, 0x8f, 0xaf, 0xc0, 0x4f, 0x77, 0x7f, 0x84, 0xdd, 0xe1, 0x7b, 0x21, 0xc0, 0xbb, 0xb5, 0x24, - 0xef, 0xb5, 0xb2, 0xab, 0xf0, 0x52, 0xea, 0x44, 0x4a, 0xf3, 0x70, 0xf3, 0x84, 0xd8, 0x01, 0x87, - 0xc1, 0xc7, 0xdd, 0x47, 0x92, 0x57, 0x0a, 0xa9, 0xa8, 0x0f, 0x7c, 0x46, 0xda, 0x38, 0xd6, 0x24, - 0x1a, 0x3f, 0xe4, 0xf1, 0x3f, 0x02, 0x76, 0x46, 0x7b, 0xc6, 0xa3, 0x32, 0x34, 0x1e, 0x93, 0x9c, - 0xf1, 0x48, 0x0b, 0xf2, 0x6d, 0x4f, 0xe5, 0xbd, 0xd0, 0x76, 0x1a, 0x7d, 0x36, 0x30, 0x2a, 0x69, - 0x20, 0xc4, 0xfc, 0xbc, 0x18, 0x49, 0x8a, 0x92, 0x22, 0x07, 0x1e, 0xf3, 0x0e, 0x60, 0xc2, 0x12, - 0x0b, 0x0e, 0x43, 0x79, 0x6d, 0x39, 0xcb, 0xcb, 0x01, 0x9f, 0x5c, 0xf9, 0x90, 0x92, 0xde, 0xed, - 0xbc, 0x42, 0x8e, 0x85, 0xe1, 0x31, 0xba, 0xfb, 0x6f, 0x7e, 0xc7, 0xf2, 0x81, 0x3e, 0x6d, 0x18, - 0x6c, 0x0f, 0x50, 0xdc, 0x84, 0x50, 0xd0, 0x6b, 0x67, 0x5f, 0x82, 0x8c, 0x92, 0x34, 0x2a, 0xb3, - 0xc7, 0xa3, 0x7d, 0x60, 0x6d, 0xf7, 0xcd, 0xb2, 0xf2, 0x95, 0x0e, 0x9d, 0xf8, 0x8c, 0x2d, 0x3e, - 0xff, 0x07, 0x2a, 0xa7, 0xb5, 0x6f, 0x1b, 0xd8, 0x19, 0xf6, 0xad, 0xac, 0x4c, 0x29, 0x82, 0xa2, - 0x08, 0xf0, 0x05, 0x3f, 0xee, 0xf5, 0x39, 0x6d, 0xa3, 0x1e, 0x6e, 0x1e, 0xf0, 0xe3, 0x9d, 0xd3, - 0x74, 0x28, 0x3c, 0x70, 0x73, 0x2f, 0x4f, 0x66, 0xe7, 0x63, 0x85, 0x09, 0x14, 0x8e, 0x6c, 0xf3, - 0x02, 0xc3, 0x59, 0x02, 0x27, 0x8a, 0x8e, 0xd3, 0xf2, 0xbc, 0xf1, 0x7b, 0xc2, 0xf7, 0xa9, 0x36, - 0x1e, 0x65, 0xaa, 0x8a, 0x80, 0xd0, 0x88, 0x23, 0x05, 0x07, 0xe1, 0xef, 0x69, 0x6f, 0x53, 0x14, - 0xde, 0x3a, 0x3c, 0x34, 0xf0, 0x24, 0x23, 0xdb, 0xab, 0xfd, 0x11, 0xe4, 0x01, 0x08, 0x79, 0xf9, - 0x8e, 0xf2, 0xbf, 0x19, 0x32, 0x0f, 0x26, 0x04, 0x4e, 0x66, 0x65, 0x55, 0x03, 0x52, 0xb7, 0xeb, - 0xd4, 0xe0, 0xc8, 0x90, 0xca, 0x65, 0x97, 0x66, 0xb1, 0x22, 0xfc, 0x33, 0xaf, 0x59, 0xa7, 0xa7, - 0x32, 0x9c, 0x25, 0x70, 0xaf, 0xfa, 0x1e, 0xf7, 0xfa, 0xd9, 0x97, 0x2c, 0xd1, 0x0e, 0xe5, 0x1d, - 0x8e, 0x80, 0x5c, 0x4d, 0x45, 0x26, 0x0f, 0x85, 0xe2, 0xaa, 0xbb, 0x10, 0x37, 0x30, 0x19, 0x3c, - 0xc9, 0xb0, 0x68, 0x74, 0x52, 0xd5, 0x07, 0x94, 0x18, 0x83, 0xc6, 0x3f, 0xe2, 0xee, 0xed, 0x14, - 0xe3, 0xd1, 0x1e, 0xdd, 0x23, 0x40, 0xde, 0x33, 0x83, 0xeb, 0x65, 0xd7, 0xa0, 0xad, 0x6f, 0x3b, - 0x25, 0xfe, 0x6a, 0xe6, 0xd1, 0xdd, 0x01, 0xcd, 0x16, 0xa9, 0x14, 0xa0, 0x7b, 0x13, 0x52, 0xa9, - 0x5f, 0x33, 0xbb, 0xe9, 0x80, 0xe6, 0x2a, 0xd4, 0x28, 0xc0, 0x8c, 0x80, 0xc6, 0x0a, 0xd4, 0x5c, - 0x5c, 0xd1, 0x95, 0xe6, 0xc8, 0x91, 0x23, 0xe0, 0xe1, 0xe1, 0x01, 0x03, 0x07, 0x0e, 0xd4, 0xac, - 0x50, 0x4e, 0x40, 0x56, 0x56, 0x16, 0x90, 0x87, 0x86, 0x94, 0x4c, 0x1e, 0x26, 0xca, 0xb1, 0x59, - 0xe3, 0xed, 0x5d, 0xbf, 0x77, 0xec, 0xd8, 0x41, 0x9f, 0x26, 0x92, 0x92, 0x36, 0x59, 0x7d, 0x7c, - 0x7c, 0xb8, 0xed, 0xdb, 0xb7, 0xdb, 0xe4, 0xb1, 0x45, 0x44, 0xf9, 0xfc, 0x61, 0x8b, 0xcf, 0x92, - 0x66, 0xdb, 0xaa, 0x07, 0xdc, 0x7d, 0xfa, 0xf4, 0xa1, 0xc2, 0x2d, 0x0b, 0x0b, 0xf3, 0xa8, 0x3c, - 0x32, 0x32, 0x52, 0x88, 0x52, 0x0d, 0x93, 0xb5, 0x91, 0x76, 0xf5, 0x58, 0x0a, 0x55, 0xd5, 0x89, - 0x07, 0x0c, 0x18, 0xc0, 0x1e, 0x74, 0x57, 0x56, 0x56, 0x12, 0x9b, 0x01, 0x6a, 0x6a, 0x6a, 0x60, - 0xdd, 0xba, 0x75, 0x14, 0x26, 0xaf, 0x5c, 0xd3, 0x87, 0xdc, 0x1b, 0x36, 0x6c, 0xa0, 0x79, 0xfc, - 0xc1, 0x99, 0x2a, 0x1e, 0x2d, 0x5b, 0xb6, 0xa4, 0xe7, 0xe5, 0xcb, 0x97, 0x33, 0x1c, 0x63, 0xd2, - 0x02, 0x58, 0x7a, 0x24, 0x95, 0xe7, 0x23, 0x10, 0x1c, 0x1c, 0xcc, 0x91, 0x27, 0xf2, 0xb4, 0x96, - 0x82, 0x82, 0x82, 0x28, 0x6b, 0x5c, 0x5c, 0x1c, 0x0b, 0x3d, 0xb1, 0x83, 0xc1, 0xa7, 0x4e, 0x9d, - 0xa2, 0xf4, 0x21, 0x43, 0x86, 0x50, 0xdc, 0xec, 0xd9, 0xb3, 0x19, 0x6d, 0xdb, 0xb6, 0x6d, 0x14, - 0x8e, 0x89, 0x89, 0x11, 0xa9, 0x73, 0x24, 0x02, 0x0e, 0x35, 0x21, 0xde, 0x50, 0xa1, 0x76, 0xc4, - 0x49, 0x35, 0xa1, 0xfd, 0xfb, 0xf7, 0x53, 0x63, 0x91, 0x37, 0x34, 0x34, 0x94, 0xc1, 0xc8, 0x1f, - 0x15, 0x15, 0x25, 0x14, 0xc1, 0x39, 0xe2, 0x80, 0xaa, 0x26, 0x44, 0x94, 0x36, 0xb8, 0xa4, 0xab, - 0x03, 0x87, 0x0e, 0x1d, 0xa2, 0x0e, 0x66, 0x64, 0x64, 0x40, 0xdf, 0xbe, 0x7d, 0x9d, 0xe3, 0xac, - 0x28, 0x86, 0x12, 0x19, 0x1c, 0x1a, 0x89, 0x25, 0xf4, 0x70, 0x77, 0x77, 0xe7, 0xc6, 0x8d, 0x1b, - 0xc7, 0xf2, 0x63, 0xc7, 0x8e, 0x65, 0x25, 0xda, 0xb5, 0x6b, 0xc7, 0xf0, 0x3c, 0x7f, 0x6d, 0x6d, - 0xad, 0x08, 0xc7, 0x37, 0x21, 0xbe, 0xa9, 0x20, 0x5f, 0x55, 0x55, 0x15, 0xd7, 0xb4, 0x69, 0x53, - 0x11, 0x1f, 0x5f, 0x3e, 0x3b, 0x3b, 0x9b, 0xc9, 0x97, 0x03, 0x74, 0x9d, 0x4e, 0xe3, 0x88, 0x44, - 0xde, 0x44, 0x81, 0x5e, 0xbd, 0x7a, 0x41, 0xa3, 0x46, 0xe2, 0x97, 0x5c, 0x89, 0x51, 0x86, 0x24, - 0x5d, 0x1d, 0x30, 0xc4, 0x42, 0x3b, 0x42, 0x75, 0xed, 0x03, 0x76, 0x74, 0x19, 0x42, 0x36, 0x1d, - 0x30, 0xa4, 0x5a, 0x55, 0x08, 0x35, 0x23, 0xa0, 0xa2, 0xb2, 0x0c, 0x61, 0x35, 0x23, 0x60, 0x48, - 0xb5, 0xaa, 0x10, 0xfa, 0xd0, 0x5f, 0x07, 0x54, 0xf8, 0xda, 0x20, 0x59, 0x1f, 0xfa, 0x2e, 0xd0, - 0x20, 0x6b, 0x55, 0x85, 0x51, 0x66, 0x00, 0x54, 0x54, 0x96, 0x11, 0xac, 0x66, 0x00, 0x8c, 0xa8, - 0x55, 0x15, 0x32, 0xcd, 0x00, 0xa8, 0xa8, 0x2c, 0x23, 0x58, 0xcd, 0x00, 0x18, 0x51, 0xab, 0x2a, - 0x64, 0x9a, 0x01, 0x50, 0x51, 0x59, 0x46, 0xb0, 0x9a, 0x01, 0x30, 0xa2, 0x56, 0x55, 0xc8, 0x34, - 0x03, 0xa0, 0xa2, 0xb2, 0x8c, 0x60, 0x55, 0xf4, 0x68, 0xcc, 0x08, 0xc5, 0x46, 0xc8, 0x7c, 0xe3, - 0xdc, 0x0c, 0xf8, 0xa5, 0x24, 0x1d, 0x9e, 0x6e, 0xf9, 0x2c, 0xfc, 0xa9, 0xed, 0x74, 0x78, 0xb2, - 0x71, 0xa8, 0x11, 0x6a, 0x74, 0x95, 0xd9, 0x20, 0x7a, 0xc0, 0xa9, 0xa2, 0x13, 0xb0, 0xf8, 0xa7, - 0xb7, 0xa0, 0x8a, 0xab, 0x7b, 0x58, 0xe5, 0x88, 0x87, 0xcb, 0xc8, 0xeb, 0x81, 0x3f, 0x17, 0x5f, - 0x20, 0xaf, 0x0b, 0xd6, 0x40, 0xc2, 0x2d, 0xf2, 0x02, 0x28, 0x79, 0x98, 0x25, 0x95, 0xde, 0xcf, - 0x58, 0x02, 0x3f, 0xe4, 0xed, 0x93, 0x22, 0xb9, 0x04, 0xe7, 0x92, 0x5b, 0x11, 0xf8, 0x1e, 0x4e, - 0x6c, 0xee, 0x37, 0xb0, 0xf5, 0xca, 0x46, 0x20, 0xaf, 0x6c, 0x31, 0xc7, 0x3d, 0xdd, 0x3d, 0xe1, - 0x93, 0xde, 0x3b, 0xe0, 0x89, 0x46, 0xc1, 0x0c, 0xa7, 0x04, 0xf8, 0xf8, 0xf2, 0x5a, 0x20, 0xfb, - 0xbe, 0x31, 0xd6, 0x65, 0xa1, 0xff, 0x84, 0x81, 0x2d, 0xc4, 0x0f, 0x98, 0x4b, 0xaa, 0x8b, 0x61, - 0xc6, 0xa9, 0x49, 0x50, 0x54, 0x59, 0xff, 0x6a, 0xb1, 0x97, 0xbb, 0x17, 0x4c, 0x0e, 0x7a, 0x11, - 0xa6, 0xb5, 0x9b, 0x09, 0x5e, 0x6e, 0x8f, 0xb0, 0xf2, 0xce, 0x04, 0x9c, 0x16, 0x00, 0x7c, 0xbf, - 0x74, 0x5b, 0xd6, 0x16, 0xf8, 0xfa, 0xfa, 0x6e, 0xda, 0x4a, 0x85, 0x4e, 0xfe, 0xae, 0xf1, 0x93, - 0xf0, 0xd7, 0x90, 0xc5, 0x0e, 0x0d, 0x19, 0x5f, 0x11, 0x79, 0x1f, 0x5d, 0x5a, 0xc3, 0xc4, 0xbd, - 0x11, 0x3c, 0x17, 0x9e, 0x6f, 0x33, 0x85, 0xe5, 0x2d, 0x81, 0x1b, 0xe5, 0xd7, 0x81, 0x6c, 0x6f, - 0x07, 0x27, 0x6e, 0x1f, 0xb3, 0x24, 0xd1, 0x17, 0x79, 0x5f, 0x27, 0xe5, 0x9b, 0x79, 0x35, 0xb7, - 0xa2, 0x19, 0x85, 0x30, 0x34, 0x00, 0x05, 0x95, 0xf9, 0xb0, 0x81, 0x38, 0x4b, 0x36, 0xe8, 0x10, - 0xd9, 0x8f, 0xc3, 0xc3, 0xf0, 0x80, 0xe7, 0xe0, 0xd5, 0x0e, 0x73, 0xe0, 0x51, 0xaf, 0x66, 0x22, - 0x9a, 0x9a, 0x4c, 0x62, 0x41, 0x3c, 0x2c, 0x4d, 0x5b, 0xc4, 0x8a, 0x4c, 0x6a, 0x1b, 0x05, 0xaf, - 0x75, 0x8c, 0x66, 0x79, 0x7b, 0x00, 0x6e, 0x7b, 0xb1, 0x3d, 0x7b, 0x2b, 0xfc, 0x3b, 0x67, 0x07, - 0x54, 0xd7, 0xd6, 0xed, 0x82, 0xc2, 0x97, 0xe9, 0xd2, 0xa4, 0x1b, 0xe0, 0x3b, 0xe8, 0xc1, 0x7e, - 0xc6, 0xae, 0x24, 0xd6, 0x3d, 0x00, 0x19, 0xf7, 0xd2, 0x60, 0xcd, 0x2f, 0x2b, 0x21, 0x93, 0x6c, - 0x48, 0x22, 0x4c, 0x8d, 0x3c, 0xfd, 0x60, 0x46, 0xfb, 0x57, 0x61, 0x02, 0x79, 0x7f, 0xd7, 0xd1, - 0x8d, 0x47, 0x84, 0xf2, 0xd2, 0xc9, 0x4b, 0xcf, 0xe4, 0x6d, 0x53, 0x86, 0x1a, 0xf4, 0xd8, 0x10, - 0x88, 0xe9, 0x2c, 0xbf, 0x4d, 0x01, 0x63, 0xb4, 0x01, 0x1c, 0xb9, 0xf5, 0x5f, 0xf8, 0x88, 0x0c, - 0x67, 0x05, 0x15, 0xb7, 0x44, 0x5c, 0x01, 0x3e, 0xad, 0x60, 0x0e, 0xd9, 0xb7, 0xa7, 0x5f, 0x73, - 0xfd, 0xdf, 0xcf, 0xd1, 0x35, 0x00, 0x7f, 0x39, 0x33, 0x0d, 0x2e, 0x5a, 0xac, 0xf0, 0x79, 0xc2, - 0xaf, 0x23, 0xdd, 0x11, 0x26, 0xd0, 0xa7, 0xad, 0xc8, 0x29, 0x2d, 0x99, 0x5b, 0x15, 0x79, 0x64, - 0x87, 0xa5, 0x48, 0xb6, 0x77, 0x4f, 0xe7, 0x26, 0xa1, 0xb0, 0xa9, 0xe7, 0x36, 0x2d, 0x22, 0x45, - 0x65, 0xef, 0x56, 0xdd, 0x81, 0xf7, 0x33, 0xde, 0x03, 0xb2, 0x09, 0xa9, 0x08, 0x8f, 0xd7, 0xa8, - 0xb8, 0xa7, 0x93, 0x45, 0x38, 0xad, 0x19, 0x5d, 0x03, 0x80, 0xc6, 0x14, 0x91, 0xf5, 0x33, 0xb8, - 0x56, 0x20, 0x2e, 0xef, 0x7b, 0x7c, 0x71, 0x44, 0x64, 0x1f, 0xae, 0x3b, 0x78, 0xad, 0xe3, 0x5b, - 0xf0, 0xec, 0x63, 0xc3, 0x44, 0x78, 0x35, 0x99, 0xf2, 0xda, 0x32, 0x78, 0x21, 0xe5, 0x39, 0x72, - 0xf1, 0x2e, 0xa1, 0xc5, 0x1e, 0x27, 0xad, 0x73, 0x57, 0xdf, 0x6f, 0x35, 0xf7, 0xaa, 0xf3, 0x77, - 0xcf, 0xd0, 0xe1, 0x92, 0xec, 0x91, 0x64, 0x65, 0x4e, 0x58, 0xf3, 0x08, 0x78, 0x33, 0x78, 0x3e, - 0x5d, 0x9c, 0x61, 0x45, 0xd4, 0x88, 0xd0, 0x3d, 0x00, 0x42, 0x7b, 0x70, 0xb6, 0x83, 0xcb, 0x09, - 0xb6, 0x66, 0x6d, 0x02, 0xb2, 0xa7, 0xb7, 0x90, 0x04, 0xb8, 0xe4, 0x60, 0x5c, 0xe0, 0x44, 0xf8, - 0xf3, 0x13, 0xb3, 0xc1, 0xcf, 0xc3, 0x5f, 0x44, 0x93, 0xcb, 0xa0, 0xbc, 0x17, 0x53, 0x27, 0x90, - 0x37, 0x99, 0x73, 0x28, 0x8b, 0xaf, 0x87, 0x2f, 0x7c, 0x11, 0xfe, 0x3d, 0xe0, 0xda, 0x23, 0xb5, - 0xa9, 0x9a, 0xec, 0x7c, 0xf5, 0x65, 0xce, 0x4e, 0xd8, 0x91, 0xfd, 0x29, 0x59, 0x49, 0x53, 0x26, - 0x2a, 0xee, 0xed, 0xe1, 0x03, 0x51, 0x41, 0x33, 0xc8, 0x0c, 0x69, 0xba, 0xe1, 0xb3, 0x23, 0x43, - 0x03, 0x20, 0xf2, 0x8a, 0x64, 0xb2, 0x4a, 0x2f, 0xd1, 0x56, 0x76, 0x8e, 0xac, 0xf5, 0xb0, 0x4c, - 0xf8, 0xa7, 0x69, 0x4e, 0xc8, 0x02, 0x9b, 0x33, 0xa1, 0xe8, 0xf3, 0xaf, 0x92, 0x75, 0x22, 0x67, - 0x68, 0x51, 0xbc, 0x90, 0xff, 0x2b, 0xec, 0x6b, 0x68, 0xe3, 0x13, 0x64, 0x29, 0x4a, 0x36, 0x8f, - 0x33, 0xa0, 0x4d, 0x97, 0x56, 0x43, 0x72, 0x61, 0xdd, 0x2e, 0x2f, 0x42, 0xc6, 0x0e, 0x7e, 0xc1, - 0xb4, 0x95, 0xf7, 0x7a, 0xf4, 0x29, 0x21, 0xda, 0x70, 0xd8, 0xa9, 0x01, 0x10, 0x7a, 0x83, 0x33, - 0x90, 0x9d, 0xd9, 0x9f, 0xd1, 0x19, 0x48, 0x65, 0x6d, 0xdd, 0x1f, 0x30, 0xdc, 0x51, 0x0c, 0x77, - 0x16, 0x93, 0x4a, 0xf8, 0x07, 0xea, 0x60, 0xde, 0x01, 0x46, 0x5a, 0xd3, 0x63, 0x33, 0xf4, 0x6c, - 0xda, 0x87, 0xe5, 0x95, 0x00, 0x6b, 0x2f, 0xae, 0x84, 0xd8, 0x1b, 0x75, 0x4b, 0x04, 0x31, 0x80, - 0x23, 0x03, 0xc6, 0xc2, 0x2b, 0x1d, 0xde, 0xd0, 0x34, 0x13, 0x53, 0xa2, 0xd7, 0x16, 0x8f, 0xcb, - 0x02, 0x60, 0x69, 0x54, 0x2e, 0x69, 0x9d, 0xad, 0x65, 0xd6, 0x8a, 0xe1, 0x10, 0xb6, 0x2b, 0x7b, - 0x1b, 0x2b, 0xb2, 0xf8, 0xf7, 0x31, 0x74, 0x1a, 0xcb, 0x10, 0x2a, 0x00, 0x5c, 0x88, 0x6a, 0x6b, - 0x11, 0x9e, 0x0a, 0x51, 0xba, 0xb0, 0x36, 0x98, 0x00, 0xc8, 0x79, 0xb3, 0x37, 0xf7, 0x6b, 0x58, - 0x97, 0x59, 0x3f, 0xbd, 0xc4, 0x6b, 0xc6, 0xf4, 0x76, 0x2f, 0xcb, 0xb1, 0x3f, 0x74, 0xf8, 0x06, - 0x71, 0x2f, 0x48, 0xae, 0xd6, 0x70, 0x35, 0x25, 0x5e, 0xac, 0xf9, 0xa5, 0x43, 0xcf, 0xb5, 0x8e, - 0xfc, 0x55, 0x55, 0x3e, 0xfa, 0xdd, 0xe0, 0x7b, 0x80, 0x5c, 0x70, 0x7e, 0x2d, 0xf8, 0x06, 0xdd, - 0x03, 0x7e, 0x2d, 0x95, 0x6c, 0xcb, 0x0f, 0x33, 0x00, 0xb6, 0x6a, 0xc7, 0x09, 0x34, 0x33, 0x00, - 0x4e, 0xa8, 0x64, 0x5b, 0x2a, 0xcc, 0x00, 0xd8, 0xaa, 0x1d, 0x27, 0xd0, 0xcc, 0x00, 0x38, 0xa1, - 0x92, 0x6d, 0xa9, 0x30, 0x03, 0x60, 0xab, 0x76, 0x9c, 0x40, 0xd3, 0x25, 0x00, 0xc9, 0xc9, 0xc9, - 0x40, 0xd6, 0x30, 0xb1, 0x45, 0x84, 0xf8, 0x37, 0x7f, 0xe3, 0xc6, 0x8d, 0x0e, 0x9b, 0x5f, 0x5a, - 0x5a, 0x0a, 0x77, 0xee, 0xdc, 0x71, 0xb8, 0xbc, 0x96, 0x82, 0x68, 0x37, 0xda, 0x6f, 0x79, 0x90, - 0xf5, 0x59, 0x5a, 0xc4, 0xca, 0x96, 0xd5, 0x25, 0x00, 0xdd, 0xbb, 0x77, 0x87, 0x25, 0x4b, 0x96, - 0x40, 0xb3, 0x66, 0xf5, 0x4f, 0xb7, 0xee, 0xdd, 0xab, 0x7f, 0xd6, 0x2b, 0xab, 0x5d, 0x82, 0xf0, - 0xce, 0x3b, 0xef, 0x80, 0x9f, 0x9f, 0x1f, 0x95, 0x45, 0xd6, 0x22, 0x4a, 0x70, 0x18, 0x8b, 0x1a, - 0x33, 0x66, 0x0c, 0x2c, 0x5a, 0xb4, 0x08, 0x26, 0x4e, 0x9c, 0x08, 0xc2, 0x7d, 0x75, 0xf9, 0xd5, - 0xad, 0x7a, 0x6b, 0xd7, 0xe5, 0xb5, 0x14, 0xac, 0x30, 0xb2, 0xf2, 0x14, 0xf6, 0xed, 0xdb, 0x07, - 0xa7, 0x4f, 0xd7, 0xdf, 0xe9, 0x44, 0xa3, 0xc9, 0xaa, 0x55, 0x8a, 0xf3, 0xf7, 0xf7, 0x87, 0xde, - 0xbd, 0x7b, 0x43, 0x8f, 0x1e, 0xb6, 0x77, 0x7d, 0x22, 0x9f, 0x43, 0x64, 0x3e, 0x2a, 0xfd, 0xb0, - 0xd4, 0xf5, 0xeb, 0xd7, 0x01, 0x3f, 0x44, 0x85, 0x8b, 0xeb, 0xc8, 0x67, 0x9a, 0xe8, 0xc7, 0xa5, - 0x70, 0xaf, 0xeb, 0x92, 0x92, 0x12, 0xc0, 0x9d, 0x98, 0x3b, 0x76, 0xec, 0x08, 0xf9, 0xf9, 0xf9, - 0x10, 0x1f, 0x1f, 0x0f, 0xb9, 0xb9, 0xb9, 0x40, 0x56, 0x0c, 0xc2, 0xb0, 0x61, 0xc3, 0x24, 0xdf, - 0x9c, 0x68, 0xdf, 0xbe, 0x3d, 0xdb, 0x00, 0x7c, 0xde, 0xbc, 0x79, 0xb0, 0x66, 0x4d, 0xfd, 0xf3, - 0x66, 0x66, 0x98, 0x9e, 0x80, 0xdc, 0x12, 0x44, 0x47, 0xf0, 0xfc, 0xb2, 0x62, 0x62, 0x1f, 0x47, - 0x96, 0xd8, 0x4b, 0x2e, 0x7f, 0x44, 0x1a, 0xd9, 0x72, 0x5a, 0x24, 0xfe, 0xc0, 0x81, 0x03, 0xb2, - 0xbc, 0xc8, 0x6f, 0x79, 0x9c, 0x38, 0x71, 0x82, 0x95, 0x9f, 0x3a, 0x75, 0xaa, 0x15, 0xdd, 0x92, - 0x5f, 0x2e, 0x4f, 0xb6, 0x02, 0x60, 0x72, 0xa4, 0x00, 0xe1, 0x92, 0x4e, 0x35, 0x7b, 0x75, 0x4b, - 0xc9, 0x92, 0xc3, 0xe9, 0x32, 0x04, 0x11, 0x07, 0xad, 0x12, 0x51, 0x08, 0xd7, 0xae, 0x5d, 0xa3, - 0x4f, 0xc5, 0x10, 0x26, 0x6b, 0x5e, 0x19, 0xcf, 0xc2, 0x85, 0x0b, 0x45, 0x9f, 0x4d, 0xc3, 0x56, - 0x8a, 0xad, 0x13, 0x77, 0x57, 0x1f, 0x34, 0x68, 0x10, 0xe3, 0xeb, 0xda, 0xb5, 0x2b, 0x6d, 0x81, - 0xd8, 0x0a, 0xf1, 0x58, 0xbf, 0x7e, 0x3d, 0x24, 0x25, 0x25, 0x89, 0x16, 0xf2, 0x92, 0x2d, 0x09, - 0x80, 0x2c, 0xa9, 0x66, 0x65, 0x70, 0xd7, 0x76, 0xd4, 0x87, 0x07, 0xc2, 0x7c, 0xda, 0xbc, 0x79, - 0x33, 0xc5, 0xad, 0x5e, 0xbd, 0x9a, 0x47, 0x49, 0x7e, 0x80, 0x98, 0x11, 0x9d, 0x04, 0xe8, 0x32, - 0x04, 0x49, 0xd9, 0xba, 0x6c, 0xd9, 0x32, 0x68, 0xdb, 0xb6, 0xfe, 0x39, 0x70, 0xbf, 0x7e, 0xfd, - 0x18, 0x1b, 0x56, 0xce, 0xcd, 0x9b, 0x37, 0xa1, 0x43, 0x87, 0x0e, 0x14, 0x87, 0x17, 0x70, 0xdc, - 0x28, 0x02, 0x0f, 0xb2, 0x40, 0x18, 0x8e, 0x1e, 0x3d, 0x4a, 0xf1, 0x38, 0x9c, 0xe0, 0x9e, 0xfd, - 0x6a, 0x52, 0x44, 0x44, 0x04, 0x63, 0x6f, 0xd5, 0xaa, 0x15, 0x1d, 0x9a, 0x10, 0x11, 0x1e, 0x1e, - 0x4e, 0xf1, 0x81, 0x81, 0x81, 0x8c, 0x5e, 0x5c, 0x5c, 0xcc, 0x60, 0x57, 0x01, 0x86, 0xf5, 0x00, - 0xf2, 0xf9, 0x5a, 0x87, 0x7c, 0xc2, 0xdd, 0x41, 0xf8, 0xe4, 0xaa, 0x99, 0x10, 0xaf, 0xdf, 0x29, - 0x67, 0xd2, 0x1a, 0x35, 0x27, 0xd2, 0x9a, 0x39, 0x32, 0x8c, 0x70, 0xe4, 0xeb, 0x14, 0x6c, 0x3c, - 0xc6, 0x6f, 0x1a, 0x2e, 0x58, 0xb0, 0x80, 0xca, 0x8e, 0x8d, 0x8d, 0xe5, 0xba, 0x74, 0xe9, 0xc2, - 0x68, 0xc4, 0x31, 0xba, 0xfb, 0x02, 0xb9, 0x68, 0x5b, 0xe9, 0xde, 0xb9, 0x73, 0xa7, 0x88, 0x0f, - 0x97, 0xe8, 0x87, 0x85, 0x85, 0x71, 0x01, 0x01, 0x01, 0x22, 0x3c, 0xca, 0x48, 0x4b, 0x4b, 0xe3, - 0xf0, 0xfa, 0x41, 0x2e, 0xb2, 0x8c, 0xe6, 0xeb, 0xeb, 0xcb, 0x91, 0x4f, 0x1a, 0x50, 0xb9, 0xfc, - 0xf2, 0x7c, 0xe4, 0x45, 0xfd, 0xc7, 0x8f, 0x1f, 0x67, 0xdf, 0x64, 0x40, 0x1c, 0x99, 0x3c, 0xd0, - 0x5d, 0x1e, 0x78, 0x23, 0x56, 0xac, 0x58, 0xc1, 0x75, 0xee, 0xdc, 0x99, 0x23, 0x3d, 0x97, 0x1e, - 0x64, 0xe2, 0xc0, 0xe4, 0xe2, 0xae, 0x2a, 0x3c, 0x1e, 0xb7, 0xce, 0x98, 0x35, 0x6b, 0x16, 0x5f, - 0x4c, 0xd3, 0x59, 0x97, 0x1e, 0x80, 0x33, 0x17, 0xfc, 0xac, 0x25, 0x7e, 0x5d, 0x83, 0x4f, 0x38, - 0x97, 0xe7, 0x3f, 0x75, 0x89, 0x5d, 0x1d, 0xbf, 0xcc, 0x21, 0x4c, 0xe4, 0xb3, 0x8c, 0x56, 0x38, - 0xa4, 0xe3, 0xd4, 0x13, 0x67, 0x2c, 0x53, 0xa6, 0x4c, 0xa1, 0x9f, 0x1b, 0x21, 0x7b, 0x1e, 0x40, - 0x6a, 0x6a, 0x2a, 0x95, 0x85, 0x9f, 0x1f, 0xc1, 0xeb, 0xc5, 0xae, 0x5d, 0xbb, 0xe8, 0x78, 0x4e, - 0x2a, 0x0b, 0x50, 0xb6, 0x70, 0x28, 0xc1, 0x99, 0x17, 0xaf, 0x17, 0x67, 0x34, 0x7c, 0x42, 0xfd, - 0x38, 0x2b, 0x22, 0x81, 0x64, 0x9f, 0x31, 0xa9, 0xa8, 0xa8, 0xa0, 0x43, 0x21, 0xcf, 0x83, 0x33, - 0xa9, 0x9c, 0x9c, 0x1c, 0x76, 0x08, 0xa7, 0xd2, 0xe8, 0x23, 0x4f, 0xc3, 0x6b, 0x1b, 0xce, 0xa6, - 0xf4, 0x48, 0xe6, 0xf3, 0x00, 0x3d, 0x6a, 0x51, 0x83, 0x0c, 0x5d, 0x7a, 0x80, 0x06, 0xfd, 0xbf, - 0xf9, 0xa2, 0x66, 0x00, 0x5c, 0xdc, 0x04, 0xcc, 0x00, 0x98, 0x01, 0x70, 0x71, 0x0d, 0xb8, 0x58, - 0xbd, 0xd9, 0x03, 0xcc, 0x00, 0xb8, 0xb8, 0x06, 0x5c, 0xac, 0xde, 0xec, 0x01, 0x66, 0x00, 0x5c, - 0x5c, 0x03, 0x2e, 0x56, 0xff, 0x7f, 0x0f, 0x62, 0xce, 0xd5, 0xad, 0xd5, 0x92, 0x0c, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXAudioIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x32, 0x39, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xa6, - 0xa8, 0x92, 0xdf, 0x00, 0x00, 0x09, 0x77, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x99, 0x57, - 0x4c, 0x94, 0x4b, 0x14, 0xc7, 0xd9, 0xa2, 0xd2, 0x44, 0x40, 0x2c, 0x14, 0x51, 0xc0, 0xa8, 0xd8, - 0x30, 0x8a, 0x77, 0xc5, 0xcb, 0xb5, 0xbc, 0x20, 0xf6, 0x68, 0xa2, 0x89, 0x3d, 0x24, 0xbe, 0x58, - 0x5e, 0x7c, 0xd0, 0x18, 0xbd, 0x46, 0xe3, 0x8b, 0x4f, 0x1a, 0x8d, 0x31, 0xea, 0x83, 0x35, 0x6a, - 0x2c, 0xb9, 0x24, 0x46, 0x0d, 0x8a, 0x41, 0x54, 0x04, 0x0d, 0x08, 0x42, 0x58, 0x69, 0xa2, 0xec, - 0x52, 0xa4, 0x08, 0xb2, 0x74, 0x41, 0x81, 0xfb, 0x93, 0xb9, 0x99, 0x7c, 0x77, 0x29, 0xba, 0x1f, - 0x4d, 0x93, 0xfd, 0xb2, 0xd9, 0x9c, 0x99, 0x39, 0x33, 0xdf, 0xf9, 0x9f, 0x36, 0x73, 0xe6, 0xd3, - 0xb4, 0xb7, 0xb7, 0x3b, 0xfc, 0xce, 0x8f, 0xf6, 0x77, 0x16, 0xfe, 0xbb, 0xec, 0x76, 0x00, 0x83, - 0x6d, 0x41, 0xbb, 0x05, 0x6c, 0xb4, 0x40, 0x65, 0x65, 0x65, 0x7e, 0x7e, 0xfe, 0xb7, 0x6f, 0xdf, - 0x6c, 0x9c, 0xd7, 0x2d, 0xbb, 0xa6, 0x6f, 0xb3, 0x50, 0x71, 0x71, 0x71, 0xb5, 0xc5, 0xa2, 0xd7, - 0xe9, 0xbc, 0xc7, 0x7a, 0xbb, 0x7b, 0xb8, 0x2b, 0x5f, 0xcb, 0x8b, 0x34, 0x1a, 0x4d, 0x5d, 0x5d, - 0xdd, 0xf3, 0xe7, 0xcf, 0x1b, 0x1b, 0x1b, 0x97, 0x2e, 0x5d, 0xea, 0xea, 0xea, 0xaa, 0x64, 0x50, - 0x47, 0xf7, 0x25, 0x80, 0x9c, 0x9c, 0x9c, 0x4c, 0xa3, 0xd1, 0xa1, 0x5d, 0xd3, 0xdc, 0xd2, 0xac, - 0xd7, 0xeb, 0x02, 0x03, 0x02, 0xa6, 0x4f, 0x9f, 0xee, 0xec, 0xec, 0x2c, 0x24, 0x43, 0xf4, 0xf2, - 0xf2, 0x72, 0x3f, 0x3f, 0x3f, 0xad, 0x56, 0xfb, 0xf0, 0xe1, 0xc3, 0xcf, 0x9f, 0x3f, 0xaf, 0x5f, - 0xbf, 0x5e, 0x8e, 0xaa, 0x93, 0x9e, 0x59, 0xba, 0x23, 0x47, 0x8e, 0xa8, 0x9e, 0xac, 0x9c, 0xd8, - 0xd0, 0xd0, 0x90, 0x9a, 0x9a, 0x86, 0x9a, 0x1f, 0x3f, 0x8e, 0x8d, 0x7f, 0x12, 0x57, 0x55, 0x59, - 0xd9, 0xd4, 0xd8, 0x44, 0xa7, 0x97, 0xd7, 0x28, 0x27, 0x27, 0x47, 0x38, 0xf5, 0x7a, 0x3d, 0x42, - 0xbf, 0x79, 0xf3, 0xc6, 0xdb, 0xdb, 0x7b, 0xda, 0xb4, 0x69, 0xa0, 0xcd, 0xcd, 0xcd, 0x9d, 0x31, - 0x63, 0x86, 0x72, 0x11, 0x15, 0x74, 0x9f, 0x01, 0x30, 0x9b, 0xcd, 0x38, 0x46, 0x7c, 0x7c, 0x7c, - 0x74, 0xf4, 0x3f, 0xc8, 0xf1, 0xb9, 0xba, 0xda, 0x64, 0x36, 0xe1, 0xeb, 0xad, 0xad, 0xad, 0x63, - 0xc6, 0x8c, 0x71, 0x72, 0x72, 0x42, 0xfd, 0x82, 0x78, 0xf5, 0xea, 0xd5, 0xf8, 0xf1, 0xe3, 0x27, - 0x4c, 0x98, 0xf0, 0xe2, 0xc5, 0x8b, 0xa1, 0x43, 0x87, 0xfa, 0xf8, 0xf8, 0xa8, 0x90, 0x5b, 0x4e, - 0xe9, 0x33, 0x00, 0x65, 0x65, 0x65, 0xb5, 0xb5, 0x75, 0x0f, 0x1e, 0xdc, 0xd7, 0x68, 0x1c, 0xc6, - 0x8e, 0x1d, 0xeb, 0xe2, 0xe2, 0x82, 0xca, 0x09, 0x09, 0x8b, 0xa5, 0x1a, 0x0c, 0xe3, 0xc6, 0x8d, - 0x1b, 0x36, 0x6c, 0x98, 0xd1, 0x68, 0x0c, 0x08, 0x08, 0xc0, 0x85, 0xc0, 0x30, 0x67, 0xce, 0x1c, - 0x7a, 0x9e, 0x3d, 0x7b, 0x36, 0x75, 0xea, 0x54, 0x47, 0xc7, 0xef, 0x26, 0x52, 0xf7, 0xf4, 0x59, - 0x1a, 0x45, 0x2c, 0x44, 0x47, 0x14, 0x6f, 0x6f, 0x1f, 0x4f, 0x4f, 0x4f, 0x0f, 0x0f, 0x8f, 0x11, - 0x23, 0x46, 0xb8, 0xbb, 0xbb, 0x17, 0x14, 0x14, 0x20, 0x6e, 0x42, 0x42, 0x02, 0xee, 0x0e, 0x0c, - 0x5c, 0x28, 0x38, 0x38, 0x18, 0x6c, 0xa9, 0xa9, 0xa9, 0xb3, 0x66, 0xcd, 0xa2, 0x93, 0x51, 0x75, - 0xa2, 0x8b, 0x59, 0x7d, 0x03, 0xa0, 0xa9, 0xa9, 0x29, 0x3b, 0x3b, 0x1b, 0xe9, 0x3d, 0x3c, 0xdc, - 0xbd, 0xbc, 0xbc, 0x46, 0x8e, 0x1c, 0x29, 0x31, 0xd0, 0x24, 0x6f, 0x26, 0x25, 0x25, 0xbe, 0x7e, - 0xfd, 0x1a, 0x6f, 0x01, 0xd5, 0xbb, 0x77, 0xef, 0x16, 0x2e, 0x5c, 0x98, 0x96, 0x96, 0x56, 0x5f, - 0x5f, 0x3f, 0x7f, 0xfe, 0xfc, 0xcc, 0xcc, 0x4c, 0xe2, 0x5b, 0x35, 0x86, 0xbe, 0x01, 0x40, 0x76, - 0x7f, 0xff, 0xfe, 0xbd, 0x4e, 0xa7, 0x77, 0x77, 0xf7, 0x70, 0x73, 0x73, 0x43, 0xf1, 0xc2, 0x02, - 0xd0, 0xc3, 0x87, 0x0f, 0x87, 0xce, 0xcb, 0x7b, 0xf7, 0xf2, 0xe5, 0x4b, 0xc2, 0x60, 0xf2, 0xe4, - 0xc9, 0x26, 0x93, 0x89, 0x90, 0x20, 0x0c, 0x92, 0x92, 0x92, 0xa6, 0x4c, 0x99, 0x82, 0x11, 0x80, - 0x34, 0xc8, 0x00, 0x4a, 0x4a, 0x3e, 0xf2, 0x23, 0x64, 0x51, 0x3c, 0xd9, 0x1d, 0xb9, 0x79, 0x80, - 0x21, 0x09, 0x9d, 0x4e, 0x47, 0xda, 0x49, 0x4c, 0x4c, 0x1c, 0x32, 0x64, 0x08, 0x59, 0x08, 0xad, - 0x13, 0x03, 0x44, 0xc8, 0xd7, 0xaf, 0x5f, 0xf1, 0xa8, 0xbc, 0xbc, 0x3c, 0xe2, 0x44, 0x1d, 0x86, - 0x3e, 0xb0, 0x00, 0xef, 0x36, 0x99, 0x0a, 0xb0, 0x40, 0x5d, 0x5d, 0x2d, 0x79, 0x86, 0x26, 0x18, - 0x04, 0x0c, 0x30, 0xe0, 0x33, 0x18, 0x61, 0xd4, 0xa8, 0x51, 0x44, 0x79, 0x46, 0x46, 0x06, 0xa2, - 0xa3, 0xf5, 0xaa, 0xaa, 0x2a, 0x8c, 0x80, 0x77, 0x7d, 0xf8, 0xf0, 0x81, 0x20, 0xa6, 0x59, 0x5b, - 0x5b, 0x3b, 0x38, 0x00, 0x2c, 0x16, 0x4b, 0x4c, 0xcc, 0xc3, 0x94, 0x94, 0x94, 0xaa, 0xaa, 0x4a, - 0x93, 0xc9, 0x4c, 0x98, 0xea, 0xf5, 0x43, 0xd8, 0x71, 0x9b, 0x9b, 0x9b, 0x09, 0x6b, 0x81, 0x44, - 0xfc, 0xe3, 0x48, 0xa4, 0x5a, 0xbc, 0x85, 0x7e, 0x68, 0xbc, 0x2e, 0x28, 0x28, 0xa8, 0xb0, 0xb0, - 0x10, 0x84, 0xc4, 0x34, 0xf0, 0x06, 0x01, 0x00, 0x81, 0x6b, 0x36, 0x97, 0x14, 0x14, 0x98, 0xd8, - 0xb0, 0xf0, 0x9f, 0x8c, 0x8c, 0x74, 0x12, 0x28, 0xe2, 0xd2, 0x24, 0xcd, 0xe3, 0xdc, 0x6d, 0x6d, - 0x6d, 0x68, 0x9a, 0x07, 0x1a, 0x77, 0xa2, 0x1f, 0xa8, 0x9f, 0x3e, 0x7d, 0x22, 0x9a, 0x2b, 0x2a, - 0x2a, 0x60, 0x26, 0x7c, 0xd9, 0xfb, 0xb0, 0x5b, 0x69, 0x69, 0xe9, 0x40, 0x03, 0xa8, 0xa9, 0xa9, - 0x49, 0x4f, 0x37, 0x56, 0x56, 0x56, 0x39, 0x38, 0x68, 0x5a, 0x5b, 0xbf, 0x7b, 0xff, 0xdb, 0xb7, - 0x6f, 0x11, 0xc8, 0xc7, 0xc7, 0x1b, 0x47, 0x9f, 0x39, 0x73, 0x66, 0x64, 0x64, 0x24, 0xbb, 0x01, - 0x62, 0xb1, 0x5b, 0x91, 0xf2, 0xc9, 0x51, 0x10, 0xd5, 0xd5, 0xd5, 0x64, 0x52, 0xd2, 0x14, 0xbb, - 0x1e, 0xa3, 0x3c, 0x98, 0x8b, 0xa8, 0x50, 0x9d, 0x88, 0xd4, 0xc7, 0x00, 0xdb, 0x56, 0x43, 0x43, - 0x3d, 0xa2, 0x18, 0x0c, 0x86, 0xc6, 0xc6, 0x26, 0xd2, 0x0b, 0x61, 0x90, 0x9c, 0x9c, 0x82, 0x63, - 0xb4, 0xb4, 0xb4, 0x20, 0x37, 0x7e, 0x42, 0xaa, 0xc1, 0x97, 0x90, 0x1b, 0x48, 0xf8, 0x09, 0xc6, - 0xe1, 0x34, 0x61, 0x36, 0x17, 0x62, 0x2e, 0x3c, 0x07, 0x5f, 0x42, 0x74, 0x2c, 0xc0, 0x22, 0x8c, - 0xaa, 0xb3, 0x80, 0xca, 0x69, 0xbc, 0xcc, 0xd5, 0xd5, 0x05, 0xd3, 0x07, 0x05, 0x05, 0xea, 0x74, - 0xd0, 0xae, 0x44, 0x2a, 0xe1, 0x88, 0x7c, 0x48, 0x8c, 0xe8, 0x29, 0x29, 0xaf, 0xbf, 0x7c, 0xf9, - 0xc2, 0xfe, 0x80, 0xac, 0xe8, 0x1e, 0x35, 0xf3, 0x20, 0x25, 0xcd, 0xb2, 0xf2, 0x52, 0xa0, 0x8a, - 0x70, 0x1f, 0x3d, 0x7a, 0x34, 0xd8, 0xf0, 0x31, 0xa6, 0x0c, 0x34, 0x00, 0x5e, 0x89, 0xe8, 0x1a, - 0x4d, 0x9b, 0xb3, 0xb3, 0xcb, 0x82, 0x05, 0x0b, 0xee, 0xdd, 0xbb, 0xb7, 0x6b, 0xd7, 0xae, 0xe6, - 0xe6, 0x96, 0xec, 0xec, 0x9c, 0xe0, 0xe0, 0x29, 0xf1, 0xf1, 0x4f, 0xb0, 0x8f, 0x88, 0x0d, 0x24, - 0x43, 0xcd, 0x3c, 0x10, 0x88, 0x5b, 0x5e, 0x56, 0x86, 0xfb, 0xe1, 0x63, 0x44, 0x08, 0x61, 0x00, - 0x2a, 0x10, 0x62, 0x2b, 0x75, 0x00, 0xd4, 0xbb, 0x10, 0xef, 0x43, 0xf1, 0x45, 0x45, 0x85, 0xc8, - 0xf5, 0xe7, 0x9f, 0xe1, 0xf8, 0x74, 0x71, 0xf1, 0x47, 0xb2, 0x26, 0x82, 0x92, 0x16, 0x03, 0x02, - 0x82, 0xb2, 0xb2, 0xb2, 0xf1, 0x6c, 0xfc, 0x07, 0xad, 0x23, 0x6b, 0x07, 0x84, 0x76, 0xdc, 0x06, - 0x7f, 0x03, 0x1a, 0x04, 0xa2, 0x33, 0xca, 0x3a, 0xc4, 0x37, 0x48, 0x06, 0x01, 0xc0, 0xa4, 0x49, - 0x93, 0xd2, 0xde, 0xa4, 0x7f, 0x2c, 0xa9, 0x68, 0x6b, 0xd3, 0x86, 0x86, 0xce, 0x4d, 0x4c, 0x4c, - 0x40, 0xe7, 0x1d, 0x19, 0xe6, 0x93, 0x9f, 0x9f, 0x2f, 0x25, 0x01, 0xc9, 0x91, 0x2d, 0x8c, 0xdd, - 0x4a, 0x60, 0x60, 0x8b, 0x00, 0x09, 0x7e, 0x65, 0xa9, 0xb1, 0x60, 0x04, 0x29, 0x31, 0x66, 0x81, - 0x4d, 0x36, 0x6d, 0x22, 0x7a, 0x65, 0x01, 0xd4, 0xe6, 0xe4, 0xe8, 0x94, 0x90, 0xf0, 0x9c, 0xfd, - 0x28, 0x34, 0xd4, 0x80, 0x7c, 0x89, 0x89, 0x2f, 0xc8, 0x8f, 0x15, 0x15, 0xe5, 0x9c, 0xe1, 0xfe, - 0x30, 0x18, 0xd8, 0x9e, 0xc0, 0x40, 0x30, 0xf0, 0x10, 0x1b, 0x04, 0x37, 0x0f, 0x04, 0xa7, 0x20, - 0xbc, 0xcb, 0x26, 0x41, 0xbb, 0x63, 0xee, 0x15, 0x00, 0x16, 0x0d, 0x0b, 0x33, 0x64, 0x65, 0x19, - 0x39, 0x48, 0xa0, 0xd7, 0xad, 0x5b, 0xa3, 0x38, 0x2f, 0xc4, 0xc6, 0x3e, 0x4a, 0x4e, 0x4e, 0xbe, - 0x7f, 0xff, 0x7e, 0x6d, 0x4d, 0x4d, 0x44, 0xc4, 0x12, 0xdc, 0x89, 0x1c, 0x8f, 0xc4, 0xf8, 0x18, - 0x0f, 0x6c, 0x18, 0x41, 0xab, 0xd5, 0xf1, 0xdf, 0x9d, 0x4c, 0x36, 0xf5, 0xf7, 0x0a, 0x00, 0x6e, - 0x4d, 0x1e, 0x5c, 0xbe, 0x2c, 0x32, 0x37, 0x2f, 0x27, 0x24, 0x64, 0xc6, 0xaa, 0x55, 0xcb, 0x0f, - 0x1e, 0xfc, 0xdb, 0xd1, 0xd1, 0xc9, 0xd7, 0xd7, 0xd7, 0xc7, 0xc7, 0x97, 0xda, 0x17, 0x7d, 0x87, - 0x87, 0xff, 0x85, 0xfa, 0x39, 0xc0, 0x61, 0x17, 0x72, 0x14, 0xff, 0x6c, 0x6a, 0xe4, 0x4d, 0xdc, - 0xc6, 0x26, 0x41, 0xbb, 0x63, 0x56, 0x5f, 0xd0, 0x20, 0x3d, 0x5a, 0x44, 0x44, 0x7f, 0x7f, 0x7f, - 0x9d, 0x4e, 0x63, 0x34, 0x66, 0xb2, 0x5f, 0x79, 0x7a, 0x8e, 0x1c, 0xee, 0xe6, 0xa6, 0xd5, 0x68, - 0xe7, 0xcd, 0x33, 0x40, 0x37, 0x35, 0x35, 0xe2, 0xdc, 0x41, 0x41, 0x13, 0x21, 0x38, 0xb1, 0x71, - 0x1a, 0x25, 0x76, 0x57, 0xad, 0x5c, 0xe5, 0xef, 0x3f, 0x8e, 0x13, 0x91, 0x6a, 0xbf, 0x57, 0x82, - 0x51, 0x59, 0xd4, 0x23, 0x3d, 0xab, 0xe0, 0xf4, 0x00, 0xc0, 0x2b, 0x68, 0xb2, 0x0d, 0xf3, 0x20, - 0x13, 0xea, 0x9f, 0x38, 0x71, 0x22, 0x99, 0x91, 0x14, 0x44, 0x0c, 0xe0, 0x36, 0xf8, 0x4f, 0x6b, - 0x6b, 0x3b, 0x2d, 0x0e, 0x11, 0x1c, 0xef, 0x28, 0x16, 0x28, 0x7a, 0xc2, 0xc2, 0xe6, 0x75, 0xf8, - 0x12, 0x65, 0x90, 0x46, 0x29, 0x90, 0xad, 0x74, 0xaf, 0x00, 0x20, 0x01, 0xe9, 0x05, 0x00, 0x88, - 0x08, 0x01, 0x18, 0x12, 0x0e, 0x18, 0xc0, 0x43, 0x7e, 0xe4, 0xf8, 0x80, 0x9f, 0xd0, 0x0f, 0x8c, - 0xfc, 0xfc, 0xf7, 0xf5, 0x0d, 0xf5, 0xe4, 0x4d, 0xac, 0x86, 0x11, 0x42, 0x43, 0x43, 0x39, 0x9f, - 0x02, 0x12, 0x7a, 0x70, 0x00, 0x08, 0x3d, 0x21, 0x28, 0x0f, 0x30, 0x04, 0x12, 0xfe, 0x69, 0x22, - 0x90, 0xc8, 0xf1, 0x82, 0x87, 0x4e, 0x80, 0x61, 0x2b, 0x40, 0x82, 0x04, 0x0c, 0x88, 0x2e, 0x8e, - 0x46, 0xbd, 0x97, 0x9e, 0x57, 0xa8, 0xb4, 0x80, 0xad, 0x86, 0xee, 0x3f, 0xfe, 0x5e, 0x65, 0xa1, - 0xfe, 0x13, 0xeb, 0xe7, 0x57, 0xb6, 0x03, 0xf8, 0x79, 0x5d, 0xf5, 0x0f, 0xa7, 0xdd, 0x02, 0xfd, - 0xa3, 0xd7, 0x9f, 0x5f, 0xd5, 0x6e, 0x81, 0x1f, 0xe9, 0x4a, 0x6c, 0x11, 0x6c, 0x67, 0x9d, 0x19, - 0xb9, 0x5d, 0x3c, 0x7a, 0xf4, 0x28, 0xe7, 0x8b, 0xce, 0x43, 0x36, 0xf4, 0x74, 0xec, 0x45, 0xfd, - 0xf5, 0x77, 0xe0, 0xc0, 0x01, 0x79, 0xe0, 0xd9, 0xb1, 0x63, 0x87, 0xd5, 0x6b, 0x36, 0x6c, 0xd8, - 0x80, 0xa0, 0x57, 0xaf, 0x5e, 0xb5, 0xea, 0xb7, 0xa9, 0xd9, 0xbf, 0x2e, 0x44, 0xa1, 0x48, 0x8d, - 0xcf, 0x85, 0x05, 0x82, 0xb2, 0x0d, 0x5b, 0xe9, 0x95, 0x32, 0x1a, 0x78, 0x14, 0xc7, 0x56, 0xfd, - 0xb6, 0x35, 0x7b, 0x86, 0x2b, 0x4e, 0x07, 0x3d, 0xf3, 0xfc, 0x70, 0xf4, 0xc4, 0x89, 0x13, 0xc8, - 0xb4, 0x79, 0xf3, 0xe6, 0xce, 0x9c, 0x9c, 0x32, 0x3a, 0x77, 0xda, 0xd4, 0xd3, 0x85, 0x05, 0xb8, - 0xae, 0xda, 0xb6, 0x6d, 0xdb, 0xdc, 0xb9, 0x73, 0xd1, 0x10, 0x67, 0x77, 0x2e, 0xc1, 0xef, 0xde, - 0xbd, 0x2b, 0xb5, 0x72, 0xec, 0xd8, 0xb1, 0x79, 0x1d, 0x0f, 0x55, 0x0b, 0x9d, 0xe7, 0xcf, 0x9f, - 0x0f, 0xa3, 0xa8, 0x31, 0x18, 0xa8, 0x60, 0x24, 0x0f, 0xc4, 0xad, 0x5b, 0xb7, 0xb6, 0x6c, 0xd9, - 0x12, 0x11, 0x11, 0xc1, 0x17, 0xa0, 0xce, 0xba, 0x8f, 0x8d, 0x8d, 0xe5, 0x82, 0x9a, 0x59, 0xe1, - 0xe1, 0xe1, 0x27, 0x4f, 0x9e, 0x54, 0x4e, 0x14, 0x74, 0x49, 0x49, 0x49, 0x54, 0x54, 0x14, 0x47, - 0x6e, 0xca, 0x6e, 0x04, 0xd8, 0xb7, 0x6f, 0x5f, 0xb7, 0x15, 0x5c, 0x67, 0xb8, 0x88, 0xc7, 0x2a, - 0x9c, 0xc9, 0xc0, 0xc0, 0xb5, 0x07, 0x34, 0x67, 0x2f, 0x2a, 0x12, 0xc1, 0x29, 0x3f, 0x0a, 0xdd, - 0xbe, 0x7d, 0x9b, 0x9e, 0x25, 0x4b, 0x96, 0x88, 0x57, 0x1e, 0x3f, 0x7e, 0x5c, 0x2e, 0xb5, 0x7d, - 0xfb, 0x76, 0xd1, 0x29, 0xfe, 0xc5, 0x79, 0x53, 0x69, 0x81, 0xfd, 0xfb, 0xf7, 0x4b, 0x06, 0x94, - 0x25, 0x27, 0x0a, 0x82, 0xe0, 0xa6, 0xcc, 0x97, 0x0c, 0x82, 0xe0, 0xcb, 0x08, 0xb7, 0x91, 0x56, - 0x9c, 0x34, 0xff, 0xbb, 0xf0, 0x50, 0x0e, 0x44, 0x47, 0x47, 0x23, 0x0d, 0x57, 0xc7, 0x74, 0x52, - 0xbf, 0x0a, 0x0c, 0x32, 0xd4, 0xb8, 0xcd, 0x0c, 0x0c, 0x0c, 0x64, 0x51, 0x01, 0x80, 0x1c, 0x32, - 0x7b, 0xf6, 0x6c, 0x9a, 0x12, 0x80, 0x34, 0x17, 0xda, 0xbd, 0x78, 0xf1, 0xe2, 0xe2, 0xc5, 0x8b, - 0x85, 0x04, 0x9b, 0x36, 0x6d, 0x92, 0x6f, 0xa1, 0x54, 0x88, 0x89, 0x89, 0x59, 0xb3, 0x66, 0x0d, - 0x43, 0x56, 0x00, 0x38, 0x90, 0xf3, 0x69, 0x90, 0x7e, 0x6a, 0xbd, 0x33, 0x67, 0xce, 0xf0, 0x6d, - 0xe1, 0xf0, 0xe1, 0xc3, 0x5c, 0x1c, 0xd1, 0xb3, 0x71, 0xe3, 0x46, 0xb9, 0x82, 0x24, 0xba, 0xb8, - 0xd8, 0x62, 0xdd, 0xb8, 0xb8, 0x38, 0x24, 0xa6, 0xfc, 0xa3, 0xfe, 0x60, 0x21, 0x08, 0x6c, 0x2a, - 0xe4, 0xe0, 0xfa, 0x96, 0x4e, 0x68, 0xa1, 0x57, 0xe0, 0x59, 0x45, 0xe1, 0xa5, 0x4b, 0x97, 0x18, - 0xa5, 0x9f, 0xcf, 0x47, 0x1c, 0x98, 0xf1, 0x04, 0xee, 0x49, 0xb9, 0xd6, 0x15, 0xd3, 0xc5, 0x3f, - 0x8e, 0xc1, 0xc5, 0xe3, 0xd3, 0xa7, 0x4f, 0x95, 0x9d, 0x82, 0xc6, 0x81, 0xf9, 0x12, 0x05, 0xbd, - 0x77, 0xef, 0xde, 0x9d, 0x3b, 0x77, 0x42, 0xe0, 0x84, 0xc0, 0xb8, 0x7e, 0xfd, 0x3a, 0x9a, 0xe5, - 0x58, 0x2e, 0xd3, 0x9a, 0xe0, 0xb7, 0x06, 0x80, 0x02, 0x56, 0xae, 0x5c, 0xf9, 0xe8, 0xd1, 0x23, - 0x86, 0x29, 0x4a, 0x90, 0x12, 0x23, 0x40, 0x33, 0x53, 0x4c, 0xf8, 0xe1, 0x3f, 0x75, 0x3d, 0x3c, - 0xcb, 0x96, 0x2d, 0x43, 0x7a, 0xc1, 0xbc, 0x62, 0xc5, 0x0a, 0x74, 0xf9, 0xc3, 0x89, 0x82, 0x41, - 0x4c, 0x87, 0x5e, 0xbd, 0x7a, 0xb5, 0x9c, 0x02, 0x0d, 0x00, 0x51, 0x5b, 0x93, 0xd6, 0x64, 0x3f, - 0x84, 0x75, 0x10, 0x5f, 0xbb, 0x76, 0x4d, 0x48, 0x7f, 0xe7, 0xce, 0x1d, 0xae, 0x6e, 0x28, 0x08, - 0xd7, 0xae, 0x5d, 0xab, 0x9c, 0x00, 0x2d, 0x74, 0xc0, 0x75, 0x83, 0xe8, 0x27, 0x3c, 0x94, 0x0c, - 0x68, 0x97, 0x26, 0xd7, 0x2a, 0xb2, 0x53, 0x49, 0xcb, 0xce, 0xee, 0x08, 0x0c, 0x2e, 0x86, 0xb8, - 0xc7, 0x96, 0x3c, 0x82, 0x46, 0x9b, 0x9d, 0xef, 0xbf, 0xac, 0x01, 0x60, 0x41, 0xa6, 0x51, 0x34, - 0xe1, 0x48, 0x94, 0x7c, 0xa4, 0x39, 0xae, 0x12, 0xe8, 0xc1, 0xe7, 0xe4, 0x72, 0x22, 0x2a, 0xf8, - 0x48, 0x4a, 0x27, 0x6e, 0x20, 0xa6, 0x48, 0x06, 0x3e, 0xbd, 0xc0, 0xc9, 0x28, 0xdf, 0x63, 0x20, - 0x78, 0x37, 0x0e, 0x29, 0xe7, 0x0a, 0x02, 0x66, 0xf6, 0x66, 0x72, 0x34, 0x4d, 0x25, 0x4d, 0x93, - 0x2b, 0x47, 0xb2, 0x1f, 0xc4, 0xe9, 0xd3, 0xa7, 0x8b, 0x8a, 0x8a, 0x20, 0xd2, 0xd3, 0xd3, 0x51, - 0x3f, 0x04, 0xe9, 0x88, 0xdb, 0x6c, 0x88, 0xff, 0x3d, 0xcc, 0x57, 0x3e, 0x97, 0x2f, 0x5f, 0x16, - 0xc3, 0x84, 0xe6, 0xba, 0x75, 0xeb, 0xa8, 0xd0, 0x45, 0x93, 0xea, 0xf6, 0xca, 0x95, 0x2b, 0x82, - 0x93, 0xfd, 0x5f, 0x74, 0xf2, 0xd9, 0x5d, 0x10, 0xfc, 0xe3, 0x6f, 0x37, 0x6f, 0xde, 0x84, 0x81, - 0x28, 0x97, 0xaf, 0x21, 0x0f, 0x4a, 0x06, 0xf4, 0x77, 0xe8, 0xd0, 0x21, 0x18, 0xb0, 0xad, 0x08, - 0x4a, 0x39, 0x24, 0xa6, 0x9f, 0x3d, 0x7b, 0x56, 0xac, 0x7f, 0xee, 0xdc, 0x39, 0x31, 0x44, 0xfd, - 0x19, 0x12, 0x12, 0x22, 0x68, 0xcc, 0xce, 0x57, 0x36, 0xc1, 0xa0, 0xfc, 0xb7, 0xce, 0x42, 0x28, - 0x66, 0xf7, 0xee, 0xdd, 0x42, 0xc7, 0xcc, 0xe4, 0x2b, 0xe2, 0xa9, 0x53, 0xa7, 0x48, 0x6a, 0x58, - 0xe3, 0xc2, 0x85, 0x0b, 0x62, 0x26, 0xce, 0x43, 0x0a, 0x17, 0xeb, 0x2e, 0x5a, 0xb4, 0x68, 0xcf, - 0x9e, 0x3d, 0xd0, 0xec, 0x18, 0xe8, 0x49, 0x30, 0xf0, 0x26, 0xbe, 0x7c, 0x09, 0x06, 0x5c, 0x82, - 0x4c, 0x2f, 0xaa, 0x64, 0x09, 0x40, 0x22, 0x14, 0x3c, 0xfc, 0x93, 0xa9, 0x25, 0x00, 0x16, 0xb9, - 0x71, 0xe3, 0x86, 0xf2, 0xba, 0x17, 0xab, 0xf2, 0xa1, 0x56, 0x29, 0xb7, 0xa4, 0xbb, 0xae, 0x89, - 0x31, 0x2e, 0xc1, 0x84, 0x82, 0x3b, 0xe7, 0x63, 0xf9, 0x4a, 0x34, 0x0d, 0x2a, 0x09, 0x55, 0xf6, - 0x4b, 0x82, 0x0b, 0x39, 0x76, 0x1f, 0x62, 0x4e, 0xe4, 0x2b, 0xd9, 0xff, 0xf3, 0x04, 0x89, 0x9f, - 0x45, 0x48, 0x62, 0xc2, 0xa9, 0xba, 0x9c, 0xd8, 0x35, 0x80, 0x2e, 0x59, 0x7f, 0xcd, 0x4e, 0xeb, - 0x20, 0xfe, 0x35, 0xa5, 0xec, 0x41, 0x2a, 0x3b, 0x80, 0x1e, 0x94, 0x33, 0x20, 0x43, 0x76, 0x0b, - 0x0c, 0x88, 0x9a, 0x7b, 0x78, 0x89, 0xdd, 0x02, 0x3d, 0x28, 0x67, 0x40, 0x86, 0xec, 0x16, 0x18, - 0x10, 0x35, 0xf7, 0xf0, 0x12, 0xbb, 0x05, 0x7a, 0x50, 0xce, 0x80, 0x0c, 0xfd, 0x0b, 0xbe, 0x35, - 0x47, 0x3f, 0x08, 0xc9, 0x3b, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, - 0x60, 0x82 -}; - -static const u_int8_t FLEXAudioIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x1e, 0x78, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x5d, 0x09, 0x7c, 0x94, 0xd5, 0xb5, 0xff, 0x27, 0x93, 0x4c, 0x32, 0xd9, 0xc9, 0x46, 0xc8, 0x06, - 0x04, 0x12, 0x08, 0x09, 0x24, 0x40, 0x58, 0x02, 0x28, 0x9b, 0x40, 0x15, 0xaa, 0xaf, 0x08, 0x42, - 0x9f, 0xd6, 0xa5, 0x82, 0x88, 0x3f, 0xea, 0xd3, 0xb6, 0x56, 0x5b, 0x5f, 0x4b, 0x5d, 0xb0, 0x5a, - 0xab, 0x3e, 0xad, 0xc2, 0xd3, 0xa7, 0xa8, 0x45, 0x7c, 0xe2, 0x82, 0xa2, 0x65, 0x91, 0x45, 0xd9, - 0x21, 0x80, 0x81, 0x40, 0x08, 0xbb, 0x40, 0x12, 0x92, 0x90, 0x7d, 0x5f, 0x67, 0xf2, 0xbd, 0xff, - 0xf9, 0xe0, 0x1b, 0x26, 0x99, 0x49, 0x26, 0xcb, 0x84, 0xa5, 0x2f, 0xf7, 0xf7, 0x9b, 0xf9, 0xee, - 0x77, 0xef, 0xb9, 0xdb, 0x39, 0xf7, 0x9e, 0xbb, 0x9d, 0x73, 0x3e, 0x27, 0x85, 0x0e, 0xed, 0x70, - 0xce, 0xad, 0xc1, 0x7e, 0x56, 0x59, 0x6f, 0x15, 0x6d, 0x33, 0x81, 0xab, 0xab, 0x0e, 0x5e, 0x5e, - 0x5e, 0x48, 0xd6, 0x11, 0xbe, 0x59, 0x05, 0x6c, 0x26, 0xc8, 0x2d, 0xae, 0x82, 0xab, 0xab, 0x2b, - 0xe6, 0x4d, 0x9f, 0x8e, 0x06, 0xa6, 0x59, 0x5d, 0x66, 0x34, 0x97, 0xe4, 0xd4, 0xbc, 0x0d, 0x46, - 0xa3, 0x11, 0xbf, 0xfe, 0xed, 0xef, 0xd0, 0x6f, 0xc8, 0x18, 0xe4, 0x64, 0x9d, 0x06, 0x0b, 0xc3, - 0x93, 0x4f, 0xfe, 0x16, 0xde, 0xae, 0x2e, 0x97, 0x12, 0x49, 0x02, 0x4b, 0xf7, 0xe9, 0x67, 0x9f, - 0x29, 0x09, 0xc3, 0x47, 0x2a, 0xb7, 0x4d, 0x9f, 0xae, 0x2c, 0xff, 0xf4, 0x5b, 0x25, 0x36, 0x7e, - 0x88, 0x65, 0xb4, 0xc2, 0x2a, 0x5a, 0xbb, 0xe4, 0xd1, 0xa3, 0x95, 0x99, 0x3f, 0xff, 0x85, 0x75, - 0x04, 0x43, 0xac, 0xaa, 0x64, 0xae, 0x6c, 0x0b, 0x1e, 0x9b, 0x8d, 0x6e, 0x01, 0x56, 0x0d, 0x36, - 0x27, 0x58, 0xb9, 0x72, 0xa5, 0x19, 0xee, 0x77, 0xbf, 0xfb, 0x9d, 0xd9, 0xef, 0xe4, 0xe4, 0x84, - 0xc6, 0xc6, 0xc6, 0x2b, 0xef, 0x52, 0x51, 0xf3, 0x5b, 0x1b, 0x3c, 0xe6, 0x12, 0xda, 0x00, 0xab, - 0x82, 0x38, 0xae, 0xd1, 0x2b, 0x72, 0xab, 0x6d, 0x16, 0x6a, 0x55, 0xa5, 0xf7, 0x56, 0x7e, 0x01, - 0x5f, 0xbf, 0x1e, 0x38, 0xb6, 0xf4, 0x35, 0x35, 0x41, 0x63, 0xf3, 0x26, 0xda, 0xa2, 0x8e, 0xbb, - 0xbb, 0xbb, 0x12, 0x17, 0x3f, 0x58, 0x79, 0xe5, 0x1f, 0x9f, 0x5b, 0x45, 0x5f, 0xee, 0x20, 0x57, - 0x4a, 0x1f, 0x38, 0x28, 0x1e, 0x5f, 0xad, 0xf9, 0x0a, 0xe9, 0x67, 0x4b, 0x71, 0xb6, 0xb4, 0x0c, - 0x59, 0x65, 0x95, 0x88, 0xf0, 0xf5, 0x32, 0x03, 0x58, 0x35, 0x7a, 0xce, 0x3d, 0x0f, 0xa0, 0x24, - 0x2f, 0x1b, 0xd5, 0xd5, 0xd5, 0x48, 0x3f, 0x76, 0x14, 0xd1, 0x31, 0x71, 0xd8, 0x9f, 0xb2, 0xcb, - 0x9c, 0xc0, 0xaa, 0x2f, 0x99, 0x4c, 0x26, 0xe5, 0x96, 0x5b, 0x6f, 0xb7, 0xaa, 0x8a, 0x16, 0x60, - 0x55, 0xc2, 0x95, 0xac, 0x6c, 0xfb, 0xac, 0xb0, 0xa4, 0x81, 0x49, 0x97, 0xb0, 0xe5, 0xd4, 0x04, - 0x12, 0xe9, 0xe6, 0xe6, 0x06, 0x79, 0x06, 0x05, 0x05, 0x21, 0x27, 0x27, 0xa7, 0x09, 0xec, 0x5d, - 0x77, 0xdd, 0xa5, 0xc6, 0x49, 0xa0, 0xe3, 0xaa, 0xd4, 0xa4, 0x08, 0x8b, 0x97, 0x76, 0x97, 0x60, - 0x91, 0xb6, 0x4d, 0xde, 0x16, 0x91, 0xd4, 0x3c, 0xf5, 0xfb, 0x9f, 0x6d, 0xc4, 0xdf, 0xff, 0x67, - 0x25, 0x64, 0xec, 0x6c, 0x4e, 0x3f, 0xa5, 0x46, 0x37, 0xc8, 0x4b, 0xf3, 0xae, 0xd6, 0x3c, 0xa1, - 0x46, 0xbf, 0xd6, 0x9e, 0x3b, 0xf6, 0xec, 0x53, 0xa6, 0xfd, 0xf4, 0x4e, 0xc5, 0xdb, 0xc7, 0x47, - 0x09, 0x09, 0xef, 0xad, 0x3c, 0xfe, 0xbf, 0xff, 0x54, 0x16, 0xbf, 0xb6, 0xec, 0x52, 0x12, 0xf6, - 0x0b, 0xa5, 0x91, 0x3d, 0xba, 0x05, 0xd7, 0x26, 0x14, 0x09, 0x2b, 0x4c, 0xd9, 0x77, 0x00, 0x67, - 0x0b, 0x6a, 0x90, 0x90, 0x94, 0x80, 0xb4, 0xb4, 0x0c, 0x2c, 0x7d, 0x69, 0x31, 0x22, 0x07, 0xc4, - 0x62, 0xea, 0xf4, 0xdb, 0x11, 0x37, 0x65, 0x32, 0x46, 0x79, 0x08, 0x17, 0xb6, 0x76, 0x76, 0x51, - 0xf4, 0xb3, 0x59, 0x73, 0xf0, 0xe0, 0xc2, 0x47, 0xa5, 0x3f, 0x60, 0xcd, 0x47, 0xcb, 0xb0, 0x6c, - 0xc9, 0xd3, 0x28, 0xcc, 0xb9, 0x80, 0xda, 0xaa, 0x72, 0xe4, 0x5f, 0xc8, 0xc2, 0xea, 0x0f, 0x97, - 0xe3, 0xe3, 0xe7, 0x5e, 0xb0, 0xce, 0xf9, 0x72, 0x48, 0x9b, 0x5a, 0xf0, 0xcb, 0x79, 0xf3, 0xf0, - 0xf9, 0xe7, 0x5f, 0xc0, 0xd8, 0x60, 0xc4, 0xc8, 0xa4, 0xe1, 0x44, 0xbb, 0x11, 0x6f, 0xbf, 0xf3, - 0x2e, 0x76, 0x6c, 0xdf, 0x06, 0x45, 0xef, 0x03, 0x93, 0xb1, 0x1e, 0x0b, 0xe7, 0xdd, 0x67, 0xb3, - 0x90, 0x36, 0x15, 0x60, 0x33, 0x65, 0x1b, 0x03, 0xed, 0xa2, 0xa8, 0x79, 0x3e, 0xdb, 0xb7, 0x6f, - 0xc7, 0xfe, 0xfd, 0xfb, 0xcd, 0xc1, 0x06, 0x83, 0xc1, 0xec, 0xb7, 0xe9, 0xb1, 0x24, 0xfe, 0x94, - 0x29, 0x53, 0x94, 0xb4, 0xb4, 0x34, 0x65, 0xf2, 0xe4, 0xc9, 0xca, 0xf9, 0xf3, 0xe7, 0xd5, 0x4e, - 0xb8, 0x6e, 0xdd, 0x3a, 0x25, 0x30, 0x30, 0x50, 0x05, 0x63, 0x06, 0x8a, 0x87, 0x87, 0xc7, 0xa5, - 0xce, 0xc9, 0x90, 0xa7, 0x9f, 0x7e, 0xda, 0xec, 0x17, 0x00, 0x89, 0x7f, 0xef, 0xbd, 0xf7, 0x9a, - 0x86, 0xa9, 0x29, 0x2f, 0xff, 0x09, 0x80, 0xf6, 0xd3, 0x12, 0x74, 0xe4, 0xdd, 0xdf, 0xdf, 0xdf, - 0x9c, 0xed, 0xf5, 0x47, 0x03, 0xb6, 0xa8, 0x5d, 0xee, 0xc6, 0x6f, 0x41, 0xbb, 0xbb, 0xa9, 0x30, - 0xb7, 0x4f, 0xca, 0xeb, 0x50, 0x61, 0xba, 0xb2, 0x80, 0x68, 0x15, 0x67, 0x66, 0x72, 0xb7, 0xe2, - 0xd9, 0xb4, 0xeb, 0x90, 0xb2, 0x78, 0xc9, 0xab, 0x4a, 0xfa, 0xc9, 0xb3, 0x64, 0x6c, 0x64, 0x6e, - 0x97, 0xdd, 0x47, 0x67, 0xf3, 0x35, 0x6f, 0x8b, 0x4f, 0xab, 0x59, 0xb3, 0x39, 0xa4, 0xc9, 0x64, - 0x54, 0x3e, 0xdb, 0xb0, 0x57, 0xf1, 0xf6, 0xf6, 0x56, 0x7a, 0xf4, 0xf0, 0x57, 0xe6, 0xbd, 0xf1, - 0x9e, 0xb2, 0xed, 0x87, 0x23, 0xca, 0x9b, 0x27, 0x72, 0x54, 0xd0, 0x2d, 0x25, 0xb5, 0xcd, 0x93, - 0x34, 0x79, 0xb7, 0x8b, 0x22, 0x67, 0x67, 0x1d, 0x42, 0x7b, 0xf6, 0x40, 0x43, 0x43, 0x03, 0x64, - 0x99, 0x71, 0x96, 0x6b, 0xdd, 0xa7, 0x52, 0xd2, 0x70, 0x87, 0x97, 0x13, 0x3e, 0xce, 0xab, 0xc4, - 0x24, 0x3f, 0x37, 0xec, 0xaa, 0x35, 0xb5, 0x88, 0x25, 0xbb, 0x05, 0x48, 0xca, 0x5e, 0x3d, 0x3c, - 0xf1, 0x93, 0x3b, 0xe6, 0xa2, 0xae, 0xb6, 0x06, 0x91, 0x55, 0xc5, 0xb8, 0xcb, 0xcb, 0x80, 0x67, - 0x8f, 0x9c, 0xc1, 0x64, 0x5d, 0x1d, 0xbe, 0xad, 0x34, 0x62, 0xac, 0xbb, 0x0e, 0x2d, 0x51, 0xa4, - 0x4d, 0x05, 0xfc, 0x65, 0xc9, 0x33, 0x58, 0xf6, 0xf7, 0x97, 0xf1, 0xfc, 0x5f, 0xfe, 0x86, 0xc7, - 0x7e, 0xf9, 0x00, 0x6a, 0xca, 0x4b, 0x11, 0x93, 0x93, 0x8d, 0xc7, 0xd6, 0x6c, 0x82, 0xdf, 0xc9, - 0xa3, 0x6a, 0xed, 0x57, 0x56, 0xd9, 0x2e, 0xc2, 0x6e, 0x01, 0xfe, 0x81, 0x81, 0x88, 0x4d, 0x48, - 0xc2, 0x6f, 0x1f, 0x7f, 0x1c, 0x33, 0x6e, 0x9f, 0x81, 0x83, 0x07, 0xd3, 0x98, 0xa1, 0x0b, 0xb2, - 0xf3, 0xf2, 0xe0, 0x1e, 0xdc, 0x1b, 0x9f, 0xa7, 0x5e, 0x2a, 0xe0, 0x17, 0x9e, 0xb6, 0xb3, 0xb2, - 0x3b, 0xd0, 0x66, 0xfd, 0xfb, 0xbd, 0xc8, 0xc9, 0xce, 0x42, 0x6c, 0x4c, 0x7f, 0xd4, 0x70, 0x7d, - 0x35, 0xe3, 0xce, 0x39, 0xd8, 0xfd, 0xfd, 0x06, 0xae, 0xb3, 0xce, 0xc0, 0xcb, 0xc7, 0x07, 0x20, - 0x8d, 0x3e, 0x59, 0xf1, 0x01, 0xbc, 0x3c, 0xdc, 0xd5, 0x96, 0x34, 0xff, 0xb3, 0x5d, 0xac, 0x05, - 0x94, 0x8b, 0x8b, 0x1e, 0x3e, 0xbe, 0x7e, 0x38, 0x75, 0xea, 0x14, 0x8a, 0x4b, 0x8a, 0xb1, 0x72, - 0xf9, 0x7f, 0x23, 0x2f, 0x27, 0x1f, 0x81, 0x3d, 0x7b, 0xe1, 0x70, 0xea, 0x01, 0x64, 0x9d, 0xff, - 0x11, 0x9b, 0xb6, 0xa5, 0x58, 0xa4, 0x68, 0xea, 0xb5, 0x5a, 0x3e, 0x36, 0x8d, 0x06, 0xc6, 0x8f, - 0x49, 0xc2, 0x8b, 0x2f, 0xbd, 0x8c, 0x0b, 0xd9, 0x99, 0xe8, 0x1f, 0x3d, 0x10, 0xf7, 0xdd, 0x33, - 0x17, 0xf3, 0x1f, 0x5a, 0x80, 0x95, 0x1f, 0xad, 0xc0, 0x6d, 0x53, 0x26, 0x00, 0x7a, 0x5f, 0xdc, - 0x3c, 0x32, 0xae, 0x79, 0xb2, 0x2b, 0xef, 0x4d, 0x3a, 0x6d, 0x0b, 0x2f, 0xf3, 0xe6, 0xcf, 0x53, - 0x12, 0x93, 0x46, 0x2a, 0x3f, 0xbf, 0xf7, 0x41, 0x25, 0xfd, 0xe8, 0xd1, 0x16, 0xa0, 0x6c, 0x07, - 0xdb, 0xa5, 0xc1, 0x95, 0xaa, 0x74, 0xcc, 0x67, 0x97, 0x06, 0x1d, 0xcb, 0xf6, 0x4a, 0xaa, 0x76, - 0x17, 0xf0, 0xfd, 0xf7, 0xdf, 0x9b, 0x53, 0x73, 0x3a, 0x35, 0xfb, 0x5b, 0xf2, 0xb4, 0x1b, 0x45, - 0x3d, 0x7b, 0xf6, 0xc4, 0xc5, 0x8b, 0x17, 0x5b, 0xca, 0xcf, 0x3a, 0x5c, 0x23, 0xcd, 0xb4, 0x69, - 0xd3, 0xcc, 0x13, 0xbd, 0x84, 0xe9, 0x74, 0x3a, 0x35, 0x8a, 0x29, 0xcc, 0x4f, 0x59, 0x0c, 0x68, - 0xef, 0x12, 0x98, 0x94, 0x94, 0xa4, 0xc6, 0xc9, 0x5f, 0xef, 0xde, 0xbd, 0x95, 0x5b, 0x6f, 0xbd, - 0x55, 0x71, 0x76, 0x76, 0x56, 0x17, 0x0e, 0x5a, 0x84, 0x99, 0x9b, 0x4a, 0xc2, 0xc5, 0x8b, 0x17, - 0x9b, 0x33, 0xf0, 0xf4, 0xf4, 0x54, 0x61, 0xb4, 0x0c, 0xb5, 0x27, 0x37, 0x05, 0x5a, 0x5a, 0xe5, - 0xeb, 0xaf, 0xbf, 0x36, 0xfb, 0xb5, 0x78, 0x09, 0x68, 0xe2, 0xd7, 0x20, 0x24, 0x50, 0x7e, 0xdc, - 0x59, 0x28, 0x8f, 0x3d, 0xf6, 0x98, 0x5a, 0x0b, 0x2d, 0xec, 0x4f, 0x7f, 0xfa, 0x93, 0x32, 0x62, - 0xc4, 0x08, 0x35, 0xbe, 0x6f, 0xdf, 0xbe, 0x4a, 0x72, 0x72, 0xb2, 0x32, 0x75, 0xea, 0x54, 0xf5, - 0x5d, 0x60, 0x56, 0xac, 0x58, 0xa1, 0x1c, 0x3f, 0x7e, 0xdc, 0xfc, 0xae, 0xe5, 0x29, 0xcf, 0x76, - 0xd3, 0x80, 0x19, 0xb6, 0xcb, 0xb5, 0xbb, 0x17, 0xb5, 0x2b, 0x77, 0x02, 0xdf, 0xf8, 0x05, 0x74, - 0x39, 0x0d, 0xda, 0x8b, 0xd2, 0xf6, 0xc2, 0x77, 0x39, 0x09, 0x2c, 0x2b, 0x24, 0xdd, 0xd8, 0xd1, - 0xce, 0xe1, 0x0d, 0xa8, 0xad, 0xaf, 0x47, 0x5d, 0xbd, 0x1c, 0xb0, 0x5d, 0x71, 0x15, 0x46, 0x13, - 0x7e, 0x2c, 0x29, 0x87, 0x76, 0x76, 0xb0, 0xb3, 0xb8, 0x1a, 0xdb, 0x78, 0x1c, 0x07, 0xc5, 0xf6, - 0x32, 0xe1, 0x4a, 0x4a, 0xfb, 0x3e, 0x87, 0x35, 0xe0, 0xcb, 0x75, 0x9b, 0xf0, 0xe9, 0x86, 0x14, - 0x04, 0x07, 0x06, 0xc0, 0xc7, 0xdb, 0x0b, 0x3c, 0xe3, 0x81, 0x1f, 0x0f, 0x86, 0x7e, 0x36, 0xfb, - 0x6e, 0xac, 0x38, 0x78, 0x16, 0x55, 0x35, 0xf5, 0x78, 0x2f, 0xa7, 0x18, 0x07, 0xab, 0xeb, 0x31, - 0xce, 0xdf, 0x03, 0xe3, 0xfd, 0x3d, 0x59, 0x3b, 0x27, 0xfc, 0x33, 0xaf, 0x14, 0xc6, 0xc6, 0x8e, - 0xd3, 0xc6, 0x21, 0x0d, 0x20, 0x3f, 0x43, 0x75, 0x55, 0x0d, 0x7a, 0x06, 0x05, 0xc0, 0xc9, 0xd9, - 0x45, 0x3d, 0x86, 0x71, 0x63, 0x03, 0x9c, 0x9c, 0x9d, 0xb1, 0xf5, 0xbb, 0x0d, 0xd8, 0xf1, 0xc1, - 0x5b, 0x98, 0x36, 0x6e, 0x14, 0x52, 0x5e, 0x7d, 0x15, 0x21, 0xd5, 0x95, 0xe0, 0xd2, 0x19, 0x6f, - 0x1c, 0xbf, 0xa0, 0x52, 0x60, 0x46, 0x88, 0x1f, 0x5c, 0x9c, 0x9d, 0xb0, 0xa3, 0x8a, 0x54, 0xb3, - 0x38, 0xee, 0xb3, 0x8f, 0xfb, 0x4b, 0x10, 0x0e, 0x1b, 0xc4, 0xe5, 0x15, 0x95, 0x38, 0x71, 0x2e, - 0x13, 0xc5, 0xe5, 0x26, 0xcc, 0x98, 0x30, 0x94, 0x14, 0x30, 0x40, 0xe7, 0xe2, 0x02, 0x77, 0x0f, - 0x2f, 0x8c, 0xbd, 0x7b, 0x01, 0x6a, 0x4f, 0xa7, 0x43, 0xd7, 0x58, 0x8f, 0xc6, 0x39, 0x0f, 0x61, - 0x8a, 0x5e, 0xc1, 0xed, 0x23, 0x86, 0xa0, 0x4f, 0x64, 0x18, 0xbe, 0x2d, 0xab, 0xc3, 0x4f, 0x7c, - 0xdd, 0xd4, 0xda, 0xd4, 0x90, 0x12, 0x45, 0x8d, 0x4e, 0x08, 0xb7, 0xbb, 0x8e, 0xba, 0xd2, 0x3c, - 0x87, 0x50, 0x40, 0xb2, 0x93, 0x6e, 0xd3, 0x58, 0x53, 0x89, 0xe1, 0x83, 0x22, 0x70, 0x2a, 0xa7, - 0x1c, 0x3a, 0x57, 0x3d, 0x16, 0xfd, 0xc7, 0x13, 0x78, 0xe1, 0xad, 0x7f, 0x60, 0xe2, 0xb0, 0xe1, - 0x98, 0xfd, 0xe0, 0x02, 0xfc, 0x78, 0xfa, 0x0c, 0xa6, 0xa1, 0x0e, 0xeb, 0x97, 0xbd, 0x8e, 0xf7, - 0xcb, 0x6a, 0xb1, 0xe4, 0xf5, 0x77, 0x30, 0xb8, 0xae, 0x02, 0x67, 0x88, 0x7c, 0x19, 0x35, 0x06, - 0x52, 0x22, 0xdc, 0xc9, 0x84, 0x73, 0xc6, 0xb6, 0x77, 0x29, 0x87, 0x34, 0xa0, 0xa6, 0xa6, 0x06, - 0x3c, 0x44, 0xc2, 0xba, 0x4d, 0xdb, 0x71, 0xc7, 0x4f, 0x6f, 0x47, 0x61, 0xd6, 0x31, 0xa4, 0x1d, - 0x49, 0x47, 0x44, 0x74, 0x3c, 0xfa, 0x47, 0x04, 0x62, 0x78, 0x6c, 0x0c, 0x9c, 0x6b, 0x1b, 0x30, - 0xff, 0x0f, 0x7f, 0x41, 0x51, 0x51, 0x21, 0x4c, 0x9e, 0xbe, 0x28, 0x5b, 0xf5, 0x31, 0x6a, 0x43, - 0x7a, 0xe1, 0xa1, 0xf9, 0x0b, 0x51, 0x7e, 0xec, 0x04, 0xb6, 0xf0, 0x74, 0x6b, 0xdb, 0x91, 0xe3, - 0x38, 0x5a, 0x54, 0x8e, 0xbc, 0xf2, 0x9a, 0x2b, 0x28, 0xb6, 0xe3, 0xeb, 0x74, 0x17, 0xba, 0x73, - 0xd6, 0x2c, 0x14, 0x95, 0x56, 0xc2, 0xd3, 0xcb, 0x1b, 0x91, 0x11, 0xa1, 0x48, 0x1e, 0x35, 0x0a, - 0xeb, 0xd7, 0xad, 0x85, 0x9b, 0xbb, 0x1b, 0x86, 0x0d, 0x4d, 0x44, 0xd2, 0x98, 0x89, 0xd8, 0x9e, - 0x72, 0x08, 0x45, 0xb9, 0x99, 0xf0, 0xf7, 0xf3, 0xc6, 0x85, 0xac, 0x4c, 0x9c, 0x3e, 0x77, 0x1e, - 0x1e, 0x72, 0x5c, 0xc9, 0xca, 0x99, 0x74, 0x3a, 0x28, 0x75, 0x75, 0xb8, 0xff, 0xe1, 0x5f, 0xe1, - 0x67, 0x53, 0xc6, 0xda, 0xa9, 0xae, 0x75, 0x74, 0xa7, 0x1b, 0xf0, 0xe4, 0xd3, 0x8b, 0x91, 0x9b, - 0x77, 0x91, 0x95, 0x71, 0x42, 0x2d, 0x2b, 0x52, 0x54, 0x90, 0x83, 0xa9, 0xb7, 0x4c, 0x42, 0x4a, - 0xca, 0x7e, 0xee, 0x15, 0x1b, 0xd5, 0x4a, 0xd6, 0xd5, 0xd4, 0x22, 0x3e, 0x71, 0x18, 0x7a, 0xf5, - 0x4f, 0xc4, 0x2b, 0x8b, 0x1f, 0x87, 0x2b, 0x2b, 0xef, 0xd7, 0xc3, 0x1f, 0x2e, 0x6e, 0xee, 0x30, - 0xd0, 0xaf, 0xe8, 0x5c, 0xe0, 0xc5, 0x06, 0x3f, 0xff, 0xc2, 0x5f, 0x31, 0x2c, 0x3e, 0xda, 0xba, - 0x96, 0xad, 0x84, 0x74, 0xba, 0x01, 0x67, 0xce, 0x9c, 0xc1, 0xfe, 0x1f, 0x52, 0xf1, 0xf6, 0xbb, - 0x1f, 0x70, 0x63, 0x55, 0x85, 0x82, 0x8b, 0x79, 0x5c, 0xb1, 0xe6, 0xa2, 0x57, 0x48, 0x08, 0x82, - 0x03, 0x02, 0x10, 0x37, 0x38, 0x1e, 0xc5, 0x45, 0x45, 0xf8, 0x91, 0x58, 0xf7, 0xe4, 0xc0, 0xf6, - 0xf3, 0xf5, 0xc6, 0xc8, 0x71, 0x93, 0x11, 0x18, 0x1e, 0x85, 0xf5, 0x6b, 0x3e, 0xc1, 0xc1, 0xfd, - 0x29, 0x30, 0x99, 0x1a, 0x70, 0xc7, 0x5d, 0xf7, 0x61, 0xc6, 0xad, 0xd3, 0x30, 0x7d, 0xea, 0xf8, - 0x56, 0xaa, 0x6b, 0x1d, 0xd5, 0xe9, 0x06, 0x48, 0x96, 0xbc, 0xa6, 0xc1, 0x5d, 0xb3, 0xe7, 0xe0, - 0xcc, 0xe9, 0xd3, 0x38, 0x78, 0xe8, 0x20, 0xbb, 0x93, 0x17, 0x06, 0xc6, 0x0d, 0x46, 0x48, 0xaf, - 0x30, 0x62, 0x3a, 0x00, 0xf9, 0xf9, 0x79, 0xf8, 0xed, 0x63, 0x8b, 0x48, 0x99, 0x5b, 0xcc, 0x35, - 0x28, 0x2c, 0x2c, 0x44, 0x2e, 0x4f, 0xba, 0xeb, 0xea, 0x6a, 0x70, 0x31, 0x37, 0x17, 0x23, 0x46, - 0x8d, 0x46, 0x70, 0xcf, 0x10, 0x73, 0x7c, 0x5b, 0x3d, 0x0e, 0x69, 0x80, 0x65, 0x61, 0xb9, 0xb9, - 0x39, 0x38, 0x74, 0xf0, 0x20, 0x5c, 0xf5, 0xae, 0x70, 0x37, 0x78, 0x23, 0x31, 0x71, 0x08, 0xbc, - 0x3c, 0x65, 0xd2, 0xea, 0x1a, 0xe7, 0xf0, 0x06, 0x74, 0x4d, 0x35, 0x5b, 0xce, 0xd5, 0x21, 0x6c, - 0xb4, 0xe5, 0xec, 0xbb, 0x3e, 0xa6, 0x4b, 0x1b, 0xb0, 0x67, 0xcf, 0x1e, 0xf5, 0xf6, 0x46, 0x6e, - 0x77, 0xe4, 0xd7, 0xdc, 0x71, 0x6f, 0x66, 0x33, 0xbc, 0x39, 0x5c, 0xab, 0xef, 0x96, 0x1b, 0x34, - 0xcd, 0xbf, 0x79, 0xf3, 0x66, 0x99, 0x0a, 0xcd, 0x3f, 0xd9, 0x08, 0x6a, 0xee, 0xe3, 0x8f, 0x3f, - 0x36, 0x87, 0x4b, 0xd8, 0xcc, 0x99, 0x33, 0xd5, 0xf7, 0x88, 0x88, 0x08, 0x0d, 0x44, 0x7d, 0x8e, - 0x1c, 0x39, 0x52, 0x0d, 0x4f, 0x4c, 0x4c, 0x54, 0x78, 0x35, 0xa5, 0xfa, 0x2d, 0x01, 0xe4, 0x42, - 0x4f, 0x2b, 0xc3, 0x32, 0x5c, 0xf3, 0xcf, 0x9f, 0x3f, 0xdf, 0x1c, 0x2f, 0x70, 0x19, 0x19, 0x19, - 0x5a, 0x54, 0x93, 0xa7, 0x79, 0x5b, 0xdc, 0x24, 0x94, 0x2f, 0xb2, 0x53, 0x9d, 0x34, 0x69, 0x92, - 0x32, 0x6b, 0xd6, 0x2c, 0x35, 0x23, 0xcb, 0x46, 0xc8, 0x96, 0x59, 0x32, 0xd5, 0x9c, 0xf8, 0xb5, - 0x03, 0xf9, 0xaf, 0xbe, 0xfa, 0x4a, 0x8d, 0x5b, 0xbe, 0x7c, 0xb9, 0x16, 0x6d, 0xae, 0x88, 0x39, - 0xe0, 0xb2, 0x47, 0xb6, 0xd5, 0x96, 0xf9, 0x68, 0xf1, 0x12, 0x36, 0x60, 0xc0, 0x00, 0xed, 0x55, - 0x7d, 0x4a, 0x18, 0x6f, 0xc3, 0x9b, 0x84, 0xc9, 0xcb, 0x95, 0x5a, 0x5c, 0x8e, 0x22, 0x7b, 0x53, - 0x33, 0xbd, 0xff, 0xfe, 0xfb, 0xcd, 0xc0, 0x92, 0x58, 0xaf, 0xd7, 0x9b, 0xdf, 0x87, 0x0f, 0x1f, - 0xae, 0xc2, 0xf0, 0xb2, 0x58, 0xc9, 0xcd, 0xcd, 0x55, 0xfd, 0x5a, 0x03, 0xb4, 0xed, 0xf7, 0xc0, - 0x81, 0x03, 0x55, 0xf8, 0x92, 0x92, 0x12, 0x35, 0xde, 0x56, 0x45, 0x5b, 0x6b, 0x80, 0xc0, 0xd7, - 0xd5, 0xd5, 0xa9, 0x79, 0xbc, 0xf2, 0xca, 0x2b, 0x6a, 0x1e, 0xb7, 0xdd, 0x76, 0x9b, 0xb9, 0x0e, - 0x9a, 0xc7, 0xaa, 0x01, 0x5a, 0xc4, 0x81, 0x03, 0x07, 0x5a, 0x24, 0x9b, 0xc0, 0x48, 0xe6, 0x3b, - 0x77, 0xee, 0xd4, 0xc0, 0xad, 0x9e, 0x72, 0xc9, 0xba, 0x61, 0xc3, 0x06, 0xab, 0xf0, 0xf6, 0x04, - 0xe4, 0xe7, 0xe7, 0x2b, 0xd2, 0x9d, 0x05, 0x51, 0x2d, 0xb9, 0x6e, 0x36, 0x4a, 0x52, 0x5f, 0x53, - 0xd7, 0xa5, 0x6c, 0xf4, 0x6a, 0xb4, 0xec, 0x86, 0x6f, 0x40, 0xf7, 0x18, 0xb8, 0x1a, 0xdd, 0xa4, - 0xb5, 0x32, 0x6e, 0xf8, 0x2e, 0x74, 0xd5, 0x1a, 0x20, 0x47, 0x58, 0x32, 0x1b, 0x39, 0xda, 0xb5, - 0xe3, 0x00, 0xa3, 0xe3, 0x45, 0x9f, 0xab, 0x31, 0xe1, 0x50, 0xad, 0x11, 0x39, 0x44, 0xd7, 0x78, - 0x83, 0x33, 0x06, 0x71, 0xaf, 0x60, 0xbd, 0xb4, 0xeb, 0x60, 0xfe, 0x2d, 0xcd, 0x70, 0x1d, 0x09, - 0x37, 0x1a, 0x4d, 0x4a, 0x4d, 0x6d, 0x9d, 0x22, 0x4f, 0x4b, 0x97, 0x92, 0x5f, 0x66, 0x7e, 0x35, - 0x72, 0x56, 0x5d, 0x7a, 0xb6, 0x40, 0x29, 0x69, 0x30, 0x9a, 0xc3, 0x3a, 0xe3, 0x71, 0x18, 0x17, - 0x2a, 0x28, 0x2a, 0xc6, 0xe6, 0xbd, 0xc7, 0x91, 0x73, 0xee, 0x04, 0x6a, 0x79, 0xcc, 0x32, 0x68, - 0x50, 0x2c, 0x26, 0xde, 0x34, 0x0a, 0x7e, 0xde, 0x1e, 0xc8, 0x2a, 0x2a, 0x45, 0x08, 0xa5, 0xc1, - 0x5c, 0x79, 0xd0, 0xa5, 0xb9, 0x6f, 0x79, 0xa4, 0x18, 0xe5, 0xe9, 0x8e, 0x68, 0x6f, 0xdb, 0x97, - 0x90, 0x1a, 0x9c, 0xdd, 0x67, 0x67, 0x5a, 0xaf, 0xa5, 0x2d, 0x2d, 0x2b, 0x53, 0x3e, 0x5c, 0xbd, - 0x45, 0x79, 0xf0, 0xe1, 0x47, 0xd5, 0x45, 0x97, 0x9b, 0x9b, 0xbb, 0x62, 0x30, 0xb8, 0x2b, 0xfd, - 0x62, 0x06, 0x2a, 0x2f, 0xbd, 0xb5, 0x5c, 0x59, 0x7d, 0xbe, 0x54, 0xf9, 0xdb, 0x96, 0x14, 0x65, - 0x45, 0x61, 0x95, 0x62, 0x89, 0xf7, 0xfc, 0x7a, 0xa3, 0xb2, 0x31, 0xbf, 0x5c, 0xcb, 0xa6, 0x43, - 0x4f, 0x87, 0x0c, 0xe2, 0xcc, 0xec, 0x1c, 0x78, 0x7a, 0x18, 0x70, 0x2c, 0x23, 0x1d, 0x1e, 0x14, - 0x96, 0xd1, 0xbb, 0xe9, 0xf9, 0x33, 0xf0, 0x88, 0x25, 0x1f, 0xab, 0x56, 0xad, 0xc0, 0x1b, 0xbf, - 0x59, 0x84, 0x50, 0x93, 0x82, 0xd9, 0x5e, 0x2e, 0x58, 0x9d, 0x59, 0x88, 0x2c, 0x1e, 0x72, 0x89, - 0x0b, 0xa2, 0xd0, 0xe7, 0xa8, 0x00, 0x2f, 0xec, 0x28, 0xb3, 0x16, 0x49, 0xb5, 0x8b, 0xf9, 0xcb, - 0x00, 0x0e, 0x69, 0x80, 0x54, 0x5e, 0x31, 0xd5, 0x21, 0x61, 0xc4, 0x18, 0x18, 0x4d, 0x94, 0x0f, - 0x20, 0x1d, 0x64, 0x90, 0xca, 0xe1, 0x6e, 0x66, 0x5a, 0x2a, 0xc2, 0x06, 0x0d, 0xc1, 0x93, 0x73, - 0x6f, 0xc3, 0xdb, 0x6b, 0xb7, 0x60, 0x76, 0x84, 0x3f, 0x6a, 0xeb, 0x8d, 0xf8, 0xa1, 0x84, 0xc7, - 0xeb, 0x74, 0x3e, 0x3c, 0x4e, 0x1c, 0xea, 0xa3, 0x47, 0x6e, 0x5d, 0xcb, 0x72, 0x05, 0x2a, 0x60, - 0x0b, 0x7f, 0x0e, 0x69, 0x40, 0x2f, 0xde, 0x5e, 0xba, 0xb1, 0x7b, 0x4f, 0xbf, 0xfd, 0xce, 0xcb, - 0x02, 0xa5, 0x8a, 0x7a, 0xa8, 0x65, 0x6a, 0xa8, 0xc7, 0xc8, 0x3f, 0xbd, 0x0e, 0x94, 0x5c, 0x44, - 0xc2, 0xca, 0xf5, 0xf8, 0x96, 0xd7, 0xa8, 0xef, 0x7c, 0xb6, 0x16, 0xfd, 0xd9, 0xef, 0xfb, 0x52, - 0x6e, 0x21, 0xed, 0xb2, 0x30, 0x30, 0xe5, 0x23, 0x90, 0xcf, 0x0a, 0x56, 0x71, 0x7f, 0xd2, 0x5e, - 0xe7, 0x90, 0x06, 0xb0, 0xbf, 0xa3, 0x57, 0xb0, 0x3f, 0x62, 0xa3, 0xfb, 0x62, 0xdc, 0xa4, 0x69, - 0x10, 0x99, 0x38, 0x95, 0xe9, 0x73, 0x1f, 0xec, 0x55, 0x9c, 0x8b, 0xad, 0x9f, 0x7f, 0x82, 0xa4, - 0x13, 0x07, 0x51, 0x5e, 0x57, 0x8b, 0xe3, 0xbe, 0xc1, 0x78, 0x63, 0xf9, 0x2a, 0xf8, 0xbb, 0x3a, - 0x23, 0xd4, 0xe0, 0x82, 0xc2, 0x86, 0x4b, 0x97, 0x1c, 0x09, 0x6e, 0x3a, 0x6c, 0xa8, 0x60, 0x03, - 0xda, 0xdb, 0x88, 0x0e, 0x8d, 0x1c, 0x1b, 0x89, 0x2a, 0xab, 0xaa, 0x94, 0xcc, 0x9c, 0x8b, 0x4a, - 0x4a, 0x46, 0x26, 0xb7, 0x7e, 0x7a, 0x0e, 0x62, 0x83, 0x2a, 0xeb, 0xd2, 0xbb, 0x6f, 0x7f, 0x65, - 0xd1, 0xb3, 0x2f, 0x2b, 0x43, 0x86, 0x26, 0x29, 0x7f, 0xfb, 0xef, 0xf7, 0x95, 0x09, 0xb3, 0xe7, - 0x2a, 0xaf, 0xa4, 0x9d, 0x53, 0x5e, 0x7d, 0x67, 0xa5, 0x2a, 0x3d, 0xb8, 0xaf, 0xc6, 0x78, 0x45, - 0x88, 0xd0, 0x68, 0x54, 0xd2, 0x6b, 0x2d, 0x87, 0xb9, 0x8d, 0x82, 0x9a, 0x05, 0x39, 0x8c, 0x8d, - 0x72, 0x87, 0x86, 0xac, 0x0b, 0x39, 0x08, 0x08, 0xee, 0x89, 0x25, 0x2f, 0xbf, 0x89, 0xed, 0xeb, - 0xbf, 0xc0, 0xbc, 0x5f, 0x51, 0x5e, 0xd9, 0x3b, 0x10, 0x3a, 0xf6, 0xaf, 0xed, 0x9f, 0x7f, 0x88, - 0x06, 0x27, 0x17, 0xf4, 0x89, 0x8a, 0x46, 0x66, 0x55, 0x29, 0x7a, 0xc7, 0x26, 0x20, 0x86, 0x2c, - 0xf6, 0xbe, 0x19, 0x53, 0xb0, 0x9a, 0x98, 0x9f, 0xe9, 0x77, 0x89, 0xc5, 0xae, 0xae, 0x68, 0xc4, - 0xcf, 0xbc, 0x9d, 0xdb, 0x3c, 0xd1, 0x39, 0xa4, 0x0b, 0x49, 0xbf, 0x3d, 0x70, 0x60, 0x3f, 0xfe, - 0xf8, 0x9f, 0x7f, 0x44, 0x03, 0x65, 0x73, 0x9e, 0xfc, 0xf5, 0xa3, 0x1c, 0xd0, 0x63, 0x31, 0x30, - 0x76, 0x20, 0x6e, 0x4a, 0x1e, 0x8a, 0x08, 0x1f, 0x2f, 0x4c, 0xfd, 0xf7, 0xf9, 0x28, 0x2b, 0x29, - 0xe2, 0x31, 0xe2, 0x05, 0x84, 0xea, 0x0d, 0xc8, 0x0f, 0xef, 0x8f, 0x3d, 0xeb, 0xbe, 0xc1, 0xca, - 0x2d, 0x7b, 0x60, 0x28, 0xce, 0x37, 0x2f, 0x33, 0x6e, 0x31, 0x38, 0xa1, 0xba, 0x1d, 0x43, 0xc1, - 0x21, 0x14, 0xf8, 0xcd, 0x6f, 0x7e, 0x83, 0xed, 0x7b, 0xf6, 0x63, 0xca, 0xa4, 0xf1, 0x28, 0x29, - 0x2e, 0xc1, 0xa2, 0x5f, 0x3d, 0xc2, 0x53, 0x00, 0x7f, 0xec, 0xdc, 0xb5, 0x1d, 0xa3, 0xc6, 0x8e, - 0x45, 0x5e, 0x56, 0x2e, 0x4e, 0x9d, 0xcd, 0x86, 0x8b, 0xb7, 0x01, 0xbb, 0xbf, 0xdb, 0x88, 0xb2, - 0x82, 0x8b, 0x18, 0x3b, 0x75, 0x1a, 0x8e, 0x64, 0x9e, 0x47, 0x3f, 0xbd, 0x1e, 0x4f, 0xfc, 0xfa, - 0x57, 0xd8, 0x96, 0x71, 0x12, 0x21, 0xc1, 0xc1, 0xc8, 0x68, 0x70, 0xc2, 0xdd, 0xfd, 0x7a, 0x42, - 0x67, 0xe3, 0x1c, 0xc9, 0xd6, 0x00, 0xef, 0x34, 0x05, 0x5e, 0x78, 0xe1, 0x05, 0x7c, 0xb3, 0x6e, - 0x03, 0xbc, 0x3d, 0x3d, 0x10, 0x33, 0x60, 0x20, 0x32, 0x8e, 0x1d, 0xc3, 0xfe, 0x7d, 0xfb, 0x50, - 0x98, 0x7d, 0x9c, 0x42, 0x34, 0x83, 0xb0, 0x67, 0xd7, 0x2e, 0x64, 0xe6, 0xe6, 0xa1, 0x92, 0x72, - 0xa7, 0x35, 0xc4, 0xb4, 0x0b, 0x15, 0x05, 0x62, 0xc7, 0x4f, 0x44, 0x3a, 0xef, 0x30, 0x02, 0xfc, - 0x83, 0xd1, 0x18, 0x18, 0x84, 0xd7, 0xbf, 0xdb, 0x8b, 0x19, 0x49, 0x43, 0x30, 0x38, 0x3c, 0x18, - 0x3f, 0x6f, 0x47, 0xe5, 0xa5, 0x41, 0x57, 0xe6, 0x76, 0x5b, 0xcd, 0xb3, 0x13, 0x26, 0x72, 0xe0, - 0x6f, 0xbf, 0xfb, 0x3e, 0x06, 0x0f, 0x49, 0xe4, 0x49, 0x73, 0x36, 0xe2, 0xe2, 0xe3, 0x31, 0x28, - 0x36, 0x16, 0x6b, 0xd6, 0x7c, 0x83, 0xe4, 0xe4, 0x51, 0x08, 0x0b, 0x0f, 0x47, 0x78, 0x78, 0x0c, - 0xbe, 0xdf, 0xbc, 0x8e, 0x97, 0x1b, 0xfe, 0xa8, 0xe3, 0x4d, 0x65, 0x51, 0xe6, 0x19, 0xe4, 0x9e, - 0x3f, 0x8b, 0x1e, 0x1e, 0x6e, 0x38, 0x47, 0xd6, 0x4f, 0xe6, 0x03, 0x83, 0x8f, 0x3f, 0xca, 0x27, - 0x8e, 0x86, 0x0f, 0x59, 0x6b, 0x7b, 0x5d, 0xa7, 0x28, 0x20, 0x17, 0x1a, 0xd1, 0xc4, 0xba, 0x8f, - 0xaf, 0x2f, 0x62, 0x62, 0xe3, 0xb0, 0xe6, 0xcb, 0xd5, 0x18, 0x3d, 0x6a, 0xa4, 0xaa, 0x8e, 0xb1, - 0x6b, 0xd7, 0x1e, 0xec, 0xd9, 0xbd, 0x1b, 0xfb, 0xb6, 0x7e, 0x8d, 0xb1, 0xe3, 0xa7, 0xa0, 0xac, - 0x28, 0x17, 0x19, 0x69, 0x3f, 0x20, 0x9b, 0xe2, 0x4d, 0x8d, 0x75, 0xd5, 0x28, 0xe4, 0xa5, 0xa0, - 0x93, 0x91, 0x72, 0x84, 0x35, 0x75, 0x28, 0xce, 0xcb, 0xc2, 0xf6, 0xfd, 0x22, 0x11, 0xd6, 0x7e, - 0xd7, 0xa9, 0x06, 0x1c, 0x4c, 0x3d, 0x08, 0x7f, 0xff, 0x00, 0x1e, 0xa5, 0xeb, 0xa1, 0xe3, 0xac, - 0xbb, 0x6e, 0xc3, 0x46, 0x14, 0x14, 0xe6, 0xab, 0xcb, 0x0a, 0x57, 0xaa, 0x84, 0x64, 0x65, 0x65, - 0xe3, 0x58, 0xfa, 0x51, 0xfc, 0xef, 0xdb, 0x7f, 0x43, 0xf4, 0xe0, 0x11, 0x9c, 0x07, 0x9c, 0x90, - 0x9b, 0x99, 0x89, 0xdc, 0x0b, 0xd9, 0x28, 0xcc, 0xbf, 0xc8, 0x8b, 0x8f, 0x42, 0xd4, 0x56, 0x94, - 0xa1, 0xa2, 0xb2, 0x12, 0x87, 0x0e, 0x1d, 0xb9, 0x34, 0x8b, 0xb7, 0xb3, 0x0d, 0x9d, 0x6a, 0x40, - 0x5c, 0x5c, 0x2c, 0xa6, 0xf0, 0x3a, 0xa9, 0xbe, 0xae, 0x1e, 0x95, 0x95, 0x15, 0xf0, 0xf1, 0xf1, - 0xc3, 0x6b, 0xaf, 0xbf, 0x09, 0xb9, 0xf4, 0xcb, 0xcb, 0xc9, 0x95, 0x43, 0x33, 0xde, 0xda, 0xd7, - 0xa1, 0xb4, 0xb4, 0x04, 0x1f, 0xbd, 0xf9, 0x12, 0x12, 0x86, 0x24, 0xe0, 0xa9, 0x25, 0xff, 0x85, - 0x72, 0x56, 0x3a, 0xfb, 0xec, 0x29, 0x5c, 0xcc, 0xcb, 0x45, 0x71, 0x61, 0x01, 0x07, 0x7e, 0x31, - 0x2a, 0xca, 0xcb, 0x51, 0x41, 0xaa, 0xb4, 0xd7, 0x75, 0xaa, 0x01, 0x21, 0xbc, 0x65, 0xf4, 0x32, - 0xe8, 0x29, 0x31, 0xd0, 0x80, 0xb2, 0xd2, 0x52, 0x14, 0xb1, 0x32, 0x0a, 0xef, 0x7a, 0xbf, 0x59, - 0xbb, 0x96, 0x8d, 0xa8, 0x86, 0x9e, 0x03, 0x36, 0x84, 0x57, 0x4d, 0xf5, 0x94, 0xad, 0xac, 0xe5, - 0x1a, 0x69, 0xe7, 0xa6, 0xb5, 0xc8, 0xd8, 0xb3, 0x19, 0x7f, 0x7c, 0xee, 0x55, 0xfc, 0x72, 0xe1, - 0xaf, 0xc1, 0xe3, 0x4a, 0x14, 0x14, 0x70, 0x80, 0x53, 0x5a, 0x51, 0x14, 0x32, 0xb8, 0x2c, 0x6a, - 0xb7, 0xeb, 0x34, 0x1b, 0xe5, 0xd9, 0x27, 0xfe, 0xf2, 0xe2, 0x4b, 0xd8, 0xb0, 0x71, 0x13, 0xf2, - 0x79, 0x3f, 0x26, 0xd8, 0x34, 0xb2, 0xc2, 0xa1, 0xe1, 0x11, 0xf0, 0xe6, 0x55, 0xd3, 0xcd, 0xe3, - 0x92, 0x11, 0x1c, 0x14, 0x88, 0xf4, 0x8c, 0xe3, 0x78, 0xf3, 0xcd, 0x37, 0xd9, 0x55, 0x0e, 0xf1, - 0xbe, 0xf8, 0x34, 0x78, 0x40, 0x0c, 0x93, 0xb3, 0x1e, 0x8d, 0x3a, 0x37, 0x36, 0xd4, 0x0d, 0x5e, - 0xae, 0x26, 0xcc, 0x9a, 0x35, 0xf3, 0xea, 0x37, 0x40, 0x4a, 0xdc, 0x45, 0x56, 0xf9, 0x87, 0xa7, - 0xff, 0x13, 0x29, 0x7b, 0xf7, 0x10, 0xdb, 0xf5, 0x88, 0xec, 0x1d, 0x85, 0xa8, 0xfe, 0xd1, 0x08, - 0x0a, 0x0e, 0xa1, 0xf0, 0xa4, 0x4e, 0xed, 0x26, 0xeb, 0xff, 0xf9, 0x25, 0x31, 0x7c, 0x89, 0xe0, - 0xf5, 0x14, 0x08, 0xc9, 0xce, 0xca, 0x42, 0x71, 0x71, 0x11, 0x8c, 0xec, 0x62, 0x15, 0x15, 0xe5, - 0xb8, 0x65, 0xda, 0x6d, 0x1d, 0xba, 0x2b, 0xe8, 0x34, 0x05, 0x34, 0x94, 0xa5, 0x1e, 0x4c, 0xc5, - 0xbc, 0x07, 0xe7, 0x73, 0x1f, 0x20, 0xd7, 0xa6, 0x7a, 0x84, 0x86, 0x86, 0xa9, 0x77, 0xc7, 0xa2, - 0xe7, 0xb5, 0xfc, 0x9d, 0x65, 0x2d, 0x56, 0x4e, 0xc6, 0x89, 0xad, 0xcb, 0x0f, 0x2d, 0x5f, 0x7b, - 0x4f, 0x87, 0x35, 0x40, 0x0a, 0x32, 0x1a, 0x1b, 0x70, 0x80, 0x9a, 0x00, 0x85, 0x05, 0x85, 0x08, - 0xe2, 0x8d, 0xa3, 0xa7, 0x97, 0x27, 0xe2, 0xe3, 0x5a, 0x91, 0xfc, 0xb4, 0x57, 0xbb, 0x36, 0xc4, - 0x3b, 0xb4, 0x01, 0x6d, 0x28, 0xcf, 0xe1, 0x20, 0x9d, 0xe2, 0x42, 0x0e, 0xaf, 0x4d, 0x07, 0x32, - 0xec, 0x6e, 0x40, 0x07, 0x90, 0xe6, 0xd0, 0x24, 0x5d, 0x4a, 0x81, 0x8a, 0x8a, 0x0a, 0x88, 0x38, - 0xb1, 0xfc, 0x84, 0xdb, 0x34, 0x77, 0x54, 0x8c, 0xc1, 0x87, 0x1f, 0x7e, 0xd8, 0x3c, 0xb8, 0x7d, - 0xef, 0xcd, 0x76, 0x68, 0x0e, 0x7d, 0x65, 0x4d, 0xa4, 0xd6, 0xea, 0x2f, 0x25, 0x25, 0xc5, 0x2a, - 0x6f, 0x89, 0x93, 0xeb, 0xd4, 0xce, 0xb8, 0x4e, 0x2d, 0xa7, 0xed, 0xa1, 0x8a, 0x15, 0x53, 0x41, - 0x5a, 0xba, 0xe8, 0xd6, 0xe2, 0xed, 0xe5, 0xd3, 0x5a, 0xbc, 0xcd, 0x2e, 0x14, 0x13, 0x13, 0xa3, - 0x4e, 0x2e, 0x5a, 0xc1, 0x4f, 0x3c, 0xf1, 0x84, 0x39, 0x0f, 0x17, 0x1e, 0x0f, 0x4a, 0x38, 0x31, - 0xda, 0x62, 0xe5, 0xd6, 0xaf, 0x5f, 0x0f, 0x2a, 0x6f, 0x81, 0xb2, 0xda, 0xdc, 0x1b, 0xac, 0x31, - 0xa7, 0xd5, 0x3c, 0x87, 0x0f, 0x1f, 0x36, 0xe7, 0xdf, 0xab, 0x57, 0x2f, 0x2d, 0xd8, 0xfc, 0x2c, - 0x28, 0x28, 0x00, 0xe5, 0xc3, 0xcd, 0x30, 0x94, 0xa4, 0x36, 0xc7, 0x59, 0x79, 0x6c, 0x91, 0x8f, - 0x95, 0x54, 0x96, 0x2d, 0xbb, 0xa4, 0x7b, 0x18, 0x1f, 0x1f, 0xaf, 0x76, 0x01, 0x0d, 0xee, 0xe1, - 0x87, 0x1f, 0x56, 0xdf, 0xb7, 0x6e, 0xdd, 0xaa, 0x06, 0x8d, 0x1b, 0x37, 0xae, 0x49, 0xfc, 0xd2, - 0xa5, 0x4b, 0xd5, 0x77, 0xb9, 0x89, 0xb7, 0x14, 0xe1, 0xb6, 0xec, 0x42, 0x95, 0x95, 0x95, 0xca, - 0x8c, 0x19, 0x33, 0x54, 0x38, 0x5f, 0x5f, 0x5f, 0x2d, 0x6b, 0xf5, 0x69, 0x79, 0xaf, 0xfc, 0xd6, - 0x5b, 0x6f, 0x29, 0x0f, 0x3c, 0xf0, 0x80, 0x39, 0xbf, 0x26, 0x80, 0x97, 0x5f, 0x64, 0x70, 0x59, - 0xb9, 0x13, 0x27, 0x4e, 0x28, 0xf7, 0xde, 0x7b, 0xaf, 0x32, 0x61, 0xc2, 0x04, 0x65, 0xce, 0x9c, - 0x39, 0x4d, 0x2a, 0x28, 0xc0, 0xc4, 0x82, 0xa2, 0x35, 0xe0, 0x8b, 0x2f, 0xbe, 0x68, 0x12, 0x2f, - 0x71, 0xf2, 0xd3, 0xdc, 0xea, 0xd5, 0xab, 0xd5, 0x77, 0xcb, 0x06, 0x68, 0x71, 0x02, 0xd7, 0xbc, - 0x01, 0xda, 0x25, 0xba, 0xdc, 0x33, 0x6b, 0x6e, 0xee, 0xdc, 0xb9, 0x6a, 0x1e, 0xda, 0xc5, 0xb7, - 0x16, 0x2e, 0x4f, 0xab, 0x2e, 0xf4, 0xe8, 0xa3, 0x8f, 0x82, 0xd7, 0xfc, 0xdc, 0x39, 0x65, 0x43, - 0xfc, 0xd4, 0x63, 0x62, 0x39, 0xd6, 0x4e, 0x53, 0xe9, 0x96, 0x6d, 0x65, 0x6b, 0x8e, 0xaa, 0x03, - 0xad, 0x45, 0x5b, 0xc5, 0xf1, 0xa6, 0x5f, 0x0d, 0x93, 0xee, 0xa7, 0xb9, 0xa1, 0x43, 0x87, 0xaa, - 0xde, 0xd3, 0x5c, 0xc5, 0x5a, 0x39, 0xcb, 0xd6, 0x88, 0x9f, 0x00, 0x4d, 0x30, 0xf8, 0xc1, 0x07, - 0x1f, 0x34, 0x79, 0xd7, 0x60, 0x84, 0xb4, 0xe2, 0x44, 0x51, 0x4b, 0xd2, 0x68, 0x8e, 0xe3, 0x43, - 0x7d, 0x97, 0x5b, 0x76, 0x71, 0xc3, 0x86, 0x0d, 0x53, 0xdf, 0xdb, 0x4a, 0x01, 0x91, 0xd1, 0x90, - 0xfc, 0x9a, 0x8b, 0x3a, 0x58, 0x96, 0xa1, 0x95, 0x25, 0xcf, 0x2b, 0x25, 0x5f, 0x0e, 0x5d, 0xb2, - 0x64, 0x89, 0x9a, 0x81, 0xd6, 0x10, 0xcb, 0xa7, 0x96, 0xd0, 0x32, 0x8c, 0xd8, 0x31, 0xc3, 0x4b, - 0xbc, 0xf4, 0x6f, 0xcb, 0x78, 0x19, 0x4f, 0xda, 0xbb, 0xad, 0xf4, 0x5a, 0x9c, 0x3c, 0x35, 0x17, - 0x1d, 0x1d, 0x6d, 0x4e, 0xa3, 0xc5, 0x93, 0x31, 0x68, 0xd1, 0x4d, 0x9e, 0x57, 0x52, 0x59, 0x04, - 0x97, 0x97, 0x97, 0x2b, 0x6b, 0xd7, 0xae, 0x35, 0x0b, 0x5b, 0x58, 0x44, 0x99, 0xbd, 0xe4, 0x24, - 0x4a, 0x15, 0x8f, 0x13, 0x5b, 0x72, 0x32, 0x8e, 0x32, 0x33, 0x33, 0x5b, 0x8a, 0x6e, 0x53, 0xf8, - 0x8e, 0x1d, 0x3b, 0x94, 0xac, 0xac, 0xac, 0x56, 0x61, 0xbb, 0x57, 0xa3, 0x24, 0xf1, 0x35, 0x75, - 0x57, 0x86, 0xfa, 0x35, 0xad, 0x46, 0xc7, 0x0b, 0xef, 0x6e, 0x40, 0xc7, 0x71, 0xe7, 0x98, 0x94, - 0xdd, 0x14, 0x70, 0x0c, 0x1e, 0x3b, 0x9e, 0xcb, 0x0d, 0x4f, 0x81, 0x1b, 0x7e, 0x1e, 0xe8, 0x38, - 0xed, 0xae, 0x8f, 0x94, 0x37, 0x7c, 0x0f, 0xba, 0x3e, 0xd0, 0xd8, 0xf1, 0x5a, 0x74, 0x13, 0xa0, - 0xe3, 0xb8, 0x73, 0x48, 0xca, 0x2e, 0x3d, 0x92, 0x70, 0x48, 0x0d, 0xdb, 0x91, 0x89, 0xec, 0xc5, - 0x8a, 0x78, 0x6b, 0x98, 0x45, 0xb1, 0x18, 0x8a, 0x31, 0x20, 0x90, 0xc7, 0xe2, 0xbe, 0xbc, 0x31, - 0x71, 0xe7, 0x09, 0x44, 0x07, 0x2e, 0x4e, 0xda, 0x51, 0x72, 0xc7, 0x41, 0xff, 0x65, 0x08, 0x50, - 0xcd, 0x6b, 0xad, 0x3d, 0x45, 0x55, 0xf0, 0xa0, 0x9d, 0x8e, 0x64, 0xca, 0x1f, 0x89, 0xb0, 0x8f, - 0xa8, 0x35, 0x1e, 0xa3, 0x5c, 0xd2, 0xfe, 0x8a, 0x1a, 0xf8, 0xb9, 0xe8, 0x30, 0x8c, 0xd2, 0x61, - 0x91, 0x14, 0x2e, 0x71, 0x6b, 0xe3, 0x05, 0x7a, 0xc7, 0xd1, 0xda, 0xf6, 0x94, 0xd7, 0xed, 0x24, - 0x5c, 0x5e, 0x59, 0x85, 0x73, 0xd9, 0xf9, 0xa8, 0xaa, 0xad, 0xe7, 0x9d, 0x61, 0x23, 0x95, 0x5d, - 0x9d, 0x79, 0xa5, 0x46, 0xed, 0x5e, 0x8a, 0x5c, 0xf8, 0xf9, 0x78, 0x53, 0x28, 0x4c, 0xdf, 0xa4, - 0x57, 0x8b, 0x72, 0xec, 0xa9, 0x82, 0x52, 0x54, 0xd4, 0xd6, 0x62, 0x44, 0x04, 0x35, 0xb9, 0x6c, - 0x20, 0x39, 0xbf, 0xce, 0x88, 0x8d, 0x17, 0x4b, 0x79, 0x15, 0xe7, 0x82, 0x91, 0x7e, 0x1e, 0x08, - 0x75, 0x77, 0xb5, 0x09, 0xd7, 0x76, 0xf4, 0x75, 0x1e, 0xf2, 0xba, 0x23, 0x40, 0x71, 0x49, 0x29, - 0xf6, 0x1e, 0x3a, 0x8e, 0xa2, 0x2a, 0xde, 0x2e, 0x97, 0x17, 0x22, 0x65, 0xfb, 0x46, 0x1c, 0xd8, - 0xbb, 0x13, 0x25, 0xa5, 0xc5, 0xbc, 0x4a, 0x77, 0x83, 0xaf, 0x6f, 0x0f, 0x84, 0x84, 0x47, 0x22, - 0x36, 0x2e, 0x91, 0xbf, 0x41, 0x48, 0xa2, 0x86, 0x5a, 0x54, 0x64, 0x28, 0x85, 0x79, 0xf4, 0x38, - 0x57, 0x51, 0x8b, 0x43, 0xa7, 0xcf, 0xd3, 0x36, 0x9f, 0x17, 0x12, 0xfb, 0x45, 0x22, 0xc8, 0x99, - 0xac, 0xa8, 0x09, 0x99, 0x2e, 0x21, 0x4c, 0x84, 0xab, 0x0e, 0x97, 0xd5, 0xe0, 0x48, 0x51, 0x05, - 0x12, 0xa9, 0x92, 0x3d, 0xc8, 0xcf, 0x13, 0xb6, 0x8d, 0x91, 0x75, 0x1e, 0xc1, 0xf6, 0x72, 0xb8, - 0x8e, 0x08, 0x40, 0xeb, 0x42, 0xd4, 0xa4, 0xde, 0xb1, 0x2f, 0x0d, 0xae, 0x9e, 0xfe, 0xbc, 0x8b, - 0xd5, 0x61, 0xd9, 0x2b, 0x7f, 0xc6, 0xce, 0x6d, 0x9b, 0x79, 0x13, 0xee, 0xa6, 0x8a, 0xb7, 0x88, - 0xfd, 0x08, 0xb5, 0x63, 0xb3, 0xb7, 0xcb, 0x91, 0xa0, 0xa9, 0xd1, 0x04, 0x17, 0x06, 0x0c, 0x9d, - 0x3c, 0x0d, 0xc3, 0xef, 0x7d, 0x04, 0x51, 0x3a, 0x27, 0xdc, 0x3e, 0x3c, 0x1e, 0x27, 0x79, 0xd3, - 0xee, 0x13, 0xe0, 0x07, 0x5d, 0x40, 0x10, 0xf6, 0xe7, 0x97, 0xc1, 0x87, 0xec, 0x67, 0x7a, 0x58, - 0x0f, 0xf8, 0xda, 0xb8, 0x42, 0x2f, 0xa3, 0xb1, 0xa7, 0xfd, 0x25, 0xd5, 0xaa, 0x5e, 0xff, 0x84, - 0x00, 0x4f, 0x9a, 0xcd, 0xbc, 0xba, 0xb3, 0xc5, 0x75, 0x33, 0x07, 0x98, 0x88, 0x88, 0xca, 0xaa, - 0x6a, 0x9a, 0x96, 0x6b, 0x80, 0x17, 0x91, 0xe0, 0xee, 0xe1, 0x09, 0x1f, 0x51, 0xd5, 0xe5, 0x31, - 0xbe, 0x7a, 0xfe, 0x4a, 0xa4, 0x3b, 0x39, 0x89, 0x5a, 0x2f, 0x67, 0x57, 0xb2, 0x23, 0x39, 0x76, - 0x77, 0x75, 0xd2, 0xab, 0x1d, 0x2c, 0xff, 0x0c, 0x2d, 0x07, 0xa5, 0xee, 0xc1, 0xf7, 0xfb, 0xf6, - 0xe2, 0xaf, 0x19, 0x07, 0x31, 0xf1, 0xa7, 0x73, 0x30, 0xf2, 0x8e, 0x99, 0x98, 0x14, 0xef, 0x8c, - 0x87, 0x23, 0x83, 0x50, 0xa9, 0x38, 0xe1, 0x68, 0x71, 0x05, 0xf6, 0xe4, 0x97, 0x63, 0x72, 0xb8, - 0x3f, 0x06, 0x53, 0xe0, 0x4a, 0x63, 0x51, 0xbe, 0x3a, 0x67, 0xdc, 0x12, 0xe8, 0x45, 0x18, 0x20, - 0xb5, 0xc6, 0x88, 0x60, 0x96, 0xdd, 0x57, 0x64, 0x7f, 0xae, 0x92, 0xd3, 0xfd, 0x99, 0xee, 0x2a, - 0x95, 0xd5, 0x6a, 0x31, 0x72, 0x08, 0xed, 0xcc, 0x1e, 0x9a, 0x9d, 0x93, 0xa7, 0xca, 0x7a, 0x04, - 0x51, 0x66, 0x50, 0x47, 0x91, 0xba, 0x8c, 0xc3, 0x94, 0xd2, 0x24, 0xfb, 0x11, 0x49, 0x05, 0xb9, - 0x4f, 0x11, 0xc4, 0x5d, 0x7a, 0x5c, 0x5e, 0xd9, 0x34, 0x1a, 0x61, 0x88, 0x1a, 0x84, 0xf0, 0x3b, - 0x7f, 0x81, 0x24, 0x0a, 0x80, 0x21, 0x66, 0x10, 0x4e, 0x52, 0x0c, 0xe9, 0xc8, 0xca, 0xf7, 0x70, - 0x31, 0xbf, 0x18, 0xe7, 0x4b, 0xab, 0x11, 0x15, 0x12, 0x84, 0x81, 0x81, 0x7e, 0x18, 0x15, 0xe4, - 0x0b, 0x9a, 0x1a, 0xc0, 0xea, 0x9c, 0x52, 0x12, 0xd5, 0x09, 0xbd, 0x68, 0x5a, 0x4b, 0x23, 0x84, - 0x9e, 0xe1, 0xe1, 0x5c, 0x3a, 0x55, 0x33, 0xf3, 0xb4, 0x6a, 0x23, 0x7c, 0x48, 0x18, 0x4a, 0xf1, - 0x9a, 0xe3, 0x5b, 0xad, 0x7c, 0x27, 0x22, 0xaf, 0x23, 0x16, 0x24, 0xc6, 0x24, 0x1a, 0x49, 0x80, - 0x5c, 0x9c, 0x39, 0x9f, 0x0d, 0x37, 0x1a, 0x71, 0xf0, 0xa2, 0x68, 0xec, 0xe7, 0x9f, 0x7e, 0x82, - 0xa5, 0xaf, 0x2e, 0x41, 0x45, 0x59, 0xb1, 0xca, 0x8a, 0x04, 0x61, 0x42, 0x2c, 0x27, 0x8a, 0x8b, - 0x28, 0x14, 0xdc, 0xf1, 0x0b, 0x09, 0xc3, 0xf8, 0xc7, 0x17, 0xe3, 0x14, 0x8d, 0x72, 0x95, 0x1d, - 0xda, 0x85, 0x5b, 0xef, 0x5b, 0x80, 0x12, 0x4e, 0xe0, 0x67, 0x7c, 0x29, 0x7e, 0x15, 0x19, 0x85, - 0x88, 0xca, 0x52, 0xc4, 0x19, 0x28, 0x03, 0xc3, 0x34, 0x53, 0xc7, 0x26, 0xa1, 0x6f, 0xef, 0x30, - 0xa6, 0x75, 0x42, 0x09, 0x57, 0x48, 0x3b, 0x2b, 0xea, 0x10, 0x4f, 0x41, 0xd0, 0xbe, 0xee, 0xd6, - 0x8c, 0x60, 0x73, 0xb5, 0x09, 0x3d, 0x49, 0x84, 0x41, 0xa4, 0x4c, 0x57, 0x72, 0xa5, 0xeb, 0x66, - 0x04, 0x48, 0x27, 0x12, 0xc4, 0x78, 0x51, 0xe4, 0x51, 0x4f, 0x43, 0x14, 0x32, 0x77, 0xfa, 0x78, - 0xb9, 0x63, 0xe8, 0xb0, 0x91, 0xf0, 0xf6, 0x0f, 0xc1, 0xc1, 0x03, 0x29, 0xa8, 0xa4, 0x78, 0x97, - 0x7a, 0xe3, 0x47, 0x58, 0x1e, 0xb4, 0xab, 0x30, 0x75, 0x95, 0x65, 0x70, 0xa1, 0x89, 0x90, 0xa1, - 0x13, 0xa7, 0xa1, 0x98, 0x82, 0xa8, 0x07, 0x36, 0xaf, 0xa7, 0xd0, 0x5e, 0x3c, 0x46, 0x87, 0xf6, - 0x44, 0xd6, 0xc7, 0xef, 0x22, 0x2f, 0x37, 0x1b, 0xe5, 0x09, 0xa3, 0xe0, 0x16, 0x15, 0x83, 0x73, - 0x19, 0xc7, 0xb0, 0x7b, 0xe7, 0x7e, 0xf4, 0x09, 0xeb, 0x85, 0x60, 0x1f, 0x4f, 0x0c, 0x20, 0xe2, - 0x45, 0xc4, 0x79, 0x07, 0x09, 0x11, 0x4e, 0x42, 0xb8, 0x5a, 0xf4, 0xf8, 0x28, 0x8e, 0x86, 0x12, - 0xee, 0x27, 0x52, 0x6b, 0x15, 0xf4, 0x72, 0x75, 0x22, 0xbb, 0x53, 0x8b, 0xeb, 0x44, 0x5f, 0xb7, - 0x9d, 0xf4, 0xba, 0x1a, 0x01, 0x5a, 0x15, 0x6b, 0xb9, 0x94, 0xcc, 0xa5, 0xfd, 0x2e, 0x0f, 0x8e, - 0x02, 0x1d, 0x97, 0x8c, 0x4e, 0xae, 0x5e, 0x34, 0xb4, 0xb1, 0x0d, 0xcf, 0xfd, 0xe1, 0x31, 0x9c, - 0x39, 0x91, 0xce, 0xbb, 0x3a, 0x1f, 0x0a, 0x52, 0xf5, 0x41, 0xdf, 0x7e, 0xd1, 0x70, 0xf7, 0xf2, - 0x43, 0x35, 0x4d, 0x3d, 0x04, 0x45, 0xf6, 0x46, 0xc2, 0x98, 0x71, 0xc8, 0xd8, 0xf5, 0x1d, 0xb6, - 0xfe, 0xf3, 0x6b, 0x0c, 0x18, 0x3a, 0x02, 0x3f, 0x99, 0x79, 0x17, 0x0a, 0x29, 0x54, 0xb8, 0xfb, - 0x9b, 0xd5, 0x70, 0x89, 0xea, 0x83, 0xa4, 0x85, 0x8f, 0x21, 0xa0, 0xde, 0x84, 0x8a, 0xc3, 0xa9, - 0xd4, 0x26, 0xf1, 0xc2, 0xdc, 0xe9, 0x53, 0x28, 0x02, 0xea, 0xab, 0x22, 0x7a, 0x57, 0xa5, 0x09, - 0x7d, 0xdc, 0x9c, 0x39, 0x22, 0x04, 0xd3, 0xfc, 0x5d, 0x76, 0xb9, 0x84, 0xdf, 0x5e, 0xa3, 0x60, - 0x86, 0x8f, 0x0e, 0x9e, 0x16, 0xe1, 0x5a, 0x7c, 0x67, 0x9f, 0xd7, 0x25, 0x01, 0xa4, 0x51, 0xab, - 0x57, 0x7f, 0x81, 0xe2, 0xd2, 0x72, 0xfc, 0x94, 0xd6, 0x4d, 0x9c, 0xc9, 0x0a, 0xf4, 0xee, 0x9e, - 0x48, 0x3f, 0x99, 0x8d, 0x97, 0x5f, 0x7c, 0x16, 0xa6, 0x9a, 0x52, 0x4c, 0xbd, 0xf5, 0x0e, 0xf4, - 0x8e, 0x1e, 0x00, 0xf7, 0x1e, 0x41, 0x5c, 0x21, 0xe9, 0x61, 0xa4, 0x98, 0x76, 0x11, 0xcd, 0x16, - 0xe9, 0xdc, 0xf5, 0xa8, 0xa2, 0x8a, 0xc2, 0x57, 0xff, 0x78, 0x9f, 0x36, 0x8d, 0xb3, 0x10, 0x3f, - 0x6c, 0x14, 0x12, 0x46, 0x8f, 0x43, 0xee, 0xb9, 0xd3, 0x38, 0xc6, 0x49, 0x3a, 0xf0, 0xdf, 0x66, - 0xc1, 0x8d, 0x56, 0x52, 0x9c, 0x36, 0xae, 0x41, 0x04, 0xcd, 0xfc, 0xf5, 0xec, 0xd7, 0x17, 0x63, - 0x63, 0xfb, 0xd1, 0x6a, 0x44, 0x28, 0x8e, 0x42, 0x8f, 0x30, 0x72, 0xa3, 0xde, 0xcd, 0x38, 0xd2, - 0x89, 0xda, 0x46, 0x64, 0x92, 0x65, 0x4d, 0xa4, 0xd2, 0x95, 0xac, 0xba, 0x1c, 0xe9, 0xae, 0x2b, - 0x02, 0xf0, 0x3a, 0x11, 0xcf, 0x3d, 0xf7, 0x2c, 0x56, 0x7f, 0xb9, 0x06, 0x49, 0xa3, 0xc6, 0xc2, - 0xa0, 0x97, 0x49, 0x12, 0x34, 0x19, 0x33, 0x0f, 0xa1, 0x61, 0x61, 0xaa, 0x81, 0x1f, 0xc5, 0xc5, - 0x93, 0xa2, 0xe5, 0x3f, 0xe0, 0xfc, 0xe9, 0x63, 0x18, 0x92, 0x30, 0x18, 0xfd, 0x29, 0xdc, 0x2c, - 0x04, 0x68, 0xa0, 0x45, 0xa3, 0xc2, 0x82, 0x22, 0x5c, 0xc8, 0xcb, 0x47, 0x69, 0x75, 0x1d, 0x74, - 0x54, 0xc3, 0xb8, 0x70, 0xf6, 0x24, 0xd2, 0x0e, 0xec, 0x43, 0x31, 0xc5, 0x6a, 0x03, 0x69, 0x64, - 0x3a, 0x6e, 0x78, 0x12, 0xf4, 0x34, 0x7c, 0x52, 0xe0, 0xee, 0x81, 0xaa, 0xf8, 0xa1, 0x28, 0x5e, - 0xb5, 0x1c, 0x11, 0x14, 0x4b, 0x9c, 0x36, 0xe7, 0x1e, 0x04, 0xd2, 0x94, 0x53, 0x3e, 0x45, 0x6e, - 0x8b, 0x88, 0xdd, 0x71, 0x7d, 0xc2, 0xd0, 0x97, 0xd6, 0x91, 0x74, 0x24, 0xbc, 0xb8, 0x6a, 0xb2, - 0xa2, 0xcf, 0xcb, 0x1b, 0x30, 0xd3, 0xc7, 0x55, 0x5d, 0xa1, 0xa9, 0x81, 0x0e, 0xfa, 0xbb, 0x2e, - 0x08, 0x20, 0x2c, 0xe7, 0x99, 0x67, 0x9e, 0xc1, 0xd2, 0xa5, 0xcb, 0xd8, 0xd3, 0x0d, 0x18, 0x91, - 0x3c, 0x16, 0xe3, 0xb9, 0xa2, 0x71, 0xa6, 0x05, 0x25, 0xb1, 0xe5, 0x70, 0x9c, 0x22, 0xf0, 0x0b, - 0x1e, 0x9a, 0x87, 0x31, 0x63, 0xc7, 0xa8, 0xd6, 0x48, 0x83, 0x7a, 0x86, 0x21, 0xaf, 0xa4, 0x16, - 0xa9, 0x87, 0xd2, 0x68, 0x16, 0x87, 0xba, 0x2b, 0x14, 0x4a, 0x95, 0x55, 0x4d, 0x29, 0x4d, 0x96, - 0x97, 0x72, 0xd4, 0x54, 0x91, 0x25, 0x99, 0x48, 0x38, 0x03, 0x77, 0xcb, 0x26, 0x53, 0x3d, 0xad, - 0x34, 0x95, 0x73, 0x45, 0x44, 0xd9, 0x66, 0x4e, 0xf0, 0x75, 0x95, 0xe5, 0x34, 0x3d, 0x15, 0x8c, - 0xe8, 0x9f, 0xdc, 0x4e, 0x19, 0xcf, 0x5a, 0x64, 0x1d, 0xd8, 0x03, 0xa3, 0xb3, 0x2b, 0x86, 0x0c, - 0x4e, 0x40, 0x78, 0x5c, 0x3c, 0xfa, 0xf4, 0x0a, 0x20, 0x2b, 0xa2, 0xd2, 0x02, 0x05, 0xc1, 0x73, - 0x6b, 0x28, 0xc1, 0xcb, 0x2d, 0x9a, 0x27, 0x47, 0x55, 0xa2, 0x3f, 0x77, 0xdf, 0x97, 0x09, 0xe2, - 0x20, 0xdc, 0xab, 0xd9, 0x5c, 0x53, 0x02, 0xc8, 0x44, 0xba, 0x7e, 0xc3, 0x06, 0xdc, 0x77, 0xdf, - 0xfd, 0xaa, 0xaa, 0x8a, 0x88, 0x2e, 0x8b, 0x9c, 0xb5, 0x89, 0x4a, 0x43, 0x77, 0xcd, 0x99, 0x4b, - 0xd9, 0xea, 0xc1, 0xd8, 0x47, 0xb6, 0x71, 0xf6, 0xc7, 0x1f, 0x51, 0xc5, 0xde, 0xe9, 0xc9, 0x09, - 0x7a, 0xc4, 0x88, 0x24, 0xf4, 0xf0, 0xf3, 0xa3, 0x01, 0x26, 0x6f, 0x44, 0x44, 0x0d, 0x44, 0x76, - 0x7e, 0x25, 0x32, 0x8e, 0x1f, 0x43, 0x8d, 0x4c, 0xc6, 0x1c, 0x09, 0x62, 0xd3, 0x4b, 0x31, 0x19, - 0x39, 0x70, 0xb8, 0x49, 0xe3, 0x4e, 0x58, 0x34, 0x44, 0x8e, 0x1d, 0x3f, 0xc9, 0x79, 0xc4, 0x8d, - 0x3b, 0xe8, 0x50, 0xf8, 0x86, 0x85, 0xa3, 0x9c, 0xd2, 0xc1, 0x45, 0xd9, 0x59, 0x30, 0x66, 0xfe, - 0x08, 0x4f, 0x37, 0x57, 0xd5, 0x2c, 0x90, 0x89, 0xab, 0xaa, 0xd8, 0xf8, 0x44, 0xdc, 0x33, 0x73, - 0x06, 0x27, 0xe9, 0x60, 0x22, 0xc7, 0xb1, 0xac, 0xa6, 0x25, 0xa2, 0x5d, 0x53, 0x02, 0x94, 0x95, - 0x95, 0xe1, 0xe7, 0xf7, 0xfc, 0x02, 0x85, 0x54, 0xad, 0x0c, 0xa6, 0xea, 0x99, 0x58, 0x72, 0xd3, - 0xeb, 0xdd, 0x51, 0x40, 0xeb, 0x3d, 0xa2, 0x72, 0xf6, 0xfb, 0x3f, 0x3c, 0xc5, 0x5e, 0x6c, 0xc0, - 0x3a, 0xca, 0x8e, 0x8b, 0xa5, 0x1f, 0x6a, 0x39, 0x41, 0xa4, 0x94, 0x45, 0x60, 0x86, 0x86, 0x43, - 0xd4, 0x7d, 0x43, 0x30, 0xb5, 0x54, 0x06, 0x0c, 0x1e, 0x8e, 0x1a, 0x93, 0x1b, 0x8e, 0x67, 0x1c, - 0xc5, 0xd9, 0x13, 0x69, 0xe4, 0xd3, 0x5c, 0x9e, 0x92, 0x48, 0x22, 0x77, 0x7b, 0xee, 0xec, 0x79, - 0x5c, 0xa4, 0xe5, 0x1f, 0x83, 0xc1, 0x83, 0x02, 0xc4, 0xae, 0xdc, 0x07, 0x38, 0xc1, 0xe0, 0xe2, - 0xcc, 0x1d, 0xaf, 0x8e, 0xc6, 0xd5, 0x68, 0xca, 0x8b, 0xe7, 0x12, 0xa2, 0x29, 0xe0, 0x4c, 0x5b, - 0xe3, 0x82, 0xf4, 0xe4, 0x49, 0xb7, 0x61, 0xc6, 0x2d, 0x37, 0x23, 0xb6, 0x5f, 0xb8, 0xba, 0x2a, - 0x6b, 0x09, 0x71, 0x8e, 0x0a, 0xbf, 0xa6, 0x04, 0x38, 0x42, 0x55, 0x88, 0x67, 0x97, 0xbc, 0x88, - 0x3a, 0xca, 0xb6, 0xcb, 0xca, 0x46, 0x0c, 0x1f, 0xcb, 0x1c, 0xa7, 0xe3, 0xb3, 0x50, 0xb4, 0x08, - 0x0a, 0x2f, 0xaa, 0xf2, 0xeb, 0x34, 0x2e, 0x8a, 0xd4, 0x1f, 0x7e, 0x80, 0xd8, 0x8e, 0x12, 0x95, - 0x3a, 0x13, 0xed, 0x04, 0xd2, 0x0a, 0xb3, 0xaa, 0x66, 0x21, 0x44, 0x33, 0x92, 0x28, 0xa2, 0x33, - 0x32, 0x70, 0xf0, 0x30, 0x04, 0x47, 0x0e, 0x40, 0x35, 0x59, 0xda, 0xae, 0x8d, 0x5f, 0x61, 0xeb, - 0xe6, 0x0d, 0x90, 0x79, 0x25, 0x98, 0x66, 0x99, 0xbc, 0x3c, 0xbd, 0x55, 0xe1, 0x7e, 0x67, 0x2a, - 0x00, 0x34, 0x32, 0x7f, 0x77, 0x1e, 0x4f, 0xe8, 0x49, 0x04, 0x85, 0x9b, 0x3f, 0xd5, 0x6c, 0x96, - 0x88, 0xa1, 0xd3, 0xae, 0x54, 0x20, 0xc5, 0xd3, 0xc7, 0x4f, 0x99, 0x81, 0xe9, 0x93, 0xc7, 0x22, - 0x22, 0x24, 0xd0, 0x51, 0x78, 0x6e, 0x31, 0x9f, 0x6b, 0x4a, 0x80, 0x1f, 0x88, 0xd4, 0x83, 0x69, - 0x47, 0x68, 0xbf, 0x2d, 0x03, 0xa2, 0x7c, 0xec, 0x4e, 0x31, 0xf7, 0x06, 0xf6, 0xda, 0x06, 0x22, - 0x54, 0x7a, 0x7a, 0x45, 0x79, 0x19, 0x32, 0xcf, 0x9f, 0x43, 0x9f, 0x3e, 0x11, 0x48, 0x1c, 0x3c, - 0x98, 0xb2, 0xf9, 0xc5, 0xb4, 0x3e, 0x96, 0xc7, 0xc9, 0xd1, 0x85, 0xc8, 0x74, 0x55, 0x59, 0x95, - 0xb0, 0x31, 0x27, 0x22, 0x51, 0xac, 0xe6, 0xd7, 0x54, 0xd7, 0xa8, 0x87, 0x6a, 0xa1, 0x5c, 0x92, - 0x0e, 0xbf, 0x69, 0x1a, 0xfc, 0x02, 0x43, 0x70, 0x24, 0x75, 0x2f, 0x36, 0xaf, 0xfd, 0x02, 0x99, - 0x67, 0xcf, 0x70, 0x49, 0xeb, 0x0a, 0x0f, 0x4f, 0x2a, 0x31, 0x53, 0xad, 0xd6, 0x8d, 0x9a, 0x16, - 0xa2, 0x13, 0x23, 0x79, 0xc9, 0xde, 0x42, 0x21, 0x51, 0x24, 0x2f, 0x03, 0xf3, 0x1d, 0x3b, 0x69, - 0x3a, 0x6e, 0x99, 0x70, 0x33, 0x46, 0x0f, 0x1f, 0xc4, 0x53, 0xd7, 0x4e, 0x2a, 0x37, 0xb7, 0x88, - 0xfa, 0x4b, 0x11, 0xd7, 0x94, 0x00, 0x62, 0xe2, 0x7b, 0xd3, 0xa6, 0xcd, 0x70, 0x21, 0x32, 0xb6, - 0x6e, 0xdf, 0x8d, 0xb4, 0xc3, 0x47, 0x54, 0xa4, 0x88, 0x55, 0x6e, 0x99, 0x0b, 0xaa, 0xab, 0xaa, - 0x54, 0x0b, 0xdd, 0x82, 0xf8, 0xea, 0x2a, 0x7e, 0x0f, 0x24, 0x32, 0x02, 0xfe, 0xbe, 0x3e, 0xdc, - 0x90, 0x51, 0xaf, 0x86, 0x43, 0xa5, 0x87, 0x7f, 0x0f, 0x15, 0x5e, 0x88, 0x25, 0xc8, 0xa7, 0x12, - 0x36, 0x27, 0x63, 0xc0, 0x83, 0xe6, 0xdd, 0xc4, 0x56, 0x23, 0x85, 0x07, 0xd1, 0x27, 0x3a, 0x8e, - 0xb6, 0xb2, 0x65, 0x33, 0xe7, 0x8f, 0x33, 0xa7, 0x8e, 0x23, 0x65, 0xe7, 0x77, 0x38, 0x79, 0xf4, - 0xb0, 0xaa, 0x60, 0x21, 0x3b, 0x6a, 0x29, 0x5b, 0x3e, 0x78, 0xa3, 0x73, 0xb9, 0x44, 0xd0, 0xf0, - 0xc8, 0xbe, 0xaa, 0x75, 0xb5, 0x98, 0x7e, 0xbd, 0x31, 0x61, 0x74, 0x22, 0x02, 0x02, 0xfc, 0xed, - 0xa0, 0xb0, 0x73, 0xd1, 0xd7, 0x94, 0x00, 0x52, 0x75, 0x4a, 0x52, 0x62, 0x1b, 0xbf, 0x96, 0x70, - 0xf4, 0xe8, 0x51, 0x54, 0xf1, 0x30, 0x6e, 0xcb, 0xf7, 0xdb, 0x90, 0x4f, 0x5d, 0x89, 0x46, 0xb2, - 0x03, 0x8a, 0xda, 0xa9, 0x44, 0x10, 0x1b, 0xe0, 0xf5, 0x5c, 0xb1, 0x48, 0x2f, 0x17, 0x5b, 0x93, - 0x3e, 0x64, 0x57, 0x41, 0x81, 0xfe, 0xa0, 0x18, 0x1d, 0x0d, 0x07, 0x0e, 0x45, 0xf4, 0xc0, 0x18, - 0x2a, 0x0d, 0x7a, 0x91, 0x6d, 0x15, 0xaa, 0xba, 0x16, 0xa7, 0x39, 0x69, 0x8f, 0x1e, 0x9d, 0xac, - 0xea, 0x1e, 0x95, 0x71, 0x14, 0x35, 0xb2, 0x0c, 0xe9, 0xc9, 0xde, 0x3e, 0xbe, 0xf0, 0xe6, 0x11, - 0x85, 0x9b, 0x57, 0x0f, 0x4e, 0xca, 0x7a, 0x5a, 0x83, 0x6b, 0xe0, 0xf7, 0x5b, 0xaa, 0x48, 0xec, - 0xaa, 0x4b, 0xc7, 0x1a, 0xd4, 0x1e, 0xeb, 0xc9, 0xa3, 0x0d, 0x53, 0x6d, 0x15, 0xe2, 0x62, 0x22, - 0xd4, 0x45, 0x80, 0x1c, 0x06, 0x76, 0xa5, 0xbb, 0xe6, 0x04, 0xd0, 0x1a, 0x77, 0xf2, 0xd4, 0x49, - 0x75, 0x19, 0x9a, 0x47, 0x16, 0x53, 0x58, 0x58, 0x04, 0x91, 0x14, 0x2d, 0xa6, 0x2e, 0x94, 0x9c, - 0x8e, 0xca, 0xaa, 0x48, 0xd8, 0x83, 0x1b, 0x97, 0xa8, 0x72, 0x48, 0x27, 0x8a, 0x2c, 0xde, 0xde, - 0xbe, 0xea, 0x01, 0x5d, 0x4d, 0x55, 0x05, 0xaa, 0x49, 0x28, 0x13, 0x0f, 0xe5, 0x4a, 0x09, 0x1f, - 0x40, 0x3b, 0x82, 0xaf, 0xbd, 0xf6, 0x0a, 0x26, 0x4e, 0x98, 0xa8, 0x65, 0x4d, 0x44, 0xd7, 0xd1, - 0x2c, 0x5f, 0xbe, 0xaa, 0x62, 0x24, 0xcb, 0x51, 0x4f, 0x4e, 0xc8, 0x1c, 0x20, 0xaa, 0x6a, 0x52, - 0x35, 0x47, 0x5a, 0x0d, 0x97, 0xad, 0x32, 0xe2, 0x1a, 0xa8, 0x7a, 0xd4, 0x83, 0x3b, 0xe3, 0x9b, - 0x27, 0x4c, 0xe2, 0xbe, 0xe3, 0xff, 0xc1, 0x24, 0x6c, 0xc6, 0xd0, 0x65, 0x8f, 0x8c, 0x86, 0xad, - 0x5b, 0xb7, 0xe2, 0x8d, 0xbf, 0xff, 0x1d, 0x94, 0xcd, 0xa4, 0x26, 0x5c, 0x05, 0x72, 0xa8, 0xd6, - 0x27, 0x47, 0xd5, 0xc1, 0x62, 0xa4, 0x91, 0x3b, 0x57, 0x99, 0xac, 0x0d, 0x94, 0x20, 0x77, 0x27, - 0x12, 0xc5, 0x54, 0x82, 0x5c, 0xd2, 0xd4, 0x92, 0x65, 0xb9, 0x93, 0x95, 0xfc, 0xc7, 0xa2, 0x85, - 0x5c, 0xcf, 0xc7, 0xa9, 0x87, 0x75, 0xcd, 0xf3, 0xb6, 0x7c, 0x97, 0x72, 0xe4, 0x27, 0xac, 0x4b, - 0xd8, 0xa0, 0x10, 0x58, 0xe6, 0x01, 0x31, 0xc5, 0x69, 0x30, 0x78, 0x5a, 0x9e, 0x44, 0x58, 0x26, - 0xeb, 0x12, 0xff, 0x75, 0x33, 0x02, 0x2c, 0x5b, 0x27, 0xbd, 0x5d, 0x7a, 0xec, 0xaa, 0x4f, 0x3e, - 0xc1, 0xfe, 0x03, 0x07, 0xd4, 0xd5, 0x8b, 0x07, 0x11, 0x5e, 0x45, 0xdd, 0xcc, 0x32, 0x6a, 0x7f, - 0x38, 0x51, 0x85, 0x5d, 0x56, 0x4a, 0x72, 0x35, 0x10, 0xd3, 0xbf, 0x1f, 0x16, 0x3c, 0xf8, 0x00, - 0xc2, 0xc2, 0x42, 0x19, 0x7e, 0x75, 0xd6, 0xee, 0x96, 0x75, 0xed, 0xac, 0xff, 0xba, 0x24, 0x40, - 0x67, 0x1b, 0x75, 0x23, 0xa5, 0xbf, 0x74, 0xd8, 0x71, 0x23, 0xd5, 0xf8, 0x5f, 0xac, 0xae, 0xdd, - 0x04, 0xb8, 0xc6, 0x04, 0xed, 0x26, 0x40, 0x37, 0x01, 0xae, 0x1d, 0x06, 0x64, 0x05, 0x64, 0x4f, - 0xd1, 0xaa, 0xab, 0x6b, 0x77, 0xc3, 0x8e, 0x80, 0x0b, 0x17, 0x2e, 0xa8, 0xab, 0x23, 0x59, 0xf9, - 0x34, 0xff, 0xd1, 0x02, 0xaf, 0x5d, 0xbc, 0x89, 0xc9, 0x1a, 0x31, 0xfc, 0x20, 0xf6, 0x13, 0x1e, - 0x7a, 0xe8, 0x21, 0xbb, 0xf0, 0x5d, 0x05, 0xd0, 0xb5, 0xdb, 0xbc, 0xae, 0xaa, 0x35, 0xf3, 0x0d, - 0x0d, 0x0d, 0xc5, 0x4b, 0x2f, 0xbd, 0xc4, 0xe3, 0xea, 0x7d, 0xea, 0x01, 0xdd, 0x37, 0xdf, 0x7c, - 0xa3, 0x6e, 0xb8, 0xa4, 0x48, 0xd9, 0x41, 0xdb, 0x73, 0xa2, 0x41, 0xfa, 0xe5, 0x97, 0x5f, 0xaa, - 0x60, 0xad, 0x6a, 0x93, 0xda, 0xcb, 0xa8, 0x93, 0xf1, 0xed, 0x5e, 0x86, 0x52, 0x81, 0x4d, 0x55, - 0xb5, 0x2d, 0xa2, 0xc5, 0x7a, 0x39, 0x4e, 0x96, 0x63, 0x5f, 0x39, 0x1a, 0x4e, 0x4e, 0x4e, 0x56, - 0x91, 0x62, 0xab, 0x3e, 0x72, 0x22, 0x79, 0xee, 0xdc, 0x39, 0x35, 0x4a, 0x4e, 0x2f, 0x45, 0x9d, - 0xd7, 0xd2, 0xf1, 0x7b, 0x8b, 0x6a, 0x5e, 0x12, 0x26, 0xa6, 0x4a, 0xe4, 0x88, 0xb9, 0x35, 0x27, - 0x9b, 0x28, 0x49, 0x23, 0xb0, 0xa2, 0xd6, 0x2b, 0x4e, 0xbe, 0x03, 0x25, 0x7b, 0x07, 0x71, 0x42, - 0x14, 0x7e, 0xfc, 0x48, 0xf5, 0x37, 0xff, 0x93, 0xcb, 0x1f, 0xf9, 0x02, 0x99, 0xec, 0x35, 0x34, - 0x27, 0x69, 0xe5, 0xd7, 0x56, 0x27, 0xd6, 0x4a, 0x64, 0xa7, 0x2e, 0xb8, 0x90, 0xfc, 0x44, 0xb7, - 0x94, 0x56, 0x9c, 0x61, 0x4b, 0x75, 0xd8, 0x6e, 0x9e, 0xac, 0x88, 0x5d, 0xc7, 0x23, 0x60, 0x85, - 0x5b, 0x7c, 0xa9, 0x71, 0x93, 0x1f, 0x11, 0xd0, 0xe4, 0x5d, 0xe2, 0xc5, 0xf0, 0xb7, 0xa5, 0xfb, - 0xfd, 0xef, 0x7f, 0x6f, 0x05, 0xc3, 0xdd, 0xae, 0x19, 0x24, 0x2a, 0x2a, 0xaa, 0x49, 0xbc, 0x66, - 0x9e, 0xda, 0x0c, 0x40, 0x0f, 0xc5, 0x55, 0x94, 0x05, 0x0b, 0x16, 0x34, 0x81, 0x6b, 0x5e, 0x17, - 0xcb, 0x77, 0x12, 0xc0, 0x32, 0xb9, 0xd9, 0xff, 0xe9, 0xa7, 0x9f, 0xda, 0xcc, 0xa3, 0xb9, 0xc6, - 0xaf, 0x39, 0x81, 0x85, 0x67, 0xf7, 0xee, 0xdd, 0x0a, 0x3b, 0x9b, 0xcd, 0xf4, 0x96, 0x65, 0x8b, - 0xed, 0xee, 0x77, 0xdf, 0x7d, 0xd7, 0x22, 0x65, 0xeb, 0x5e, 0xe9, 0x09, 0x6d, 0x76, 0x9c, 0xb0, - 0x6c, 0xc2, 0xbe, 0xfc, 0xf2, 0xcb, 0xe6, 0x8a, 0xf5, 0xe9, 0xd3, 0xc7, 0x26, 0x8c, 0x66, 0xcc, - 0x5c, 0x2a, 0x6b, 0x49, 0x00, 0x01, 0xd6, 0x54, 0xa6, 0x25, 0xae, 0x39, 0x01, 0x44, 0x69, 0x57, - 0x53, 0xe8, 0x95, 0x78, 0xf6, 0x32, 0x25, 0x3d, 0x3d, 0xdd, 0x5c, 0xc6, 0xc9, 0x93, 0x27, 0x15, - 0x29, 0xd3, 0x12, 0x09, 0xb6, 0x14, 0x7b, 0xcd, 0x09, 0x2e, 0x7b, 0x34, 0x9b, 0xe2, 0x92, 0xce, - 0x1e, 0x01, 0xa8, 0x35, 0xdd, 0x24, 0xff, 0xe7, 0x9f, 0x7f, 0xbe, 0x79, 0x76, 0x8a, 0x7c, 0x2d, - 0x95, 0x73, 0x91, 0x19, 0x6e, 0xcc, 0x98, 0x31, 0x56, 0x30, 0xb6, 0x02, 0xda, 0x44, 0x00, 0xae, - 0x16, 0x94, 0xbb, 0xef, 0xbe, 0xbb, 0x49, 0x01, 0x96, 0x0d, 0xb6, 0xf4, 0x5b, 0x1a, 0x60, 0xb7, - 0x2c, 0xb0, 0xa3, 0x04, 0x78, 0xee, 0xb9, 0xe7, 0xcc, 0x8d, 0x92, 0x72, 0xc8, 0xca, 0x2c, 0xb3, - 0x55, 0xfd, 0x64, 0x85, 0x4d, 0x60, 0x1c, 0x49, 0x00, 0x9e, 0x17, 0xa9, 0x46, 0xe5, 0xb5, 0x36, - 0x8a, 0x1e, 0x7e, 0x4b, 0xee, 0x8d, 0x37, 0xde, 0x68, 0x52, 0x0f, 0xde, 0x77, 0xb4, 0x04, 0x6a, - 0x0e, 0xb7, 0xbb, 0x0a, 0x22, 0xa4, 0xca, 0x1f, 0xe5, 0x73, 0xe8, 0xe2, 0xa7, 0xf2, 0xbd, 0xfa, - 0x14, 0xbf, 0xf6, 0xdb, 0xbb, 0x77, 0x2f, 0xeb, 0xd7, 0xba, 0x93, 0xd5, 0x86, 0xe6, 0xc4, 0xa4, - 0x82, 0xa5, 0xe3, 0x08, 0xb0, 0x7c, 0x6d, 0xe2, 0x97, 0xdb, 0x30, 0x4b, 0x97, 0x9a, 0x9a, 0x6a, - 0xf9, 0xaa, 0xfa, 0xe5, 0x62, 0xa7, 0xab, 0x9c, 0xdc, 0x15, 0xf0, 0xd3, 0x7f, 0xe6, 0xec, 0x69, - 0xa8, 0xbe, 0xc5, 0xa5, 0xab, 0xa5, 0x79, 0x09, 0x99, 0x9b, 0x12, 0x12, 0x12, 0xcc, 0xe9, 0x5a, - 0xf4, 0x10, 0x89, 0x76, 0x9d, 0x25, 0xff, 0x97, 0x1e, 0xfe, 0xc8, 0x23, 0x8f, 0x28, 0x1f, 0xd0, - 0x0e, 0x00, 0x0d, 0xf8, 0x29, 0x13, 0x27, 0x4e, 0x6c, 0x42, 0x75, 0x16, 0xa4, 0xc8, 0xf0, 0x6b, - 0x4e, 0xfd, 0xfb, 0xf9, 0xa9, 0x02, 0x89, 0xd3, 0x7e, 0xb1, 0xb1, 0xb1, 0xaa, 0x39, 0x08, 0x4e, - 0xb8, 0xe6, 0x30, 0x89, 0xe3, 0x25, 0x89, 0x72, 0xd3, 0x4d, 0x37, 0x35, 0x61, 0x33, 0xcd, 0x59, - 0x80, 0xb0, 0xa1, 0x85, 0x0b, 0x17, 0x2a, 0x8b, 0x16, 0x2d, 0x52, 0xe4, 0xa3, 0x12, 0x5a, 0x9e, - 0xda, 0xb3, 0x7f, 0xff, 0xfe, 0x0a, 0x3b, 0x4c, 0x93, 0x76, 0x09, 0x9b, 0x93, 0xaf, 0x12, 0x86, - 0x87, 0x87, 0xab, 0x3f, 0x61, 0x75, 0x1a, 0xbc, 0xb0, 0x0e, 0x2d, 0x3c, 0x32, 0x32, 0x52, 0x35, - 0x67, 0xc1, 0x63, 0x71, 0x73, 0x7a, 0x4e, 0xb4, 0x0a, 0x91, 0x69, 0x86, 0x97, 0x74, 0xf2, 0xe9, - 0x04, 0xf9, 0xf2, 0xe1, 0x53, 0x4f, 0x3d, 0xa5, 0xb6, 0x57, 0xcb, 0x4b, 0x9e, 0xf2, 0x9d, 0xe4, - 0xb6, 0x6a, 0xda, 0x4b, 0x2f, 0xb6, 0xeb, 0xb8, 0xea, 0x50, 0xbf, 0xe7, 0x68, 0xc9, 0x46, 0xa4, - 0x20, 0xb1, 0x45, 0x20, 0x26, 0x31, 0x68, 0x93, 0x4c, 0xf9, 0xe8, 0xa3, 0x8f, 0xf8, 0x85, 0xdc, - 0x1e, 0x6a, 0x25, 0xfb, 0xf5, 0xeb, 0xa7, 0x6c, 0xd9, 0xb2, 0xc5, 0x2a, 0xdf, 0x55, 0xab, 0x56, - 0xa9, 0xfc, 0x56, 0xab, 0xac, 0xa4, 0x9f, 0x3d, 0x7b, 0xb6, 0xc2, 0x15, 0x95, 0xf9, 0x0b, 0x1c, - 0x12, 0xc7, 0x55, 0x92, 0x42, 0x71, 0x94, 0x26, 0xe9, 0x85, 0x0d, 0x3e, 0xfb, 0xec, 0xb3, 0x4a, - 0xf3, 0x3a, 0x08, 0xe2, 0xa4, 0x2c, 0xe1, 0xcb, 0x1a, 0x0f, 0x96, 0xaf, 0x79, 0xd0, 0x56, 0x5a, - 0x93, 0xf4, 0xef, 0xbf, 0xff, 0xbe, 0x3a, 0x7f, 0x68, 0x65, 0xb7, 0xf4, 0x94, 0x3c, 0xc4, 0x06, - 0x83, 0x2d, 0x04, 0x8a, 0xc9, 0x8d, 0x17, 0x5f, 0x7c, 0x51, 0x9d, 0xa7, 0x9a, 0xa7, 0x97, 0x7a, - 0x49, 0xc7, 0x94, 0xb6, 0xb4, 0xc7, 0xb5, 0x7b, 0x19, 0xca, 0x82, 0xbb, 0x9d, 0x03, 0x31, 0x60, - 0x77, 0x0e, 0x70, 0x60, 0x59, 0xdd, 0x59, 0xd9, 0xc0, 0x40, 0x37, 0x01, 0x6c, 0x20, 0xe5, 0x6a, - 0x06, 0x75, 0x13, 0xe0, 0x6a, 0x62, 0xdb, 0x46, 0x59, 0xdd, 0x04, 0xb0, 0x81, 0x94, 0xab, 0x19, - 0xd4, 0x4d, 0x80, 0xab, 0x89, 0x6d, 0x1b, 0x65, 0x75, 0x13, 0xc0, 0x06, 0x52, 0xae, 0x66, 0x50, - 0x37, 0x01, 0xae, 0x26, 0xb6, 0x6d, 0x94, 0xd5, 0x4d, 0x00, 0x1b, 0x48, 0xb9, 0x9a, 0x41, 0xff, - 0x07, 0xaf, 0xf3, 0x8d, 0x60, 0xda, 0x1b, 0x41, 0x87, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXJSIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x38, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x0e, - 0x0a, 0xaa, 0x03, 0x00, 0x00, 0x05, 0x39, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x7d, - 0x48, 0x5b, 0x57, 0x14, 0xcf, 0x8b, 0x2f, 0x31, 0xd1, 0x1a, 0x4d, 0xb4, 0x06, 0xc7, 0xfc, 0x88, - 0x55, 0x59, 0x97, 0x5a, 0xf1, 0xb3, 0x43, 0x83, 0xba, 0x32, 0x97, 0x0d, 0x3a, 0x0b, 0x2b, 0x08, - 0x75, 0x65, 0x82, 0x8c, 0xc1, 0xdc, 0x1f, 0xab, 0x48, 0xdd, 0x64, 0x62, 0x19, 0x6e, 0x73, 0xc2, - 0xa6, 0x83, 0x6e, 0x38, 0x46, 0xff, 0x28, 0xc3, 0x75, 0x6b, 0x51, 0x36, 0x54, 0x56, 0x23, 0x88, - 0x3a, 0x3b, 0xa1, 0x22, 0xd4, 0xd8, 0xc9, 0x28, 0x9b, 0x1f, 0x0c, 0xad, 0x4c, 0xa3, 0xb5, 0x89, - 0x71, 0xd1, 0x7c, 0xb8, 0x63, 0x9f, 0xbc, 0x3c, 0x93, 0x98, 0x9b, 0xbc, 0x7b, 0xcd, 0x10, 0xde, - 0x23, 0x84, 0x73, 0xcf, 0xfb, 0xdd, 0x73, 0x7e, 0xbf, 0x73, 0xee, 0xbb, 0x2f, 0xb9, 0xd4, 0xce, - 0xce, 0x8e, 0xe8, 0x28, 0x5f, 0xe2, 0xa3, 0x4c, 0x7e, 0x97, 0xbb, 0x20, 0xe0, 0xff, 0xee, 0xa0, - 0xd0, 0x01, 0xa1, 0x03, 0x98, 0x15, 0x10, 0x96, 0x10, 0x66, 0x01, 0xb1, 0xa7, 0xd3, 0xd8, 0x11, - 0xf6, 0x02, 0xac, 0x8f, 0x19, 0xcc, 0x13, 0xbf, 0xba, 0xec, 0xdb, 0x30, 0x56, 0x16, 0xe9, 0xa3, - 0x5f, 0x78, 0xc9, 0x23, 0xf2, 0xfc, 0x17, 0x57, 0x18, 0x8f, 0x34, 0xfe, 0x99, 0xf8, 0x73, 0x97, - 0x68, 0xe5, 0x71, 0x0f, 0x00, 0xbf, 0x21, 0x19, 0x01, 0xb3, 0x1f, 0xbf, 0xb3, 0x74, 0xeb, 0x1b, - 0x96, 0x41, 0x58, 0x64, 0x94, 0xb7, 0x80, 0xc5, 0x1b, 0x9f, 0xb3, 0x80, 0x85, 0x6f, 0x3f, 0xc9, - 0xfc, 0xee, 0xae, 0x5c, 0xf3, 0x1c, 0xeb, 0xe1, 0x6d, 0x10, 0x78, 0x06, 0x2c, 0xc6, 0x31, 0x2e, - 0xfb, 0x40, 0xa8, 0xd8, 0xd7, 0x57, 0xe7, 0x5a, 0x2f, 0x07, 0x82, 0x44, 0x62, 0x08, 0x74, 0xc0, - 0x32, 0x39, 0xc6, 0xa6, 0x49, 0xfd, 0xe0, 0x4b, 0xa5, 0xee, 0x55, 0x5a, 0x19, 0xc7, 0x7a, 0x58, - 0x23, 0xf7, 0x97, 0x3f, 0x1d, 0xe6, 0xf5, 0xbf, 0xae, 0xbe, 0x65, 0x7d, 0x68, 0x04, 0x27, 0x77, - 0x16, 0x8b, 0xe1, 0x61, 0x10, 0xe8, 0x80, 0x63, 0xc3, 0xcc, 0x24, 0xa6, 0x15, 0x31, 0x09, 0x6f, - 0xbc, 0x27, 0x4b, 0xce, 0xa0, 0x15, 0x2a, 0x6f, 0x2a, 0xb2, 0xc4, 0xb4, 0x63, 0xda, 0xbc, 0xf8, - 0xf3, 0x55, 0xcc, 0x2d, 0x87, 0xd5, 0xe2, 0x8d, 0xe1, 0xe1, 0x21, 0x20, 0x80, 0xcd, 0x2a, 0x0e, - 0x97, 0xb3, 0xf6, 0x41, 0x46, 0x20, 0x98, 0x83, 0xe6, 0xfa, 0xf4, 0x93, 0x14, 0xe0, 0x33, 0xc1, - 0x61, 0x3b, 0x05, 0x01, 0x22, 0x91, 0x63, 0x7d, 0x95, 0x29, 0x33, 0x45, 0x4b, 0x90, 0xf5, 0x16, - 0x4b, 0xdc, 0x18, 0x87, 0x79, 0x0d, 0x89, 0x47, 0x02, 0x70, 0x3b, 0xb0, 0xbd, 0xf2, 0x68, 0x75, - 0xf0, 0x27, 0x26, 0x4d, 0xc4, 0x89, 0xe7, 0x91, 0xf9, 0xe4, 0xa9, 0x6e, 0xcc, 0xd2, 0xcd, 0xaf, - 0x90, 0x78, 0x24, 0x00, 0x4b, 0xc0, 0xc2, 0xf5, 0x4f, 0xef, 0x97, 0x9f, 0xdc, 0x5e, 0x59, 0x82, - 0x34, 0x61, 0x32, 0x79, 0xe2, 0xdb, 0x1f, 0x22, 0xf3, 0x45, 0x9d, 0x3e, 0xa3, 0x2a, 0x7d, 0x8d, - 0x81, 0xfd, 0xfd, 0xf5, 0xd5, 0xa9, 0x8b, 0xf9, 0x5b, 0x0b, 0xb3, 0xc8, 0x59, 0x7e, 0x00, 0x58, - 0x02, 0x36, 0xa6, 0xee, 0x31, 0x7b, 0xa8, 0x44, 0x75, 0x3c, 0xe3, 0xb3, 0xce, 0xa8, 0x6c, 0x9d, - 0x9f, 0x4c, 0x7b, 0xb7, 0x28, 0x71, 0x46, 0xeb, 0xf7, 0xb1, 0x2f, 0x96, 0x33, 0x43, 0xcb, 0xef, - 0x13, 0xf6, 0x27, 0x7b, 0x2b, 0x10, 0x3d, 0xd7, 0x17, 0x02, 0x4b, 0x40, 0xac, 0xbe, 0x22, 0x32, - 0x23, 0x13, 0xc2, 0xda, 0xd7, 0x56, 0xfe, 0xb8, 0x7c, 0xc1, 0x74, 0xe7, 0x07, 0x5f, 0x29, 0xf6, - 0xf9, 0x5c, 0x5b, 0xff, 0x3e, 0x78, 0x53, 0xb7, 0x3a, 0xd4, 0x03, 0x5e, 0xb1, 0x34, 0x5c, 0xfd, - 0x7a, 0x75, 0xb8, 0xfa, 0xd9, 0x7d, 0x88, 0x60, 0x07, 0x70, 0x2a, 0x81, 0x73, 0xb9, 0xb6, 0x6d, - 0xf7, 0x2f, 0x64, 0xdd, 0x3d, 0x25, 0x82, 0xcf, 0xd4, 0xa5, 0x42, 0x64, 0xa8, 0xc7, 0xbf, 0xf5, - 0x33, 0x60, 0xf8, 0x36, 0x19, 0x6e, 0x23, 0xf1, 0x48, 0x00, 0x56, 0x07, 0xa0, 0x58, 0x94, 0x24, - 0x5c, 0xa9, 0x7b, 0x85, 0xa9, 0x9a, 0x6d, 0x71, 0x0e, 0x59, 0x3e, 0xdb, 0x82, 0x1b, 0xa3, 0x3a, - 0x7b, 0x1e, 0x89, 0x47, 0x02, 0x70, 0x05, 0x40, 0x02, 0x4a, 0x22, 0x45, 0xa6, 0xf1, 0x09, 0xa0, - 0x68, 0x9e, 0x13, 0xb9, 0xd1, 0x08, 0x08, 0xe0, 0x86, 0x0b, 0xbd, 0x2d, 0x08, 0xe0, 0xd4, 0xdc, - 0x69, 0x35, 0x8b, 0x5c, 0x4e, 0x8e, 0xc3, 0x87, 0xe9, 0x34, 0x3f, 0xf6, 0xe1, 0xc5, 0x70, 0x11, - 0xf8, 0x3f, 0x20, 0x8d, 0x55, 0x33, 0x04, 0x9c, 0x9b, 0x56, 0xf8, 0xb9, 0x1f, 0x53, 0xf8, 0x72, - 0x64, 0xc6, 0x69, 0xf9, 0x09, 0xad, 0x07, 0x2b, 0x53, 0xff, 0x8f, 0x4e, 0xcb, 0x93, 0x47, 0x37, - 0xaf, 0x31, 0x7e, 0x69, 0x6c, 0xbc, 0x07, 0x80, 0xdf, 0x90, 0x80, 0x80, 0xe8, 0x33, 0x67, 0x29, - 0x9a, 0xde, 0x71, 0x38, 0x80, 0xc1, 0x3f, 0x3f, 0xdf, 0x80, 0x4f, 0xd2, 0xbb, 0x1f, 0x25, 0x7a, - 0x09, 0x78, 0x78, 0xe5, 0x22, 0x97, 0x62, 0x4c, 0xa1, 0x9e, 0x3b, 0xe4, 0x6d, 0x13, 0x78, 0x06, - 0xe4, 0x9a, 0x93, 0xa9, 0x0d, 0xd7, 0xe0, 0xad, 0x14, 0x38, 0x89, 0xa8, 0x53, 0x79, 0x9a, 0xf7, - 0xdb, 0x03, 0xc7, 0xfb, 0x41, 0x52, 0xf0, 0xa6, 0xf0, 0x73, 0x3b, 0xf0, 0x5b, 0xdb, 0xcb, 0x8b, - 0x1b, 0x0f, 0xee, 0x31, 0xa7, 0x12, 0x91, 0xe9, 0x99, 0x3e, 0x96, 0x90, 0xe1, 0x16, 0x13, 0x4d, - 0x1a, 0x97, 0xa0, 0xc8, 0xd1, 0x89, 0x28, 0x02, 0xb5, 0x83, 0x80, 0xc4, 0x04, 0x04, 0x2e, 0x95, - 0x2c, 0x92, 0x4c, 0x19, 0xc8, 0x72, 0x0a, 0x2a, 0x9a, 0x20, 0x20, 0xa8, 0x72, 0x1d, 0x02, 0x58, - 0xe8, 0xc0, 0x21, 0x14, 0x35, 0xa8, 0x90, 0x84, 0x3b, 0x70, 0xfd, 0xe9, 0x15, 0x14, 0x03, 0x4c, - 0x30, 0xc9, 0x6d, 0x74, 0x6b, 0x6b, 0x2b, 0x22, 0x22, 0x22, 0x2c, 0x2c, 0x6c, 0x73, 0x73, 0x93, - 0xa6, 0x09, 0xbc, 0xe3, 0x03, 0xd1, 0x46, 0x38, 0x4d, 0x74, 0x74, 0xb4, 0x5c, 0x2e, 0x0f, 0x19, - 0x7b, 0x50, 0x48, 0xb2, 0x03, 0x10, 0xce, 0xe5, 0x72, 0xc1, 0xb7, 0x58, 0x8c, 0x5e, 0x99, 0x80, - 0x0c, 0x04, 0x86, 0x6c, 0x02, 0x81, 0x0e, 0x8c, 0x8e, 0x8e, 0x36, 0x35, 0x35, 0xc1, 0xb2, 0x61, - 0x93, 0x55, 0x54, 0x54, 0xd4, 0xd5, 0xd5, 0xb1, 0x43, 0x30, 0x7a, 0x7b, 0x7b, 0xbb, 0xba, 0xba, - 0xfa, 0xfb, 0xfb, 0x2d, 0x16, 0x8b, 0x56, 0xab, 0x85, 0xc5, 0x96, 0x94, 0x94, 0xd4, 0xd7, 0xd7, - 0xc7, 0xc5, 0xf0, 0xb3, 0xc9, 0x08, 0x18, 0x1e, 0x1e, 0xe6, 0xa6, 0x4f, 0x4b, 0x4b, 0xe3, 0x0e, - 0x07, 0x07, 0x07, 0xcb, 0xcb, 0x77, 0xcf, 0x51, 0xf4, 0x7a, 0xbd, 0xd3, 0xe9, 0x84, 0x21, 0xfc, - 0x00, 0xb3, 0xdb, 0xed, 0x5c, 0x0c, 0x6f, 0x9b, 0x80, 0x80, 0xda, 0xda, 0xda, 0xfc, 0xfc, 0x7c, - 0xab, 0xd5, 0x0a, 0x24, 0x3a, 0x3b, 0x3b, 0xbb, 0xbb, 0xbb, 0x3d, 0xd8, 0x18, 0x0c, 0x06, 0xf0, - 0x40, 0xe1, 0xa1, 0x03, 0x60, 0xcc, 0xcf, 0xcf, 0x37, 0x37, 0x37, 0x83, 0x12, 0x0f, 0x18, 0xbf, - 0x21, 0x01, 0x01, 0xf0, 0xd4, 0x96, 0x95, 0x95, 0x31, 0xe9, 0xc7, 0xc7, 0xc7, 0xbd, 0x79, 0x14, - 0x14, 0x14, 0x80, 0x73, 0x7a, 0x7a, 0x3a, 0x2b, 0x2b, 0xab, 0xa4, 0xa4, 0x24, 0x3b, 0x3b, 0xbb, - 0xb1, 0xb1, 0x51, 0xa3, 0xd1, 0x78, 0x23, 0xf9, 0x78, 0x90, 0x07, 0x2f, 0x41, 0x01, 0x1a, 0x1a, - 0x1a, 0x80, 0x44, 0x65, 0x65, 0x25, 0x77, 0x16, 0xac, 0x16, 0x9d, 0x6e, 0xdf, 0xa1, 0x1d, 0x45, - 0x51, 0x35, 0x35, 0x35, 0x5c, 0x0c, 0x6f, 0x1b, 0xbd, 0x5d, 0xf0, 0xa9, 0xca, 0xfe, 0x39, 0xb0, - 0xab, 0x0e, 0x0c, 0x0c, 0x18, 0x8d, 0xc6, 0xfa, 0xfa, 0xfa, 0xe2, 0xe2, 0x62, 0x89, 0x44, 0x02, - 0x74, 0x3b, 0x3a, 0x3a, 0xe6, 0xe6, 0xdc, 0x67, 0x44, 0xfb, 0x67, 0x04, 0x31, 0x0a, 0x85, 0x80, - 0xb6, 0xb6, 0x36, 0xd8, 0x73, 0x60, 0x9b, 0x6a, 0x6d, 0x6d, 0x1d, 0x19, 0x19, 0x99, 0x99, 0x99, - 0x91, 0xc9, 0x64, 0xa0, 0x61, 0x68, 0x68, 0x28, 0x08, 0xa6, 0x07, 0x40, 0x09, 0x3c, 0x03, 0x07, - 0x44, 0x76, 0xbb, 0xa1, 0xd2, 0x26, 0x93, 0xa9, 0xb4, 0xb4, 0x14, 0x96, 0x4d, 0x6e, 0x6e, 0xee, - 0xe4, 0xe4, 0xa4, 0xcd, 0x66, 0x83, 0x97, 0x00, 0x3c, 0xfa, 0x6e, 0x10, 0x5f, 0x8b, 0xb0, 0x00, - 0x60, 0xe6, 0xcd, 0x44, 0xa1, 0x50, 0xc0, 0xa2, 0x87, 0x85, 0xd4, 0xde, 0xbe, 0xf7, 0x3f, 0x38, - 0x2e, 0x2e, 0xae, 0xa5, 0xa5, 0x25, 0x33, 0x73, 0xf7, 0x60, 0x18, 0xf3, 0x22, 0x2c, 0x00, 0xb6, - 0x48, 0x20, 0x94, 0x90, 0x90, 0xc0, 0xa5, 0x05, 0x4f, 0x76, 0x75, 0x75, 0x75, 0x4a, 0x4a, 0xca, - 0xec, 0xec, 0xec, 0xda, 0xda, 0x9a, 0x4a, 0xa5, 0x4a, 0x4e, 0x4e, 0x96, 0x4a, 0x09, 0x9c, 0x2b, - 0x42, 0x16, 0x02, 0x02, 0x7a, 0x7a, 0x7a, 0x26, 0x26, 0x26, 0xd4, 0x6a, 0x35, 0xec, 0xa1, 0xcc, - 0xcb, 0xb5, 0xa8, 0xa8, 0x88, 0x2b, 0xe0, 0xd8, 0xd3, 0x0b, 0x3c, 0xe9, 0xe9, 0xe9, 0x5c, 0x3f, - 0x19, 0x9b, 0xf7, 0xfe, 0xc5, 0x4e, 0x64, 0xde, 0xb2, 0x2c, 0x9b, 0xaa, 0xaa, 0x2a, 0xf6, 0x56, - 0x08, 0x0c, 0x02, 0x3f, 0xe6, 0x96, 0x97, 0x97, 0x61, 0x3f, 0x81, 0xc5, 0xa3, 0x54, 0x2a, 0xf3, - 0xf2, 0xf2, 0x72, 0x72, 0x72, 0x58, 0x31, 0x21, 0x30, 0x08, 0x08, 0x08, 0x01, 0x4b, 0x3f, 0x29, - 0x42, 0xf1, 0x1e, 0xf0, 0x93, 0x1e, 0xff, 0x96, 0x20, 0x00, 0xbf, 0x86, 0x78, 0x11, 0x84, 0x0e, - 0xe0, 0xd5, 0x0f, 0x7f, 0xb6, 0xd0, 0x01, 0xfc, 0x1a, 0xe2, 0x45, 0x38, 0xf2, 0x1d, 0xf8, 0x0f, - 0x1c, 0x65, 0x73, 0xb3, 0xdd, 0xbe, 0x50, 0xc7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, - 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXJSIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0b, 0x56, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x6b, 0x6c, 0x14, 0xc7, 0xf9, 0xbb, 0xf3, 0xf9, 0x89, 0x0d, 0x7e, 0xc7, 0x02, 0x0a, 0x85, - 0x26, 0xa9, 0x04, 0x49, 0x4a, 0x69, 0x6d, 0x41, 0x84, 0x30, 0xd8, 0x16, 0x21, 0xe1, 0x51, 0x89, - 0xd6, 0x32, 0x8f, 0x52, 0x35, 0xf4, 0x87, 0x8d, 0x94, 0x54, 0xfd, 0x51, 0x54, 0x14, 0xaa, 0x2a, - 0x15, 0x34, 0xa8, 0x85, 0x16, 0x45, 0xa8, 0x56, 0x5c, 0x29, 0x45, 0x40, 0x91, 0x6a, 0x70, 0x48, - 0x7e, 0x14, 0xa2, 0xd0, 0x40, 0x51, 0xc1, 0x55, 0x15, 0x5a, 0x09, 0x1c, 0x6a, 0x51, 0xd3, 0x18, - 0x81, 0x0d, 0xc6, 0x36, 0x06, 0xe3, 0xf7, 0xe3, 0x7c, 0xdb, 0xf9, 0xd6, 0xec, 0xdc, 0x3e, 0x66, - 0x6f, 0x5f, 0xb3, 0x77, 0x7b, 0x64, 0x47, 0xb2, 0xf7, 0x9b, 0x6f, 0xbe, 0xf7, 0xb7, 0x33, 0x3b, - 0xbb, 0x3b, 0xb3, 0x17, 0x10, 0x48, 0x01, 0x0b, 0x25, 0x68, 0x81, 0x56, 0x24, 0x65, 0x32, 0x74, - 0x7f, 0x2b, 0x20, 0x36, 0x4a, 0x47, 0x85, 0x50, 0x34, 0x49, 0xaf, 0x4c, 0x75, 0x77, 0x68, 0x9a, - 0x40, 0x8d, 0xb9, 0xbf, 0x54, 0x89, 0x52, 0xd7, 0x95, 0xad, 0x2a, 0x6e, 0x96, 0x06, 0xa6, 0x0f, - 0xc3, 0xf5, 0x3f, 0x17, 0xcd, 0x1e, 0x6d, 0x7a, 0x4f, 0x61, 0x3e, 0x56, 0x02, 0x28, 0x54, 0x83, - 0x8d, 0x81, 0x60, 0x6a, 0x88, 0x41, 0x0f, 0x4c, 0x86, 0x40, 0x60, 0x3a, 0xac, 0xd2, 0x51, 0x2e, - 0x80, 0xc9, 0x20, 0x11, 0xb0, 0xac, 0x65, 0x32, 0xb0, 0x08, 0x25, 0x21, 0x09, 0x70, 0xfa, 0xf1, - 0xae, 0xef, 0x4a, 0xda, 0x21, 0xf2, 0xa0, 0x8b, 0xc2, 0x14, 0xc0, 0x3c, 0xc8, 0x8b, 0xfc, 0x54, - 0x90, 0xc3, 0x12, 0x8d, 0xc6, 0xe9, 0xac, 0xcd, 0x6f, 0x52, 0x61, 0x29, 0x05, 0xcf, 0x50, 0x98, - 0x02, 0x12, 0xa7, 0x74, 0x94, 0x4b, 0x95, 0xc3, 0x52, 0xbb, 0x36, 0x4a, 0x93, 0xe3, 0x00, 0xa9, - 0xe9, 0x54, 0xa0, 0x1a, 0xd0, 0x32, 0xa8, 0x29, 0x54, 0x75, 0x8d, 0x0f, 0xaa, 0x76, 0x4d, 0x55, - 0x97, 0x61, 0xd5, 0xaa, 0x55, 0x10, 0x0a, 0x85, 0x34, 0x0c, 0x9a, 0x0e, 0xb4, 0x75, 0xeb, 0x56, - 0xc9, 0x3f, 0xe6, 0xd1, 0xb2, 0x0f, 0x96, 0x19, 0xb4, 0x36, 0xc6, 0xc6, 0xe8, 0xfa, 0x1c, 0x9b, - 0xcd, 0x7c, 0xab, 0x29, 0x05, 0xac, 0xf1, 0x6f, 0xf0, 0x37, 0x6f, 0x00, 0x0b, 0xaf, 0x56, 0x6d, - 0x4a, 0x81, 0x9a, 0x09, 0xeb, 0x39, 0x3f, 0x7d, 0x97, 0x85, 0xd6, 0xe0, 0x6c, 0x2b, 0x60, 0xf6, - 0x44, 0x8d, 0x78, 0x60, 0x8f, 0x61, 0x0c, 0x3a, 0x18, 0xd8, 0xb3, 0x55, 0x81, 0x7e, 0xb0, 0x61, - 0x81, 0xa2, 0xae, 0x57, 0xf1, 0xce, 0x59, 0xc4, 0x1a, 0x91, 0xf5, 0xac, 0x96, 0xe3, 0x4d, 0xe5, - 0x60, 0xfd, 0xfa, 0xf5, 0x72, 0x1e, 0x40, 0x65, 0xa3, 0xa3, 0xa3, 0xb0, 0x61, 0xc3, 0x06, 0x05, - 0x9e, 0x59, 0x61, 0xf6, 0x57, 0x06, 0x92, 0x30, 0x53, 0x2c, 0xc2, 0x69, 0x69, 0x69, 0xc2, 0xd2, - 0xa5, 0x4b, 0x29, 0x4e, 0x0f, 0xf0, 0x4e, 0x0e, 0x98, 0xee, 0x9b, 0x40, 0x26, 0xbf, 0x07, 0xa6, - 0xce, 0x22, 0x13, 0x91, 0xd0, 0x25, 0xf1, 0x86, 0x02, 0x1c, 0x35, 0x7b, 0x4a, 0x53, 0xa8, 0x95, - 0x58, 0x37, 0x33, 0x92, 0x22, 0x83, 0xa1, 0x07, 0x3d, 0xcb, 0xa6, 0x2f, 0xd1, 0xc5, 0x57, 0xa6, - 0xa8, 0x82, 0x67, 0xfe, 0x6d, 0x7e, 0x92, 0x67, 0xa8, 0x40, 0x98, 0x9c, 0xa0, 0x82, 0xed, 0x00, - 0x86, 0x0a, 0x50, 0x68, 0x20, 0x33, 0x8b, 0x29, 0x7b, 0xe2, 0x1f, 0x1f, 0x33, 0xf1, 0x0a, 0xa4, - 0x5e, 0x17, 0x47, 0xfc, 0x78, 0xf3, 0x59, 0x81, 0x35, 0xdd, 0xc1, 0x36, 0x9c, 0x52, 0xeb, 0xb5, - 0x61, 0xbb, 0x54, 0xa2, 0x03, 0x8c, 0x84, 0x51, 0x1d, 0x51, 0x08, 0x4b, 0x10, 0xe2, 0x22, 0x43, - 0x8f, 0x55, 0xd4, 0xda, 0xaa, 0xa9, 0x10, 0x29, 0x5c, 0x96, 0x55, 0x02, 0x33, 0x66, 0xca, 0x6a, - 0x6c, 0xd0, 0x50, 0x41, 0xe8, 0xd9, 0x17, 0x44, 0xce, 0xe1, 0xf7, 0x7e, 0x41, 0x25, 0x48, 0x37, - 0x12, 0x14, 0x11, 0x03, 0x30, 0x54, 0x50, 0xd0, 0xf8, 0x39, 0x64, 0xd7, 0xbe, 0xad, 0x11, 0x91, - 0xfb, 0xbb, 0x8f, 0x34, 0x38, 0x16, 0xe2, 0x4b, 0x32, 0xd8, 0x91, 0x73, 0x83, 0xe5, 0xbd, 0x29, - 0x9c, 0x61, 0x0e, 0x50, 0x8a, 0xdd, 0x0b, 0x3e, 0xf2, 0x1a, 0x2a, 0xd8, 0xbb, 0x77, 0x2f, 0xe0, - 0x45, 0x3f, 0x23, 0x23, 0x03, 0xe9, 0xa9, 0xb2, 0xec, 0xec, 0x6c, 0xb1, 0x6e, 0xf4, 0xcf, 0x74, - 0x92, 0x51, 0xc1, 0xd8, 0xd8, 0x98, 0x28, 0x4f, 0xf2, 0xc8, 0x4c, 0xe8, 0x0c, 0x3d, 0x50, 0x5b, - 0x28, 0x09, 0x57, 0xe3, 0xf5, 0xea, 0x8c, 0x7b, 0x12, 0x25, 0xe9, 0xf2, 0xe5, 0xcb, 0x61, 0x60, - 0x60, 0x00, 0xea, 0xeb, 0xeb, 0xc5, 0x06, 0x33, 0x56, 0xcb, 0x25, 0x98, 0x0e, 0x91, 0x9c, 0xc9, - 0x0a, 0x6c, 0x39, 0x44, 0x56, 0x84, 0x23, 0xad, 0xeb, 0x0a, 0x5c, 0x0f, 0x91, 0x55, 0x8f, 0xad, - 0xd2, 0xbb, 0x1e, 0x21, 0xab, 0x06, 0x59, 0xa5, 0xf7, 0x1d, 0xb0, 0x1a, 0x31, 0xde, 0xf4, 0x86, - 0xe3, 0x90, 0x19, 0x85, 0xc3, 0xf5, 0x7b, 0x60, 0xe8, 0xfd, 0x77, 0x28, 0x69, 0x20, 0x18, 0x04, - 0xf9, 0x34, 0x53, 0x6a, 0x50, 0xcf, 0x65, 0xad, 0x4c, 0x3f, 0x25, 0x19, 0xea, 0x23, 0x97, 0x4e, - 0x2c, 0x37, 0xcc, 0xc8, 0xa8, 0x48, 0x77, 0x07, 0xf4, 0xbe, 0x36, 0x4f, 0xb4, 0xc3, 0x88, 0x56, - 0x6d, 0x2c, 0xab, 0x1e, 0xff, 0x3e, 0xf0, 0xe4, 0x21, 0x2b, 0xcb, 0x18, 0x3b, 0x38, 0x47, 0x0e, - 0x4c, 0xdd, 0x6d, 0x87, 0xde, 0x95, 0xd1, 0x89, 0x69, 0xde, 0xef, 0x3f, 0x31, 0xb4, 0x21, 0x58, - 0x3c, 0x97, 0xce, 0x18, 0x30, 0x73, 0x83, 0xef, 0xd4, 0x19, 0xf2, 0xc4, 0x22, 0x70, 0xe4, 0x40, - 0xca, 0x9c, 0x85, 0x90, 0xfb, 0xee, 0x5f, 0xa8, 0xfc, 0x91, 0x3f, 0xfd, 0x96, 0xc2, 0xb1, 0x00, - 0xe9, 0x7a, 0x1e, 0xcc, 0x2b, 0x84, 0x9c, 0xb7, 0xb4, 0x4f, 0xe0, 0x63, 0xf1, 0xaa, 0xdb, 0xe2, - 0xdf, 0x07, 0x7a, 0x3a, 0xa1, 0xf7, 0xd5, 0xaf, 0x88, 0x76, 0x24, 0x65, 0x1f, 0x10, 0x46, 0x86, - 0xd4, 0x41, 0x74, 0x54, 0xe7, 0x92, 0x81, 0xc8, 0x83, 0x7b, 0xd0, 0xfb, 0xca, 0x1c, 0x6a, 0x88, - 0x99, 0x61, 0x14, 0x1f, 0xe9, 0x17, 0x9e, 0xbb, 0x4f, 0x79, 0xec, 0x02, 0x5c, 0x1c, 0xb0, 0xab, - 0x9c, 0x07, 0x9f, 0xa3, 0x4e, 0xcc, 0xc3, 0x00, 0xa7, 0x32, 0x7c, 0x07, 0xe4, 0x11, 0xec, 0xe8, - 0xe8, 0x10, 0xc7, 0xf8, 0xc1, 0xc1, 0x41, 0x39, 0xda, 0x55, 0x98, 0x4b, 0x06, 0xf0, 0x16, 0x16, - 0x6f, 0x06, 0xe7, 0xcd, 0x9b, 0x9e, 0x22, 0xcc, 0x9f, 0x3f, 0x5f, 0x61, 0xf4, 0xad, 0x5b, 0xb7, - 0xc4, 0x76, 0xa4, 0xc1, 0x3f, 0x7c, 0x3d, 0xb5, 0x69, 0xd3, 0x26, 0x05, 0x8d, 0xed, 0x0a, 0xb9, - 0xa8, 0x70, 0x2d, 0xc4, 0x10, 0x21, 0x3d, 0x3d, 0x5d, 0x21, 0x13, 0x71, 0xf8, 0x47, 0x0c, 0x17, - 0x36, 0x6f, 0xde, 0x2c, 0x5c, 0xbe, 0x7c, 0x59, 0xd1, 0xee, 0xa4, 0x62, 0xf8, 0x00, 0xcd, 0xaa, - 0x70, 0x3d, 0x07, 0x4e, 0x9d, 0x3a, 0x45, 0x45, 0xe5, 0xe6, 0xe6, 0x8a, 0x0e, 0x51, 0x84, 0x03, - 0x80, 0xcb, 0x74, 0x9a, 0x18, 0xad, 0x28, 0x73, 0xe7, 0xce, 0x55, 0xd4, 0xcf, 0x9f, 0x3f, 0x0f, - 0x15, 0x15, 0x15, 0x70, 0xf1, 0xe2, 0x45, 0xc0, 0xfe, 0x71, 0xe7, 0xce, 0x1d, 0xc8, 0xc9, 0xc9, - 0x51, 0xd0, 0xd8, 0xae, 0x38, 0x70, 0x9e, 0xb2, 0xce, 0x9c, 0x39, 0x53, 0x8c, 0x28, 0x31, 0x42, - 0x38, 0x74, 0xe8, 0x10, 0xc5, 0xc7, 0x03, 0xf0, 0x2f, 0x64, 0xb6, 0x53, 0xcf, 0x89, 0x91, 0xcb, - 0x30, 0xca, 0xc9, 0x16, 0x5b, 0x62, 0xfc, 0x53, 0xc8, 0x56, 0xd8, 0x38, 0x32, 0x25, 0xfd, 0x29, - 0xe4, 0x3b, 0xc0, 0xf1, 0x6c, 0xb0, 0x25, 0xca, 0xcf, 0x80, 0xad, 0xb0, 0x71, 0x64, 0x4a, 0xfa, - 0x0c, 0x70, 0x99, 0xcc, 0xa9, 0x6f, 0xea, 0x59, 0x8f, 0x4b, 0xe4, 0x8f, 0x1f, 0x33, 0xaa, 0xbe, - 0x07, 0xb3, 0x7e, 0x7d, 0x8a, 0x4b, 0x1e, 0xb8, 0x64, 0x40, 0xfe, 0x44, 0xc2, 0x8c, 0x55, 0x63, - 0x9f, 0x36, 0x81, 0xfc, 0xed, 0xb0, 0x19, 0x1e, 0x3d, 0x1a, 0x0e, 0x0e, 0xe0, 0x44, 0x74, 0xba, - 0x64, 0x6d, 0xf9, 0x31, 0xb0, 0xa2, 0x8f, 0xad, 0x88, 0x97, 0xb7, 0x0d, 0x1f, 0x3b, 0xf0, 0x84, - 0xcb, 0xd9, 0xc1, 0xb9, 0x03, 0x91, 0x08, 0xb5, 0x60, 0xc6, 0x0f, 0x7f, 0x46, 0x61, 0x23, 0x40, - 0x18, 0x9f, 0x7e, 0xe9, 0x69, 0x44, 0x67, 0xd4, 0xee, 0xdc, 0x01, 0x85, 0x86, 0xe9, 0xe5, 0xbd, - 0x0a, 0x94, 0xcb, 0x15, 0xce, 0x0e, 0xb8, 0x6c, 0x2d, 0x43, 0xbc, 0x63, 0x07, 0x26, 0x9a, 0xa3, - 0x4b, 0x63, 0x82, 0xac, 0x15, 0xc0, 0x2a, 0xa5, 0x81, 0x8c, 0x4c, 0x15, 0xc6, 0x59, 0xd5, 0x91, - 0x03, 0xf8, 0x6c, 0xff, 0xd1, 0x4f, 0xa6, 0x97, 0x01, 0xe2, 0xf3, 0x50, 0x08, 0x18, 0x8b, 0xcb, - 0x3d, 0xf0, 0x01, 0xb5, 0xb8, 0xb7, 0x7c, 0x16, 0x4c, 0x75, 0xdc, 0xa4, 0x75, 0x3b, 0x80, 0xb1, - 0xc6, 0x18, 0x52, 0x47, 0x3e, 0x68, 0x10, 0x5b, 0x53, 0x0a, 0x4b, 0xa0, 0xf0, 0xe3, 0x8e, 0x18, - 0x94, 0xd1, 0xa6, 0xb4, 0x97, 0x5f, 0x85, 0xac, 0x9a, 0x37, 0x44, 0x44, 0x64, 0x68, 0x00, 0xc2, - 0xed, 0xad, 0xd1, 0x46, 0x1b, 0x90, 0xe3, 0x1b, 0x9a, 0xde, 0xca, 0x42, 0x88, 0xf4, 0xf7, 0x89, - 0xaa, 0xe5, 0xc3, 0xa4, 0x9e, 0x2d, 0xfd, 0x3b, 0xab, 0x60, 0xfc, 0xb3, 0xf3, 0x62, 0x73, 0xfe, - 0xfb, 0x97, 0x20, 0x75, 0xc9, 0x0a, 0x3d, 0x52, 0x53, 0x78, 0x47, 0x19, 0x40, 0x0d, 0x85, 0x1f, - 0xb6, 0x51, 0x45, 0x66, 0x56, 0xf7, 0x4a, 0xc6, 0x23, 0x93, 0x53, 0xe3, 0x51, 0x86, 0x63, 0x07, - 0x02, 0xd9, 0xb3, 0x50, 0x4e, 0xc2, 0x8a, 0x63, 0x07, 0x12, 0x66, 0xf9, 0x13, 0xc5, 0x5c, 0x1d, - 0x10, 0x46, 0xf9, 0xbe, 0x3e, 0x32, 0x13, 0x1c, 0xe7, 0x0e, 0x04, 0xa3, 0x2b, 0x4b, 0xfb, 0xaa, - 0x17, 0x83, 0xde, 0xb2, 0x3d, 0xc4, 0x3f, 0x7e, 0x6b, 0x0b, 0xb5, 0x29, 0xf5, 0xf9, 0x6f, 0x50, - 0xd8, 0x09, 0xe0, 0x78, 0x14, 0x42, 0xe5, 0xbd, 0x55, 0xc5, 0x10, 0x79, 0xd4, 0x4b, 0xed, 0x60, - 0x8d, 0x46, 0xf2, 0xe9, 0x34, 0x12, 0x16, 0x9d, 0xeb, 0x82, 0x60, 0x41, 0x09, 0xe5, 0xb1, 0x0b, - 0x70, 0xb9, 0x1f, 0x28, 0xfa, 0xb4, 0x07, 0xc6, 0x2f, 0x7e, 0x04, 0xe1, 0xd6, 0x7f, 0xe9, 0xda, - 0x91, 0xfd, 0xa3, 0x3d, 0xd3, 0x6d, 0xa9, 0x69, 0x30, 0xe3, 0xf5, 0xdd, 0x00, 0xa1, 0x34, 0x5d, - 0x5a, 0x2b, 0x0d, 0x5c, 0x32, 0x60, 0x45, 0x21, 0x6f, 0x5a, 0xe7, 0x7d, 0x80, 0xb7, 0x45, 0x16, - 0xe5, 0xf9, 0x0e, 0x58, 0x0c, 0x18, 0x77, 0x72, 0x3f, 0x03, 0xf2, 0x90, 0xae, 0x58, 0xb1, 0x02, - 0x96, 0x2d, 0x5b, 0x26, 0x47, 0xb9, 0x0e, 0x73, 0x1d, 0x85, 0xa4, 0x75, 0xb7, 0xe4, 0xd5, 0x92, - 0xeb, 0x86, 0x4b, 0x0a, 0xb8, 0x5c, 0x07, 0x24, 0x61, 0xf1, 0x34, 0x5c, 0xd2, 0xe9, 0xb8, 0x0f, - 0x48, 0x6f, 0xe7, 0xa5, 0x97, 0xd8, 0x52, 0x16, 0x24, 0x05, 0x78, 0x5c, 0xbd, 0x7a, 0xb5, 0xe2, - 0x45, 0x37, 0x8b, 0x46, 0x4e, 0x6f, 0x09, 0x76, 0xfa, 0x26, 0x71, 0x72, 0x72, 0x52, 0xd8, 0xb8, - 0x71, 0xa3, 0xb0, 0x6e, 0xdd, 0x3a, 0xa1, 0xb4, 0xb4, 0x54, 0xf3, 0xfe, 0xf7, 0xd2, 0xa5, 0x4b, - 0x22, 0xee, 0xcc, 0x99, 0x33, 0xa2, 0xaa, 0xfd, 0xfb, 0xf7, 0x6b, 0x68, 0x9c, 0xd8, 0xc0, 0xf5, - 0x45, 0xf7, 0xd9, 0xb3, 0x67, 0x35, 0xc6, 0x5d, 0xbd, 0x7a, 0x55, 0xc4, 0x91, 0xa8, 0x8a, 0xbb, - 0xdc, 0x0e, 0x1e, 0x3c, 0x28, 0x84, 0xc3, 0x61, 0x27, 0x36, 0x2b, 0x78, 0x5d, 0x77, 0x00, 0xb5, - 0x35, 0x35, 0x35, 0x09, 0x64, 0x05, 0x3f, 0x75, 0x04, 0x9d, 0x69, 0x6e, 0x6e, 0x56, 0x18, 0x62, - 0xb7, 0xe2, 0xb8, 0x0f, 0x18, 0x9d, 0xaf, 0x57, 0xae, 0x5c, 0x81, 0xed, 0xdb, 0xb7, 0x8b, 0x1b, - 0x19, 0x89, 0x91, 0x70, 0xf7, 0xee, 0x5d, 0x91, 0xe5, 0xe8, 0xd1, 0xa3, 0x46, 0xac, 0xa6, 0xda, - 0xb9, 0x8e, 0x42, 0x11, 0xd9, 0x63, 0x46, 0x49, 0xfb, 0x8d, 0x1b, 0x37, 0x44, 0xe3, 0xb1, 0xe3, - 0xe2, 0x2a, 0x15, 0x72, 0xfa, 0x88, 0x4d, 0xe4, 0x8d, 0xbe, 0x44, 0xe2, 0xe8, 0xc8, 0xd5, 0x01, - 0x34, 0x56, 0x5d, 0xb6, 0x6d, 0xdb, 0x26, 0x5e, 0xdc, 0x32, 0x33, 0x33, 0x01, 0xb3, 0xb1, 0x60, - 0xc1, 0x02, 0x58, 0xb2, 0x64, 0x89, 0x9a, 0xcc, 0x7e, 0xdd, 0xee, 0xb9, 0x27, 0xf1, 0x9d, 0x3e, - 0x7d, 0x5a, 0xa8, 0xac, 0xac, 0x14, 0x76, 0xec, 0xd8, 0x41, 0xcf, 0x71, 0xa9, 0x2d, 0x1e, 0x47, - 0x2e, 0x19, 0xc0, 0xd5, 0x28, 0x58, 0x4a, 0x4a, 0x4a, 0xe0, 0xf6, 0xed, 0xdb, 0xf6, 0xa3, 0x69, - 0x83, 0x93, 0xeb, 0x54, 0xc2, 0x86, 0x7e, 0xc7, 0x2c, 0xae, 0x8f, 0x42, 0x8e, 0x2d, 0x34, 0x10, - 0xe0, 0x3b, 0x60, 0x10, 0x20, 0xd7, 0x9b, 0xfd, 0x0c, 0xb8, 0x1e, 0x62, 0x03, 0x05, 0x49, 0x3f, - 0x0a, 0x19, 0xf8, 0xe7, 0xf9, 0xe6, 0xa4, 0xef, 0x02, 0x9e, 0x8f, 0xb0, 0x81, 0x81, 0x7e, 0x02, - 0x0c, 0x02, 0xe4, 0x76, 0xb3, 0x9f, 0x00, 0xb7, 0x23, 0x6c, 0x20, 0xdf, 0x4f, 0x80, 0x41, 0x80, - 0xdc, 0x6e, 0xf6, 0x13, 0xe0, 0x76, 0x84, 0x0d, 0xe4, 0xfb, 0x09, 0x30, 0x08, 0x90, 0xdb, 0xcd, - 0x5c, 0xee, 0xe6, 0x79, 0x1b, 0x89, 0xbb, 0xa5, 0xc3, 0x37, 0x5b, 0x40, 0x08, 0x4f, 0x46, 0x45, - 0x93, 0x07, 0x4a, 0xe9, 0xe5, 0xdf, 0x89, 0xd6, 0x63, 0x40, 0xf8, 0xaa, 0x54, 0x5e, 0x02, 0xa1, - 0x54, 0x08, 0x91, 0x17, 0xd2, 0xb8, 0x07, 0xd8, 0x6b, 0xc5, 0x3b, 0xf7, 0x01, 0x63, 0x23, 0xd0, - 0xf7, 0x83, 0x32, 0x08, 0x7f, 0xf1, 0x1f, 0x66, 0x8c, 0xf4, 0x36, 0x96, 0xb2, 0x88, 0xd5, 0x2f, - 0xd3, 0xe5, 0x34, 0xa9, 0xcf, 0xbd, 0x04, 0xf9, 0x47, 0xff, 0x09, 0x90, 0xce, 0x77, 0xc5, 0x98, - 0x5c, 0x87, 0x15, 0xd8, 0x33, 0x3d, 0xe0, 0x61, 0x5d, 0x05, 0x33, 0xf8, 0xa1, 0xf9, 0xcf, 0x03, - 0x6e, 0x18, 0x07, 0x5c, 0xc9, 0x66, 0xb2, 0xa4, 0xbf, 0xbc, 0x56, 0xa4, 0x9c, 0xea, 0xfc, 0x02, - 0xc2, 0x77, 0x94, 0x2b, 0xd9, 0x26, 0x49, 0xcf, 0x7a, 0x44, 0xd6, 0x5a, 0xe5, 0xfd, 0xb1, 0xd9, - 0xa4, 0x34, 0x77, 0xc9, 0xbc, 0xd1, 0x03, 0x22, 0x53, 0xd0, 0x5d, 0xaa, 0x3d, 0x17, 0x0a, 0x1a, - 0x5b, 0x20, 0xf4, 0xec, 0x8b, 0x8e, 0x22, 0x10, 0x6e, 0xbb, 0x0a, 0x7d, 0x5b, 0xbe, 0xa9, 0x91, - 0xc1, 0x5a, 0x86, 0xa2, 0x21, 0x8a, 0x03, 0xc2, 0xfc, 0x69, 0x15, 0x07, 0x63, 0xd4, 0x2a, 0x82, - 0xb9, 0x85, 0x6a, 0x94, 0xe5, 0x3a, 0x0f, 0x19, 0x96, 0x95, 0x5a, 0x60, 0xf0, 0x74, 0x02, 0x2c, - 0xf8, 0x91, 0xb4, 0xa4, 0x9e, 0x48, 0x80, 0x30, 0x3c, 0xc0, 0x0e, 0x20, 0x99, 0xf9, 0x38, 0x2e, - 0x3a, 0x32, 0x74, 0x75, 0x3a, 0x56, 0x68, 0x4d, 0x40, 0xc2, 0x13, 0x10, 0x79, 0xd8, 0x0d, 0x0f, - 0xb7, 0x97, 0x69, 0xac, 0x4e, 0x7b, 0x69, 0x39, 0x97, 0x65, 0x80, 0xc1, 0xa2, 0x39, 0x90, 0xfa, - 0x82, 0x56, 0xfe, 0xc3, 0xef, 0x7f, 0x1b, 0x84, 0xfe, 0xe8, 0xd2, 0x44, 0x8d, 0x01, 0x71, 0x42, - 0x24, 0xec, 0x22, 0x8c, 0xdf, 0xe0, 0x7c, 0xf4, 0xe6, 0x6b, 0x1a, 0x37, 0x53, 0x9f, 0x7b, 0x11, - 0x66, 0xec, 0xdc, 0x6b, 0x7a, 0xce, 0xaf, 0x11, 0xa0, 0x83, 0x18, 0xff, 0xdb, 0x87, 0x30, 0x44, - 0xbe, 0x43, 0x19, 0xfe, 0xdf, 0x75, 0x0d, 0x05, 0x7e, 0x2e, 0xd2, 0xec, 0x3d, 0x86, 0x86, 0xd9, - 0x21, 0x22, 0x61, 0x3d, 0x20, 0x98, 0x57, 0x04, 0xa1, 0xaf, 0x2d, 0xd6, 0x98, 0x3f, 0x79, 0xf3, - 0x73, 0x18, 0x78, 0xfb, 0x75, 0xc7, 0x1b, 0x21, 0xe4, 0x82, 0xa7, 0x6e, 0xff, 0x17, 0x06, 0x7e, - 0xb9, 0x83, 0x19, 0x7c, 0xb4, 0x21, 0x98, 0xcf, 0xf8, 0xd6, 0xbc, 0x5c, 0x80, 0x8b, 0x70, 0xc2, - 0x7a, 0x80, 0xdc, 0xa7, 0xf1, 0xbf, 0x9e, 0x84, 0xfe, 0xdd, 0x35, 0x72, 0x14, 0x04, 0xb3, 0xb2, - 0xa1, 0xe8, 0xef, 0x8f, 0x4d, 0xed, 0x62, 0x51, 0x30, 0xaa, 0x2b, 0x53, 0x61, 0xe8, 0x21, 0x3b, - 0x5b, 0x84, 0xd1, 0x11, 0x45, 0x4b, 0xee, 0x81, 0x26, 0x48, 0xaf, 0x88, 0xfe, 0xa4, 0x80, 0xa2, - 0x31, 0x8e, 0x95, 0x84, 0xf5, 0x00, 0xb9, 0x8f, 0xe9, 0x95, 0xda, 0x40, 0x44, 0xc8, 0x77, 0x9f, - 0x22, 0x7d, 0xdd, 0x72, 0x32, 0x5b, 0x70, 0xa4, 0xef, 0xbe, 0x26, 0xf8, 0x28, 0xc8, 0x0b, 0xc1, - 0x47, 0x3b, 0x3c, 0x91, 0x00, 0x34, 0xe4, 0xcb, 0x5a, 0xfc, 0x04, 0x24, 0x38, 0xf3, 0xde, 0x48, - 0x00, 0x99, 0xab, 0x8b, 0xbb, 0x16, 0x55, 0xc1, 0x18, 0x3b, 0xd7, 0xa8, 0xc2, 0x58, 0xaf, 0x8e, - 0x7d, 0xf2, 0x67, 0x0d, 0x53, 0x20, 0x25, 0xba, 0xc5, 0x47, 0xd3, 0x18, 0x67, 0x84, 0x27, 0x2e, - 0xc2, 0xe8, 0xf3, 0xe0, 0xaf, 0x6a, 0x61, 0xe4, 0xf4, 0x1f, 0x74, 0xdd, 0xe7, 0xf5, 0x34, 0x14, - 0x15, 0x64, 0x55, 0xef, 0x84, 0x9c, 0xdd, 0xf5, 0xba, 0xba, 0xe2, 0xd9, 0xe0, 0x8d, 0x1e, 0x40, - 0x3c, 0xce, 0xd9, 0xd3, 0x00, 0x05, 0xe4, 0x31, 0x31, 0x3e, 0xfd, 0x74, 0xab, 0x84, 0xbe, 0xfa, - 0x75, 0x28, 0x38, 0xfe, 0x99, 0x67, 0x82, 0x8f, 0x7e, 0x7a, 0xa6, 0x07, 0xb8, 0x15, 0x74, 0xaf, - 0xcb, 0xf5, 0x4c, 0x0f, 0xf0, 0x7a, 0xa0, 0xdc, 0xb2, 0xcf, 0x4f, 0x80, 0x5b, 0x91, 0x35, 0x29, - 0xd7, 0x4f, 0x80, 0xc9, 0x40, 0xb9, 0x45, 0xe6, 0x27, 0xc0, 0xad, 0xc8, 0x9a, 0x94, 0xeb, 0xf9, - 0x04, 0xf4, 0xf7, 0xf7, 0x9b, 0x74, 0x25, 0x39, 0xc9, 0x3c, 0x9b, 0x80, 0x7b, 0xf7, 0xee, 0x89, - 0x1b, 0x14, 0xf3, 0xf2, 0xf2, 0xc4, 0x63, 0x3c, 0x3f, 0x35, 0x1c, 0xcf, 0x54, 0x7a, 0x36, 0x01, - 0xb3, 0x67, 0xcf, 0x86, 0xb5, 0x6b, 0xd7, 0x42, 0x7e, 0x7e, 0xbe, 0xf8, 0x6b, 0x40, 0xdc, 0xbe, - 0x61, 0x1b, 0xcf, 0xe8, 0x9a, 0xd0, 0xe5, 0x99, 0xfb, 0x00, 0xb2, 0xeb, 0x15, 0xda, 0xda, 0xda, - 0x60, 0x6a, 0x2a, 0xfa, 0x13, 0x70, 0x72, 0xfb, 0x8b, 0x8b, 0x8b, 0xc5, 0x6d, 0x5c, 0x72, 0x1c, - 0x0b, 0x6e, 0x69, 0x69, 0x81, 0xeb, 0xd7, 0xaf, 0x43, 0x67, 0x67, 0x27, 0x90, 0x9f, 0x51, 0x14, - 0x79, 0xca, 0xca, 0xca, 0x20, 0x85, 0x3c, 0x7e, 0x38, 0x72, 0xe4, 0x08, 0x54, 0x57, 0x57, 0xc3, - 0xe2, 0xc5, 0xda, 0xf7, 0x10, 0x2c, 0x59, 0x71, 0xc1, 0xc5, 0x63, 0x33, 0x9d, 0x91, 0x8e, 0x0b, - 0x17, 0x2e, 0xd0, 0x4d, 0x7e, 0xc4, 0x69, 0x26, 0xac, 0xfe, 0xd6, 0xb6, 0x5c, 0x26, 0xf9, 0x41, - 0x4c, 0x81, 0x04, 0x95, 0xf2, 0x05, 0x83, 0x41, 0x61, 0xd1, 0xa2, 0x45, 0xc2, 0xca, 0x95, 0x2b, - 0x05, 0xe9, 0x13, 0xd6, 0x92, 0x5c, 0xb2, 0xad, 0x5f, 0xce, 0x9a, 0x70, 0x98, 0xeb, 0x6e, 0x61, - 0xde, 0xde, 0x48, 0xdb, 0xa7, 0x31, 0x78, 0xb1, 0x12, 0x70, 0xec, 0xd8, 0x31, 0x1a, 0x7c, 0xa4, - 0x25, 0x3f, 0x62, 0x26, 0x90, 0x5f, 0xe8, 0x52, 0x98, 0x43, 0x36, 0x40, 0x0a, 0xfb, 0xf6, 0xed, - 0x13, 0xae, 0x5d, 0xbb, 0xa6, 0xc0, 0x27, 0xba, 0xf2, 0x54, 0x24, 0x00, 0x83, 0x58, 0x57, 0x57, - 0xa7, 0x48, 0x82, 0x74, 0xc6, 0xcb, 0x8f, 0x0b, 0x17, 0x2e, 0x14, 0x1a, 0x1b, 0x1b, 0x13, 0x1d, - 0x73, 0x85, 0x7e, 0xcf, 0x5e, 0x84, 0x49, 0xe0, 0x4c, 0x17, 0xe2, 0x91, 0xf8, 0x5b, 0x05, 0xf8, - 0x1b, 0x06, 0x08, 0x8f, 0x8f, 0x8f, 0x03, 0xf9, 0xd0, 0x00, 0x90, 0x9e, 0x01, 0x64, 0x0f, 0x33, - 0xe0, 0x05, 0x1d, 0x4b, 0x7b, 0x7b, 0x3b, 0xd4, 0xd4, 0xd4, 0xc0, 0xae, 0x5d, 0xbb, 0x4c, 0xcb, - 0x76, 0x9d, 0x50, 0x91, 0x0e, 0x8f, 0x55, 0xcc, 0x0e, 0x41, 0xc7, 0x8f, 0x1f, 0xa7, 0x67, 0x3f, - 0x8e, 0xff, 0xb5, 0xb5, 0xb5, 0x42, 0x6b, 0x6b, 0xab, 0x30, 0x31, 0x31, 0x21, 0x90, 0x9f, 0x39, - 0x14, 0x4e, 0x9e, 0x3c, 0x29, 0x90, 0xed, 0xfa, 0x94, 0xa6, 0xa1, 0xa1, 0xc1, 0x33, 0x9e, 0x7a, - 0x7a, 0x08, 0x3a, 0x71, 0xe2, 0x04, 0x0d, 0x1a, 0x7e, 0x71, 0x42, 0xaf, 0x90, 0x9f, 0x5c, 0x10, - 0xe9, 0xc8, 0x4c, 0x47, 0x20, 0x1b, 0xde, 0x29, 0x0f, 0x39, 0x7b, 0x29, 0x4c, 0x3e, 0x37, 0x20, - 0x0e, 0x53, 0x5d, 0x5d, 0x5d, 0x7a, 0x62, 0x12, 0x82, 0xd7, 0xae, 0x88, 0x75, 0xbd, 0xcf, 0x99, - 0x53, 0x80, 0xd3, 0xd2, 0xc3, 0x87, 0x0f, 0x53, 0x62, 0xf2, 0x49, 0x04, 0x0a, 0xab, 0x81, 0xf2, - 0xf2, 0x72, 0x71, 0xe8, 0x51, 0xe3, 0x93, 0xa2, 0x9e, 0x90, 0xb4, 0xab, 0x94, 0xae, 0x59, 0xb3, - 0x86, 0x9e, 0xa9, 0x24, 0x68, 0x1a, 0xb8, 0xaa, 0xaa, 0x4a, 0x20, 0x5f, 0x03, 0x51, 0x71, 0x3d, - 0x1d, 0x55, 0xcf, 0xdc, 0x88, 0xe1, 0xa7, 0x54, 0xf0, 0x46, 0x0c, 0x9f, 0xfd, 0xe0, 0x4f, 0xd4, - 0x92, 0x19, 0x0b, 0x90, 0x39, 0x7c, 0x52, 0x9c, 0xc4, 0x4e, 0x8c, 0xf4, 0x4c, 0x02, 0x9c, 0x38, - 0x91, 0xcc, 0xbc, 0x4f, 0xc5, 0x34, 0xd4, 0x4f, 0x40, 0x32, 0x47, 0x20, 0xc1, 0xb6, 0xfb, 0x3d, - 0xc0, 0x4f, 0x40, 0x82, 0x23, 0x90, 0x60, 0xf5, 0x7e, 0x0f, 0x48, 0x70, 0x02, 0xfe, 0x0f, 0x63, - 0xba, 0xa3, 0x5c, 0x3e, 0x86, 0x45, 0x02, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXPlistIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x33, 0x35, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc8, - 0x4f, 0xd5, 0xc2, 0x00, 0x00, 0x06, 0xa8, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x7b, - 0x4c, 0x53, 0x57, 0x18, 0xb7, 0xef, 0x77, 0x91, 0x87, 0x82, 0x20, 0x68, 0x01, 0xd1, 0xf8, 0x20, - 0x6e, 0x09, 0xd1, 0x44, 0xc1, 0xcc, 0xa0, 0xce, 0x4c, 0x0d, 0xfc, 0xb7, 0x11, 0xa6, 0x93, 0xb0, - 0x65, 0x53, 0x18, 0x31, 0x41, 0xcd, 0x4c, 0x4c, 0x96, 0x25, 0xfe, 0xb3, 0xa0, 0x46, 0x8c, 0x61, - 0x03, 0x5f, 0x7f, 0xb0, 0x31, 0x46, 0x74, 0x31, 0x6e, 0xcb, 0x62, 0x80, 0x6c, 0x73, 0x8a, 0x12, - 0xc5, 0xa0, 0x19, 0xbe, 0x98, 0x48, 0x43, 0x71, 0x56, 0x94, 0xd2, 0x07, 0xa5, 0x94, 0xb6, 0xfb, - 0xe1, 0x71, 0xb7, 0x87, 0xdb, 0xf6, 0xda, 0x7b, 0x5b, 0x75, 0x66, 0xbd, 0x69, 0x9a, 0xef, 0x7c, - 0x8f, 0xdf, 0xf9, 0x5e, 0xe7, 0x3b, 0xed, 0x15, 0xf9, 0x7c, 0xbe, 0x69, 0xaf, 0xf3, 0x23, 0x7e, - 0x9d, 0x9d, 0x9f, 0xf4, 0x3d, 0x16, 0xc0, 0xab, 0xae, 0x60, 0xac, 0x02, 0xb1, 0x0a, 0x44, 0x98, - 0x81, 0x58, 0x0b, 0x45, 0x98, 0xc0, 0x88, 0xcd, 0x63, 0x15, 0x88, 0x38, 0x85, 0x11, 0x02, 0xc4, - 0x2a, 0x10, 0x61, 0x02, 0x23, 0x36, 0x8f, 0x55, 0x20, 0x58, 0x0a, 0x87, 0xdc, 0xde, 0x40, 0xb6, - 0xcd, 0xe3, 0xf3, 0x04, 0x72, 0x23, 0xe6, 0x44, 0xb9, 0x02, 0x5d, 0xd6, 0xf1, 0x0f, 0xba, 0x1f, - 0xcf, 0x6b, 0x37, 0x05, 0x3a, 0xf6, 0xfb, 0xe3, 0xb1, 0xcc, 0x36, 0xd3, 0x97, 0x7f, 0x59, 0x87, - 0x83, 0x85, 0x17, 0xa8, 0x1f, 0x26, 0x47, 0x14, 0x95, 0xff, 0x03, 0x48, 0xed, 0x0f, 0x0f, 0x46, - 0x0f, 0xf5, 0xd9, 0xfe, 0x78, 0x32, 0x86, 0x8d, 0x95, 0x12, 0x91, 0x73, 0x7d, 0x06, 0xcb, 0x83, - 0x9f, 0xcc, 0xce, 0x0d, 0x9d, 0x66, 0x30, 0xd5, 0x12, 0xf1, 0xfb, 0xb3, 0x35, 0x9f, 0x1a, 0x74, - 0x0b, 0xb5, 0x32, 0x96, 0x8e, 0x80, 0xa5, 0x54, 0x80, 0x0d, 0x6d, 0xf2, 0xc4, 0xed, 0x3d, 0x6a, - 0xb4, 0x1f, 0xb9, 0x6f, 0x33, 0x3a, 0x27, 0x68, 0x3e, 0x07, 0x3d, 0xea, 0xf1, 0x7e, 0xdd, 0x6f, - 0xc3, 0xa7, 0x70, 0x86, 0xaa, 0xca, 0xa0, 0x7b, 0x67, 0xa6, 0x4a, 0xc4, 0xa1, 0xfd, 0x3c, 0x91, - 0xf0, 0x00, 0xfe, 0xb4, 0xbb, 0x6b, 0xfb, 0x6c, 0x8d, 0x03, 0x0e, 0x38, 0x44, 0xef, 0x32, 0x4b, - 0x29, 0xdd, 0x9a, 0xae, 0xa1, 0x39, 0x84, 0xce, 0xd5, 0xcb, 0x4b, 0x67, 0x6b, 0x4f, 0x3d, 0x18, - 0x75, 0xfe, 0xab, 0xdf, 0xfa, 0xc8, 0x89, 0x4f, 0xb6, 0x46, 0x56, 0x31, 0x57, 0xb7, 0x35, 0x5d, - 0xab, 0x97, 0x0a, 0x09, 0x84, 0x77, 0x0b, 0xc1, 0xd9, 0x9f, 0xcd, 0x4e, 0x74, 0x0b, 0xf6, 0xa6, - 0xbd, 0x94, 0x89, 0x45, 0x1b, 0x92, 0x55, 0x65, 0xe9, 0xda, 0xf5, 0x33, 0x55, 0x12, 0x5a, 0x30, - 0x95, 0xb6, 0x4c, 0xf8, 0xbe, 0x35, 0x39, 0x8e, 0x1a, 0x6d, 0xd7, 0x46, 0xc6, 0x69, 0x89, 0x4e, - 0x2a, 0x46, 0x0c, 0x95, 0x06, 0x5d, 0xb6, 0x9a, 0x5f, 0x4e, 0x79, 0x07, 0xb0, 0xbe, 0xd3, 0xfc, - 0x8b, 0x79, 0x8a, 0xeb, 0x8b, 0xf5, 0x72, 0xf8, 0x5d, 0x9a, 0xa6, 0x99, 0x21, 0xe7, 0x31, 0x12, - 0xae, 0x59, 0xdd, 0x08, 0x03, 0xc1, 0x58, 0xa8, 0x33, 0x2d, 0x12, 0x89, 0xea, 0x73, 0x13, 0xca, - 0xd3, 0xb5, 0x74, 0x6c, 0xdc, 0x34, 0xbf, 0x70, 0x81, 0x35, 0x34, 0xee, 0x6f, 0x98, 0xe2, 0x59, - 0xea, 0xcf, 0xb2, 0xe3, 0xf2, 0xe2, 0xe4, 0xdc, 0x7b, 0x04, 0x95, 0xbe, 0xa1, 0x97, 0x1d, 0x59, - 0x9c, 0x50, 0xb3, 0x30, 0x1e, 0x4d, 0xf5, 0xc5, 0xdd, 0x91, 0xbb, 0x76, 0x37, 0xd4, 0x30, 0x51, - 0xcc, 0x2e, 0x3f, 0x7e, 0x50, 0x43, 0x16, 0x93, 0x77, 0x00, 0xb4, 0xfd, 0x8f, 0x0f, 0x9d, 0xe2, - 0x69, 0xa2, 0x8f, 0xe6, 0x68, 0xd7, 0x24, 0x29, 0x05, 0xf4, 0xaf, 0xd3, 0xeb, 0xfb, 0x7e, 0x70, - 0x14, 0x33, 0x80, 0x78, 0x4f, 0x23, 0x87, 0x4f, 0xf3, 0x0e, 0xe0, 0xc3, 0x0c, 0xad, 0xd9, 0xe5, - 0x21, 0x33, 0xc7, 0xed, 0xf5, 0x9d, 0x7a, 0xe0, 0xc0, 0x67, 0xae, 0x5a, 0x5a, 0x9e, 0x81, 0x83, - 0xa8, 0x49, 0x55, 0x70, 0xf4, 0xbf, 0xdf, 0x2b, 0xd2, 0x3f, 0xdf, 0x98, 0x1c, 0x23, 0x54, 0xff, - 0x40, 0x5c, 0x90, 0xa8, 0x5c, 0x33, 0x43, 0xe9, 0xd7, 0x0b, 0x83, 0xe2, 0x7d, 0x06, 0x80, 0xc9, - 0x9a, 0xfa, 0xcc, 0x2e, 0x52, 0xb1, 0x08, 0x33, 0x11, 0x11, 0xbe, 0x1d, 0xe2, 0x1c, 0x5b, 0x27, - 0x7c, 0x4d, 0x83, 0x8e, 0x06, 0xa3, 0xfd, 0xaa, 0xc5, 0xc5, 0x58, 0x81, 0x90, 0x8b, 0x45, 0xef, - 0xa5, 0x69, 0xaa, 0x0c, 0x7a, 0xf4, 0x15, 0xcd, 0x0f, 0x87, 0x16, 0x12, 0x00, 0x83, 0x7b, 0x75, - 0x64, 0x1c, 0xe3, 0xa8, 0x79, 0xd0, 0x31, 0xee, 0x9d, 0xf2, 0x76, 0x2c, 0x4b, 0x23, 0xeb, 0x7d, - 0x2b, 0x95, 0x51, 0x23, 0x44, 0x87, 0x65, 0xbc, 0xb0, 0xe3, 0x21, 0x6b, 0xe6, 0x26, 0x2b, 0x24, - 0x9f, 0xcc, 0xd5, 0x7d, 0x3c, 0x47, 0x97, 0xcc, 0x67, 0x00, 0xd0, 0xc8, 0x11, 0x05, 0x40, 0x80, - 0xfe, 0x76, 0x79, 0xbf, 0xea, 0xb7, 0xd5, 0xf5, 0xdb, 0xd0, 0x5a, 0x84, 0xc3, 0x7d, 0x13, 0x13, - 0x9d, 0x37, 0xe3, 0x14, 0xb8, 0xc5, 0xde, 0x4d, 0xd3, 0xc8, 0x05, 0x9c, 0x1e, 0x2a, 0x02, 0xde, - 0x67, 0x80, 0xb2, 0x7d, 0x46, 0xa6, 0x28, 0xc4, 0x9f, 0xe7, 0xc4, 0x61, 0x1c, 0x7d, 0x37, 0xe8, - 0x38, 0xd4, 0x67, 0x65, 0x0d, 0x78, 0x96, 0xbe, 0x44, 0x24, 0x2a, 0x4a, 0x51, 0xc3, 0xf5, 0xfc, - 0x04, 0x05, 0x4b, 0x24, 0x70, 0x89, 0xc9, 0x15, 0xdd, 0xe7, 0xb7, 0xc7, 0x63, 0x25, 0x5d, 0x8f, - 0x02, 0x31, 0xc1, 0xaf, 0xee, 0x19, 0xbe, 0x3f, 0x3a, 0x11, 0x28, 0x8a, 0x84, 0x13, 0x85, 0x16, - 0x12, 0x98, 0xb9, 0x28, 0x99, 0xf1, 0xb8, 0x3b, 0xa3, 0xb4, 0x63, 0x94, 0x61, 0x62, 0x01, 0x44, - 0x39, 0xa1, 0xbc, 0xe1, 0x62, 0x15, 0xe0, 0x9d, 0xb2, 0x28, 0x1b, 0xc4, 0x2a, 0x10, 0xe5, 0x84, - 0xf2, 0x86, 0xfb, 0x7f, 0x57, 0x60, 0xe2, 0xe9, 0xe3, 0xf5, 0x86, 0xfc, 0x0b, 0x02, 0xf9, 0x81, - 0x03, 0x07, 0x4e, 0x9f, 0x3e, 0xcd, 0x3b, 0xb1, 0xe1, 0x1b, 0x08, 0xbb, 0xc6, 0x7b, 0x7b, 0x7b, - 0x13, 0x12, 0x12, 0xc8, 0x2e, 0xd3, 0xa7, 0x4f, 0x0f, 0x05, 0x72, 0xfb, 0xf6, 0x6d, 0xe8, 0x64, - 0x66, 0x66, 0x86, 0x52, 0xe0, 0xe0, 0xbb, 0xdd, 0xee, 0xf6, 0xf6, 0xf6, 0xc1, 0xc1, 0x41, 0x0e, - 0x1d, 0x88, 0x04, 0xb6, 0x90, 0x4e, 0xa7, 0x9b, 0x3f, 0x7f, 0x7e, 0x6a, 0xea, 0xe4, 0x6f, 0x66, - 0x87, 0xc3, 0x11, 0x2a, 0x5f, 0x72, 0xb9, 0x5c, 0xa1, 0x50, 0xa4, 0xa5, 0xa5, 0x85, 0x52, 0xe0, - 0xe0, 0x9f, 0x3b, 0x77, 0x6e, 0xf5, 0xea, 0xd5, 0xe5, 0xe5, 0xe5, 0x1c, 0x3a, 0x93, 0x22, 0xee, - 0xf8, 0xb8, 0xa5, 0x57, 0xae, 0x5c, 0x01, 0x82, 0x4c, 0x26, 0xe3, 0x50, 0x43, 0x22, 0x39, 0xa4, - 0xb4, 0xc8, 0xe3, 0xf1, 0xd0, 0xcb, 0x93, 0x27, 0x4f, 0x02, 0x3c, 0x2f, 0x2f, 0x8f, 0x66, 0x06, - 0xd2, 0x41, 0x2a, 0xb0, 0x77, 0xef, 0xde, 0x65, 0xcb, 0x96, 0xad, 0x5d, 0xbb, 0xb6, 0xb3, 0xb3, - 0x73, 0xf9, 0xf2, 0xe5, 0x6a, 0xb5, 0x7a, 0xc9, 0x92, 0x25, 0x35, 0x35, 0x35, 0x1c, 0xbd, 0x8e, - 0x9d, 0x02, 0x9f, 0xcd, 0x9b, 0x37, 0x03, 0x67, 0xc5, 0x8a, 0x15, 0x2b, 0x57, 0xae, 0xb4, 0x58, - 0x2c, 0x2c, 0x85, 0xb3, 0x67, 0xcf, 0x6e, 0xd9, 0xb2, 0x25, 0x39, 0x39, 0x19, 0xf8, 0xf0, 0x32, - 0x37, 0x37, 0x77, 0xd3, 0xa6, 0x4d, 0x8c, 0xce, 0xcd, 0x9b, 0x37, 0x6f, 0xdd, 0xba, 0x85, 0xa5, - 0xcd, 0x66, 0xfb, 0xf5, 0xe9, 0x03, 0x67, 0x70, 0xa2, 0x18, 0x05, 0x3f, 0x11, 0x18, 0x93, 0xc1, - 0x60, 0x20, 0x62, 0x8d, 0x66, 0xca, 0xfb, 0xa9, 0xd2, 0xd2, 0x52, 0x96, 0x32, 0x47, 0x05, 0xb0, - 0xb1, 0x54, 0xea, 0xff, 0xb3, 0xd1, 0xd7, 0xd7, 0x47, 0xdb, 0xb6, 0xb6, 0xb6, 0x92, 0x2d, 0xd6, - 0xad, 0x5b, 0x57, 0x58, 0x58, 0x88, 0xb7, 0x29, 0x58, 0x2e, 0x58, 0xb0, 0x80, 0xe8, 0x74, 0x75, - 0x75, 0xf9, 0xfd, 0xa3, 0xa8, 0x7d, 0xfb, 0xf6, 0xd1, 0x20, 0x84, 0x0e, 0xd2, 0x42, 0xf7, 0xee, - 0xdd, 0x43, 0x62, 0x60, 0x18, 0x1f, 0x1f, 0x5f, 0x5f, 0x5f, 0x7f, 0xfd, 0xfa, 0xf5, 0xe2, 0xe2, - 0x62, 0x82, 0x83, 0x8d, 0x69, 0x08, 0x8e, 0x00, 0xa0, 0x76, 0xe3, 0xc6, 0x8d, 0xe6, 0xe6, 0x66, - 0x62, 0xc8, 0x0a, 0x60, 0xe7, 0xce, 0x9d, 0xe0, 0x2f, 0x5a, 0xb4, 0x88, 0xa0, 0x41, 0x5a, 0x56, - 0x56, 0x86, 0x82, 0x90, 0xa5, 0xd9, 0x6c, 0xce, 0xcf, 0xcf, 0x27, 0x3e, 0xe0, 0x08, 0xcd, 0x7b, - 0xfa, 0x2c, 0x5d, 0xba, 0x14, 0xa7, 0x82, 0x28, 0xd0, 0xdf, 0x41, 0x02, 0x80, 0x18, 0x73, 0x03, - 0x1b, 0x6c, 0xdb, 0xb6, 0x8d, 0xa8, 0x0e, 0x0d, 0x0d, 0x49, 0x24, 0x93, 0xaf, 0x1b, 0x76, 0xef, - 0xde, 0x4d, 0x1b, 0x73, 0x07, 0x00, 0x4d, 0xa7, 0xf3, 0xd9, 0x2b, 0x30, 0x56, 0x00, 0x2d, 0x2d, - 0x2d, 0x24, 0x30, 0x74, 0x4e, 0x65, 0x65, 0xe5, 0xf1, 0xe3, 0xc7, 0x91, 0x35, 0x1a, 0x19, 0xb4, - 0xf0, 0x33, 0x40, 0xa0, 0xf1, 0xbd, 0x6a, 0xd5, 0x2a, 0x42, 0x27, 0x26, 0x26, 0x22, 0x5b, 0xa0, - 0x07, 0x06, 0x06, 0x18, 0x69, 0x24, 0x44, 0x51, 0x51, 0x11, 0x0e, 0x06, 0x10, 0x50, 0xde, 0xc3, - 0x87, 0x0f, 0x23, 0xfd, 0x59, 0x59, 0x59, 0xdb, 0xb7, 0x6f, 0x17, 0x80, 0x19, 0xe4, 0x10, 0x33, - 0x28, 0x17, 0x2e, 0x5c, 0x20, 0xf4, 0xf0, 0xf0, 0x70, 0x4f, 0x4f, 0x0f, 0x68, 0xe6, 0x78, 0x30, - 0x3a, 0xc2, 0x08, 0x1c, 0x0f, 0xf4, 0x43, 0x77, 0x77, 0xf7, 0xae, 0x5d, 0xbb, 0x0a, 0x0a, 0x0a, - 0xc8, 0x1c, 0xab, 0xab, 0xab, 0x43, 0xa1, 0x18, 0x40, 0xb1, 0x78, 0xd2, 0x37, 0xbb, 0xdd, 0xce, - 0x70, 0x82, 0x13, 0xac, 0xc2, 0x91, 0x25, 0x69, 0xa1, 0xa4, 0xa4, 0xa4, 0xa6, 0xa6, 0x26, 0x14, - 0xb7, 0xa4, 0xa4, 0x84, 0x18, 0x9f, 0x3f, 0x7f, 0x9e, 0xd1, 0xc7, 0x7c, 0xbc, 0x7c, 0xf9, 0x32, - 0xf8, 0xd8, 0x1e, 0x34, 0x46, 0x04, 0x23, 0x22, 0x04, 0x38, 0x38, 0xca, 0xc4, 0x10, 0x17, 0x1f, - 0x3d, 0x4f, 0xf7, 0xef, 0xdf, 0x0f, 0xf0, 0x8e, 0x8e, 0x0e, 0xa2, 0x69, 0x34, 0x1a, 0x95, 0xca, - 0xc9, 0xf7, 0x59, 0xc7, 0x8e, 0x1d, 0x63, 0x40, 0xce, 0x9c, 0x39, 0x03, 0x0e, 0x5a, 0x17, 0x0e, - 0x8c, 0x8d, 0x8d, 0xb5, 0xb5, 0xb5, 0xa1, 0xa5, 0xd1, 0x57, 0x8c, 0x02, 0x21, 0xb8, 0xce, 0x00, - 0xd9, 0x9b, 0xf9, 0xc6, 0x58, 0x24, 0x36, 0x56, 0xab, 0x35, 0xe8, 0xdd, 0x84, 0xc9, 0xcb, 0xa0, - 0x63, 0x32, 0x32, 0x86, 0x0c, 0x91, 0x9d, 0x9d, 0xed, 0x72, 0xb9, 0xa0, 0x53, 0x51, 0x51, 0x01, - 0x26, 0x0e, 0xe8, 0x8e, 0x1d, 0x3b, 0x1a, 0x1b, 0x1b, 0xab, 0xab, 0xab, 0xb1, 0x44, 0xca, 0xd1, - 0x51, 0x0c, 0x02, 0xb9, 0xc5, 0x09, 0x5f, 0xa5, 0x52, 0x11, 0x10, 0x7a, 0x0b, 0xa2, 0xc9, 0x15, - 0xc0, 0x9e, 0x3d, 0x7b, 0x30, 0x0d, 0x52, 0x52, 0x52, 0x70, 0x1b, 0x1c, 0x3c, 0x78, 0x10, 0xf7, - 0x00, 0xb1, 0x41, 0x00, 0x19, 0x19, 0x19, 0x04, 0x91, 0xfe, 0xc6, 0x4c, 0x64, 0xb6, 0xc7, 0x0d, - 0x40, 0x8b, 0x08, 0x9d, 0x93, 0x93, 0x83, 0x5c, 0x42, 0x07, 0xc8, 0x18, 0x9d, 0xf4, 0x98, 0x46, - 0x41, 0x1a, 0x1a, 0x1a, 0x18, 0x73, 0x42, 0xd4, 0xd6, 0xd6, 0xe2, 0xca, 0x87, 0x2d, 0x62, 0xc3, - 0x90, 0xc5, 0xad, 0x6c, 0x32, 0x99, 0x58, 0x3a, 0x5c, 0x01, 0x5c, 0xbc, 0x78, 0x91, 0xa5, 0x1d, - 0xad, 0x25, 0x5a, 0x0b, 0x4d, 0x85, 0x1e, 0xbb, 0x73, 0xe7, 0xce, 0xa5, 0x4b, 0x97, 0xf0, 0x4d, - 0x2a, 0x13, 0x88, 0x8f, 0xac, 0xf5, 0xf7, 0xf7, 0x23, 0x65, 0x81, 0x22, 0xc2, 0x61, 0x07, 0x80, - 0x2b, 0x13, 0x8d, 0x88, 0xb1, 0x83, 0xb8, 0xab, 0xaa, 0xaa, 0x4e, 0x9c, 0x38, 0xc1, 0x61, 0x1c, - 0x0a, 0xf4, 0x65, 0xf2, 0xd9, 0x01, 0xe0, 0xe6, 0x62, 0x95, 0x3e, 0xf0, 0xdc, 0xbc, 0x4c, 0xff, - 0x9e, 0xbb, 0x97, 0xff, 0xb6, 0x27, 0x7e, 0x63, 0x42, 0xe3, 0xd7, 0x25, 0x33, 0x3d, 0xf4, 0x7a, - 0xfd, 0xc6, 0x8d, 0x1b, 0x59, 0x21, 0xfd, 0xa7, 0x96, 0xb1, 0x37, 0x73, 0xaf, 0xba, 0x1c, 0x5c, - 0x37, 0xf1, 0xab, 0xf6, 0x2d, 0xac, 0xfd, 0x63, 0x01, 0x84, 0x95, 0xa6, 0x17, 0xa8, 0x14, 0xab, - 0xc0, 0x0b, 0x4c, 0x6e, 0x58, 0xd0, 0xb1, 0x0a, 0x84, 0x95, 0xa6, 0x17, 0xa8, 0xf4, 0x0f, 0x7b, - 0x3c, 0x70, 0xd0, 0xa5, 0xfc, 0x34, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXPlistIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x10, 0xc5, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x09, 0x90, 0x15, 0xc5, 0xf5, 0xb1, 0x17, 0xbb, 0x2c, 0xcb, 0x1e, 0x20, 0xec, 0xc2, 0x1e, - 0xb2, 0x1c, 0xe1, 0x46, 0x08, 0x8b, 0x20, 0x97, 0x68, 0x20, 0x80, 0x10, 0x90, 0x80, 0x80, 0xd1, - 0xa4, 0x62, 0x45, 0x41, 0x28, 0x83, 0x5c, 0x52, 0x42, 0x52, 0xa9, 0x04, 0x04, 0x2a, 0x12, 0x10, - 0xa5, 0x10, 0xca, 0x12, 0x15, 0x85, 0x0a, 0xa7, 0x84, 0x08, 0x28, 0xe7, 0x22, 0x87, 0x01, 0xe4, - 0x94, 0x4b, 0xc0, 0x05, 0xf6, 0x3e, 0x60, 0xd9, 0x5d, 0xf6, 0xbe, 0x26, 0xef, 0xf5, 0xff, 0xdd, - 0x3b, 0x33, 0x7f, 0x66, 0x76, 0xfe, 0xbd, 0xc8, 0xef, 0xaa, 0xff, 0xa7, 0x8f, 0x77, 0xf5, 0x7b, - 0x3d, 0xdd, 0x3d, 0xd3, 0xdd, 0x6f, 0x1a, 0x49, 0x18, 0xc0, 0x8e, 0xe0, 0x67, 0x07, 0x2c, 0x03, - 0x75, 0x1e, 0xa1, 0xd1, 0x57, 0x77, 0x18, 0xa5, 0xa2, 0x6a, 0x8b, 0xa4, 0x3c, 0x2d, 0x24, 0xa1, - 0x3a, 0xf0, 0x00, 0xff, 0xbd, 0xcd, 0xa3, 0x92, 0x6e, 0x5c, 0x40, 0x58, 0x23, 0x3f, 0x95, 0x54, - 0xa9, 0xb3, 0x14, 0xe9, 0x46, 0x94, 0x12, 0xec, 0x4c, 0x44, 0x5c, 0x50, 0xe9, 0x46, 0x8d, 0x34, - 0xf9, 0x3c, 0xff, 0xfc, 0xf3, 0x2c, 0x5f, 0xc1, 0x21, 0x35, 0x35, 0x55, 0x00, 0x37, 0xb2, 0x22, - 0xf2, 0xab, 0x28, 0xe0, 0x35, 0x9a, 0x31, 0x63, 0x06, 0x8f, 0x1a, 0x5e, 0xed, 0xae, 0xb4, 0xdd, - 0x08, 0x8a, 0x3a, 0x08, 0x39, 0x0d, 0x22, 0xce, 0x21, 0x5c, 0x28, 0xaa, 0x82, 0x7b, 0x55, 0xb5, - 0x8c, 0x7e, 0xe2, 0xa1, 0x4c, 0x08, 0xde, 0x5b, 0xa7, 0x35, 0xc1, 0x94, 0xab, 0xa4, 0xd9, 0xd7, - 0xa9, 0x3c, 0xaa, 0xb8, 0xbe, 0x7f, 0xab, 0x48, 0x91, 0x06, 0x45, 0xca, 0x9a, 0xe0, 0x0d, 0x2f, - 0x66, 0x7f, 0xba, 0x4d, 0x71, 0x43, 0xd5, 0x12, 0xb5, 0x97, 0x25, 0x4b, 0x96, 0x08, 0x45, 0xc8, - 0x23, 0xea, 0xb6, 0xc4, 0xea, 0x40, 0x99, 0x58, 0x3b, 0x39, 0x9c, 0x6e, 0x9c, 0x19, 0xce, 0x2c, - 0x30, 0x51, 0xb1, 0x5b, 0x4b, 0xba, 0xac, 0x75, 0x0a, 0xec, 0x6e, 0x4a, 0x3a, 0x74, 0x74, 0xb3, - 0x1d, 0x62, 0x60, 0xd3, 0xb5, 0xe9, 0x92, 0xc7, 0x02, 0x9b, 0xa6, 0x65, 0xcd, 0xa0, 0xd6, 0xd7, - 0xfd, 0x48, 0xa6, 0x4d, 0x31, 0x6f, 0x95, 0xf2, 0x02, 0xca, 0x9b, 0x7b, 0xe5, 0xbe, 0x3c, 0x4b, - 0xc4, 0x75, 0x19, 0x10, 0x04, 0x21, 0x3e, 0xb6, 0x2f, 0xad, 0x0e, 0x58, 0xd6, 0xef, 0xf2, 0x4c, - 0x82, 0x99, 0x70, 0x26, 0x8f, 0x27, 0x6d, 0xae, 0x86, 0x0c, 0xe4, 0xd0, 0x1d, 0x0f, 0x67, 0x48, - 0xb9, 0x15, 0x35, 0xf2, 0x2c, 0x53, 0x71, 0xef, 0xb7, 0xa2, 0xc3, 0x87, 0x0f, 0x2b, 0x4c, 0x18, - 0x15, 0x15, 0xa5, 0x48, 0xd7, 0x9b, 0x90, 0xd7, 0x93, 0x6c, 0x3e, 0x75, 0xea, 0x54, 0xba, 0xe5, - 0x44, 0xb6, 0x3c, 0x5e, 0x5c, 0x5c, 0xac, 0x59, 0x16, 0x1a, 0x1a, 0xca, 0xe0, 0x09, 0x96, 0xff, - 0x38, 0x01, 0x85, 0x8a, 0xe4, 0xf7, 0x39, 0x02, 0x80, 0xbd, 0x69, 0x24, 0x2e, 0x70, 0x6a, 0x6b, - 0x6b, 0x59, 0x5c, 0xc1, 0x80, 0x00, 0x5c, 0x1d, 0x1c, 0xba, 0xd1, 0xec, 0x11, 0xe2, 0xe1, 0xaf, - 0x81, 0xdb, 0x55, 0xf4, 0x08, 0x32, 0x38, 0x71, 0xbf, 0x02, 0x7e, 0x77, 0xee, 0xae, 0xf9, 0x86, - 0xc4, 0xef, 0x38, 0xad, 0x2b, 0xf5, 0x94, 0xd8, 0xf7, 0x2b, 0x8a, 0x28, 0x8f, 0x42, 0x19, 0xf6, - 0x7b, 0x14, 0xff, 0x26, 0xaf, 0x4c, 0x51, 0xae, 0x4e, 0xd4, 0xf5, 0x09, 0xb2, 0x92, 0x15, 0x29, - 0x45, 0x8a, 0x69, 0xb0, 0xac, 0x48, 0xf2, 0x57, 0x31, 0x7c, 0xf6, 0xbb, 0x1c, 0x5d, 0x58, 0xc2, - 0xd3, 0x64, 0x40, 0x92, 0xbd, 0x7d, 0xcd, 0x76, 0x00, 0xe1, 0xd2, 0xcb, 0x19, 0x32, 0x22, 0x08, - 0x1f, 0xb8, 0x5b, 0x59, 0x53, 0x0e, 0xa3, 0xd9, 0x8a, 0xa4, 0xd1, 0x09, 0x50, 0x8c, 0x33, 0x7f, - 0x1a, 0x1a, 0xa9, 0xf7, 0xd2, 0x0b, 0x1d, 0x93, 0x33, 0x2d, 0x30, 0x08, 0x5f, 0x39, 0x2a, 0x5e, - 0x1b, 0x8c, 0x73, 0xd2, 0xbb, 0x06, 0x59, 0x25, 0xd3, 0x92, 0xf0, 0x54, 0x41, 0x85, 0x1e, 0x9a, - 0xc8, 0xd7, 0xac, 0x81, 0x5c, 0x94, 0x0a, 0xab, 0x64, 0x55, 0xb5, 0xb6, 0x75, 0x49, 0x0a, 0x0f, - 0x92, 0x83, 0x6a, 0xc6, 0x7d, 0x7d, 0x91, 0xa6, 0x5a, 0xe4, 0x99, 0x86, 0x36, 0xa0, 0xf1, 0x38, - 0x27, 0x27, 0x47, 0x0e, 0x0f, 0x9f, 0x7d, 0xf6, 0x99, 0x22, 0x5d, 0x6f, 0x42, 0x98, 0x5b, 0x27, - 0x32, 0x62, 0xc4, 0x08, 0x9d, 0x12, 0xdb, 0x6c, 0x64, 0x66, 0x93, 0x29, 0x6a, 0xb0, 0x66, 0xcd, - 0x1a, 0x36, 0x86, 0x2e, 0x5a, 0xb4, 0x48, 0x8c, 0xab, 0x6a, 0xe9, 0xc6, 0x8c, 0x19, 0x03, 0x11, - 0x11, 0x11, 0x22, 0x9b, 0xc6, 0xec, 0xb2, 0xb2, 0x32, 0xa0, 0xfc, 0xfd, 0xfb, 0xf7, 0xb3, 0x7c, - 0xca, 0x3b, 0x73, 0xe6, 0x8c, 0x80, 0x51, 0xb0, 0x1c, 0x34, 0x68, 0x10, 0x93, 0x00, 0x4b, 0x85, - 0x24, 0xea, 0x1a, 0x84, 0x87, 0x87, 0x8b, 0xb2, 0x21, 0x43, 0x86, 0xb0, 0x59, 0x84, 0xbf, 0xbf, - 0xbf, 0x0d, 0x1e, 0x07, 0xaa, 0xa3, 0x84, 0x39, 0x61, 0x61, 0x61, 0x0c, 0xe1, 0xe2, 0xc5, 0x8b, - 0x02, 0x81, 0x98, 0x71, 0x86, 0x3c, 0x2e, 0x4f, 0x07, 0x05, 0x05, 0x49, 0xbd, 0x7b, 0xf7, 0x66, - 0xf0, 0xf1, 0xf1, 0xf1, 0x0c, 0x96, 0x97, 0x53, 0xa6, 0x60, 0x30, 0x6d, 0xda, 0x34, 0xa9, 0x7d, - 0xfb, 0xf6, 0x0c, 0xd0, 0x95, 0x7f, 0xbe, 0x1b, 0x0d, 0xd5, 0x6d, 0x1c, 0xdc, 0xae, 0x22, 0x63, - 0xf6, 0xce, 0x97, 0x8a, 0xfb, 0xcc, 0x79, 0x52, 0xde, 0xa1, 0xe0, 0xab, 0x80, 0x77, 0xf4, 0x5e, - 0xc7, 0xd5, 0x63, 0x16, 0xb8, 0x55, 0x56, 0x5d, 0xc7, 0xd5, 0x85, 0x31, 0xa7, 0x2b, 0x30, 0x05, - 0xe7, 0xc0, 0xf5, 0xbd, 0xb6, 0x08, 0xd8, 0x9d, 0x0a, 0x89, 0x07, 0x33, 0x14, 0x62, 0x13, 0xce, - 0xd3, 0xdf, 0x29, 0x47, 0x62, 0x05, 0x80, 0xc9, 0x84, 0x43, 0xbd, 0x50, 0x02, 0x0a, 0x93, 0x6a, - 0xd5, 0xe8, 0xea, 0xee, 0x51, 0x30, 0x23, 0x21, 0x4c, 0x97, 0x5d, 0xdb, 0x43, 0x19, 0x70, 0xbb, - 0xb4, 0x1a, 0x8a, 0x46, 0xc6, 0x43, 0x98, 0xbf, 0xf2, 0xad, 0xec, 0x97, 0xd9, 0x65, 0x30, 0xfe, - 0xfb, 0x5c, 0x86, 0x1b, 0x11, 0xe8, 0x07, 0xf9, 0xbf, 0x8e, 0x03, 0x25, 0x84, 0x2e, 0x59, 0x51, - 0x60, 0xba, 0x02, 0xfe, 0xa8, 0xc5, 0x5a, 0x1c, 0xfa, 0x28, 0x64, 0x0e, 0x8b, 0x85, 0x98, 0xc6, - 0xfe, 0x82, 0x88, 0x5e, 0x64, 0xf2, 0xd9, 0xbb, 0xb0, 0x39, 0xb3, 0x04, 0x8e, 0x0d, 0x88, 0x86, - 0x01, 0x91, 0x8d, 0xf5, 0xc0, 0x58, 0xfe, 0x83, 0x1a, 0x09, 0xa2, 0xbe, 0x49, 0x83, 0x6a, 0xeb, - 0xdc, 0x94, 0x66, 0xde, 0x66, 0x82, 0xe9, 0x0a, 0x10, 0xb1, 0xff, 0x15, 0x54, 0x42, 0xff, 0x63, - 0x59, 0x82, 0xee, 0xc5, 0x21, 0xad, 0xa1, 0x7b, 0x58, 0xa0, 0x48, 0xcb, 0x23, 0x1f, 0xdc, 0x7e, - 0x00, 0x7f, 0xbe, 0x94, 0x0f, 0xcb, 0x3a, 0x47, 0xc2, 0xfc, 0x76, 0xcd, 0xe4, 0x45, 0x8a, 0x78, - 0x46, 0x79, 0x0d, 0xc4, 0x1e, 0x48, 0x17, 0x79, 0x5f, 0x26, 0xb5, 0x84, 0x71, 0xad, 0x42, 0x44, - 0xba, 0xbe, 0x88, 0x5d, 0x15, 0x50, 0x13, 0x8b, 0xc7, 0xa6, 0x94, 0x66, 0x6d, 0x4a, 0x47, 0x9e, - 0x8a, 0x86, 0xc1, 0x51, 0x16, 0x2d, 0x9f, 0x29, 0xac, 0x84, 0x3e, 0x47, 0xb3, 0x60, 0x4c, 0xab, - 0x26, 0xb0, 0x2b, 0xe9, 0x31, 0x35, 0x1a, 0x64, 0x56, 0xd4, 0x40, 0x9b, 0xfd, 0x16, 0xa1, 0xc3, - 0xb1, 0xe9, 0xdc, 0x1d, 0x1e, 0x07, 0x01, 0xf6, 0xb6, 0x1d, 0x2b, 0x55, 0xa7, 0x2a, 0x60, 0x23, - 0x19, 0x66, 0x94, 0x62, 0x13, 0x08, 0xdd, 0x93, 0x0a, 0xd1, 0xc1, 0xfe, 0x90, 0xf5, 0xab, 0x58, - 0x2d, 0x10, 0x97, 0xe6, 0xb9, 0xbc, 0x02, 0x24, 0xdd, 0xd6, 0xac, 0x52, 0x98, 0x18, 0xd3, 0xc4, - 0xa5, 0x82, 0xea, 0x11, 0x73, 0x4b, 0x05, 0xf4, 0x98, 0xb9, 0x23, 0xdf, 0xe9, 0x71, 0xc0, 0x1d, - 0x42, 0xd9, 0x43, 0xf3, 0xd1, 0xad, 0xc0, 0xac, 0x59, 0xb3, 0x2c, 0x6f, 0x5a, 0xf1, 0x29, 0x6f, - 0xe4, 0xc8, 0x91, 0xba, 0x4a, 0xa3, 0xa7, 0xc0, 0xd7, 0x5e, 0x7b, 0x4d, 0xb7, 0xdc, 0xa8, 0x20, - 0x24, 0x24, 0x04, 0xbe, 0xf8, 0xe2, 0x0b, 0x23, 0x10, 0xd9, 0xe3, 0xa3, 0xec, 0x41, 0x2c, 0x36, - 0x36, 0x96, 0x3d, 0xbc, 0xe1, 0xa3, 0xa8, 0x78, 0x88, 0xa3, 0x07, 0x42, 0x7c, 0x3d, 0x2c, 0x83, - 0xb2, 0x44, 0x91, 0xba, 0xa4, 0x7e, 0xf2, 0xa4, 0x92, 0x0b, 0x17, 0x2e, 0x08, 0xdc, 0xe8, 0xe8, - 0x68, 0x1b, 0xbc, 0x94, 0x94, 0x14, 0x51, 0x4e, 0x34, 0xe8, 0xc9, 0x14, 0xd7, 0x49, 0x19, 0x5c, - 0x75, 0x75, 0xb5, 0xb4, 0x72, 0xe5, 0x4a, 0x56, 0xde, 0xad, 0x5b, 0x37, 0x69, 0xc5, 0x8a, 0x15, - 0xd2, 0xaa, 0x55, 0xab, 0x6c, 0x68, 0x50, 0x86, 0x78, 0xa8, 0x54, 0x97, 0x12, 0x51, 0xf9, 0x43, - 0x26, 0x2d, 0xa1, 0x52, 0x5e, 0x5e, 0x9e, 0x72, 0x71, 0x43, 0xaf, 0x02, 0x9c, 0x1e, 0x95, 0xcb, - 0x1f, 0xa5, 0xe5, 0xf9, 0x54, 0x16, 0x10, 0x10, 0x20, 0x4d, 0x9e, 0x3c, 0x59, 0x3a, 0x76, 0xec, - 0x18, 0x2f, 0x12, 0x57, 0x2a, 0x1f, 0x37, 0x6e, 0x9c, 0x48, 0x6b, 0x45, 0x0c, 0x2b, 0x40, 0x04, - 0x6e, 0xdf, 0xbe, 0x2d, 0x95, 0x96, 0x96, 0x0a, 0x6d, 0xa9, 0x89, 0x10, 0x8c, 0x96, 0x05, 0x38, - 0x1c, 0x95, 0xeb, 0x55, 0x60, 0xeb, 0xd6, 0xad, 0x1c, 0x4c, 0xc2, 0x17, 0x12, 0x8c, 0x87, 0xc8, - 0xc0, 0x08, 0xe1, 0x92, 0xe5, 0x29, 0x5c, 0xbb, 0x76, 0x4d, 0x4a, 0x4a, 0x4a, 0x62, 0x71, 0xf9, - 0x9f, 0x61, 0x05, 0x5e, 0x7f, 0xfd, 0x75, 0x39, 0xac, 0x4b, 0xe3, 0x07, 0x0f, 0x1e, 0x64, 0xf4, - 0xf0, 0xfd, 0x90, 0xb4, 0x6b, 0xd7, 0x2e, 0xa9, 0xa8, 0x48, 0xb9, 0xcc, 0xcb, 0x99, 0x51, 0x73, - 0x22, 0xeb, 0x94, 0x94, 0x94, 0xf0, 0x2c, 0xc5, 0x55, 0x73, 0x1c, 0x90, 0x2f, 0xa3, 0xa0, 0x16, - 0xa8, 0x92, 0x74, 0x69, 0x90, 0x21, 0x40, 0x4b, 0xaa, 0x86, 0x2c, 0xb0, 0x5a, 0xde, 0x47, 0x77, - 0x1c, 0x50, 0x6b, 0xc2, 0x5b, 0x69, 0xcd, 0x7b, 0xc0, 0x5b, 0xc2, 0x38, 0xc2, 0xd7, 0xd7, 0x84, - 0x1c, 0xd1, 0x9a, 0x2b, 0x71, 0x7c, 0x16, 0x70, 0xa5, 0x36, 0x1d, 0xa1, 0xe5, 0xb3, 0x80, 0x23, - 0x5a, 0x73, 0x25, 0x8e, 0xcf, 0x02, 0xae, 0xd4, 0xa6, 0x23, 0xb4, 0x3c, 0x62, 0x81, 0xb3, 0x45, - 0x95, 0x8e, 0xc8, 0x66, 0x0a, 0xc7, 0x23, 0x23, 0x31, 0x7f, 0xf9, 0x6b, 0xf6, 0x75, 0xa1, 0x29, - 0xc9, 0xad, 0x40, 0x4e, 0x59, 0x20, 0xbb, 0x02, 0x77, 0x20, 0xe1, 0x5b, 0xe6, 0x85, 0x3f, 0x16, - 0xe8, 0xf2, 0xbc, 0x5d, 0x56, 0xc3, 0xca, 0x06, 0x46, 0x05, 0x0b, 0x98, 0x4d, 0x99, 0xa5, 0x0c, - 0xef, 0x6a, 0xb1, 0xf3, 0xaf, 0xdc, 0x1d, 0xae, 0x40, 0xff, 0xe3, 0xd9, 0x10, 0xb3, 0x3f, 0x8d, - 0x09, 0x95, 0x8b, 0x15, 0xd1, 0x0b, 0x3d, 0xbf, 0xcd, 0x64, 0x45, 0xc9, 0x4f, 0xb5, 0x12, 0x20, - 0x3f, 0x16, 0x57, 0xb1, 0x78, 0x97, 0xe4, 0x0c, 0xe8, 0x70, 0xd8, 0x52, 0x2e, 0x0a, 0xed, 0x8c, - 0xd8, 0xdd, 0x84, 0x76, 0xe5, 0x94, 0xc1, 0xd8, 0xd3, 0x75, 0xaf, 0xc4, 0xef, 0xe1, 0x2b, 0x71, - 0x3d, 0x2d, 0x90, 0xee, 0x03, 0xd0, 0x42, 0xcd, 0xf0, 0xfd, 0x67, 0x21, 0xc2, 0xa9, 0x83, 0xfc, - 0x35, 0xfd, 0x87, 0x3d, 0x9a, 0xc3, 0xb4, 0xf8, 0xa6, 0x6a, 0x90, 0x7a, 0xd3, 0xa6, 0x2b, 0x40, - 0xc2, 0x44, 0x7c, 0x9d, 0x86, 0x9b, 0x4d, 0x2c, 0xda, 0x3e, 0x8a, 0xaf, 0xcc, 0x07, 0xd6, 0xf3, - 0xca, 0x7c, 0xc0, 0x89, 0x1c, 0x38, 0x91, 0x5f, 0x0e, 0xb7, 0x9e, 0x8d, 0x85, 0xc7, 0x43, 0xb4, - 0x5f, 0xc7, 0x5f, 0x2b, 0xa9, 0x86, 0xce, 0x87, 0x2d, 0x8b, 0x1f, 0x01, 0x7e, 0x8d, 0xa0, 0x00, - 0x2b, 0x1a, 0xaa, 0x5a, 0x47, 0x30, 0xaa, 0x85, 0x9e, 0xf2, 0x14, 0x38, 0x7f, 0xc1, 0x36, 0x4e, - 0x9a, 0x24, 0xe1, 0xa7, 0xb4, 0x09, 0x05, 0xba, 0x19, 0xeb, 0x13, 0x9e, 0x08, 0x90, 0xf0, 0x14, - 0xf4, 0x84, 0xa7, 0xb2, 0x4e, 0xa1, 0x01, 0x8c, 0xde, 0x1c, 0x7c, 0x05, 0x4f, 0x6b, 0x03, 0x4d, - 0x71, 0xdf, 0xf4, 0x84, 0x33, 0xe6, 0x77, 0x3e, 0x99, 0xaa, 0x40, 0x6c, 0x48, 0xdd, 0x93, 0xe7, - 0x8e, 0xec, 0x52, 0x28, 0xc1, 0xc5, 0x88, 0xfa, 0xc2, 0x5b, 0x57, 0x2d, 0x37, 0xf6, 0xa6, 0xde, - 0xb6, 0xaf, 0xd7, 0xd5, 0xb8, 0x64, 0xdd, 0x8f, 0x53, 0x8b, 0x45, 0x76, 0x62, 0x93, 0x3a, 0x7e, - 0x22, 0x53, 0x27, 0x62, 0xba, 0x09, 0x11, 0x7e, 0xd2, 0xb1, 0x6c, 0xf8, 0xbe, 0xa0, 0x82, 0x91, - 0x1a, 0xd2, 0x3c, 0x18, 0x92, 0xfb, 0xd7, 0xdd, 0x98, 0x6a, 0xfa, 0x66, 0xbb, 0x4e, 0x5a, 0x63, - 0xfb, 0x77, 0x46, 0x09, 0x43, 0x6f, 0xdb, 0x24, 0x10, 0x52, 0x9e, 0x69, 0xad, 0x26, 0x65, 0x98, - 0x36, 0x65, 0x01, 0x4e, 0xe1, 0xf4, 0xc0, 0x68, 0xb8, 0x3f, 0x22, 0x1e, 0xfc, 0xf1, 0x75, 0xe1, - 0x91, 0x7b, 0xe5, 0xac, 0x2b, 0xfc, 0x38, 0xad, 0x4e, 0x73, 0x1c, 0x6e, 0x27, 0xde, 0xe8, 0x14, - 0x66, 0x3c, 0xae, 0xbf, 0x32, 0xb3, 0x27, 0xd7, 0x82, 0xcf, 0x85, 0xbf, 0x83, 0x6b, 0x09, 0xf6, - 0x0a, 0x4f, 0x3c, 0xec, 0xb2, 0x00, 0x21, 0xf0, 0xb0, 0x05, 0xd7, 0x00, 0x26, 0x9d, 0xc9, 0x63, - 0x49, 0x7a, 0x0d, 0x53, 0xfb, 0x5c, 0xdd, 0xce, 0xb0, 0xfa, 0xb4, 0x1f, 0x82, 0xed, 0xbc, 0xdc, - 0xda, 0x0c, 0xdf, 0xeb, 0x1a, 0x05, 0x33, 0xdb, 0xea, 0x2f, 0x12, 0x72, 0x7e, 0xba, 0x57, 0xc5, - 0x5b, 0x22, 0x07, 0x12, 0xbf, 0x39, 0x9d, 0x2b, 0x5d, 0x2d, 0xae, 0x3b, 0xa6, 0x92, 0x5e, 0x86, - 0x7b, 0xe2, 0x70, 0x2f, 0xdd, 0x13, 0xdf, 0xda, 0x6e, 0xf4, 0xe6, 0xe4, 0x0b, 0x70, 0x97, 0x59, - 0xdf, 0x63, 0x59, 0x3c, 0xe9, 0xd4, 0xd5, 0x61, 0x0b, 0xe8, 0x69, 0xa4, 0xf9, 0xbe, 0x74, 0xc8, - 0xaf, 0xac, 0x81, 0x8a, 0xe7, 0x12, 0x20, 0xc8, 0xc1, 0x75, 0x2f, 0x3d, 0xda, 0x5a, 0xf9, 0x76, - 0xdd, 0x03, 0x5a, 0x04, 0xe4, 0x79, 0xd4, 0x37, 0x91, 0xf0, 0xc1, 0xd8, 0x8f, 0x7b, 0x42, 0x78, - 0xe2, 0xed, 0x72, 0x0b, 0xd0, 0x30, 0x77, 0x13, 0x07, 0xa7, 0x8e, 0xd8, 0xbf, 0x7b, 0x22, 0xb8, - 0xbc, 0x02, 0x9e, 0x10, 0x5a, 0xce, 0xc3, 0xa5, 0x4d, 0x48, 0x4e, 0xd8, 0x53, 0x71, 0x5f, 0x05, - 0x3c, 0xa5, 0x69, 0x3d, 0x3e, 0x3e, 0x0b, 0xe8, 0x69, 0xc6, 0x53, 0xf9, 0x0e, 0x5b, 0x00, 0xd7, - 0xce, 0x80, 0xb6, 0x0f, 0xab, 0x8f, 0xf4, 0xc8, 0x05, 0xdf, 0xb3, 0x67, 0x0f, 0xd0, 0x52, 0xa9, - 0x5b, 0x83, 0xa3, 0xe3, 0x38, 0x0a, 0xc5, 0x16, 0xe1, 0xe8, 0xaa, 0x17, 0x66, 0xce, 0x9c, 0xc9, - 0x60, 0xf4, 0xca, 0x8d, 0xf2, 0x93, 0x93, 0x93, 0xd9, 0x0a, 0xa6, 0x11, 0x0c, 0x95, 0xe9, 0x73, - 0xaf, 0x0f, 0x13, 0xcb, 0x67, 0xcf, 0x9e, 0xed, 0xb0, 0x80, 0xf5, 0x91, 0xc7, 0x85, 0x74, 0x53, - 0xb4, 0x6d, 0x9a, 0x10, 0xae, 0x0a, 0x8a, 0x15, 0xf8, 0xe1, 0xc3, 0x87, 0x8b, 0x38, 0xed, 0xdf, - 0xb6, 0x27, 0x50, 0xd3, 0xa1, 0x59, 0xaa, 0x7a, 0xc1, 0x90, 0xd3, 0x18, 0x3a, 0x74, 0xa8, 0x28, - 0x57, 0xc3, 0x1d, 0x38, 0x70, 0x00, 0xce, 0x9e, 0x3d, 0xcb, 0x40, 0x71, 0xc1, 0x1b, 0xe8, 0x77, - 0xf4, 0xe8, 0x51, 0x8e, 0xaa, 0xbc, 0x6a, 0x69, 0x82, 0x16, 0xb8, 0x11, 0x4a, 0xf2, 0xf3, 0xf3, - 0x93, 0x36, 0x6c, 0xd8, 0x20, 0xe1, 0x51, 0x35, 0x96, 0xc6, 0xed, 0xf1, 0x0a, 0x70, 0x23, 0x0b, - 0x2c, 0x5c, 0xb8, 0x50, 0xea, 0xd3, 0xa7, 0x8f, 0xa6, 0x16, 0x51, 0x18, 0x96, 0xbf, 0x7b, 0xf7, - 0x6e, 0x46, 0x6f, 0xe9, 0xd2, 0xa5, 0x0a, 0x38, 0xe2, 0xad, 0xf5, 0x53, 0x30, 0xb7, 0x26, 0x34, - 0x9b, 0xd0, 0x9c, 0x39, 0x73, 0x14, 0x04, 0x09, 0x96, 0x13, 0x94, 0x13, 0x31, 0xaa, 0x00, 0xc1, - 0xd1, 0xfa, 0x2f, 0xe1, 0xa9, 0xc3, 0xf9, 0xf3, 0xe7, 0x05, 0x3d, 0xda, 0x9b, 0xbe, 0x7c, 0xf9, - 0x72, 0x89, 0xd6, 0x83, 0xe5, 0xc1, 0xe1, 0x26, 0x84, 0x0c, 0xdd, 0x1e, 0x7a, 0xf6, 0xec, 0x09, - 0xdb, 0xb6, 0x6d, 0x83, 0xe0, 0xe0, 0x60, 0xd6, 0x54, 0xe6, 0xce, 0x9d, 0x0b, 0xb8, 0xe5, 0x00, - 0x4e, 0x9c, 0x38, 0x61, 0x37, 0x6f, 0x9b, 0x7b, 0x40, 0x4e, 0xa1, 0x5f, 0xbf, 0x7e, 0x2c, 0x89, - 0x9b, 0xf3, 0xd9, 0x75, 0xfa, 0xf4, 0xe9, 0xf2, 0x62, 0x87, 0xe3, 0xa7, 0x4f, 0x9f, 0x86, 0x97, - 0x5f, 0x7e, 0x99, 0x9d, 0x6f, 0x40, 0xad, 0x43, 0x46, 0x86, 0xe5, 0xb5, 0x8a, 0xfc, 0x04, 0x07, - 0x6e, 0x31, 0x60, 0xf4, 0xef, 0xdc, 0xb9, 0xc3, 0xae, 0xef, 0xbe, 0xfb, 0x2e, 0xbc, 0xf2, 0xca, - 0x2b, 0xb6, 0x3c, 0xe5, 0x66, 0xe3, 0x71, 0xde, 0x84, 0x10, 0x5a, 0x98, 0xba, 0x7b, 0xf7, 0xee, - 0xbc, 0x98, 0xed, 0x7d, 0x90, 0x97, 0xf1, 0x38, 0x1e, 0xc0, 0x67, 0x30, 0x78, 0xf3, 0x0b, 0x3c, - 0x5e, 0x46, 0xd7, 0xcf, 0x3f, 0xff, 0x9c, 0x95, 0xd3, 0x7d, 0xc5, 0xf3, 0x69, 0xb3, 0x07, 0x8f, - 0xcb, 0xb7, 0x13, 0x94, 0x97, 0x97, 0x8b, 0x7c, 0x5e, 0x3e, 0x6a, 0xd4, 0x28, 0x21, 0x03, 0x8f, - 0xd8, 0x36, 0x50, 0x2c, 0xe1, 0x15, 0xe0, 0x40, 0xae, 0xbe, 0xd6, 0xd4, 0xd4, 0x48, 0xd7, 0xaf, - 0x5f, 0x97, 0xd2, 0xd2, 0xd2, 0xa4, 0x1d, 0x3b, 0x76, 0x48, 0xe7, 0xce, 0x9d, 0xd3, 0x65, 0x41, - 0x70, 0xf4, 0xd3, 0x0b, 0x36, 0x15, 0xa0, 0xcd, 0x17, 0x9d, 0x3a, 0x75, 0x62, 0xb5, 0xa7, 0x6d, - 0x30, 0xc7, 0x8f, 0x1f, 0xd7, 0xc3, 0x6d, 0x10, 0xf9, 0x36, 0x15, 0x18, 0x36, 0x6c, 0x98, 0xc2, - 0x74, 0x7c, 0x13, 0x52, 0x83, 0x90, 0x56, 0x43, 0x08, 0xdf, 0x13, 0x19, 0xde, 0x60, 0x5e, 0x0d, - 0x86, 0xdd, 0xa8, 0x57, 0x25, 0x33, 0xc9, 0xdc, 0x57, 0x01, 0x93, 0x8a, 0x72, 0x1b, 0xd8, 0x43, - 0x6f, 0x81, 0x87, 0xbe, 0x17, 0x72, 0x9b, 0x69, 0x3d, 0x44, 0xf8, 0xa1, 0x6f, 0x41, 0x1e, 0xd2, - 0x93, 0xdb, 0xd8, 0xf8, 0x0c, 0xe0, 0x36, 0xd5, 0x9a, 0x23, 0xec, 0x33, 0x80, 0x39, 0x3d, 0xb9, - 0x0d, 0xca, 0x67, 0x00, 0xb7, 0xa9, 0xd6, 0x1c, 0x61, 0x9f, 0x01, 0xcc, 0xe9, 0xc9, 0x6d, 0x50, - 0x3e, 0x03, 0xb8, 0x4d, 0xb5, 0xe6, 0x08, 0xfb, 0x0c, 0x60, 0x4e, 0x4f, 0x6e, 0x83, 0xf2, 0x19, - 0xc0, 0x6d, 0xaa, 0x35, 0x47, 0xf8, 0x67, 0x65, 0x80, 0x27, 0x71, 0x03, 0x25, 0xf9, 0x1d, 0x98, - 0x88, 0x27, 0xe0, 0x4f, 0xe2, 0xa1, 0xf3, 0x87, 0x21, 0x34, 0x08, 0x03, 0xec, 0xbb, 0x5b, 0x0e, - 0x23, 0x4f, 0xe5, 0x42, 0xb9, 0xfe, 0xa6, 0xd3, 0x7a, 0x75, 0x49, 0x4a, 0x3f, 0x85, 0x0e, 0xd2, - 0x6a, 0xf0, 0x25, 0xfd, 0x36, 0x74, 0x3f, 0x80, 0xdb, 0x1e, 0x35, 0xc3, 0x4b, 0xe7, 0xef, 0xc1, - 0xa7, 0xe9, 0x96, 0x8d, 0x6d, 0x9a, 0x00, 0x1e, 0xce, 0xf4, 0xca, 0xab, 0x08, 0xd2, 0xf3, 0xba, - 0x3b, 0xc5, 0x80, 0x6e, 0xd4, 0xa0, 0xd0, 0xea, 0x9f, 0x96, 0xea, 0x1d, 0x88, 0x5a, 0x3b, 0x3b, - 0x28, 0x06, 0xba, 0xe9, 0xb8, 0x47, 0xd0, 0xd3, 0xcd, 0xec, 0x2b, 0xf7, 0x61, 0x65, 0x4a, 0x91, - 0x28, 0xde, 0xde, 0xa7, 0x25, 0x8c, 0x8f, 0x56, 0x2e, 0x4a, 0xe7, 0x23, 0x9f, 0xce, 0xe8, 0x31, - 0x0d, 0xbd, 0x6a, 0x0a, 0xb8, 0x20, 0xe4, 0xf7, 0x56, 0xbb, 0x70, 0x58, 0xd8, 0x21, 0x1c, 0x82, - 0xbd, 0xd4, 0x14, 0x3d, 0x66, 0x00, 0xda, 0x5f, 0xfa, 0xb7, 0xeb, 0x05, 0xf0, 0x5e, 0xca, 0x03, - 0xd6, 0x4a, 0x85, 0x16, 0x30, 0xd2, 0x3b, 0xbc, 0x31, 0xac, 0x41, 0xaf, 0x20, 0x4f, 0x46, 0x04, - 0xc9, 0xb3, 0x4d, 0xc5, 0x57, 0xde, 0x7a, 0x00, 0xb3, 0x2f, 0xe7, 0x0b, 0xd8, 0x95, 0xb8, 0x71, - 0xf0, 0x4d, 0x83, 0x8d, 0x83, 0x3f, 0xa1, 0x67, 0x91, 0x37, 0xd0, 0xc7, 0xc5, 0xde, 0x5c, 0xcb, - 0x6e, 0x4a, 0x81, 0x88, 0x11, 0xda, 0xc8, 0x4b, 0xf8, 0xad, 0x82, 0x3c, 0x67, 0x0d, 0xb7, 0x1a, - 0x20, 0x1d, 0x1d, 0x75, 0x50, 0x65, 0x77, 0xe2, 0x06, 0x5f, 0x79, 0xa0, 0xb5, 0xec, 0xdf, 0xc7, - 0x86, 0xc2, 0x3f, 0xd1, 0xd1, 0x47, 0x4b, 0x27, 0x2a, 0xbb, 0x1d, 0xe9, 0x4e, 0xf8, 0xde, 0xb2, - 0xdb, 0x93, 0xe8, 0xcf, 0x4a, 0x6c, 0x06, 0x2b, 0xba, 0x44, 0xca, 0x59, 0x19, 0xc6, 0xc9, 0xed, - 0xc5, 0xa2, 0xeb, 0x85, 0xf0, 0x2f, 0xbc, 0x7b, 0xd4, 0x1e, 0xfa, 0xfa, 0xe1, 0x56, 0xf0, 0xb5, - 0xdd, 0x9b, 0x43, 0xcf, 0x66, 0xda, 0xce, 0x4a, 0x0c, 0x09, 0xdb, 0x51, 0xe8, 0x72, 0x03, 0x9c, - 0x46, 0x47, 0x24, 0x53, 0x2f, 0xde, 0x83, 0x73, 0x78, 0x95, 0x87, 0xb0, 0x00, 0x3f, 0xf8, 0xfb, - 0x2f, 0x22, 0xe0, 0x8d, 0xc7, 0xc3, 0x1c, 0x76, 0x3c, 0x22, 0xa7, 0x77, 0x0a, 0x07, 0xd9, 0x27, - 0x65, 0x9e, 0x5d, 0x7e, 0x1b, 0x13, 0x0a, 0xdb, 0x7e, 0xd9, 0x42, 0x0e, 0x62, 0x77, 0x7c, 0x33, - 0x6e, 0xdf, 0x9d, 0x7d, 0xf9, 0x3e, 0x64, 0x96, 0x2b, 0x8f, 0x62, 0xc4, 0xe3, 0x6e, 0x71, 0xf2, - 0xdb, 0x33, 0xa6, 0xa5, 0xb2, 0x5b, 0xb3, 0x9b, 0x81, 0x06, 0x82, 0x4b, 0x0d, 0xd0, 0x0b, 0x3d, - 0xc0, 0x9c, 0x57, 0x29, 0xbe, 0x4b, 0x58, 0x10, 0xfc, 0x07, 0x3d, 0xc2, 0xb4, 0xb7, 0x63, 0x0b, - 0xba, 0x86, 0x9c, 0x8a, 0xac, 0x34, 0xbc, 0xb3, 0x12, 0xd1, 0x51, 0x11, 0xf7, 0xdd, 0xd3, 0x17, - 0x5b, 0xeb, 0x49, 0x3c, 0xc0, 0xe0, 0xaa, 0x90, 0x57, 0x59, 0x0b, 0x2f, 0xe1, 0x2e, 0xf4, 0x7d, - 0x79, 0xca, 0x6e, 0x8a, 0xc6, 0x28, 0x5d, 0x6f, 0x9b, 0x0e, 0x32, 0x77, 0xa9, 0x01, 0x48, 0x86, - 0x1c, 0x14, 0x7e, 0xfe, 0xd5, 0xfb, 0xb0, 0x01, 0x67, 0x1a, 0xb8, 0x0a, 0xaa, 0x10, 0x8b, 0xce, - 0x1d, 0x2c, 0xc7, 0x2e, 0x62, 0x92, 0x13, 0x8e, 0x62, 0x8a, 0x71, 0x2c, 0x89, 0x43, 0xff, 0x43, - 0xb8, 0xdf, 0x9a, 0xd1, 0x8e, 0x43, 0x9a, 0x29, 0xcf, 0xb4, 0x71, 0xfa, 0xae, 0x3a, 0x92, 0x5f, - 0xc1, 0xba, 0xcb, 0x1f, 0x34, 0x8e, 0x88, 0x0d, 0x7f, 0x2c, 0x04, 0x56, 0x75, 0x8b, 0x62, 0x87, - 0x33, 0x14, 0x15, 0x72, 0x41, 0xc2, 0xe5, 0x06, 0x90, 0xcb, 0x44, 0x2a, 0x5a, 0x8f, 0xc7, 0x09, - 0x16, 0x5c, 0x2b, 0x80, 0x3c, 0xd9, 0xec, 0x83, 0x60, 0xe8, 0xc8, 0xc1, 0x74, 0xec, 0x8e, 0xfe, - 0x81, 0xdd, 0x52, 0x84, 0x49, 0x67, 0x48, 0x44, 0xaf, 0x23, 0x1e, 0x72, 0xc2, 0x6f, 0x38, 0x10, - 0x09, 0x08, 0xc5, 0x6e, 0x2d, 0xed, 0xd9, 0x36, 0x10, 0x89, 0x67, 0x8a, 0xec, 0x0d, 0x95, 0xd8, - 0x36, 0xd0, 0x63, 0x2e, 0x2c, 0xbe, 0x51, 0x08, 0x25, 0xd6, 0x63, 0x40, 0x9c, 0x46, 0x88, 0xbf, - 0x1f, 0xbc, 0xdd, 0xbe, 0x19, 0xcc, 0xc3, 0x19, 0x92, 0xbb, 0x67, 0x47, 0x6e, 0x35, 0x00, 0xaf, - 0x10, 0xbf, 0x5e, 0x7a, 0x50, 0x05, 0x6f, 0xe0, 0x8c, 0x25, 0x19, 0xe7, 0xfd, 0xea, 0x90, 0x14, - 0xd1, 0x18, 0x3e, 0xc0, 0x56, 0x66, 0x34, 0x13, 0x1a, 0x82, 0x4e, 0xdc, 0xbe, 0xc5, 0x73, 0x22, - 0x14, 0x68, 0x20, 0xff, 0xf1, 0xe9, 0xd6, 0xd0, 0xc1, 0x8e, 0x2d, 0xe5, 0x34, 0x03, 0x7a, 0x13, - 0xfb, 0xf8, 0xaf, 0x72, 0x94, 0x93, 0x02, 0xa2, 0xd7, 0x15, 0xbb, 0xca, 0xf7, 0xbb, 0x45, 0xc2, - 0x33, 0x78, 0x90, 0xc6, 0x93, 0xc1, 0xa3, 0x06, 0x90, 0x57, 0x8c, 0x66, 0x20, 0x4b, 0xb0, 0xf5, - 0x2d, 0xc7, 0x56, 0x88, 0x0e, 0xef, 0x59, 0xd1, 0x20, 0xac, 0xfc, 0x11, 0x3c, 0x45, 0xa4, 0xf5, - 0x0c, 0x45, 0x0f, 0x50, 0x1b, 0xd3, 0xeb, 0x0e, 0xe7, 0x1c, 0xea, 0x1f, 0x0d, 0x43, 0x9b, 0x1b, - 0xfb, 0x79, 0x93, 0xf3, 0xa3, 0xf8, 0xb4, 0x1f, 0xf2, 0xf1, 0xf9, 0xe3, 0x01, 0xcb, 0x26, 0x03, - 0xfe, 0x31, 0x2e, 0x14, 0x96, 0x76, 0x72, 0x6e, 0x26, 0xa6, 0xe6, 0x61, 0x6f, 0xda, 0x6b, 0x06, - 0x50, 0x0b, 0x9a, 0x82, 0xad, 0x53, 0xef, 0xac, 0xd8, 0xdb, 0xd8, 0x85, 0x2d, 0xbb, 0x59, 0x28, - 0x50, 0x3e, 0x7d, 0xa2, 0x05, 0xfc, 0x01, 0xa7, 0xb1, 0x8e, 0x04, 0x3a, 0x88, 0x9a, 0x80, 0x27, - 0x08, 0xb5, 0x8c, 0xec, 0x08, 0x3d, 0x67, 0x71, 0x1a, 0x8c, 0x01, 0xf4, 0x2a, 0xf2, 0x21, 0x3e, - 0x31, 0x4f, 0xff, 0xe1, 0x9e, 0x28, 0xa6, 0x31, 0xe3, 0xaf, 0xf8, 0xe4, 0xfa, 0x73, 0x09, 0xf6, - 0x8f, 0x5e, 0x1e, 0xac, 0x39, 0xbd, 0x34, 0xa0, 0xf1, 0xb9, 0x43, 0x53, 0xcb, 0xc3, 0xd0, 0x9f, - 0xe2, 0xc3, 0x7e, 0x56, 0xca, 0x27, 0x55, 0x36, 0xf8, 0x3b, 0xc0, 0x83, 0xf6, 0xf6, 0x0a, 0xab, - 0x06, 0x7d, 0x07, 0x78, 0x45, 0x23, 0x1e, 0x66, 0xea, 0x33, 0x80, 0x87, 0x15, 0xae, 0x66, 0xe7, - 0x33, 0x80, 0x5a, 0x23, 0x1e, 0x4e, 0xfb, 0x0c, 0xe0, 0x61, 0x85, 0xab, 0xd9, 0xf9, 0x0c, 0xa0, - 0xd6, 0x88, 0x87, 0xd3, 0x0f, 0xbd, 0x01, 0xaa, 0xaa, 0xaa, 0x00, 0x5d, 0x9e, 0x7a, 0x58, 0x6d, - 0xae, 0x63, 0xe7, 0x71, 0x03, 0xac, 0x5e, 0xbd, 0xda, 0xe6, 0x90, 0x21, 0xbd, 0x16, 0x18, 0x3b, - 0x76, 0xac, 0xdd, 0xb5, 0xc2, 0xe3, 0x48, 0x80, 0x9f, 0x72, 0x01, 0xfc, 0x02, 0x9d, 0xc3, 0xae, - 0x87, 0xed, 0x66, 0x6a, 0x45, 0x20, 0xa3, 0x17, 0x14, 0xe8, 0xbb, 0x7e, 0x32, 0x4b, 0xd7, 0xe3, - 0x06, 0xa0, 0x2f, 0xf7, 0xcc, 0x9f, 0x3f, 0x1f, 0x26, 0x4c, 0x98, 0x00, 0x1d, 0x3a, 0x74, 0x10, - 0x72, 0x56, 0x56, 0x2a, 0x17, 0x70, 0x44, 0x81, 0x41, 0x84, 0x4e, 0xa3, 0xb6, 0x6d, 0xdb, 0x96, - 0xfd, 0x28, 0xee, 0xa9, 0xb0, 0x60, 0xc1, 0x02, 0x66, 0xf4, 0xc8, 0xc8, 0x48, 0x78, 0xf1, 0xc5, - 0x17, 0x9d, 0x62, 0x6b, 0xda, 0x3b, 0x05, 0x7d, 0x72, 0xf0, 0xc6, 0x8d, 0x1b, 0x50, 0x51, 0x51, - 0xc1, 0xce, 0x38, 0x76, 0xec, 0xd8, 0x11, 0x28, 0xef, 0xf2, 0xe5, 0xcb, 0x70, 0xea, 0xd4, 0x29, - 0x20, 0x05, 0xa2, 0x0f, 0x68, 0xa0, 0x73, 0x90, 0xcd, 0x9a, 0xe9, 0x7b, 0xad, 0x49, 0x48, 0x48, - 0x80, 0x65, 0xcb, 0x96, 0x31, 0xa1, 0xa9, 0x05, 0xa3, 0xcf, 0x68, 0xbb, 0x2b, 0x80, 0xa7, 0xf8, - 0x98, 0x2c, 0x31, 0x31, 0x31, 0xb0, 0x73, 0xe7, 0x4e, 0x86, 0xdf, 0xaa, 0x95, 0xbe, 0x2b, 0x20, - 0x2d, 0x06, 0xf8, 0xc1, 0x24, 0xb8, 0x74, 0xe9, 0x12, 0xa4, 0xa7, 0xa7, 0xb3, 0xbb, 0x08, 0x7d, - 0x5f, 0x43, 0xdf, 0xbe, 0x7d, 0x01, 0xfd, 0x5b, 0xc3, 0x27, 0x9f, 0x7c, 0x02, 0x13, 0x27, 0x4e, - 0x84, 0xae, 0x5d, 0xbb, 0x6a, 0xa1, 0x02, 0xf1, 0xe7, 0x81, 0x3e, 0x07, 0xe5, 0x54, 0xd0, 0x38, - 0x3a, 0x66, 0x93, 0x95, 0x95, 0x95, 0x25, 0x61, 0x37, 0xa1, 0x38, 0xff, 0x86, 0x4a, 0x56, 0xa4, - 0x51, 0x08, 0x45, 0xfa, 0x85, 0x17, 0x5e, 0xb0, 0xa1, 0xa3, 0xce, 0xe0, 0xa7, 0x75, 0x09, 0xd7, - 0xc8, 0x35, 0xb5, 0x1c, 0x6f, 0xcb, 0x96, 0x2d, 0x0a, 0x3e, 0x9c, 0xaf, 0x96, 0xeb, 0x6a, 0x39, - 0x1e, 0xc5, 0x51, 0x59, 0x12, 0x2a, 0x55, 0xe0, 0xd3, 0x71, 0xe8, 0x2e, 0x5d, 0xba, 0x48, 0x83, - 0x07, 0x0f, 0x16, 0x6e, 0xad, 0x39, 0xbd, 0x81, 0x03, 0x07, 0x2a, 0xd0, 0xf7, 0xee, 0xdd, 0x2b, - 0xf0, 0x38, 0x8c, 0xd1, 0xf5, 0xe4, 0xc9, 0x93, 0x0a, 0x7c, 0xbd, 0x84, 0xcd, 0x41, 0x43, 0x3d, - 0x40, 0xca, 0xe7, 0x47, 0x40, 0x39, 0xe3, 0xf5, 0xeb, 0xd7, 0x2b, 0xc0, 0x6f, 0xde, 0xbc, 0x29, - 0x35, 0x69, 0xd2, 0x44, 0x08, 0x1a, 0x17, 0x17, 0xa7, 0x28, 0x57, 0x27, 0x1c, 0x31, 0x80, 0x9c, - 0x06, 0x3f, 0x4e, 0x4d, 0xf2, 0x98, 0x31, 0x80, 0xfc, 0x8c, 0x2c, 0xe1, 0xe0, 0xc7, 0xcf, 0x6c, - 0xdc, 0x71, 0xe3, 0xe1, 0x5e, 0x69, 0xf1, 0xe2, 0xc5, 0xcc, 0x33, 0xbc, 0x9c, 0x17, 0x1d, 0x4f, - 0x3d, 0x74, 0xe8, 0x10, 0xf3, 0xf8, 0x4e, 0x06, 0xe3, 0x3a, 0xe0, 0x9e, 0xdf, 0xc9, 0xfb, 0x3b, - 0xf7, 0x00, 0xaf, 0xe5, 0x64, 0x5d, 0x4e, 0x4b, 0x1e, 0x77, 0xd8, 0x00, 0x38, 0x68, 0xca, 0xe9, - 0x88, 0xf8, 0xda, 0xb5, 0x6b, 0x85, 0x70, 0x24, 0xa4, 0x91, 0x30, 0x9e, 0x36, 0x00, 0x09, 0x49, - 0x9f, 0x55, 0xe3, 0xca, 0xd3, 0xbb, 0x26, 0x26, 0x26, 0x4a, 0x9b, 0x37, 0x6f, 0x16, 0x75, 0x52, - 0x47, 0xf8, 0x59, 0x78, 0xc2, 0xaf, 0xcf, 0x73, 0xbd, 0x1a, 0x57, 0x9d, 0x76, 0x78, 0x10, 0xde, - 0xb7, 0x6f, 0x1f, 0xc8, 0x3f, 0x8f, 0x8e, 0xc2, 0xb0, 0x35, 0xe0, 0x8f, 0x3e, 0xfa, 0x88, 0xa2, - 0x2c, 0xd0, 0x58, 0x30, 0x60, 0xc0, 0x00, 0x9e, 0xf4, 0xfa, 0x15, 0x2b, 0x0f, 0xe3, 0xc7, 0x8f, - 0x87, 0x5b, 0xb7, 0x6e, 0x31, 0x59, 0x69, 0x3c, 0x43, 0xe7, 0x03, 0x80, 0x77, 0x06, 0x3b, 0xca, - 0xde, 0xba, 0x75, 0x6b, 0x26, 0x23, 0x7e, 0xf7, 0x00, 0x26, 0x4d, 0x9a, 0x04, 0xf3, 0xe6, 0xcd, - 0xd3, 0x94, 0x99, 0xc6, 0x09, 0x1e, 0x9c, 0x9e, 0x09, 0xa9, 0x2d, 0x62, 0x94, 0x56, 0x77, 0x41, - 0x28, 0x04, 0x6b, 0x4d, 0xf4, 0x31, 0x88, 0xc0, 0xc0, 0x40, 0x45, 0xcb, 0x6a, 0xd3, 0xa6, 0x8d, - 0x54, 0x58, 0x58, 0xa8, 0x20, 0xf7, 0xce, 0x3b, 0xef, 0x48, 0x9d, 0x3b, 0x77, 0x96, 0x08, 0x9e, - 0x7e, 0x4d, 0x9b, 0x36, 0x15, 0x38, 0xe8, 0xbc, 0x40, 0xe4, 0xb7, 0x6b, 0xd7, 0x4e, 0x7a, 0xf5, - 0xd5, 0x57, 0x15, 0xb8, 0x94, 0xd8, 0xbe, 0x7d, 0x3b, 0xfb, 0xbc, 0x00, 0xc7, 0x6f, 0xd1, 0xa2, - 0x85, 0xc0, 0xa7, 0x31, 0x8a, 0xe7, 0xd3, 0x97, 0x05, 0x47, 0x8f, 0x1e, 0x2d, 0x65, 0x67, 0x67, - 0x2b, 0x68, 0xd0, 0x71, 0x7d, 0x2e, 0x33, 0xf5, 0xff, 0xf4, 0xd1, 0xe5, 0x2b, 0x57, 0xae, 0x48, - 0x38, 0x81, 0x90, 0xe8, 0x78, 0x3e, 0x8d, 0x2f, 0xf2, 0xb1, 0x6e, 0xdd, 0xba, 0x75, 0x0a, 0x7c, - 0x9e, 0xd8, 0xb8, 0x71, 0xa3, 0xa0, 0x43, 0xf4, 0x88, 0x16, 0x7d, 0xf6, 0x00, 0x27, 0x02, 0x8a, - 0x7c, 0x2a, 0x23, 0xfa, 0x46, 0xc1, 0xe1, 0x2e, 0x88, 0x3e, 0x9b, 0x40, 0xae, 0x59, 0x68, 0xb0, - 0xed, 0xd1, 0xa3, 0x07, 0xfb, 0x90, 0x05, 0xb6, 0x2e, 0xe6, 0xbe, 0x82, 0x2a, 0xa3, 0x15, 0xa8, - 0xcb, 0xe1, 0x9f, 0x6d, 0xe4, 0x8a, 0xd0, 0xba, 0xd2, 0x67, 0x1a, 0x49, 0x81, 0xea, 0x80, 0xb3, - 0x13, 0x09, 0x67, 0x3e, 0x36, 0x95, 0x54, 0xd3, 0x20, 0x25, 0xf6, 0xea, 0xd5, 0x4b, 0xe2, 0xfe, - 0x13, 0x38, 0x1d, 0x92, 0x97, 0x60, 0xe9, 0x4b, 0x1e, 0xf4, 0xc5, 0x0f, 0x35, 0x1e, 0xa5, 0xd1, - 0x59, 0x0a, 0xeb, 0xa6, 0x68, 0xe2, 0x61, 0x14, 0x72, 0x73, 0x73, 0xa5, 0x29, 0x53, 0xa6, 0xd8, - 0x34, 0x3c, 0x6a, 0x88, 0xe4, 0xaf, 0x61, 0xd3, 0xa6, 0x4d, 0x46, 0xe8, 0xa2, 0xcc, 0x29, 0x03, - 0x08, 0x2a, 0xbe, 0x88, 0xc3, 0x1a, 0x30, 0xb5, 0x20, 0x43, 0x0f, 0x4c, 0x38, 0xc3, 0xc1, 0x06, - 0xa2, 0x1d, 0xf0, 0x0e, 0x00, 0xfc, 0x9e, 0x8c, 0x76, 0xa1, 0x2f, 0xd7, 0x50, 0x03, 0xa6, 0x0c, - 0xc0, 0x1f, 0xb8, 0xf0, 0x0b, 0x2a, 0x36, 0xc4, 0xe8, 0x69, 0x10, 0xfb, 0x75, 0x5d, 0xff, 0x46, - 0x36, 0x08, 0xbe, 0x0c, 0x85, 0x06, 0x4c, 0x19, 0x40, 0x81, 0xe1, 0x4b, 0xb8, 0x54, 0x03, 0x0e, - 0x4f, 0x43, 0x5d, 0x2a, 0xc5, 0x23, 0x4c, 0xcc, 0x67, 0x00, 0x2f, 0x1b, 0xdf, 0x67, 0x00, 0x9f, - 0x01, 0xbc, 0xac, 0x01, 0x2f, 0xb3, 0xf7, 0xdd, 0x01, 0x5e, 0x36, 0xc0, 0xff, 0x01, 0x60, 0x99, - 0xd3, 0x96, 0x0f, 0xf3, 0xae, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, - 0x60, 0x82 -}; - -static const u_int8_t FLEXTextIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x33, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xd4, - 0x6c, 0xf8, 0x31, 0x00, 0x00, 0x05, 0x4f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x5b, - 0x2c, 0x6c, 0x57, 0x18, 0x9e, 0x61, 0xce, 0x5c, 0x5c, 0xe2, 0x5a, 0xd7, 0x10, 0x97, 0x53, 0xd7, - 0xba, 0x3d, 0xd0, 0x3e, 0x20, 0x2a, 0x82, 0x88, 0x22, 0x1e, 0x08, 0xaa, 0x24, 0x08, 0x21, 0x12, - 0x11, 0x91, 0xf4, 0xa9, 0x69, 0x1a, 0xf5, 0x26, 0x22, 0xc1, 0x83, 0x04, 0x91, 0xa6, 0x09, 0x5e, - 0x2a, 0x8d, 0x34, 0x91, 0xa0, 0xe1, 0xd4, 0x83, 0x07, 0xd2, 0x70, 0x8a, 0xe8, 0x11, 0xe2, 0x1a, - 0x8a, 0xc1, 0x30, 0x86, 0x41, 0xbf, 0xb1, 0xcc, 0xea, 0x9c, 0x33, 0xec, 0xd9, 0x33, 0xb3, 0x9c, - 0x46, 0xb2, 0x57, 0x64, 0xe7, 0x5f, 0xff, 0xff, 0xfd, 0xf7, 0xb5, 0xd6, 0xac, 0xbd, 0x89, 0xef, - 0xee, 0xee, 0x44, 0x2f, 0x79, 0xd8, 0xbc, 0xe4, 0xe0, 0x75, 0xb1, 0x0b, 0x09, 0xfc, 0xdf, 0x1d, - 0x14, 0x3a, 0x20, 0x74, 0xc0, 0xca, 0x0a, 0x08, 0x4b, 0xc8, 0xca, 0x02, 0x5a, 0xad, 0x2e, 0x74, - 0xc0, 0xea, 0x12, 0x5a, 0x69, 0x40, 0xe8, 0x80, 0x95, 0x05, 0xb4, 0x5a, 0x5d, 0x62, 0xb5, 0x05, - 0x9d, 0x01, 0xad, 0xe8, 0x6e, 0x4a, 0xa5, 0x7c, 0xa7, 0x51, 0xdf, 0x9a, 0xba, 0x1a, 0xda, 0x88, - 0xc5, 0xaf, 0x65, 0x8a, 0x24, 0x07, 0x67, 0x89, 0x48, 0xcc, 0xc4, 0x35, 0x9b, 0x04, 0x7e, 0x3d, - 0xf9, 0x27, 0xff, 0xdd, 0x9f, 0xfc, 0x03, 0xfa, 0x25, 0x38, 0x26, 0xd7, 0xe9, 0x13, 0xfe, 0x78, - 0x0e, 0x24, 0x9b, 0x3d, 0xb0, 0xae, 0x51, 0x73, 0xf8, 0x30, 0x16, 0xad, 0x99, 0x89, 0x37, 0xb6, - 0x40, 0x39, 0x6c, 0x3a, 0x70, 0x7e, 0x7b, 0x43, 0x2c, 0xba, 0x49, 0xa4, 0x9e, 0xaf, 0xa4, 0xa0, - 0x8f, 0xb5, 0xd7, 0xbb, 0xd7, 0x1a, 0xc2, 0xf4, 0x91, 0xca, 0x9c, 0x6d, 0x5f, 0x81, 0xde, 0xbb, - 0xd6, 0x1c, 0x69, 0xaf, 0x41, 0x5c, 0xdc, 0xde, 0x12, 0x91, 0xf5, 0x4f, 0x36, 0x1d, 0x50, 0xeb, - 0x03, 0xaa, 0x76, 0xf7, 0x7d, 0x1b, 0xfe, 0x05, 0xfe, 0xbe, 0xf7, 0x09, 0xa6, 0xc1, 0xfd, 0xe0, - 0x1d, 0x4c, 0x98, 0x95, 0xee, 0xbe, 0x84, 0xa9, 0xbe, 0x7b, 0x48, 0x98, 0x62, 0x2c, 0x26, 0x18, - 0x25, 0x70, 0xf7, 0x50, 0x51, 0x99, 0x0d, 0x97, 0x41, 0xb9, 0xf8, 0x41, 0x7a, 0xa9, 0x4f, 0xd8, - 0xe2, 0xb8, 0xa9, 0x22, 0x97, 0x3f, 0x0a, 0x32, 0x49, 0xa8, 0xf5, 0x4b, 0x88, 0x86, 0xf8, 0xa8, - 0x8a, 0x42, 0x9f, 0x1e, 0xed, 0xd8, 0xa3, 0x30, 0xb3, 0x98, 0x6c, 0x12, 0x08, 0x95, 0xdb, 0x13, - 0xaf, 0x81, 0x32, 0x05, 0x87, 0xfb, 0x68, 0x85, 0x23, 0x91, 0x86, 0xc8, 0xed, 0x38, 0x60, 0x66, - 0x89, 0xd8, 0x6c, 0xe2, 0x6f, 0x5c, 0xbd, 0x4f, 0x6e, 0xb4, 0x38, 0xda, 0xbf, 0x72, 0x72, 0xe7, - 0x70, 0xff, 0xa5, 0xa3, 0xcb, 0x8f, 0xbe, 0xaf, 0x51, 0xfe, 0xaf, 0x5d, 0xbd, 0x38, 0x60, 0x66, - 0x89, 0xd8, 0x24, 0xe0, 0x6a, 0x2b, 0xf9, 0xce, 0x2b, 0xd0, 0xa4, 0x63, 0x85, 0xd8, 0xe6, 0x5b, - 0xcf, 0x00, 0x93, 0x30, 0xb3, 0x00, 0x6c, 0x96, 0x90, 0x59, 0x2e, 0xd9, 0x82, 0x85, 0x04, 0xd8, - 0xd6, 0xd3, 0x7c, 0x6b, 0x2f, 0xbe, 0x03, 0x6c, 0x36, 0x31, 0x2d, 0xdc, 0xd1, 0x8d, 0xf6, 0xaf, - 0x4b, 0x15, 0xa6, 0x7f, 0x6b, 0x2e, 0x28, 0x73, 0x55, 0x73, 0xf1, 0xe6, 0x5c, 0x29, 0x16, 0x89, - 0xc3, 0xe5, 0xf6, 0xd8, 0xee, 0x94, 0xcf, 0x84, 0x10, 0x33, 0xfc, 0x36, 0xfa, 0xf3, 0xf1, 0x5e, - 0xe9, 0xfa, 0x5b, 0x8e, 0x1b, 0x35, 0xee, 0xd2, 0x3f, 0x05, 0x7c, 0x56, 0xe4, 0xe2, 0xc9, 0x24, - 0x74, 0x62, 0x84, 0xe5, 0x12, 0xfa, 0x43, 0x75, 0xc2, 0x11, 0x3d, 0xfc, 0x41, 0xfa, 0x46, 0xa5, - 0x64, 0x18, 0x3d, 0x4c, 0xb1, 0x4c, 0xa0, 0xc4, 0xd5, 0x2b, 0x4a, 0xe1, 0xc0, 0x11, 0x1f, 0xa4, - 0xc0, 0x70, 0x00, 0x2c, 0x10, 0xb1, 0x5c, 0x42, 0x16, 0xb8, 0xb7, 0x5e, 0x85, 0x65, 0x07, 0xac, - 0x8f, 0xc6, 0x02, 0x0b, 0x42, 0x02, 0x16, 0x14, 0x8d, 0xa9, 0x8a, 0xd0, 0x01, 0xa6, 0xe5, 0xb4, - 0xc0, 0x98, 0xd0, 0x01, 0x0b, 0x8a, 0xc6, 0x54, 0x85, 0x6f, 0x07, 0xb4, 0x5a, 0xed, 0xe4, 0xe4, - 0xe4, 0xee, 0xee, 0x2e, 0x53, 0xef, 0xef, 0x19, 0xdb, 0xd8, 0xd8, 0x98, 0x9a, 0x9a, 0x32, 0xfb, - 0x6a, 0x03, 0x05, 0x3e, 0x63, 0x74, 0x74, 0x14, 0xde, 0xb2, 0xb2, 0xb2, 0xf8, 0x80, 0x2d, 0xc3, - 0xc4, 0xc7, 0xc7, 0xc3, 0xc5, 0xec, 0xec, 0xac, 0x59, 0xea, 0x7c, 0x3b, 0x70, 0x70, 0x70, 0x00, - 0xeb, 0xe4, 0xf9, 0x5e, 0xdd, 0xd8, 0x4d, 0x2c, 0x73, 0xc1, 0x2b, 0x81, 0xa5, 0xa5, 0xa5, 0xe5, - 0xe5, 0x65, 0x84, 0x7a, 0x76, 0x76, 0xf6, 0xfb, 0xfd, 0x40, 0x9d, 0xb0, 0xa8, 0x0c, 0x83, 0x3f, - 0x3d, 0x3d, 0x6d, 0x6c, 0x6c, 0x8c, 0x89, 0x89, 0x71, 0x70, 0x70, 0x88, 0x8c, 0x8c, 0x6c, 0x6e, - 0x6e, 0x3e, 0x3f, 0x3f, 0xa7, 0x80, 0xfa, 0xfa, 0xfa, 0xcf, 0xef, 0x47, 0x45, 0x45, 0x05, 0x0a, - 0x5c, 0x54, 0x54, 0x84, 0x59, 0x62, 0x62, 0xe2, 0xe0, 0xe0, 0x20, 0x30, 0x2a, 0x95, 0x6a, 0x7a, - 0x7a, 0xfa, 0xf2, 0xf2, 0x12, 0xf4, 0xc2, 0xc2, 0x02, 0x71, 0xb1, 0xb3, 0xb3, 0x43, 0xd5, 0xb9, - 0x08, 0x93, 0xfd, 0x9a, 0x9b, 0x9b, 0x7b, 0x54, 0xbf, 0xa5, 0xa5, 0x85, 0xea, 0x62, 0x6f, 0xf8, - 0xf9, 0xf9, 0x11, 0x98, 0x9b, 0x9b, 0x1b, 0x21, 0x22, 0x22, 0x22, 0x90, 0x03, 0x30, 0x48, 0xd5, - 0xde, 0xfe, 0xe1, 0xbb, 0x8b, 0x4c, 0x26, 0x53, 0x2a, 0x95, 0x36, 0xfa, 0x0f, 0x44, 0x25, 0x25, - 0x25, 0x00, 0xe4, 0xe4, 0xe4, 0x18, 0xbb, 0xb0, 0xb3, 0xb3, 0xbb, 0xba, 0xba, 0xa2, 0x2e, 0x9e, - 0x22, 0x44, 0x4f, 0x09, 0x28, 0x7f, 0x7f, 0x7f, 0x3f, 0x29, 0x29, 0xc9, 0xd3, 0x53, 0x77, 0x89, - 0x87, 0xfb, 0x4f, 0xef, 0x47, 0x6c, 0x6c, 0xec, 0xd8, 0xd8, 0x18, 0xc5, 0xe4, 0xe5, 0xe5, 0x41, - 0x9a, 0x96, 0x96, 0xb6, 0xb5, 0xb5, 0x05, 0xe6, 0xfc, 0xfc, 0xbc, 0xaf, 0xaf, 0xee, 0x2b, 0x62, - 0x53, 0x53, 0x13, 0xc1, 0xa0, 0x81, 0x65, 0x65, 0x65, 0xe0, 0x24, 0x24, 0x24, 0x1c, 0x1f, 0x1f, - 0x87, 0x87, 0x87, 0x4b, 0xa5, 0xd2, 0xde, 0xde, 0xde, 0xa3, 0xa3, 0x23, 0x00, 0x3a, 0x3a, 0x3a, - 0xc2, 0xc2, 0xc2, 0x24, 0x12, 0xdd, 0xbb, 0x8e, 0x8f, 0x8f, 0x0f, 0x71, 0x51, 0x58, 0x58, 0x48, - 0xed, 0x73, 0x10, 0xa6, 0x13, 0x20, 0xca, 0xfd, 0xfd, 0xfd, 0xb0, 0x8e, 0x7d, 0x66, 0x6c, 0x4b, - 0xad, 0x56, 0xdb, 0xda, 0xda, 0x42, 0xda, 0xde, 0xde, 0xfe, 0x9b, 0x7e, 0x60, 0xa9, 0x80, 0x13, - 0x1d, 0x1d, 0x4d, 0xf1, 0xe8, 0x43, 0x66, 0x66, 0x26, 0x98, 0x5e, 0x5e, 0xba, 0x1b, 0x75, 0x5f, - 0x5f, 0x1f, 0x15, 0x11, 0x22, 0x20, 0x20, 0x00, 0x7c, 0x9c, 0x16, 0x1f, 0xf0, 0xb9, 0xa7, 0x0c, - 0x5e, 0xf0, 0x56, 0x57, 0x57, 0x6f, 0x6e, 0x74, 0x1f, 0x6b, 0x1b, 0x1a, 0x1a, 0xf0, 0x34, 0x1c, - 0x17, 0x17, 0xff, 0xbd, 0x58, 0x22, 0xc9, 0xa1, 0xa1, 0xa1, 0xc0, 0xc0, 0xc0, 0xbd, 0xbd, 0xbd, - 0x94, 0x94, 0x94, 0xf2, 0xf2, 0x72, 0x43, 0xa4, 0xc5, 0x34, 0xdf, 0x04, 0xc8, 0xaa, 0xc5, 0x6e, - 0x33, 0xf6, 0x84, 0xa6, 0x13, 0x66, 0x4f, 0x4f, 0x4f, 0x54, 0x54, 0x14, 0x05, 0x20, 0xe2, 0x90, - 0x90, 0x10, 0x3a, 0x05, 0xd1, 0xd6, 0xd6, 0x76, 0x78, 0x78, 0x28, 0x97, 0xcb, 0xb1, 0x4d, 0x3b, - 0x3b, 0x3b, 0xeb, 0xea, 0xea, 0x0c, 0xa5, 0x1c, 0x2e, 0x0c, 0x61, 0x1f, 0xd2, 0xdc, 0x0d, 0xa2, - 0xd2, 0x91, 0x91, 0x11, 0x68, 0x22, 0xa6, 0xb5, 0xb5, 0x35, 0x1c, 0x17, 0xe3, 0xe3, 0xe3, 0xb5, - 0xb5, 0xb5, 0x58, 0x57, 0x04, 0x10, 0x1a, 0x1a, 0x0a, 0x69, 0x7a, 0x7a, 0x3a, 0xd9, 0xb5, 0x60, - 0x2e, 0x2e, 0x2e, 0x56, 0x57, 0x57, 0xb7, 0xb6, 0xb6, 0x52, 0x0b, 0xdd, 0xdd, 0xdd, 0xc0, 0xe0, - 0xe4, 0x81, 0xc8, 0xd9, 0xd9, 0x19, 0xe1, 0x0e, 0x0f, 0x0f, 0x53, 0x29, 0x88, 0xb8, 0xb8, 0x38, - 0x00, 0xaa, 0xaa, 0xaa, 0xb0, 0xd8, 0xd6, 0xd7, 0xd7, 0xbb, 0xba, 0xba, 0x4a, 0x4b, 0x4b, 0x91, - 0xb0, 0x21, 0xc6, 0x98, 0xe6, 0xbb, 0x07, 0x56, 0x56, 0x56, 0x60, 0x1d, 0x03, 0x8e, 0x15, 0x8a, - 0x87, 0x2f, 0xb8, 0x88, 0x98, 0x58, 0xc4, 0x8f, 0xb4, 0x58, 0xac, 0xfb, 0x9f, 0x17, 0x44, 0xa9, - 0xa9, 0xa9, 0x64, 0x07, 0x63, 0x5a, 0x50, 0x50, 0x40, 0x00, 0xd8, 0xdf, 0x3a, 0x65, 0x91, 0x28, - 0x3f, 0x3f, 0x1f, 0x9b, 0xd8, 0xdb, 0xdb, 0x9b, 0x4c, 0x33, 0x32, 0x32, 0x68, 0x4c, 0xc5, 0xc5, - 0xc5, 0x84, 0x49, 0x8f, 0x2c, 0x4c, 0x67, 0x66, 0x66, 0x28, 0xe0, 0x51, 0x82, 0x6f, 0x02, 0x50, - 0xc6, 0x59, 0xe1, 0xe8, 0xa8, 0xfb, 0xbc, 0x8c, 0x1c, 0x70, 0x68, 0x54, 0x56, 0x56, 0x6e, 0x6f, - 0x6f, 0x53, 0xa3, 0x13, 0x13, 0x13, 0x38, 0x9a, 0x48, 0x04, 0x00, 0xe0, 0x9c, 0xa9, 0xa9, 0xa9, - 0x21, 0x87, 0x0c, 0x30, 0xf8, 0x09, 0x27, 0xa2, 0xdc, 0xdc, 0x5c, 0x24, 0xe0, 0xe1, 0xe1, 0x81, - 0x29, 0x72, 0xce, 0xce, 0xce, 0xa6, 0x16, 0x50, 0xf5, 0xe4, 0xe4, 0x64, 0x02, 0x73, 0x72, 0x72, - 0x42, 0x21, 0x06, 0x06, 0x06, 0xa8, 0xf4, 0x29, 0xc2, 0xbc, 0x77, 0x62, 0x58, 0xd9, 0xdc, 0xdc, - 0x74, 0x71, 0x71, 0x21, 0x99, 0x10, 0x67, 0x86, 0x4f, 0xfc, 0x9c, 0xe1, 0x4a, 0x13, 0x14, 0x14, - 0x64, 0x58, 0x45, 0x43, 0x80, 0x49, 0x1a, 0xdb, 0x0c, 0xcb, 0xc6, 0xdf, 0xdf, 0x9f, 0xb4, 0xd4, - 0x24, 0xde, 0xbc, 0x04, 0x4c, 0x9a, 0xfb, 0xf8, 0x00, 0x5e, 0x57, 0x89, 0x8f, 0x1f, 0x16, 0x7f, - 0x8f, 0x42, 0x02, 0xfc, 0x6b, 0xf5, 0x3c, 0x48, 0xa1, 0x03, 0xcf, 0x53, 0x57, 0xfe, 0x56, 0x85, - 0x0e, 0xf0, 0xaf, 0xd5, 0xf3, 0x20, 0x85, 0x0e, 0x3c, 0x4f, 0x5d, 0xf9, 0x5b, 0x15, 0x3a, 0xc0, - 0xbf, 0x56, 0xcf, 0x83, 0xfc, 0x17, 0xab, 0x70, 0xa9, 0x05, 0xf0, 0x5c, 0xd1, 0x77, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXTextIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0b, 0x9d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x59, 0x6c, 0x14, 0xc9, 0xf5, 0xf9, 0x02, 0xdb, 0xd8, 0x66, 0x8d, 0xd6, 0xf6, 0x2e, 0xc1, - 0x46, 0x59, 0x41, 0x62, 0x2c, 0xc2, 0x8d, 0x20, 0x80, 0x04, 0x24, 0x8a, 0x11, 0x88, 0x0f, 0x20, - 0xc1, 0x12, 0x20, 0x21, 0x81, 0x58, 0x89, 0x0f, 0x40, 0x80, 0x20, 0x04, 0x14, 0xe0, 0x0b, 0x3e, - 0x88, 0xb8, 0x43, 0x40, 0x09, 0x87, 0x10, 0xe7, 0x86, 0x2b, 0x8a, 0x84, 0x20, 0xe6, 0x10, 0x26, - 0x2c, 0x87, 0x82, 0x62, 0x90, 0x02, 0xd8, 0x60, 0x0e, 0x1f, 0xd8, 0x6b, 0x7b, 0x85, 0xef, 0x03, - 0x7b, 0x3c, 0x9d, 0x7a, 0x65, 0x57, 0x4d, 0xf7, 0x74, 0x4f, 0x4f, 0x77, 0xbb, 0x0f, 0x1f, 0x55, - 0x52, 0x4f, 0x55, 0xbd, 0x7a, 0xf7, 0xab, 0xea, 0xee, 0xe9, 0xae, 0xaa, 0x8e, 0x90, 0x48, 0x02, - 0x13, 0x29, 0xd2, 0x04, 0x2e, 0x45, 0x8d, 0x0e, 0x26, 0xb8, 0x93, 0xfd, 0x9a, 0x82, 0x06, 0x26, - 0x47, 0x43, 0x44, 0x54, 0x04, 0x4c, 0x3f, 0xff, 0x53, 0x25, 0x0a, 0xaa, 0x14, 0x9c, 0xca, 0xff, - 0x55, 0x47, 0x41, 0xb7, 0x7f, 0x53, 0x28, 0xe1, 0x21, 0x4f, 0x61, 0x55, 0xfa, 0x75, 0xee, 0xcf, - 0x14, 0x12, 0xc2, 0x12, 0x54, 0x7f, 0xdf, 0xa8, 0x20, 0x88, 0x40, 0x71, 0x0a, 0x48, 0x98, 0x4a, - 0x58, 0x09, 0xc1, 0xf4, 0x86, 0x08, 0x9e, 0x3f, 0x7f, 0xce, 0xe9, 0x34, 0x09, 0x16, 0x2e, 0x5c, - 0x48, 0x11, 0x22, 0x22, 0x22, 0x38, 0x22, 0x2b, 0x38, 0x6f, 0x83, 0xf3, 0x12, 0x14, 0x46, 0x63, - 0x3f, 0x62, 0x07, 0x1a, 0x99, 0xff, 0xfb, 0x32, 0x66, 0x6b, 0x20, 0x97, 0xf7, 0x13, 0x2c, 0xb3, - 0xbe, 0xa3, 0xd5, 0x8f, 0xb0, 0x5d, 0x21, 0x21, 0xc0, 0x06, 0x00, 0xfb, 0x50, 0xc2, 0xf0, 0x81, - 0x72, 0x10, 0x2d, 0x87, 0x24, 0xc0, 0xd6, 0xc6, 0xe2, 0xcf, 0x2a, 0x02, 0x17, 0xbd, 0xb4, 0x71, - 0xe3, 0x46, 0x95, 0x78, 0x04, 0xd4, 0xd7, 0xd7, 0x2b, 0xe0, 0x2a, 0x1b, 0xb0, 0xff, 0xb0, 0xbe, - 0xa4, 0xc0, 0xec, 0xaa, 0x38, 0x6f, 0x83, 0x69, 0x09, 0x5a, 0x6a, 0xea, 0xc1, 0x54, 0x36, 0xeb, - 0x21, 0x5b, 0x69, 0x33, 0x24, 0x00, 0xfb, 0x6f, 0x45, 0xae, 0x32, 0x1a, 0x08, 0x7b, 0xf2, 0x6d, - 0x71, 0x58, 0x99, 0x86, 0x04, 0x84, 0xe5, 0xa2, 0x83, 0xd0, 0x73, 0x05, 0xe0, 0x60, 0xf4, 0x35, - 0xf9, 0xe9, 0xf0, 0xd7, 0x31, 0x00, 0xfa, 0x68, 0x2f, 0xc2, 0xe1, 0xc9, 0x0e, 0x34, 0x1f, 0xcb, - 0xef, 0xdf, 0xbf, 0xa7, 0x39, 0xd6, 0xa3, 0xa3, 0x3b, 0x2f, 0xba, 0x03, 0x07, 0x76, 0x9e, 0xaf, - 0x18, 0x2e, 0xe6, 0xaa, 0x84, 0x67, 0xbd, 0xe0, 0xd4, 0xda, 0xda, 0x8a, 0x97, 0x3b, 0x7a, 0x60, - 0xdb, 0xe0, 0xc1, 0x83, 0x15, 0x75, 0x6c, 0xc3, 0xc4, 0x72, 0x56, 0x96, 0xd7, 0x29, 0x02, 0xf9, - 0xe9, 0xfd, 0x31, 0xe8, 0xfd, 0x16, 0xf4, 0xdc, 0x91, 0x4c, 0x7a, 0x8c, 0xa1, 0xa4, 0xba, 0x8b, - 0x64, 0x54, 0x78, 0xb6, 0xd4, 0x4a, 0xec, 0x9e, 0xef, 0xfb, 0xa5, 0xef, 0xd5, 0x77, 0x98, 0x5a, - 0x04, 0xac, 0xbf, 0x86, 0xca, 0x0b, 0x8f, 0x54, 0xf1, 0xbb, 0x07, 0x39, 0x0e, 0xbb, 0xa3, 0x90, - 0xc3, 0xb4, 0xca, 0x96, 0x62, 0xc0, 0xac, 0x63, 0xb9, 0x96, 0xe2, 0x0c, 0x66, 0x49, 0x00, 0x73, - 0x13, 0xcb, 0x19, 0x33, 0xad, 0xdc, 0x92, 0x00, 0x2d, 0x46, 0xa1, 0x60, 0x3d, 0x5b, 0xc0, 0x9b, - 0xbf, 0x56, 0x43, 0x7b, 0x5d, 0x47, 0x28, 0xe5, 0x29, 0xdc, 0xb2, 0x05, 0x3f, 0x5f, 0x93, 0x0a, - 0x25, 0x97, 0x6b, 0xa0, 0xb5, 0xda, 0xa7, 0x2b, 0x40, 0x9c, 0x8b, 0x74, 0xdd, 0x83, 0x8d, 0x96, - 0x63, 0x10, 0x96, 0x73, 0x17, 0x82, 0xa6, 0x00, 0xcd, 0x6b, 0xab, 0x0e, 0x47, 0x3d, 0x7c, 0xd5, - 0xc9, 0x8e, 0x21, 0x63, 0x4e, 0xce, 0x2d, 0xf0, 0xe8, 0xd1, 0x23, 0x38, 0x78, 0xf0, 0x20, 0x24, - 0x25, 0x25, 0xc1, 0x90, 0x21, 0x43, 0x60, 0xdc, 0xb8, 0x71, 0xb0, 0x64, 0xc9, 0x12, 0x88, 0x89, - 0x89, 0x81, 0x93, 0x27, 0x4f, 0xc2, 0xd1, 0xa3, 0x47, 0xa9, 0x68, 0x86, 0xaf, 0xd2, 0x43, 0xeb, - 0x04, 0x45, 0x90, 0x38, 0x18, 0xcb, 0x0b, 0x16, 0x2c, 0xa0, 0xc7, 0xce, 0x9d, 0x3b, 0x29, 0x3c, - 0x27, 0x27, 0x47, 0x4a, 0x4b, 0x4b, 0x53, 0xe0, 0xf0, 0x4a, 0x50, 0x41, 0x65, 0x01, 0xd3, 0x00, - 0x35, 0x9a, 0x37, 0x6f, 0x1e, 0xb5, 0x82, 0x59, 0x35, 0x74, 0xe8, 0x50, 0xc8, 0xcc, 0xcc, 0x84, - 0xc2, 0xc2, 0x42, 0x8a, 0x26, 0xd7, 0x1a, 0xcb, 0x89, 0x89, 0x89, 0xaa, 0xbf, 0x2c, 0x62, 0x1c, - 0x30, 0x8f, 0x86, 0xcc, 0x35, 0xbb, 0x69, 0x48, 0x6c, 0x0b, 0x0d, 0x8e, 0xc7, 0xc0, 0x82, 0x4e, - 0xa6, 0x48, 0x1c, 0xf7, 0x90, 0x29, 0x6d, 0x2c, 0x20, 0x0b, 0x03, 0x2c, 0x38, 0xcd, 0x56, 0x92, - 0x90, 0x27, 0x3a, 0x3d, 0x29, 0x46, 0xee, 0xe6, 0x18, 0x3d, 0x3e, 0x25, 0x9d, 0xf1, 0xdd, 0x37, - 0xac, 0xca, 0xff, 0xf2, 0xe2, 0xb3, 0xa8, 0x29, 0x7f, 0x1b, 0xce, 0xe1, 0x56, 0x0b, 0xb6, 0x0c, - 0xe2, 0xd7, 0x7f, 0xa9, 0x86, 0xd2, 0x7f, 0xd4, 0x50, 0x1d, 0xb2, 0x36, 0x7d, 0x05, 0x5f, 0x67, - 0x27, 0xa9, 0xf4, 0xd1, 0x33, 0xda, 0xc8, 0xdd, 0xa7, 0x8a, 0x61, 0x17, 0xc0, 0x52, 0x04, 0x42, - 0x31, 0xd3, 0x83, 0x8f, 0xde, 0xf6, 0x35, 0x6d, 0xfe, 0xdf, 0xee, 0x0a, 0x9a, 0xc7, 0xa6, 0xc4, - 0xc0, 0x88, 0x6f, 0xbf, 0xd4, 0x23, 0x31, 0xd4, 0xe6, 0x9a, 0x01, 0x69, 0xb3, 0x12, 0x15, 0x06, - 0x44, 0xc7, 0x47, 0x02, 0x83, 0x19, 0xd2, 0x34, 0x04, 0x92, 0x38, 0x0b, 0x85, 0x70, 0x4c, 0x58, - 0x70, 0xeb, 0x8f, 0xfa, 0x77, 0xfb, 0x61, 0x19, 0x74, 0x21, 0xb8, 0x1e, 0x81, 0xf8, 0x9f, 0x0c, - 0xa0, 0xa2, 0x7d, 0x4d, 0x1d, 0xfc, 0x19, 0x7c, 0x7d, 0x41, 0xab, 0x51, 0x7d, 0x55, 0x78, 0xb6, - 0x9c, 0x85, 0x54, 0x5c, 0x5d, 0x04, 0xb8, 0x1e, 0x01, 0xbb, 0x6d, 0x13, 0x06, 0xd8, 0xed, 0x51, - 0xb3, 0xfc, 0x0c, 0x47, 0x20, 0x2f, 0x2f, 0x8f, 0xfe, 0xd3, 0x33, 0x2b, 0xc0, 0x0c, 0xbe, 0xfc, - 0x3f, 0x98, 0x61, 0xba, 0xa0, 0x3f, 0x81, 0x9a, 0xd5, 0x5b, 0xb7, 0x6e, 0x49, 0x33, 0x67, 0xce, - 0xa4, 0x8f, 0x8e, 0xf7, 0xed, 0xdb, 0x27, 0xe1, 0x71, 0xff, 0xfe, 0x7d, 0x05, 0xee, 0xb3, 0x67, - 0xcf, 0xf8, 0xe3, 0x66, 0x22, 0x5c, 0x3a, 0x7c, 0xf8, 0x30, 0x6f, 0x9f, 0x32, 0x65, 0x0a, 0x6f, - 0x43, 0x20, 0xb6, 0xe3, 0x31, 0x71, 0xe2, 0x44, 0x8a, 0x53, 0x52, 0x52, 0x22, 0xed, 0xde, 0xbd, - 0x9b, 0xc2, 0x36, 0x6d, 0xda, 0x44, 0xf9, 0x9f, 0x39, 0x73, 0x86, 0xd3, 0xeb, 0x15, 0x02, 0xff, - 0x7f, 0xf5, 0xb0, 0x48, 0xdb, 0x86, 0x0d, 0x1b, 0xa8, 0x00, 0x2d, 0x34, 0xa6, 0xd0, 0xe9, 0xd3, - 0xa7, 0x25, 0x76, 0x44, 0x46, 0x46, 0xaa, 0xf0, 0x11, 0x2f, 0x2a, 0x2a, 0x4a, 0x05, 0x47, 0x9e, - 0x75, 0x75, 0x75, 0x14, 0x8e, 0x8e, 0x30, 0x93, 0x0c, 0x1b, 0xb0, 0x63, 0xc7, 0x0e, 0x2a, 0xe0, - 0xc3, 0x87, 0x0f, 0x94, 0xff, 0x9e, 0x3d, 0x7b, 0xa4, 0x15, 0x2b, 0x56, 0xd0, 0xf2, 0xf4, 0xe9, - 0xd3, 0x69, 0xdb, 0xcb, 0x97, 0x2f, 0xb9, 0xec, 0xf3, 0xe7, 0xcf, 0x73, 0x0f, 0x23, 0x70, 0xd9, - 0xb2, 0x65, 0x5c, 0x71, 0x34, 0x64, 0xd8, 0xb0, 0x61, 0x1c, 0x17, 0x0b, 0x3e, 0x9f, 0x8f, 0xb6, - 0x93, 0x37, 0x90, 0x14, 0x7e, 0xfd, 0xfa, 0x75, 0x05, 0xbd, 0x02, 0x59, 0x56, 0x31, 0x7d, 0x1d, - 0x78, 0xf3, 0xe6, 0x0d, 0x91, 0x0f, 0x30, 0x72, 0xe4, 0x48, 0x9a, 0xcb, 0x7f, 0x08, 0x5f, 0xb8, - 0x7d, 0xfb, 0x36, 0x90, 0x87, 0x16, 0x30, 0x66, 0xcc, 0x18, 0x79, 0x93, 0xe1, 0x72, 0x4d, 0x4d, - 0x0d, 0x10, 0x27, 0xc1, 0xf8, 0xf1, 0xe3, 0x0d, 0xd1, 0x98, 0x36, 0xc0, 0x10, 0x57, 0x17, 0x91, - 0x0c, 0x9f, 0x85, 0x5c, 0xd4, 0xc9, 0x94, 0x28, 0x61, 0x80, 0x29, 0x77, 0x39, 0x80, 0x2c, 0xc6, - 0x80, 0x03, 0x4e, 0x35, 0xc5, 0x52, 0x8c, 0x01, 0x53, 0xee, 0x72, 0x00, 0x59, 0x44, 0xc0, 0x01, - 0xa7, 0x9a, 0x62, 0x29, 0x22, 0x60, 0xca, 0x5d, 0x0e, 0x20, 0x9b, 0x7e, 0xb0, 0xe5, 0x6b, 0xf0, - 0x43, 0xde, 0x6f, 0x8b, 0x0c, 0xab, 0x22, 0x7f, 0x6c, 0xf8, 0xfc, 0x8f, 0xe5, 0xd0, 0xf8, 0xae, - 0x73, 0xba, 0x9d, 0x6a, 0x46, 0xa9, 0x61, 0x8e, 0x4a, 0x44, 0xd3, 0x06, 0x28, 0xc9, 0xcd, 0xd5, - 0xda, 0xea, 0x7c, 0xd0, 0xfa, 0x63, 0xbb, 0x39, 0xa2, 0x30, 0xd8, 0xa6, 0x0d, 0x88, 0x4e, 0x8c, - 0xa4, 0x33, 0x1d, 0xe5, 0x7c, 0xe5, 0x0f, 0x6e, 0xe5, 0x1e, 0x97, 0xe3, 0x38, 0x55, 0x36, 0x6d, - 0x80, 0x15, 0x45, 0x8a, 0xff, 0x5e, 0x03, 0x45, 0xc7, 0xab, 0x15, 0xa4, 0x76, 0x19, 0xdd, 0xeb, - 0xcf, 0x42, 0xae, 0x44, 0x20, 0xe5, 0x97, 0x09, 0x10, 0x9b, 0x1a, 0x0d, 0x05, 0xfb, 0x2b, 0xc1, - 0xd7, 0xe2, 0xa7, 0x91, 0x60, 0x8f, 0xdb, 0x15, 0x61, 0xb1, 0x50, 0x71, 0xc5, 0x80, 0xf8, 0xf4, - 0x18, 0xc0, 0xa3, 0xf0, 0xcf, 0x55, 0x00, 0x2d, 0x9d, 0x5a, 0xda, 0xf1, 0x68, 0x1d, 0x39, 0xf5, - 0xfa, 0x2e, 0x24, 0x0c, 0xb0, 0xd0, 0x6d, 0x6d, 0x25, 0x11, 0x11, 0x30, 0xe3, 0xce, 0xc8, 0x18, - 0x8d, 0x69, 0xb2, 0x66, 0x18, 0x68, 0xe0, 0xba, 0x1a, 0x81, 0x2f, 0x7e, 0x11, 0xc7, 0x55, 0xc8, - 0x5b, 0x50, 0x04, 0x3f, 0xdc, 0xaa, 0x87, 0xca, 0x7b, 0x0d, 0x1c, 0x66, 0xa5, 0xe0, 0xaa, 0x01, - 0x59, 0x9b, 0xbf, 0xe2, 0x3a, 0xfa, 0x9a, 0xfd, 0xf0, 0xe2, 0x4f, 0x3f, 0x00, 0x7b, 0xed, 0xca, - 0x1b, 0x4c, 0x16, 0x5c, 0x35, 0x00, 0xbb, 0xd0, 0xaf, 0xae, 0x8f, 0x84, 0xc1, 0xa3, 0xe2, 0xe8, - 0x1a, 0x27, 0xd4, 0xb5, 0xbb, 0xdd, 0x4a, 0x3c, 0x56, 0x31, 0x19, 0x71, 0xdb, 0xd1, 0x5d, 0xed, - 0x42, 0xb6, 0x6b, 0x8f, 0x5d, 0xd0, 0x09, 0xa6, 0x6e, 0xf2, 0x14, 0x06, 0xb8, 0xe9, 0x6d, 0x2d, - 0x59, 0x22, 0x02, 0x5a, 0x5e, 0x71, 0x13, 0x66, 0x38, 0x02, 0x71, 0x71, 0x71, 0x70, 0xf6, 0xec, - 0x59, 0xc7, 0x74, 0x9b, 0x3b, 0x77, 0x2e, 0x64, 0x65, 0x65, 0x99, 0xe7, 0x2f, 0x7b, 0xe1, 0xa7, - 0x5b, 0x24, 0x9c, 0xe9, 0x0c, 0x64, 0x5d, 0xa4, 0x6e, 0x34, 0x22, 0x7f, 0x3c, 0xcc, 0xa6, 0xb0, - 0x11, 0xe8, 0xe8, 0xe8, 0x80, 0x03, 0x07, 0x0e, 0x50, 0xcf, 0x14, 0x15, 0x15, 0xc1, 0xfe, 0xfd, - 0xfb, 0xe1, 0xd0, 0xa1, 0x43, 0xb4, 0x2e, 0xff, 0x21, 0x2f, 0xc2, 0xf9, 0x42, 0xae, 0xe4, 0xe4, - 0x64, 0x40, 0x3a, 0x96, 0xf0, 0x0d, 0x3c, 0x1e, 0x63, 0xc7, 0x8e, 0x85, 0x63, 0xc7, 0x8e, 0x71, - 0x3c, 0xd6, 0x7e, 0xea, 0xd4, 0x29, 0x56, 0xa4, 0xfc, 0x51, 0x46, 0x65, 0x65, 0x25, 0x87, 0xe9, - 0x16, 0xc2, 0x59, 0x9c, 0x9b, 0x9b, 0x4b, 0x3d, 0x43, 0x98, 0x28, 0xf2, 0xa7, 0x4f, 0x9f, 0x72, - 0x52, 0xb2, 0xca, 0x8c, 0xb6, 0xe1, 0xbb, 0xe1, 0xcb, 0x97, 0x2f, 0xab, 0x5e, 0x66, 0x93, 0x05, - 0xa4, 0xb4, 0x7d, 0xed, 0xda, 0xb5, 0x52, 0x7e, 0x7e, 0x3e, 0x2d, 0x2f, 0x5a, 0xb4, 0x88, 0xd3, - 0x07, 0xf3, 0xc6, 0xfa, 0xfc, 0xf9, 0xf3, 0x79, 0xbb, 0x5e, 0xc1, 0x70, 0xcc, 0x90, 0x29, 0x4e, - 0x64, 0x0f, 0x4e, 0xe4, 0xbd, 0x2e, 0x55, 0x08, 0x27, 0xb7, 0xb3, 0xb7, 0xf4, 0x24, 0x42, 0x14, - 0x46, 0xde, 0x19, 0x73, 0x74, 0x9c, 0x9e, 0xc0, 0x14, 0x25, 0xb3, 0xea, 0x39, 0x9c, 0x15, 0x58, - 0x1b, 0xab, 0x1b, 0xcd, 0x0d, 0xdf, 0xcc, 0x61, 0x17, 0x20, 0x06, 0xc0, 0xb5, 0x6b, 0xd7, 0x88, - 0xac, 0x40, 0x7a, 0xf8, 0xf0, 0x21, 0x90, 0x37, 0xf5, 0x30, 0x67, 0xce, 0x1c, 0xc0, 0x81, 0xce, - 0x12, 0x2e, 0x01, 0x38, 0x71, 0xe2, 0x04, 0x9d, 0x34, 0x8f, 0x30, 0xec, 0x52, 0x6c, 0x3d, 0xe0, - 0xab, 0x57, 0xaf, 0xe8, 0x44, 0x7b, 0x86, 0x8b, 0x39, 0xf2, 0xc7, 0x44, 0x14, 0xa7, 0xb9, 0xe1, - 0x1f, 0xa3, 0x96, 0x22, 0x6f, 0x32, 0x83, 0x9f, 0xa2, 0x17, 0x14, 0x14, 0x48, 0x93, 0x27, 0x4f, - 0xe6, 0xa4, 0xd8, 0x16, 0x1b, 0x1b, 0xcb, 0xeb, 0x0d, 0x0d, 0x0d, 0xb4, 0xbd, 0xad, 0xad, 0x8d, - 0xc2, 0x88, 0xf2, 0xd4, 0xfb, 0xcb, 0x97, 0x2f, 0x97, 0xd6, 0xac, 0x59, 0x43, 0xcb, 0xef, 0xde, - 0xbd, 0xe3, 0xf8, 0x58, 0x20, 0x06, 0x50, 0x38, 0x4e, 0x39, 0x40, 0x7a, 0x9c, 0x9a, 0x70, 0xef, - 0xde, 0x3d, 0x05, 0x8e, 0x56, 0xc5, 0x70, 0x17, 0xca, 0xc8, 0xc8, 0xa0, 0x02, 0x50, 0x59, 0x76, - 0xf8, 0xfd, 0x7e, 0xca, 0xf3, 0xca, 0x95, 0x2b, 0x1c, 0xc6, 0xda, 0x30, 0x67, 0x89, 0xc1, 0xa6, - 0x4e, 0x9d, 0x2a, 0x91, 0x65, 0x0f, 0x1c, 0xf7, 0xc2, 0x85, 0x0b, 0x0c, 0x45, 0xc2, 0x6e, 0xc5, - 0xf0, 0x58, 0x8e, 0xb3, 0x64, 0xc2, 0xa5, 0x80, 0x94, 0x70, 0x98, 0xa4, 0x1d, 0xbd, 0xf3, 0xe0, - 0xc1, 0x03, 0xa9, 0xa9, 0xa9, 0x49, 0x13, 0xbb, 0xb8, 0xb8, 0x58, 0xc2, 0x41, 0x8f, 0x33, 0x4f, - 0xac, 0xa6, 0xc7, 0x8f, 0x1f, 0x4b, 0xe5, 0xe5, 0xe5, 0x86, 0xc9, 0x0d, 0x8f, 0x01, 0xe2, 0x95, - 0x1e, 0x99, 0xc2, 0x5e, 0x07, 0x7a, 0xa4, 0xd6, 0x32, 0xa5, 0x84, 0x01, 0x32, 0x67, 0x78, 0x52, - 0x14, 0x11, 0xf0, 0xc4, 0xed, 0x32, 0xa1, 0x22, 0x02, 0x32, 0x67, 0x78, 0x52, 0xec, 0xf5, 0xd7, - 0x01, 0x4f, 0xbc, 0x66, 0xa3, 0xd0, 0x5e, 0x3f, 0x04, 0x6c, 0xf4, 0x85, 0x27, 0xac, 0x44, 0x00, - 0x3c, 0x71, 0x7b, 0x40, 0xa8, 0x08, 0x40, 0xc0, 0x17, 0x9e, 0x94, 0x44, 0x00, 0x3c, 0x71, 0x7b, - 0x40, 0xa8, 0x08, 0x40, 0xc0, 0x17, 0x9e, 0x94, 0x44, 0x00, 0x3c, 0x71, 0x7b, 0x40, 0xa8, 0x2b, - 0x13, 0x85, 0x70, 0x8a, 0xe3, 0xfd, 0xdf, 0xbd, 0x0d, 0x48, 0xb5, 0xb1, 0x34, 0x60, 0x48, 0x14, - 0xcc, 0xb8, 0xf0, 0x8d, 0x8d, 0x1c, 0xdd, 0x65, 0xe5, 0x4a, 0x00, 0xd0, 0x24, 0xf2, 0x84, 0xca, - 0x19, 0xcb, 0x3a, 0x67, 0xae, 0x69, 0xf2, 0xfe, 0xcf, 0xda, 0x12, 0xa8, 0x2f, 0x54, 0xae, 0x90, - 0xb5, 0x6b, 0x0d, 0xbf, 0xa6, 0x40, 0x0b, 0x40, 0xd7, 0x02, 0x10, 0x6e, 0x2a, 0x84, 0x44, 0x5e, - 0x83, 0x48, 0x7e, 0x75, 0x90, 0x22, 0xc9, 0x76, 0xb1, 0x7a, 0x2f, 0xb1, 0x23, 0x1c, 0x98, 0xb9, - 0x63, 0xc1, 0x8f, 0x96, 0x49, 0x5c, 0x09, 0x00, 0xce, 0xf1, 0x9d, 0x4d, 0xe6, 0xa6, 0xe8, 0x25, - 0xf9, 0x86, 0x0e, 0x72, 0xbc, 0xcc, 0x0d, 0x69, 0x9a, 0x9b, 0x3b, 0xc8, 0x71, 0x58, 0xd9, 0x4f, - 0xf6, 0x10, 0xf4, 0xb5, 0x06, 0x86, 0x04, 0x06, 0x35, 0x38, 0xf9, 0xc9, 0xf3, 0xfd, 0xb6, 0x5a, - 0x75, 0xc3, 0x80, 0x2f, 0xa2, 0x82, 0x51, 0x5d, 0xa9, 0xbb, 0x12, 0x00, 0x57, 0x2c, 0x21, 0x42, - 0x4a, 0xff, 0x59, 0xab, 0x9a, 0xd7, 0x1c, 0x2c, 0xbb, 0xb9, 0xac, 0x0d, 0xfe, 0x9d, 0xa3, 0xbe, - 0x1e, 0xb9, 0x3d, 0xd1, 0x9b, 0xe9, 0x25, 0xee, 0x82, 0x98, 0x27, 0x3c, 0xca, 0xfb, 0xd4, 0x08, - 0x18, 0x9e, 0x93, 0x0c, 0x78, 0xb0, 0x84, 0x77, 0x5e, 0xed, 0xf5, 0xca, 0xd3, 0x4d, 0x4f, 0xbb, - 0x08, 0x8b, 0x11, 0xc0, 0xa2, 0xe5, 0x51, 0x2e, 0x02, 0xe0, 0x91, 0xe3, 0x99, 0x58, 0x11, 0x00, - 0xe6, 0x09, 0x8f, 0x72, 0x11, 0x00, 0x8f, 0x1c, 0xcf, 0xc4, 0xf6, 0xbb, 0x00, 0x38, 0xf6, 0x8f, - 0x9c, 0x79, 0xd4, 0x64, 0xde, 0xa7, 0x03, 0xc0, 0x36, 0xef, 0x92, 0xfb, 0xa4, 0xa9, 0xa4, 0x0d, - 0x3e, 0xfd, 0xb7, 0x59, 0x0e, 0xf2, 0xb4, 0xdc, 0xa7, 0x6e, 0x43, 0x83, 0x3d, 0x99, 0x3a, 0x23, - 0x01, 0xea, 0x5e, 0x75, 0x2d, 0x13, 0x94, 0x35, 0xe6, 0xff, 0xa1, 0x4c, 0x56, 0xeb, 0x2c, 0x4e, - 0x3e, 0x94, 0x01, 0x49, 0x99, 0xb1, 0x2a, 0xb8, 0xd3, 0x80, 0x3e, 0x3d, 0x02, 0x32, 0x16, 0x27, - 0xc3, 0xc4, 0x7d, 0xe9, 0x10, 0xfb, 0x65, 0x8c, 0xd3, 0x7e, 0xb4, 0xcc, 0xbf, 0x7f, 0xce, 0x8a, - 0x20, 0xcf, 0xfc, 0xe8, 0xf3, 0x20, 0x92, 0x47, 0xc5, 0x46, 0x40, 0x14, 0xd9, 0xa2, 0xd2, 0xab, - 0xd4, 0x3f, 0x03, 0xe0, 0x95, 0xb7, 0x35, 0xe4, 0x7a, 0x17, 0x7a, 0x0d, 0x65, 0xfa, 0x23, 0x48, - 0x04, 0xc0, 0xe3, 0xa8, 0x8b, 0x00, 0x88, 0x00, 0x78, 0xec, 0x01, 0x8f, 0xc5, 0x8b, 0x11, 0x20, - 0x02, 0xe0, 0xb1, 0x07, 0x3c, 0x16, 0xef, 0xc8, 0x08, 0x68, 0x6e, 0x6e, 0x86, 0xda, 0xda, 0x5a, - 0x8f, 0x4d, 0xeb, 0x9e, 0xf8, 0x8a, 0x8a, 0x0a, 0xe7, 0x66, 0x72, 0xc8, 0x54, 0xb3, 0x3d, 0x00, - 0xdb, 0xb6, 0x6d, 0x83, 0x41, 0x83, 0x06, 0x01, 0xae, 0xf8, 0x5c, 0xba, 0x74, 0xa9, 0x4c, 0x54, - 0xef, 0x28, 0xb6, 0xb4, 0xb4, 0x00, 0xd9, 0xb9, 0x18, 0xf0, 0xbb, 0x3d, 0x64, 0x67, 0x63, 0x78, - 0xfd, 0x5a, 0xfb, 0x13, 0x6c, 0x76, 0x59, 0x63, 0xfb, 0xb3, 0x20, 0xf2, 0x79, 0x43, 0xae, 0x1b, - 0x1a, 0x63, 0x35, 0x7d, 0xfc, 0xf8, 0x11, 0xc8, 0x92, 0x46, 0xea, 0x80, 0x84, 0x84, 0x04, 0x18, - 0x35, 0x6a, 0x14, 0x5d, 0x10, 0x1d, 0x1f, 0x1f, 0x1f, 0x92, 0xe5, 0xdb, 0xb7, 0x6f, 0x81, 0x2c, - 0xc2, 0xa3, 0xed, 0xe8, 0x44, 0xfc, 0xf0, 0x11, 0xe6, 0x98, 0xca, 0xca, 0xca, 0xe0, 0xd3, 0xa7, - 0x4f, 0xb4, 0x8c, 0x3c, 0x46, 0x8c, 0x18, 0x41, 0xcb, 0xc1, 0x3f, 0xed, 0xed, 0xed, 0x40, 0x56, - 0x20, 0x72, 0x70, 0x77, 0x6c, 0xe0, 0x4c, 0xf4, 0x0a, 0x86, 0x97, 0xf4, 0xe9, 0x20, 0xde, 0xb8, - 0x71, 0x03, 0x27, 0xf4, 0x18, 0x3e, 0x9e, 0x3c, 0x79, 0xa2, 0xc9, 0x8d, 0xac, 0xab, 0xe6, 0x4b, - 0x8d, 0xf5, 0xf8, 0xcd, 0x9e, 0x3d, 0x5b, 0x22, 0x8e, 0xe2, 0x3c, 0xf0, 0x9b, 0x96, 0x64, 0xa1, - 0xac, 0x4a, 0x3e, 0x2e, 0x63, 0xfe, 0xfc, 0xf9, 0xb3, 0xb4, 0x7a, 0xf5, 0x6a, 0x55, 0x1b, 0xf9, - 0x80, 0xa6, 0x44, 0x9c, 0xcb, 0x79, 0xc8, 0x37, 0x1f, 0xd7, 0x93, 0x8d, 0x6d, 0x64, 0x75, 0x3c, - 0xa7, 0xeb, 0x6e, 0xc1, 0x96, 0x47, 0x11, 0xd8, 0x63, 0x70, 0xeb, 0x78, 0xfc, 0x8a, 0x34, 0xae, - 0x26, 0x26, 0xbb, 0xae, 0x13, 0x3d, 0x01, 0x46, 0x8f, 0x1e, 0x0d, 0x2b, 0x57, 0xae, 0xa4, 0x65, - 0xfc, 0xc1, 0xde, 0x48, 0x76, 0x53, 0xa7, 0xab, 0x8b, 0x39, 0xb0, 0xab, 0x80, 0xb8, 0x2f, 0x5e, - 0xbc, 0xa0, 0x35, 0x5c, 0x79, 0x7c, 0xf3, 0xe6, 0xcd, 0x60, 0x14, 0x58, 0xb7, 0x6e, 0x1d, 0x90, - 0x1d, 0xdb, 0x29, 0x1c, 0x57, 0x17, 0xe3, 0x16, 0xda, 0xe4, 0x03, 0xa2, 0x0a, 0x3c, 0xfc, 0x48, - 0xd9, 0xaa, 0x55, 0xab, 0xe8, 0xf9, 0x1b, 0x3f, 0xef, 0x75, 0xe7, 0xce, 0x1d, 0xd8, 0xbc, 0x79, - 0x33, 0xd5, 0x0f, 0x4f, 0x29, 0x17, 0x2f, 0x5e, 0x84, 0xc5, 0x8b, 0x17, 0x2b, 0x68, 0xb0, 0x42, - 0x96, 0x97, 0x02, 0x59, 0xa6, 0x0a, 0x78, 0xee, 0xc7, 0xd3, 0x28, 0x4b, 0x64, 0xa7, 0x77, 0x7a, - 0x3a, 0x62, 0xf5, 0x94, 0x94, 0x14, 0xba, 0x32, 0x1a, 0x73, 0x5b, 0x52, 0x77, 0x23, 0x18, 0x4c, - 0xcf, 0x76, 0x90, 0x27, 0xca, 0x69, 0xae, 0x4f, 0x0f, 0xc6, 0xc7, 0xfa, 0xdd, 0xbb, 0x77, 0x55, - 0x3d, 0x14, 0xe9, 0xc3, 0x1d, 0xf2, 0xc5, 0xc6, 0xc1, 0x7c, 0xb7, 0x6f, 0xdf, 0xae, 0xa0, 0x27, - 0xc1, 0x0b, 0x46, 0xd1, 0xac, 0xb3, 0x1d, 0xea, 0x99, 0x6c, 0xb3, 0x3b, 0xd5, 0x6b, 0x32, 0xd5, - 0x01, 0x9a, 0x5a, 0xec, 0xac, 0xc3, 0x87, 0x37, 0xe1, 0xb7, 0x01, 0x98, 0xf2, 0xb3, 0x66, 0xcd, - 0xe2, 0x70, 0xbd, 0x42, 0x63, 0x63, 0xa3, 0xc4, 0xb6, 0xf2, 0x47, 0x5a, 0xf6, 0x65, 0x3c, 0x3d, - 0x9a, 0x50, 0x6d, 0xb8, 0x20, 0x9b, 0x7c, 0xb2, 0x8f, 0xeb, 0x30, 0x6d, 0xda, 0x34, 0x5e, 0x26, - 0x17, 0x56, 0x89, 0x6c, 0x6c, 0x1f, 0x8a, 0x94, 0xc2, 0x51, 0x17, 0xa6, 0x3f, 0xe6, 0x46, 0x96, - 0xbc, 0xeb, 0x32, 0x0c, 0xd3, 0x68, 0x7b, 0x00, 0xce, 0x9d, 0x3b, 0xa7, 0x30, 0x00, 0x1d, 0x8b, - 0x7b, 0x03, 0xe0, 0x27, 0x06, 0xe5, 0x86, 0x61, 0x59, 0xfe, 0x29, 0x02, 0x72, 0xb7, 0x21, 0x91, - 0x8b, 0x2d, 0xc7, 0xc1, 0xf5, 0xff, 0x13, 0x26, 0x4c, 0x90, 0xb6, 0x6e, 0xdd, 0x2a, 0x6d, 0xd9, - 0xb2, 0x45, 0xc2, 0x73, 0x34, 0xdb, 0x9a, 0x02, 0x69, 0xb1, 0x9d, 0x5c, 0x58, 0xb9, 0x79, 0x47, - 0x8e, 0x1c, 0x91, 0xd2, 0xd3, 0xd3, 0x15, 0xf4, 0x6c, 0x84, 0xe0, 0x67, 0x0a, 0xc8, 0x06, 0x0a, - 0xbc, 0x8d, 0x5c, 0x84, 0xa5, 0xec, 0xec, 0x6c, 0xa9, 0xba, 0xba, 0x9a, 0xd3, 0xcb, 0x0b, 0xe4, - 0xab, 0x03, 0x1c, 0x17, 0x65, 0xa5, 0xa6, 0xa6, 0x4a, 0x93, 0x26, 0x4d, 0x52, 0xc8, 0x47, 0x38, - 0x7e, 0x3a, 0xb1, 0xbb, 0xc9, 0xf6, 0x00, 0xa0, 0x42, 0x55, 0x55, 0x55, 0xb4, 0x17, 0xca, 0x8d, - 0x46, 0x85, 0xb1, 0x8e, 0x86, 0xe3, 0xde, 0x1e, 0xa1, 0x12, 0xd9, 0x6c, 0x44, 0x22, 0xd7, 0x0d, - 0x09, 0x9d, 0x84, 0x34, 0xf2, 0x03, 0xe9, 0xc9, 0xf5, 0x41, 0xba, 0x7a, 0xf5, 0xaa, 0x8a, 0x7c, - 0xd7, 0xae, 0x5d, 0x12, 0xb9, 0xf5, 0xe5, 0xf8, 0x48, 0xbf, 0x77, 0xef, 0x5e, 0x8a, 0x77, 0xfc, - 0xf8, 0x71, 0xba, 0x59, 0x04, 0xe3, 0x85, 0x9d, 0x02, 0xbf, 0xec, 0xa1, 0xb7, 0xad, 0xc0, 0xa5, - 0x4b, 0x97, 0x24, 0xad, 0x3d, 0x1a, 0x10, 0xb6, 0x7e, 0xfd, 0x7a, 0xa9, 0xb4, 0xb4, 0x54, 0xa5, - 0x83, 0x15, 0x80, 0x2d, 0x17, 0x61, 0x62, 0x98, 0x48, 0x16, 0x3d, 0x60, 0xfb, 0x1f, 0x31, 0x8b, - 0x7a, 0xf4, 0x5b, 0x32, 0x11, 0x00, 0x8f, 0x43, 0x2f, 0x02, 0x20, 0x02, 0xe0, 0xb1, 0x07, 0x3c, - 0x16, 0x2f, 0x46, 0x80, 0x08, 0x80, 0xc7, 0x1e, 0xf0, 0x58, 0xbc, 0x18, 0x01, 0x22, 0x00, 0x1e, - 0x7b, 0xc0, 0x63, 0xf1, 0xff, 0x07, 0x81, 0x2f, 0x8c, 0xaf, 0x25, 0xdb, 0xd9, 0x2e, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXVideoIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x37, 0x39, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xcc, - 0x4b, 0x33, 0xb9, 0x00, 0x00, 0x09, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x7b, - 0x4c, 0x54, 0xd9, 0x19, 0x9f, 0x99, 0x7b, 0x67, 0x18, 0x9e, 0x83, 0xc0, 0xcc, 0x30, 0x83, 0x2c, - 0xa2, 0x80, 0x3c, 0x15, 0x96, 0xe2, 0xae, 0x8f, 0xd4, 0xf5, 0x11, 0x13, 0xb7, 0xb6, 0x31, 0xa6, - 0xd5, 0x08, 0x6a, 0xb4, 0xba, 0x3e, 0x6a, 0x1a, 0x13, 0x63, 0xac, 0x35, 0x21, 0x9a, 0xfe, 0x63, - 0x62, 0x8d, 0xb1, 0x35, 0x46, 0x8d, 0xd1, 0xac, 0xa6, 0x35, 0xd1, 0xa6, 0x66, 0xdd, 0x9a, 0xad, - 0x31, 0x0d, 0x6e, 0xa3, 0x8d, 0x6f, 0x08, 0x6f, 0x99, 0x05, 0x11, 0x81, 0x85, 0x79, 0xc0, 0xbc, - 0x98, 0xc7, 0xbd, 0x33, 0xf7, 0x4e, 0x7f, 0x77, 0xce, 0xee, 0x75, 0x32, 0x28, 0x8f, 0x19, 0x08, - 0x6b, 0x32, 0x07, 0xb8, 0x7c, 0xe7, 0x9c, 0xef, 0x3b, 0xe7, 0xfb, 0x7d, 0xdf, 0x77, 0xce, 0x77, - 0xee, 0xb9, 0xd2, 0x40, 0x20, 0x20, 0xf9, 0x90, 0x8b, 0xec, 0x43, 0x56, 0x5e, 0xd0, 0x3d, 0x06, - 0x60, 0xa6, 0x3d, 0x18, 0xf3, 0x40, 0xcc, 0x03, 0x51, 0x5a, 0x60, 0x86, 0x43, 0xe8, 0xd9, 0xb3, - 0x67, 0x83, 0x83, 0x83, 0xd1, 0x60, 0x98, 0x19, 0x00, 0x0c, 0xc3, 0xb4, 0xb6, 0x77, 0x9d, 0xf9, - 0xeb, 0xc5, 0x23, 0x7f, 0xfc, 0xc3, 0xed, 0xdb, 0x5f, 0x45, 0x03, 0x80, 0x8e, 0x46, 0x78, 0xb2, - 0xb2, 0x83, 0x83, 0x16, 0xe3, 0x90, 0xcd, 0x60, 0xe8, 0xf9, 0xde, 0x62, 0x4d, 0x4e, 0x4e, 0xee, - 0x1d, 0xb4, 0xf5, 0xf5, 0x7e, 0xff, 0xe2, 0xc5, 0x8b, 0xc9, 0x8e, 0x13, 0xca, 0x1f, 0x15, 0x80, - 0xbb, 0x77, 0xef, 0x32, 0x5e, 0x6f, 0x5c, 0x42, 0xb2, 0xcb, 0xed, 0x95, 0x4a, 0xa5, 0x18, 0x97, - 0xa6, 0x69, 0xa5, 0x52, 0x91, 0x9c, 0x94, 0xa4, 0xce, 0x48, 0xcb, 0xd4, 0x6a, 0x92, 0x92, 0x92, - 0xd0, 0xd8, 0xdf, 0x6f, 0x6c, 0x6c, 0xed, 0xec, 0x37, 0x59, 0x19, 0x2f, 0x23, 0x95, 0xd1, 0x1f, - 0x65, 0xeb, 0xca, 0xb4, 0x6a, 0x9e, 0x93, 0x98, 0x4c, 0x96, 0x21, 0xab, 0xfd, 0xf1, 0xe3, 0xc7, - 0x0e, 0x87, 0x23, 0x25, 0x25, 0x25, 0x54, 0xad, 0x89, 0xd3, 0x51, 0x01, 0x18, 0x1a, 0x1a, 0xea, - 0xea, 0xfc, 0x4e, 0x9d, 0x53, 0x2e, 0x97, 0xcb, 0xe7, 0xcc, 0xce, 0xc0, 0xa1, 0x84, 0x65, 0x39, - 0x37, 0xe3, 0xb3, 0xd8, 0x6c, 0xcd, 0x86, 0x01, 0x9b, 0xfd, 0x89, 0x67, 0xc4, 0xe9, 0xb0, 0x19, - 0xfb, 0x8c, 0xb6, 0xb4, 0x0c, 0x5d, 0x41, 0x5e, 0xee, 0xec, 0xac, 0xcc, 0xa4, 0xe4, 0x44, 0xc0, - 0x18, 0x30, 0x5a, 0xad, 0x56, 0x67, 0xf7, 0xeb, 0x3e, 0xa9, 0x4c, 0x3e, 0x38, 0x68, 0xec, 0xea, - 0xea, 0xaa, 0xa8, 0xa8, 0x98, 0xb8, 0xd2, 0xa1, 0x9c, 0x51, 0x01, 0x50, 0x05, 0x8b, 0x5e, 0xa7, - 0xcb, 0xc9, 0xd6, 0xe6, 0xe7, 0xea, 0x29, 0x19, 0xdc, 0x00, 0x3f, 0x08, 0x0f, 0x9e, 0x97, 0x70, - 0x5c, 0x80, 0xf1, 0xb1, 0x76, 0xa7, 0xbb, 0x7f, 0xc0, 0xdc, 0xfa, 0xb2, 0xeb, 0xf5, 0xab, 0xae, - 0xde, 0xbe, 0x3e, 0xf4, 0x26, 0x26, 0x26, 0x3b, 0x9c, 0xae, 0xef, 0xda, 0x5b, 0xf4, 0x9a, 0xa4, - 0x3f, 0x1d, 0xaf, 0x8d, 0x53, 0x50, 0x5a, 0xad, 0x36, 0x54, 0xa7, 0x49, 0xd1, 0x51, 0x01, 0xa8, - 0xab, 0xab, 0x63, 0x3d, 0x9e, 0xf8, 0xb4, 0x5c, 0x4d, 0xba, 0xca, 0x6e, 0x77, 0xd0, 0x32, 0x4a, - 0x4a, 0x41, 0x7b, 0x19, 0x0d, 0x24, 0x40, 0x23, 0x91, 0xc4, 0xc9, 0xa9, 0xcc, 0x8c, 0x94, 0x2c, - 0xad, 0x6a, 0x51, 0x79, 0x01, 0xc3, 0xfa, 0x7b, 0x7a, 0x07, 0x9a, 0x5a, 0x0d, 0xf7, 0x1f, 0xd4, - 0x1b, 0xda, 0x1b, 0xaa, 0x7f, 0xfd, 0xf9, 0x6f, 0xb7, 0x57, 0xc3, 0x75, 0x93, 0x52, 0x77, 0x34, - 0x73, 0x54, 0x00, 0x1a, 0x1a, 0x1a, 0x1c, 0x56, 0x2b, 0x9d, 0xf2, 0x51, 0x6e, 0x4e, 0xae, 0xd5, - 0xee, 0xa2, 0x64, 0x28, 0xd0, 0x5f, 0x22, 0x10, 0xf8, 0x93, 0x0a, 0x0f, 0x50, 0x14, 0x25, 0x21, - 0xf4, 0x6c, 0x9d, 0x7a, 0xb6, 0x5e, 0xf3, 0xf3, 0x25, 0x95, 0x4f, 0xea, 0x5f, 0xb6, 0xb7, 0xb5, - 0x3e, 0x7b, 0xd1, 0xb4, 0xe4, 0xd3, 0xca, 0xd1, 0x3a, 0x4d, 0xaa, 0x25, 0x2a, 0x00, 0x1e, 0x8f, - 0x47, 0x4a, 0xd1, 0x0c, 0xcb, 0xf5, 0xf4, 0x9b, 0x38, 0xde, 0x27, 0xa7, 0x69, 0xb9, 0x9c, 0xa2, - 0x69, 0x4a, 0x4e, 0x09, 0x4f, 0xc1, 0x17, 0x14, 0x01, 0x22, 0x38, 0xe6, 0x47, 0x54, 0x52, 0x84, - 0xd8, 0xa7, 0x1f, 0x17, 0x16, 0xe4, 0xcd, 0xfe, 0xe6, 0xde, 0xa3, 0xaf, 0xbf, 0xf9, 0x0f, 0xcd, - 0x3b, 0xf7, 0xed, 0xdb, 0x97, 0x95, 0x95, 0x35, 0x29, 0xbd, 0x45, 0xe6, 0xa8, 0x00, 0x64, 0x66, - 0x66, 0x42, 0x43, 0x9b, 0xd5, 0xf2, 0x8f, 0x7f, 0xfe, 0xab, 0xb4, 0xa4, 0x38, 0x0b, 0xb1, 0x92, - 0x9c, 0xa8, 0x4a, 0x49, 0x50, 0x25, 0x27, 0xc4, 0xc7, 0x2b, 0x04, 0x00, 0xf8, 0x09, 0x16, 0xc1, - 0x1d, 0x32, 0xf8, 0x41, 0x08, 0x2c, 0x50, 0x41, 0x5a, 0xb6, 0xf8, 0x93, 0x8a, 0x53, 0xa7, 0xeb, - 0x92, 0x65, 0xce, 0xa6, 0xa6, 0xa6, 0x99, 0x01, 0x70, 0xf2, 0xe4, 0x49, 0xa4, 0xa4, 0x53, 0xa7, - 0xff, 0xd2, 0xd3, 0xd1, 0xa8, 0xd5, 0xaa, 0x0b, 0x8b, 0xe7, 0x27, 0x26, 0xd0, 0x71, 0x71, 0x4a, - 0xa8, 0xe8, 0xf7, 0x07, 0xa4, 0xd2, 0x80, 0xa0, 0x2e, 0x60, 0xc8, 0xa4, 0x3c, 0x4f, 0xd0, 0x70, - 0xa8, 0x52, 0x94, 0x54, 0xc6, 0x07, 0x38, 0xce, 0xef, 0xf3, 0xb1, 0x0a, 0x05, 0x9d, 0xae, 0x4a, - 0x17, 0x82, 0x2c, 0xd2, 0x12, 0x95, 0x07, 0x0a, 0x0a, 0x0a, 0x30, 0x6f, 0xda, 0xac, 0x59, 0x99, - 0x5a, 0xb5, 0x32, 0x4e, 0x9e, 0xa8, 0xa4, 0x52, 0x92, 0xe2, 0x3b, 0x0d, 0x2f, 0x47, 0x1c, 0xc3, - 0x89, 0x49, 0x49, 0x64, 0x3f, 0x12, 0x00, 0x08, 0x19, 0x22, 0xe8, 0x08, 0x81, 0x90, 0xb8, 0xdd, - 0x6e, 0x8d, 0x36, 0xb3, 0xb0, 0xa8, 0x94, 0xe3, 0x78, 0xaf, 0xcb, 0x5b, 0xf7, 0xfc, 0xf1, 0x2f, - 0xd6, 0xfd, 0x52, 0xe8, 0x88, 0xa8, 0x44, 0x05, 0x80, 0xcc, 0x18, 0x90, 0x04, 0x54, 0xaa, 0xd4, - 0x00, 0xcf, 0xf9, 0x18, 0x6c, 0x9b, 0x72, 0x1f, 0xeb, 0x5b, 0xbe, 0x7c, 0x79, 0x5a, 0x5a, 0x3a, - 0x72, 0x1c, 0xb4, 0x86, 0xe6, 0x34, 0x25, 0xc3, 0x53, 0x22, 0x81, 0x43, 0x64, 0xf1, 0x4a, 0x65, - 0x6f, 0x7f, 0x7f, 0x73, 0x6b, 0x1b, 0x03, 0xfb, 0xe3, 0x97, 0xf5, 0x19, 0x4d, 0xc6, 0x68, 0x5e, - 0x6b, 0xa7, 0x00, 0x00, 0x76, 0xcf, 0x0c, 0xb5, 0x9a, 0xe7, 0x39, 0xb7, 0x87, 0x89, 0x53, 0xca, - 0x19, 0x96, 0x0d, 0x48, 0xa9, 0xcb, 0x97, 0x2e, 0x74, 0xb4, 0x37, 0x05, 0xfd, 0x20, 0xc5, 0x82, - 0x86, 0xa2, 0x00, 0x33, 0x3c, 0x6c, 0x59, 0xf7, 0xab, 0xdf, 0xfc, 0x6c, 0xd1, 0x12, 0x96, 0xf5, - 0xb3, 0x00, 0xcb, 0xf8, 0x59, 0x24, 0x0a, 0xbb, 0x23, 0x1a, 0x00, 0x53, 0x70, 0x98, 0xc3, 0x8e, - 0xa3, 0xd5, 0x68, 0xfc, 0x7e, 0x0e, 0xeb, 0xc1, 0xeb, 0x15, 0xdc, 0xe0, 0x74, 0xba, 0xe5, 0x0a, - 0x79, 0x4d, 0xcd, 0xe6, 0x3d, 0xbb, 0xbf, 0x58, 0xb7, 0xee, 0x73, 0x43, 0xc7, 0x4b, 0xb3, 0xd9, - 0x58, 0x55, 0x55, 0x69, 0x36, 0x19, 0x5f, 0xf7, 0xf4, 0xb0, 0x1c, 0x0f, 0x3c, 0x5e, 0x2f, 0xcb, - 0xb0, 0x3e, 0x9e, 0x27, 0x77, 0x0a, 0x91, 0x5f, 0x2c, 0x4c, 0x01, 0x00, 0xb9, 0x9c, 0xd6, 0x68, - 0xb5, 0x7e, 0xbf, 0x1f, 0x1e, 0xf0, 0x7a, 0xa0, 0x16, 0xeb, 0x74, 0x8e, 0x28, 0xe4, 0xf2, 0xfc, - 0xfc, 0xfc, 0xd2, 0x92, 0x12, 0xbd, 0x5e, 0xf7, 0xaa, 0xfb, 0xd5, 0x67, 0x9f, 0x2d, 0x37, 0x18, - 0x0c, 0x26, 0x8b, 0xd9, 0xef, 0xe7, 0x3d, 0x6e, 0xaf, 0x00, 0x80, 0x65, 0xbd, 0x8c, 0x8f, 0xf7, - 0x73, 0x11, 0x45, 0xfe, 0x5b, 0xa1, 0x29, 0x08, 0x21, 0x8a, 0xa6, 0x34, 0x6a, 0x35, 0xc7, 0x75, - 0xc2, 0x01, 0x0c, 0x93, 0x80, 0xf0, 0xc0, 0xd9, 0xce, 0x64, 0xb6, 0x7c, 0xfb, 0x6d, 0x9d, 0x5e, - 0x9f, 0xdd, 0xd2, 0xda, 0x1c, 0x17, 0x17, 0x67, 0xe8, 0x30, 0x48, 0xa4, 0x92, 0x8a, 0xf2, 0x72, - 0x97, 0xdb, 0xed, 0x72, 0x7b, 0x58, 0x9f, 0x1f, 0xda, 0xc3, 0x09, 0x7e, 0xde, 0xff, 0x56, 0x97, - 0x88, 0xa8, 0x29, 0x00, 0x40, 0x53, 0x74, 0x7a, 0x3a, 0xb6, 0xc2, 0x60, 0xfa, 0x52, 0x20, 0x97, - 0xd1, 0xd0, 0xaf, 0xec, 0xe3, 0xa5, 0x76, 0xbb, 0xb5, 0xcf, 0xcc, 0xa4, 0xeb, 0x8a, 0x0e, 0xd7, - 0xfe, 0x19, 0x51, 0x8e, 0x83, 0x2a, 0x96, 0xad, 0x5a, 0xa3, 0x19, 0x71, 0xb9, 0x20, 0x82, 0xbd, - 0x15, 0x8d, 0x3c, 0xcf, 0xc3, 0x75, 0x08, 0xbf, 0x88, 0x94, 0x17, 0x84, 0xa6, 0x00, 0x00, 0x96, - 0xaf, 0x5e, 0xa7, 0x4d, 0x49, 0x55, 0x69, 0x35, 0x50, 0x2f, 0xdd, 0xed, 0x1c, 0x52, 0xa9, 0x52, - 0x32, 0x34, 0x6a, 0xa4, 0x01, 0x21, 0x7f, 0x61, 0xdf, 0xa7, 0x29, 0x09, 0x94, 0x0d, 0xf0, 0xd8, - 0x8b, 0xc0, 0x3c, 0x64, 0x36, 0xa5, 0xce, 0x52, 0xcd, 0x52, 0xa5, 0x3a, 0xdd, 0x01, 0x5a, 0xae, - 0x28, 0x2a, 0x2a, 0x8a, 0xf8, 0x2c, 0x1d, 0x2d, 0x00, 0x28, 0x85, 0xbd, 0x25, 0x5e, 0x19, 0xff, - 0xdf, 0xff, 0x3d, 0xf1, 0x30, 0xfc, 0x90, 0xc3, 0x23, 0xa1, 0xdd, 0x43, 0x76, 0x37, 0x6d, 0xb4, - 0x8f, 0xb0, 0x32, 0xf4, 0x06, 0x01, 0x08, 0x89, 0x80, 0xc7, 0x5e, 0x8b, 0xe5, 0x8a, 0x7f, 0x52, - 0xc9, 0x88, 0xc3, 0x6e, 0x32, 0xdb, 0xe8, 0x04, 0x4b, 0x7b, 0x5b, 0xdb, 0xc1, 0xdf, 0x7f, 0xb1, - 0x64, 0xd1, 0x02, 0x8d, 0x46, 0x13, 0xb1, 0x07, 0x04, 0x3f, 0x46, 0x26, 0xec, 0xf3, 0xf9, 0x90, - 0x92, 0x46, 0x46, 0x46, 0xcc, 0x66, 0x4b, 0x43, 0x63, 0xd3, 0xc9, 0x93, 0xa7, 0xcc, 0x96, 0x21, - 0xe4, 0x54, 0xa4, 0x58, 0xc1, 0xee, 0x38, 0x2d, 0x08, 0x23, 0x23, 0x0f, 0x08, 0xc3, 0x07, 0xa9, - 0xe0, 0x3f, 0xa1, 0xc6, 0x23, 0x85, 0xc1, 0x1b, 0xc5, 0x85, 0x05, 0x7f, 0xff, 0xdb, 0x97, 0x19, - 0x19, 0x6a, 0x9c, 0x49, 0x11, 0x60, 0x42, 0xcf, 0xe4, 0x4b, 0x84, 0x62, 0x64, 0x22, 0x44, 0x30, - 0xc7, 0x71, 0x0a, 0x85, 0x1c, 0x47, 0xb3, 0xdf, 0xed, 0xdd, 0x69, 0x32, 0x99, 0x84, 0xa0, 0x41, - 0xce, 0x22, 0x56, 0x79, 0x8f, 0x65, 0xd0, 0x8f, 0x13, 0x2a, 0xf8, 0xf2, 0xf2, 0xf3, 0x81, 0xd0, - 0xeb, 0xf5, 0x46, 0xac, 0x3d, 0xd4, 0x88, 0xdc, 0x03, 0x10, 0x86, 0x9e, 0xc0, 0x80, 0x02, 0x02, - 0x56, 0x14, 0x54, 0x9f, 0x64, 0x01, 0xfe, 0x1f, 0x30, 0x4f, 0x52, 0x50, 0x64, 0x8f, 0x0a, 0x80, - 0x38, 0xca, 0x0c, 0x12, 0x53, 0x90, 0xc8, 0x66, 0x50, 0x7b, 0x4c, 0x1d, 0x03, 0x30, 0xb3, 0xf6, - 0x8f, 0x79, 0x60, 0xa6, 0xed, 0x1f, 0xf3, 0xc0, 0x87, 0xec, 0x01, 0x9c, 0x21, 0x4f, 0x9f, 0x3e, - 0x7d, 0xeb, 0xd6, 0xad, 0xb1, 0x41, 0x20, 0xcd, 0x05, 0xcf, 0x9b, 0xd1, 0x1e, 0x9b, 0xdf, 0x3b, - 0x0b, 0x92, 0x68, 0x64, 0xa5, 0xa3, 0xa3, 0x03, 0x83, 0xce, 0x9d, 0x3b, 0x77, 0x0c, 0xf1, 0xa3, - 0x47, 0x8f, 0x8a, 0x37, 0x0e, 0xb8, 0xfc, 0x19, 0x83, 0x33, 0xe2, 0xae, 0xc8, 0xf3, 0x80, 0x42, - 0xa1, 0xc0, 0x9b, 0xca, 0xd8, 0xf7, 0x39, 0x39, 0x39, 0x39, 0xf3, 0xe6, 0xcd, 0x4b, 0x4b, 0x4b, - 0x03, 0x54, 0x5c, 0x41, 0xbf, 0xd7, 0x8a, 0xd1, 0x74, 0x44, 0x0c, 0x1d, 0x82, 0x38, 0x90, 0x4e, - 0x44, 0x1c, 0x91, 0x06, 0x0d, 0xb7, 0x6c, 0xd9, 0x32, 0x11, 0xe6, 0xc9, 0xf2, 0x84, 0x7b, 0xe0, - 0xc8, 0x91, 0x23, 0x9f, 0x04, 0xcb, 0x9a, 0x35, 0x6b, 0xda, 0xda, 0xda, 0x9e, 0x3f, 0x7f, 0xbe, - 0x6a, 0xd5, 0x2a, 0x34, 0x2c, 0x5d, 0xba, 0xf4, 0xda, 0xb5, 0x6b, 0xa2, 0xa5, 0xb6, 0x6d, 0xdb, - 0x46, 0x1a, 0x97, 0x2d, 0x5b, 0x66, 0xb3, 0xd9, 0xc4, 0x76, 0x91, 0xb8, 0x71, 0xe3, 0xc6, 0xd6, - 0xad, 0x5b, 0x31, 0xc8, 0xf1, 0xe3, 0xc7, 0x47, 0xdb, 0x1e, 0x2d, 0x07, 0x0f, 0x1e, 0x5c, 0xb8, - 0x70, 0x21, 0x3e, 0x20, 0x94, 0x94, 0x94, 0x1c, 0x3e, 0x7c, 0xd8, 0xe5, 0x72, 0x89, 0xb2, 0x20, - 0xfa, 0xfb, 0xfb, 0x77, 0xec, 0xd8, 0x51, 0x58, 0x58, 0x08, 0x86, 0xf2, 0xf2, 0xf2, 0xd1, 0x0c, - 0x6f, 0x99, 0xc3, 0x10, 0xeb, 0x74, 0x3a, 0xb1, 0xef, 0xea, 0xd5, 0xab, 0x67, 0xcf, 0x9e, 0x15, - 0xab, 0x1b, 0x36, 0x6c, 0x20, 0xcc, 0x4e, 0xa7, 0x33, 0xf4, 0x00, 0xdc, 0xdd, 0xdd, 0x1d, 0x36, - 0xc8, 0xae, 0x5d, 0xbb, 0x44, 0x29, 0x10, 0xe4, 0x94, 0x2a, 0x7a, 0x60, 0x60, 0x60, 0x20, 0x3b, - 0x3b, 0x9b, 0x30, 0xe0, 0x5d, 0x94, 0x10, 0xc5, 0xc5, 0xc5, 0xc0, 0x40, 0xc6, 0xc1, 0x37, 0x9b, - 0xd1, 0xef, 0x68, 0xb9, 0xb9, 0xb9, 0x16, 0x8b, 0x25, 0x6c, 0x22, 0x54, 0x85, 0x23, 0x71, 0x68, - 0xe9, 0xec, 0xec, 0x2c, 0x2d, 0x2d, 0xc5, 0xa0, 0xbb, 0x77, 0xef, 0x46, 0x84, 0xe0, 0xa6, 0x64, - 0xf3, 0xe6, 0xcd, 0xa8, 0x6e, 0xda, 0xb4, 0x29, 0x54, 0xbe, 0xb9, 0xb9, 0x19, 0x36, 0x26, 0x73, - 0x87, 0x01, 0xb8, 0x7d, 0xfb, 0x36, 0x69, 0x87, 0x73, 0xae, 0x5c, 0xb9, 0xb2, 0x62, 0xc5, 0x0a, - 0x52, 0xad, 0xa9, 0xa9, 0x21, 0x13, 0xad, 0x5f, 0xbf, 0x1e, 0x2d, 0xab, 0x57, 0xaf, 0xee, 0xeb, - 0xeb, 0x43, 0x0b, 0xae, 0xb8, 0xc9, 0x42, 0x3a, 0x74, 0xe8, 0x10, 0xaa, 0x98, 0x94, 0x28, 0x00, - 0x53, 0x9e, 0x3b, 0x77, 0x0e, 0xfa, 0x1c, 0x3b, 0x76, 0x2c, 0x3e, 0x3e, 0x1e, 0x22, 0xd5, 0xd5, - 0xd5, 0xa1, 0xaa, 0x12, 0x3a, 0x1c, 0x00, 0x5a, 0x2f, 0x5e, 0xbc, 0x08, 0x6e, 0x7c, 0x32, 0x01, - 0x8d, 0xf3, 0x3a, 0x16, 0x22, 0x4c, 0x88, 0x3d, 0x27, 0x4c, 0x18, 0x57, 0xd3, 0x44, 0xb3, 0x30, - 0x00, 0x44, 0x3f, 0xbc, 0x25, 0x42, 0x96, 0x88, 0x60, 0x04, 0x70, 0x12, 0x00, 0x90, 0x22, 0xfb, - 0xd2, 0x99, 0x33, 0x67, 0xfe, 0xfd, 0x63, 0xd9, 0xb9, 0x73, 0x27, 0x18, 0x16, 0x2c, 0x58, 0x00, - 0x7e, 0x5c, 0xf4, 0x92, 0x61, 0xb1, 0x72, 0xc4, 0x19, 0x21, 0x8b, 0x46, 0xa5, 0x52, 0x89, 0x1d, - 0x59, 0x6c, 0x24, 0xc4, 0x3b, 0x00, 0x20, 0x42, 0xf0, 0x05, 0x0e, 0x02, 0xf5, 0xf5, 0xf5, 0x77, - 0xee, 0xdc, 0x01, 0xb1, 0x76, 0xed, 0xda, 0x30, 0x31, 0x54, 0xdf, 0x07, 0x00, 0x81, 0x0b, 0x91, - 0xed, 0xdb, 0xb7, 0x8b, 0x22, 0xfb, 0xf7, 0xef, 0x47, 0x0b, 0x01, 0x20, 0xea, 0x87, 0x96, 0xb0, - 0x92, 0x97, 0x97, 0x07, 0x91, 0x9b, 0x37, 0x6f, 0x92, 0x76, 0x7c, 0x77, 0x12, 0x47, 0x10, 0x1b, - 0xe1, 0x10, 0xb1, 0x91, 0x10, 0xef, 0x78, 0xa5, 0xc4, 0xba, 0x41, 0xbc, 0x9e, 0x3f, 0x7f, 0xfe, - 0xf2, 0xe5, 0xcb, 0x3d, 0x3d, 0x3d, 0x18, 0xee, 0xc0, 0x81, 0x03, 0x61, 0x93, 0x8d, 0x51, 0x85, - 0x38, 0x7a, 0xe1, 0x16, 0x91, 0x27, 0x94, 0xd6, 0xeb, 0xf5, 0xa4, 0xfd, 0xd2, 0xa5, 0x4b, 0x65, - 0x65, 0x65, 0x22, 0x0f, 0xdc, 0x42, 0xae, 0x8a, 0xc5, 0x45, 0x88, 0x4f, 0xc8, 0x48, 0x32, 0x84, - 0x01, 0x34, 0x08, 0x04, 0x02, 0x2e, 0xf4, 0x45, 0x91, 0x1f, 0x88, 0x30, 0x40, 0xa4, 0xda, 0xd8, - 0xd8, 0x88, 0x6e, 0xf8, 0x01, 0xef, 0x7b, 0xb0, 0x28, 0x79, 0x69, 0x0c, 0xe5, 0x84, 0x2b, 0xe1, - 0x28, 0x32, 0x04, 0xac, 0x12, 0xba, 0x9f, 0xee, 0xd9, 0xb3, 0x07, 0xed, 0x50, 0xe8, 0xe1, 0xc3, - 0x87, 0x10, 0x79, 0xfa, 0xf4, 0x29, 0xd2, 0x05, 0x5a, 0xc4, 0x35, 0x30, 0x7f, 0xfe, 0x7c, 0x54, - 0xb1, 0x41, 0x89, 0xab, 0xb6, 0xa5, 0xa5, 0x05, 0x52, 0x27, 0x4e, 0x9c, 0x00, 0xbf, 0xdd, 0x6e, - 0x27, 0xfe, 0xc7, 0xbe, 0xf7, 0xe6, 0xcd, 0x1b, 0xb4, 0x60, 0x91, 0x10, 0xd8, 0x24, 0xaa, 0x43, - 0xd5, 0x00, 0xfd, 0x8e, 0x10, 0x22, 0x1c, 0x8b, 0x17, 0x2f, 0x26, 0xfa, 0x61, 0x25, 0x85, 0xc9, - 0x54, 0x55, 0x55, 0x91, 0xae, 0xd0, 0x27, 0x02, 0x00, 0x2b, 0x1e, 0x9c, 0x98, 0x35, 0x31, 0x31, - 0x91, 0x74, 0x91, 0x70, 0x22, 0x34, 0xec, 0x57, 0x5b, 0x5b, 0x0b, 0x86, 0xfb, 0xf7, 0xef, 0x93, - 0x7d, 0x09, 0x4b, 0x73, 0xe5, 0xca, 0x95, 0x62, 0x2a, 0xdc, 0xb8, 0x71, 0x23, 0x99, 0xe8, 0xc2, - 0x85, 0x0b, 0x44, 0x04, 0x7b, 0x1d, 0xb6, 0x5a, 0x42, 0xc3, 0x22, 0x8f, 0x1e, 0x3d, 0x0a, 0xd3, - 0x04, 0xd5, 0xf7, 0x02, 0xb8, 0x77, 0xef, 0x5e, 0x6a, 0x6a, 0x2a, 0xd6, 0x1f, 0x2e, 0x4e, 0xc2, - 0xc4, 0x90, 0x01, 0xc8, 0xa0, 0xa1, 0x4f, 0x04, 0x00, 0xee, 0x17, 0x08, 0x27, 0x66, 0xc2, 0x75, - 0x15, 0xe9, 0x45, 0x48, 0x60, 0xbd, 0xc2, 0x93, 0xd0, 0x86, 0x00, 0x00, 0x0f, 0xbe, 0x0e, 0x62, - 0x77, 0x27, 0x0c, 0xe8, 0x02, 0xf3, 0xde, 0xbd, 0x7b, 0x87, 0x87, 0x87, 0xc5, 0x89, 0xae, 0x5f, - 0xbf, 0x4e, 0x96, 0x3e, 0xe1, 0xa9, 0xac, 0xac, 0x7c, 0xf0, 0xe0, 0x81, 0xd8, 0x1b, 0x4a, 0x8c, - 0xf5, 0x52, 0x8f, 0xcf, 0xc0, 0x30, 0x15, 0x39, 0x08, 0x84, 0xea, 0x3a, 0x41, 0x1a, 0xfb, 0x3d, - 0x82, 0x04, 0x47, 0x09, 0x62, 0xef, 0xd1, 0x52, 0x48, 0x67, 0x58, 0x63, 0x08, 0x74, 0xd1, 0x63, - 0x61, 0x3c, 0xd8, 0xb8, 0x31, 0xc8, 0x9c, 0x39, 0x73, 0x48, 0x50, 0x85, 0xf5, 0x92, 0xea, 0x58, - 0x00, 0xde, 0x29, 0xf0, 0x53, 0x6b, 0x0c, 0x3f, 0x4a, 0xfc, 0xd4, 0xf4, 0x1b, 0x57, 0x9f, 0x18, - 0x80, 0x71, 0x4d, 0x34, 0xcd, 0x0c, 0x31, 0x0f, 0x4c, 0xb3, 0x81, 0xc7, 0x1d, 0x3e, 0xe6, 0x81, - 0x71, 0x4d, 0x34, 0xcd, 0x0c, 0x31, 0x0f, 0x4c, 0xb3, 0x81, 0xc7, 0x1d, 0x3e, 0xe6, 0x81, 0x71, - 0x4d, 0x34, 0xcd, 0x0c, 0xff, 0x07, 0x71, 0xef, 0x64, 0x50, 0x13, 0xcd, 0x1c, 0x52, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXVideoIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x1d, 0x7b, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x5d, 0x09, 0x5c, 0x55, 0xd5, 0xd6, 0xff, 0x33, 0x5f, 0x66, 0x10, 0x70, 0x46, 0xc0, 0x11, 0x4d, - 0x02, 0x51, 0xeb, 0xe5, 0x94, 0xa5, 0x69, 0x8e, 0x5f, 0x45, 0xa9, 0x2f, 0xfd, 0x5e, 0x59, 0xaf, - 0xb9, 0xac, 0x34, 0x9b, 0x9e, 0x59, 0x9f, 0xf6, 0x9e, 0xcd, 0xbe, 0xcc, 0x29, 0x2d, 0x7d, 0x95, - 0xe6, 0x33, 0x87, 0xd4, 0xd2, 0x1c, 0x32, 0x07, 0x1c, 0x02, 0x19, 0x84, 0x00, 0x11, 0x04, 0x19, - 0x45, 0xe6, 0x79, 0x1e, 0xce, 0xb7, 0xd6, 0xbe, 0xf7, 0x1c, 0xef, 0xbd, 0x70, 0x91, 0x0b, 0xc8, - 0xd5, 0xf7, 0xd8, 0xfc, 0x2e, 0xe7, 0xec, 0x79, 0xaf, 0xb5, 0xf6, 0xb8, 0xf6, 0x5a, 0xeb, 0x98, - 0x49, 0xe4, 0x60, 0x84, 0x33, 0x6f, 0x2e, 0xed, 0xd5, 0xac, 0x2b, 0xd8, 0xb4, 0x6e, 0xb5, 0x4e, - 0x12, 0x33, 0xfd, 0x1a, 0x96, 0xbf, 0xb5, 0x08, 0x92, 0xb9, 0x25, 0xac, 0xa8, 0xa8, 0x32, 0x95, - 0x2b, 0x8a, 0x2e, 0x9e, 0xc3, 0x9a, 0x6f, 0x77, 0x29, 0x99, 0x2c, 0x95, 0x37, 0xcd, 0xcb, 0x98, - 0xb1, 0x77, 0xa3, 0xa8, 0xb0, 0x10, 0xc5, 0x6e, 0x5e, 0x48, 0x4f, 0x4a, 0xc2, 0xc2, 0x25, 0x2b, - 0x74, 0x92, 0x34, 0x6a, 0xd2, 0xee, 0xed, 0xdf, 0x21, 0x22, 0xbb, 0x14, 0x97, 0x62, 0xa2, 0x71, - 0xcf, 0x6d, 0x03, 0x91, 0x96, 0x99, 0xa9, 0x93, 0xa1, 0x51, 0x93, 0x38, 0xf6, 0x8d, 0xbf, 0x7f, - 0x0c, 0xa9, 0xa1, 0x01, 0x97, 0x92, 0x93, 0xb1, 0x7b, 0xf3, 0x97, 0x3a, 0x19, 0x1a, 0x35, 0x89, - 0x63, 0x33, 0x2f, 0xc5, 0xc3, 0xc1, 0xc9, 0x05, 0x9e, 0x0e, 0xd6, 0x3a, 0x89, 0xd9, 0xd3, 0x64, - 0x0d, 0x8d, 0x52, 0x69, 0x05, 0x34, 0x82, 0x41, 0x2b, 0xae, 0xc9, 0x57, 0x25, 0xc3, 0xe2, 0xc5, - 0x8b, 0x45, 0x02, 0x33, 0x33, 0x33, 0xbc, 0xfe, 0xfa, 0xeb, 0x4a, 0xe2, 0x07, 0x1f, 0x7c, 0x10, - 0x0d, 0x04, 0x8f, 0xec, 0x6e, 0x7c, 0x93, 0xda, 0xaf, 0x86, 0x2d, 0xff, 0xda, 0x84, 0x2b, 0x57, - 0xae, 0xc8, 0x4d, 0x57, 0x9e, 0x8d, 0xe8, 0x50, 0x5a, 0x52, 0x0c, 0x47, 0x27, 0x67, 0x1c, 0x3f, - 0xb8, 0x17, 0x31, 0x99, 0x79, 0xe8, 0x52, 0x99, 0x87, 0xd7, 0xdf, 0xff, 0xa8, 0xe9, 0x0c, 0xc7, - 0x0f, 0xee, 0x47, 0x68, 0x42, 0x0a, 0x02, 0xc6, 0x4f, 0x84, 0xca, 0x27, 0x00, 0xdf, 0xfd, 0x73, - 0x19, 0xd2, 0xb3, 0x4b, 0x94, 0xc4, 0xfc, 0xa2, 0xa0, 0x95, 0x3d, 0xfb, 0xf6, 0xec, 0x42, 0x69, - 0x3d, 0x10, 0x7c, 0xe4, 0x30, 0x1c, 0xa9, 0xbb, 0xbe, 0xbc, 0x78, 0x29, 0xcc, 0xcd, 0x75, 0x92, - 0xe8, 0x66, 0xf8, 0x6c, 0xfd, 0x26, 0xd4, 0x56, 0x57, 0xa1, 0xa6, 0xaa, 0x12, 0xc5, 0xb5, 0x12, - 0xe2, 0x32, 0x72, 0xb8, 0x1c, 0x1d, 0xd7, 0x08, 0x86, 0xe4, 0xb8, 0x68, 0xd8, 0x58, 0x58, 0xc2, - 0xce, 0xd1, 0x19, 0x36, 0x35, 0x95, 0x3a, 0x89, 0xd9, 0xd3, 0x7e, 0x68, 0xe5, 0x2e, 0xd2, 0x94, - 0x13, 0x4d, 0xe2, 0x48, 0xed, 0xb9, 0x40, 0xc6, 0xbf, 0xb7, 0xb7, 0x37, 0x86, 0x0d, 0x1b, 0x06, - 0x2b, 0x2b, 0x2b, 0xec, 0xd8, 0xb1, 0x43, 0xa4, 0x69, 0xbf, 0x26, 0x35, 0xd5, 0x1c, 0x0e, 0x33, - 0xba, 0x06, 0x43, 0x05, 0x19, 0x0a, 0x6f, 0x44, 0x06, 0x43, 0x09, 0xe5, 0xf0, 0x7d, 0xfb, 0xf6, - 0xe1, 0xfb, 0xcd, 0x5f, 0xc0, 0xab, 0x97, 0x17, 0x60, 0x61, 0x81, 0xb2, 0xd2, 0x7c, 0xdc, 0x3f, - 0x73, 0x2e, 0x66, 0x3c, 0xf0, 0xa0, 0x9c, 0x44, 0xe7, 0xa9, 0xdb, 0x4d, 0x74, 0xa2, 0x80, 0x9f, - 0xf7, 0xed, 0xc1, 0xd1, 0x23, 0x87, 0x44, 0xe8, 0x3b, 0x8b, 0x17, 0x20, 0x37, 0x37, 0x07, 0x71, - 0x51, 0x61, 0x88, 0x88, 0x8c, 0x86, 0x95, 0x8f, 0x3f, 0xf2, 0xf2, 0x8a, 0x10, 0x7b, 0x21, 0x1e, - 0xb1, 0x11, 0x21, 0x7a, 0x39, 0xaf, 0x79, 0x5b, 0x84, 0xa2, 0x27, 0x5e, 0xfb, 0x1b, 0x06, 0xfa, - 0x0e, 0x42, 0x75, 0x45, 0x05, 0x88, 0x74, 0xc8, 0x4e, 0x4b, 0xc1, 0x50, 0xff, 0x40, 0x24, 0x44, - 0x9d, 0xc3, 0x6b, 0xaf, 0xbe, 0x82, 0xde, 0xbd, 0x7b, 0x5f, 0x2b, 0x51, 0xef, 0xed, 0xba, 0x28, - 0xaa, 0xab, 0xab, 0x43, 0x8f, 0x1e, 0xdd, 0x50, 0x52, 0x50, 0x40, 0x59, 0x69, 0x19, 0xa1, 0x0a, - 0x12, 0xe2, 0x62, 0x10, 0x7b, 0x3e, 0x02, 0x66, 0x0d, 0x75, 0xc8, 0xcd, 0xc9, 0x69, 0x5b, 0x05, - 0x96, 0x96, 0x96, 0xc8, 0xce, 0x48, 0x47, 0x55, 0x59, 0x39, 0x15, 0x2f, 0xc1, 0xa3, 0x7b, 0x0f, - 0xf4, 0xf7, 0x0b, 0xc0, 0xe3, 0x0f, 0x4d, 0xc7, 0xd6, 0x1f, 0x0f, 0x60, 0x58, 0x60, 0xa0, 0x5e, - 0x9b, 0x75, 0xbd, 0x2d, 0x42, 0x91, 0x6e, 0x16, 0xe3, 0x7c, 0xcd, 0x12, 0x99, 0x8b, 0xf2, 0xf3, - 0xf3, 0xd3, 0x29, 0xf1, 0xe4, 0xc9, 0x93, 0x38, 0x77, 0xee, 0x9c, 0x4e, 0x58, 0xb3, 0x1e, 0x5e, - 0x3d, 0xd9, 0xc5, 0xc4, 0xc4, 0xf0, 0x3a, 0x2d, 0xe5, 0xe5, 0xe5, 0x89, 0x27, 0x87, 0xcd, 0x9b, - 0x37, 0x4f, 0x79, 0x67, 0x3f, 0xc7, 0xdb, 0xd9, 0xd9, 0x29, 0x61, 0xec, 0x8f, 0x8c, 0x8c, 0xd4, - 0xf1, 0x7f, 0xfd, 0xf5, 0xd7, 0x8a, 0x5f, 0xe4, 0xe1, 0x7f, 0xda, 0x8e, 0x33, 0xc9, 0x8e, 0xdf, - 0xe5, 0x1f, 0x87, 0xc9, 0xef, 0x72, 0x1a, 0x43, 0xfe, 0x2e, 0x5d, 0xba, 0xc8, 0x45, 0x48, 0xa6, - 0xa7, 0x01, 0xb5, 0xb2, 0x4d, 0xee, 0xd6, 0x87, 0xe0, 0xba, 0xdd, 0x54, 0x1f, 0x3f, 0xbc, 0x71, - 0xf8, 0xe0, 0x9d, 0xc5, 0x28, 0x2a, 0xc8, 0xc7, 0x8a, 0x25, 0xaf, 0xa1, 0xbe, 0x9e, 0x96, 0xc1, - 0x66, 0x9c, 0xd1, 0x15, 0x14, 0xe6, 0xe7, 0x22, 0x22, 0x2a, 0x0a, 0x2f, 0x3c, 0x35, 0x17, 0x97, - 0x93, 0x13, 0x11, 0x1e, 0x16, 0xd6, 0x4c, 0xf1, 0x7a, 0xeb, 0xb2, 0x7e, 0xca, 0xed, 0x5b, 0xb7, - 0x20, 0x35, 0xe5, 0x32, 0xb2, 0xae, 0x64, 0xe2, 0xeb, 0xd5, 0x9f, 0x89, 0xd6, 0x2e, 0xfb, 0xdb, - 0x62, 0x5a, 0x55, 0x81, 0x51, 0x53, 0x1f, 0x85, 0x54, 0x5f, 0x87, 0x1d, 0xff, 0x5a, 0xa7, 0x9f, - 0x4d, 0xc7, 0x6f, 0x10, 0x82, 0xb3, 0x21, 0xa1, 0x98, 0x3d, 0x77, 0x1e, 0xb6, 0x7f, 0xfb, 0x0d, - 0x4d, 0xdb, 0xfb, 0xf0, 0xe4, 0x8b, 0x0b, 0xf1, 0xf5, 0xda, 0xcf, 0xe1, 0xd6, 0xb3, 0x0f, 0x06, - 0x4e, 0x9c, 0x85, 0xac, 0xc2, 0x22, 0xc4, 0x24, 0x26, 0x62, 0x80, 0xdf, 0x30, 0x9d, 0x02, 0xf5, - 0x3d, 0x06, 0x67, 0xd3, 0x43, 0xbb, 0xb6, 0xa2, 0xaa, 0x20, 0x07, 0xc5, 0x36, 0x4e, 0x48, 0x4e, - 0x4a, 0x47, 0x8f, 0xe3, 0x67, 0x61, 0x33, 0x20, 0x10, 0xde, 0x03, 0xcd, 0x90, 0x18, 0x1b, 0x83, - 0x72, 0xda, 0xe3, 0x4c, 0x1c, 0x35, 0x1a, 0xe9, 0xf1, 0x71, 0xfa, 0x65, 0xea, 0xf8, 0x0d, 0x42, - 0x50, 0x48, 0x7b, 0xe7, 0x7b, 0xa6, 0x4c, 0x47, 0x41, 0x72, 0x1c, 0x26, 0x3f, 0xf0, 0x30, 0xce, - 0x9d, 0x3f, 0x8f, 0xcb, 0x09, 0xf1, 0x48, 0xa1, 0x5f, 0x17, 0x7b, 0x3b, 0x54, 0xe4, 0xe7, 0xa0, - 0xd2, 0xd2, 0x01, 0xcb, 0x57, 0xe9, 0xee, 0x7a, 0x75, 0x4a, 0x27, 0x8f, 0x41, 0x08, 0x3e, 0xdf, - 0xf8, 0x2d, 0xe2, 0xe2, 0x13, 0x30, 0x60, 0xe4, 0x28, 0x44, 0x86, 0x9e, 0x15, 0x5b, 0x04, 0xd4, - 0x4b, 0x68, 0xa0, 0x2d, 0xc5, 0xb0, 0xdb, 0x06, 0x21, 0x3f, 0x23, 0x09, 0xdd, 0xbb, 0xf6, 0xd0, - 0x2f, 0xaf, 0x91, 0xdf, 0x20, 0x04, 0x9c, 0x72, 0x88, 0xef, 0x40, 0xd4, 0xd6, 0xd6, 0xa2, 0x9e, - 0x7f, 0x75, 0xfc, 0xab, 0x13, 0xbf, 0xb7, 0xdf, 0x7b, 0x0f, 0x47, 0x0e, 0x1f, 0x41, 0xf0, 0xa9, - 0x93, 0x8d, 0x0a, 0xd4, 0x0f, 0x30, 0x08, 0x81, 0x9c, 0x50, 0x5d, 0x68, 0xad, 0x1a, 0x02, 0x9a, - 0xee, 0x1a, 0xa4, 0x06, 0xb8, 0x79, 0x7a, 0x43, 0x65, 0x67, 0x8f, 0x6f, 0xa9, 0x67, 0x5d, 0xcf, - 0x5d, 0xb7, 0x82, 0xea, 0xea, 0x6a, 0x64, 0x5c, 0x4e, 0xe1, 0x0d, 0x0e, 0x1a, 0xea, 0x1b, 0xd0, - 0xb5, 0x67, 0x4f, 0x8c, 0xf6, 0xf3, 0x45, 0x45, 0x55, 0x95, 0xe8, 0xbe, 0xde, 0x3e, 0x7d, 0x9b, - 0xad, 0xe3, 0xba, 0x15, 0xf4, 0xed, 0xea, 0x81, 0xa4, 0x98, 0x18, 0xf0, 0x76, 0xce, 0x82, 0x66, - 0xec, 0x2a, 0xea, 0x3d, 0x61, 0xf1, 0xe9, 0x00, 0x55, 0x76, 0xbd, 0xc2, 0xb9, 0xe6, 0xff, 0xf0, - 0xc9, 0x6e, 0xf2, 0xe4, 0xc9, 0x8d, 0xf0, 0x7b, 0xec, 0xd8, 0xb1, 0x46, 0x61, 0xcd, 0x05, 0x18, - 0x8d, 0xa2, 0x6e, 0xdd, 0xba, 0x21, 0x3b, 0x3b, 0xbb, 0xb9, 0x32, 0x75, 0xe3, 0xe4, 0xc5, 0x93, - 0x42, 0xa5, 0x23, 0x47, 0x8e, 0x48, 0xb4, 0xf7, 0x96, 0xa8, 0x95, 0x22, 0xd8, 0xc9, 0xc9, 0x49, - 0x8e, 0x16, 0xeb, 0xf1, 0x84, 0x09, 0x13, 0xc4, 0x93, 0x03, 0xa7, 0x4f, 0x9f, 0x2e, 0x2d, 0x5f, - 0xbe, 0x5c, 0x1a, 0x3a, 0x74, 0xa8, 0x94, 0x9e, 0x9e, 0x2e, 0x79, 0x79, 0x79, 0x49, 0x53, 0xa6, - 0x4c, 0x91, 0xe8, 0xd0, 0x22, 0x45, 0x45, 0x45, 0x5d, 0xcb, 0xa7, 0xbc, 0xd1, 0x8b, 0x8f, 0x8f, - 0x8f, 0x52, 0x00, 0x87, 0x07, 0x06, 0x06, 0x2a, 0xd1, 0xdc, 0x00, 0x76, 0xd4, 0x9b, 0xc4, 0x93, - 0xfd, 0x0f, 0x3c, 0xf0, 0x80, 0xf8, 0x1d, 0x3c, 0x78, 0x50, 0x27, 0x9f, 0x9c, 0x96, 0x13, 0x5e, - 0xdb, 0x42, 0xb0, 0x47, 0x53, 0x88, 0x88, 0xa0, 0x77, 0xf6, 0xcb, 0x61, 0x23, 0x47, 0x8e, 0x14, - 0xef, 0xdc, 0x88, 0xbb, 0xee, 0xba, 0x4b, 0xaa, 0xa8, 0xa8, 0x50, 0xe2, 0xa3, 0xa3, 0xa3, 0xa5, - 0xf8, 0xf8, 0x78, 0xc5, 0xcf, 0xf9, 0x65, 0x67, 0x34, 0x0d, 0xa8, 0x42, 0xa3, 0x5c, 0xb3, 0x73, - 0x91, 0x51, 0x25, 0x19, 0x48, 0x7c, 0xeb, 0x57, 0x70, 0xc3, 0x69, 0x60, 0x00, 0x73, 0xed, 0x16, - 0x7c, 0xdd, 0xc9, 0xb4, 0xdd, 0x6a, 0xa2, 0x82, 0x78, 0xed, 0x3a, 0xfd, 0xdb, 0x6f, 0x28, 0xc9, - 0xbf, 0x0a, 0x6b, 0x07, 0x17, 0x8c, 0x9f, 0x34, 0x09, 0x2a, 0x95, 0x6d, 0x9b, 0xaa, 0xe8, 0x10, - 0x0a, 0x7c, 0xf2, 0x8f, 0x65, 0xe8, 0x41, 0x6b, 0x60, 0x7e, 0x5a, 0x12, 0xce, 0x45, 0xfe, 0x0e, - 0xda, 0xdc, 0xc3, 0x8c, 0xb8, 0x20, 0x7d, 0x3d, 0xfb, 0xa1, 0xab, 0x77, 0x7f, 0x24, 0x44, 0x47, - 0x61, 0xe9, 0x87, 0x9f, 0xb6, 0x0a, 0x90, 0x36, 0x03, 0x90, 0x97, 0x97, 0x8f, 0x90, 0x93, 0xbf, - 0x21, 0xeb, 0xea, 0x55, 0xb8, 0x51, 0xc3, 0xfc, 0x47, 0xde, 0x89, 0xbe, 0xfd, 0xfa, 0x2b, 0x8d, - 0xf9, 0xe8, 0xef, 0xef, 0xc2, 0xad, 0x6b, 0x37, 0xfc, 0xb0, 0x75, 0x13, 0x2a, 0xca, 0xcb, 0x30, - 0xe6, 0x8e, 0xd1, 0xa8, 0xb1, 0xb4, 0x81, 0x3d, 0xea, 0x71, 0x3e, 0x2e, 0x0a, 0xf6, 0xb4, 0xff, - 0x09, 0x7a, 0xf4, 0x09, 0x84, 0x1e, 0x3f, 0x86, 0x8f, 0xd6, 0x7e, 0xad, 0xe4, 0x6b, 0xe9, 0x4b, - 0xab, 0x47, 0xf1, 0x87, 0x7f, 0x5f, 0x86, 0x0b, 0xb4, 0xbb, 0x5b, 0xbf, 0xf2, 0x03, 0x0c, 0x1f, - 0x35, 0x16, 0x7f, 0x7d, 0xfe, 0x25, 0x3c, 0x38, 0x67, 0x2e, 0x7e, 0xda, 0xf6, 0x2d, 0xce, 0x9e, - 0x0e, 0xc6, 0xab, 0xcf, 0xfd, 0x55, 0xb4, 0xa1, 0xe0, 0xea, 0x15, 0x1c, 0xfa, 0x69, 0x2f, 0xac, - 0xad, 0xec, 0xd0, 0xd3, 0x6b, 0x30, 0x6a, 0x7b, 0xfa, 0x22, 0x9e, 0x98, 0x58, 0x59, 0x92, 0x3d, - 0xcc, 0xea, 0x24, 0xd4, 0x55, 0xd5, 0x62, 0xdf, 0xf6, 0xad, 0xb0, 0x6e, 0x65, 0x4b, 0x5a, 0x45, - 0x81, 0xb7, 0x16, 0xbd, 0x84, 0x15, 0x9f, 0x7e, 0xa1, 0x20, 0xe9, 0xad, 0x97, 0x9f, 0xc5, 0x80, - 0xa1, 0xc4, 0x55, 0x38, 0x1f, 0x82, 0x65, 0x2b, 0xd7, 0xc1, 0xda, 0xda, 0x1a, 0x89, 0xa9, 0x99, - 0xd8, 0xb1, 0x6b, 0x37, 0x2c, 0x89, 0x57, 0x32, 0x62, 0xe4, 0x08, 0xec, 0xf9, 0xe5, 0x20, 0x54, - 0xf6, 0x8e, 0xb0, 0xa2, 0xb8, 0xf4, 0xc4, 0x78, 0xa4, 0x47, 0x06, 0xa3, 0x9b, 0xbb, 0x1b, 0x72, - 0x8b, 0xf2, 0x28, 0xee, 0x14, 0xf1, 0x56, 0x36, 0xe2, 0x99, 0x05, 0x0b, 0x95, 0x32, 0x5b, 0xfa, - 0xd2, 0x2a, 0x00, 0xde, 0x5e, 0xf0, 0x34, 0xfa, 0xf4, 0x1d, 0x48, 0x75, 0xd0, 0x52, 0x45, 0x67, - 0x9b, 0xd3, 0x89, 0xe9, 0xc8, 0x49, 0xbd, 0x0c, 0x67, 0xda, 0xd4, 0x4f, 0x0f, 0x9a, 0x85, 0xea, - 0x1a, 0xda, 0x8e, 0xa5, 0xa5, 0x51, 0xbc, 0x9a, 0x63, 0xc6, 0xbb, 0xa9, 0x8b, 0x91, 0x61, 0x50, - 0x39, 0xbb, 0xc0, 0xd6, 0xde, 0x01, 0x76, 0xb4, 0x1f, 0xec, 0xef, 0xe3, 0x8d, 0xac, 0xf0, 0xa3, - 0xb0, 0x25, 0xc6, 0xd8, 0xa2, 0xf7, 0x3f, 0x23, 0x9e, 0x10, 0x1d, 0x37, 0x5a, 0xe1, 0x5a, 0x05, - 0xc0, 0x49, 0xda, 0xb3, 0x98, 0x99, 0x9b, 0x61, 0xec, 0xdd, 0xe3, 0x71, 0xfc, 0xf8, 0x6f, 0xf8, - 0xd7, 0xfa, 0xb5, 0x98, 0xf9, 0xc2, 0xeb, 0x88, 0x08, 0x0d, 0x11, 0x18, 0x67, 0x6e, 0x09, 0x37, - 0x9e, 0xd6, 0x4b, 0x5e, 0x7d, 0xc5, 0x80, 0xb5, 0xa0, 0x2d, 0x60, 0xd0, 0x43, 0x8f, 0x50, 0x43, - 0xad, 0x50, 0x55, 0x98, 0x0e, 0x07, 0x02, 0xc4, 0xd1, 0xc9, 0x11, 0x39, 0xb4, 0x35, 0xd1, 0xe7, - 0x53, 0x18, 0x03, 0x47, 0xab, 0x00, 0xe0, 0x0a, 0xf8, 0x94, 0xb9, 0xe2, 0xbd, 0xbf, 0x21, 0x37, - 0x35, 0x11, 0x7d, 0xc6, 0x4e, 0x43, 0x51, 0x69, 0x05, 0x6d, 0x8a, 0xe5, 0x93, 0xa6, 0x06, 0x04, - 0x6e, 0x3f, 0xfd, 0x99, 0x9b, 0x99, 0xe3, 0xfc, 0xd9, 0xd3, 0xe8, 0xd3, 0xa7, 0x0f, 0x54, 0xb6, - 0x76, 0xf8, 0xf5, 0x00, 0x8d, 0x09, 0x6b, 0x1b, 0x01, 0xdc, 0x9b, 0x6f, 0xbe, 0x81, 0xa0, 0xa0, - 0x20, 0x63, 0xda, 0xac, 0x93, 0xb6, 0xd5, 0x00, 0x68, 0x97, 0xf2, 0xd1, 0xba, 0xf5, 0x28, 0x2a, - 0xab, 0xa2, 0xee, 0xc4, 0x3c, 0x77, 0xc6, 0xfe, 0xb5, 0x87, 0xa0, 0x00, 0x01, 0x10, 0x71, 0xe6, - 0x18, 0xca, 0x68, 0xc0, 0xf2, 0x71, 0x42, 0xa5, 0xb2, 0x81, 0x87, 0x8b, 0x2b, 0x36, 0x7f, 0xb9, - 0x46, 0x9d, 0xb6, 0x0d, 0xff, 0xdb, 0x65, 0x21, 0xab, 0xa9, 0xa9, 0x45, 0x2d, 0x1d, 0x43, 0xf8, - 0x12, 0x84, 0x1d, 0xed, 0xfa, 0xe8, 0xbf, 0xfa, 0x9d, 0xfb, 0x3f, 0x77, 0x25, 0xdf, 0x80, 0x91, - 0x28, 0x2f, 0x2f, 0x27, 0x76, 0x62, 0x39, 0x9c, 0x5c, 0xba, 0xc0, 0x9a, 0xf8, 0xd6, 0x97, 0x2e, - 0x5d, 0x42, 0xff, 0xfe, 0xd7, 0xa6, 0x5c, 0x91, 0xd9, 0xc8, 0x7f, 0xed, 0x02, 0x40, 0xf6, 0x95, - 0x2c, 0x3a, 0x47, 0x55, 0xa3, 0xa2, 0xb4, 0x54, 0xa9, 0x9e, 0x1b, 0xcd, 0xdd, 0xac, 0x87, 0x67, - 0x1f, 0x11, 0x56, 0x49, 0x9c, 0xc4, 0xfb, 0x47, 0xdf, 0x01, 0xef, 0xbe, 0x3e, 0x08, 0x0b, 0x0b, - 0x47, 0x44, 0xcc, 0x45, 0xb1, 0xa0, 0x29, 0x19, 0x5a, 0xf9, 0xd2, 0x2e, 0x5d, 0x88, 0xeb, 0x8e, - 0x88, 0x3c, 0x8f, 0x6d, 0xff, 0xde, 0x86, 0xec, 0x9c, 0x5c, 0x54, 0x56, 0x6a, 0x6e, 0x03, 0x34, - 0x63, 0x40, 0xdd, 0xab, 0xd4, 0x00, 0x75, 0xe9, 0xe2, 0x8a, 0x87, 0x1f, 0x0a, 0xc2, 0xe4, 0xc9, - 0x93, 0xc4, 0x59, 0xaf, 0x95, 0xed, 0x56, 0xb2, 0xb5, 0x1b, 0x00, 0x4a, 0x89, 0x1d, 0xfc, 0xd2, - 0xca, 0xf5, 0xaf, 0x83, 0x5b, 0xd9, 0x4c, 0x75, 0x6d, 0x02, 0x80, 0x07, 0x28, 0xff, 0x0c, 0xb9, - 0xb3, 0x67, 0xcf, 0x8a, 0xf8, 0xeb, 0xa5, 0x33, 0x94, 0xbf, 0x45, 0xe1, 0xf2, 0xe1, 0x4c, 0x7e, - 0x7e, 0xfc, 0xf1, 0xc7, 0x3c, 0x0f, 0x8a, 0xdf, 0xa3, 0x8f, 0x3e, 0x2a, 0xfd, 0xfa, 0xeb, 0xaf, - 0x8a, 0xff, 0xc9, 0x27, 0x9f, 0x94, 0x93, 0x29, 0x61, 0x9c, 0xb6, 0x29, 0x77, 0xc7, 0x1d, 0x77, - 0x88, 0x34, 0x01, 0x01, 0x01, 0x92, 0x87, 0x87, 0x87, 0x78, 0xd7, 0x4e, 0xf7, 0xc1, 0x07, 0x1f, - 0xe8, 0x94, 0x71, 0xf1, 0xe2, 0x45, 0xed, 0x68, 0xe9, 0xa9, 0xa7, 0x9e, 0xd2, 0x89, 0x8f, 0x8b, - 0x8b, 0xd3, 0x89, 0x97, 0x3d, 0x4d, 0xd6, 0x2e, 0x1f, 0x73, 0xf3, 0xf3, 0xf3, 0x45, 0x3a, 0x6e, - 0xe4, 0xc6, 0x8d, 0x1b, 0xe5, 0x3c, 0xca, 0x93, 0x8f, 0xcd, 0xfa, 0x00, 0xec, 0xd9, 0xb3, 0x47, - 0x84, 0x6d, 0xda, 0xb4, 0x49, 0x49, 0x27, 0x23, 0x44, 0x0e, 0x60, 0xbf, 0xbf, 0xbf, 0xbf, 0xf4, - 0xcd, 0x37, 0xdf, 0x28, 0x3f, 0x0e, 0x1b, 0x33, 0x66, 0x8c, 0x48, 0xc2, 0xef, 0x83, 0x06, 0x0d, - 0x92, 0x93, 0x2b, 0x61, 0xcc, 0x13, 0xd0, 0x77, 0x4d, 0x02, 0xc0, 0x89, 0x96, 0x2c, 0x59, 0xa2, - 0x60, 0xe0, 0x9d, 0x77, 0xde, 0xd1, 0xcf, 0x27, 0xfc, 0x4d, 0x01, 0x20, 0x1f, 0xbf, 0x7d, 0x7d, - 0x7d, 0x45, 0x1a, 0x62, 0x25, 0x2a, 0xe5, 0xc8, 0x85, 0xc8, 0x00, 0x11, 0x8f, 0x58, 0x0e, 0x92, - 0x5e, 0x78, 0xe1, 0x05, 0x69, 0xcb, 0x96, 0x2d, 0xc2, 0x2f, 0xc7, 0x13, 0xeb, 0x4b, 0xf8, 0x3f, - 0xfd, 0xf4, 0x53, 0x51, 0xc6, 0xd4, 0xa9, 0x53, 0x95, 0xf4, 0xf2, 0x8b, 0x41, 0x00, 0x38, 0x01, - 0xb1, 0x50, 0x24, 0xba, 0x95, 0x94, 0xd3, 0x1a, 0xf5, 0xe4, 0xc6, 0x31, 0x25, 0x9b, 0x73, 0xa5, - 0xa5, 0xa5, 0xd2, 0x4f, 0x3f, 0xfd, 0x24, 0x25, 0x27, 0x27, 0x37, 0x99, 0x2c, 0x27, 0x27, 0x47, - 0x74, 0x61, 0x5a, 0x4f, 0x9a, 0x8c, 0xe7, 0xc0, 0xce, 0x69, 0x94, 0xc8, 0x6d, 0x52, 0xd7, 0xa6, - 0x69, 0xd4, 0xa4, 0x2d, 0xd7, 0x54, 0x7e, 0xcb, 0x03, 0xd0, 0x39, 0x06, 0x4c, 0xdd, 0x8d, 0x6e, - 0xf9, 0x2e, 0xd4, 0x2e, 0xe7, 0x81, 0x96, 0x50, 0x81, 0xcf, 0x06, 0x97, 0x49, 0xe2, 0xeb, 0x8f, - 0xd0, 0x33, 0xbc, 0xf6, 0x60, 0xf0, 0xb0, 0xe1, 0x18, 0x34, 0xf8, 0xb6, 0x6b, 0x7b, 0x29, 0xba, - 0x65, 0x02, 0x49, 0x21, 0x18, 0xeb, 0x3a, 0x64, 0x0c, 0x24, 0x51, 0xc3, 0x7f, 0xd9, 0xb1, 0x05, - 0x7d, 0x06, 0x0c, 0xc1, 0xb8, 0x7b, 0x27, 0xd0, 0x46, 0x41, 0xc2, 0xb1, 0xdf, 0x7e, 0xc5, 0xd5, - 0xc4, 0x58, 0x4c, 0x7a, 0x78, 0x1e, 0xfa, 0xf5, 0x1f, 0x60, 0x6c, 0xbb, 0x95, 0xf4, 0x37, 0x1c, - 0x80, 0x98, 0x98, 0x58, 0xe2, 0x87, 0x1e, 0x44, 0xd2, 0xa5, 0x24, 0xba, 0xa8, 0xaa, 0xa1, 0xc3, - 0x7f, 0x21, 0xac, 0x6d, 0x6c, 0xe0, 0xe2, 0xec, 0x06, 0x3b, 0x95, 0x3d, 0x31, 0x2f, 0xcc, 0x30, - 0x63, 0xd6, 0x3c, 0x0c, 0xb9, 0xed, 0x36, 0xa5, 0x51, 0xc6, 0xbc, 0xdc, 0xf0, 0x31, 0xb0, 0x93, - 0x58, 0x8a, 0xbe, 0xb7, 0x07, 0xd0, 0x31, 0x32, 0x18, 0xee, 0x6e, 0x1e, 0xc8, 0x2b, 0x28, 0x44, - 0x61, 0x71, 0x19, 0x1c, 0x6d, 0xed, 0x11, 0x13, 0x13, 0x86, 0x29, 0x0f, 0x06, 0xe1, 0x9b, 0x75, - 0x2b, 0xa9, 0xcd, 0xbc, 0xdd, 0x31, 0xde, 0xb5, 0x99, 0x02, 0xbf, 0x13, 0x1b, 0x31, 0x25, 0x29, - 0x11, 0x75, 0xc4, 0x79, 0xee, 0xe3, 0xe5, 0x83, 0xb1, 0x13, 0xee, 0x53, 0xfa, 0x75, 0x7c, 0xfc, - 0x05, 0xba, 0x92, 0xf5, 0xc0, 0xdc, 0xd9, 0xd3, 0x51, 0x57, 0x53, 0x87, 0xba, 0xba, 0x7a, 0x8c, - 0xfe, 0xd3, 0x68, 0xd4, 0x9b, 0x59, 0x20, 0x95, 0xba, 0x4f, 0x1d, 0x1d, 0xfc, 0x6d, 0x55, 0x96, - 0x78, 0x7b, 0xf9, 0x6a, 0x64, 0x90, 0xcc, 0xd0, 0x3d, 0x13, 0x27, 0x19, 0x0d, 0x81, 0xf1, 0xa3, - 0x46, 0x53, 0x45, 0x72, 0x72, 0x0a, 0x8e, 0xee, 0xdf, 0x09, 0xef, 0xfe, 0xbe, 0x98, 0x38, 0x75, - 0x06, 0x31, 0xb4, 0x2c, 0x51, 0x90, 0x9f, 0x8b, 0x55, 0x2b, 0xde, 0xc5, 0xf0, 0xd1, 0x13, 0x30, - 0xe6, 0xee, 0xbb, 0x71, 0x25, 0x2d, 0x15, 0x27, 0x0e, 0x1f, 0x44, 0x0f, 0x8f, 0x6e, 0xc4, 0xb1, - 0x20, 0x0c, 0x93, 0x44, 0x69, 0xbd, 0x47, 0x5f, 0x38, 0x39, 0x3a, 0xc2, 0x8d, 0xce, 0xcd, 0x35, - 0x25, 0xb9, 0xb0, 0xb6, 0xb4, 0x40, 0xf0, 0xd1, 0x43, 0x68, 0xa8, 0xad, 0x6a, 0x15, 0x00, 0xad, - 0xea, 0x42, 0x99, 0x24, 0xb7, 0xf8, 0xfd, 0xe6, 0xf5, 0x70, 0xec, 0xd2, 0x15, 0x29, 0x74, 0xd3, - 0xeb, 0xee, 0xee, 0x01, 0x17, 0x57, 0x57, 0x84, 0x45, 0x44, 0x21, 0x37, 0xbf, 0x10, 0xd5, 0x55, - 0xe5, 0x38, 0xb4, 0x7f, 0xbf, 0xa0, 0x4a, 0x4a, 0x4a, 0x12, 0xb2, 0x73, 0x0b, 0x91, 0x44, 0x00, - 0xf7, 0x1b, 0x37, 0x1d, 0xa1, 0x27, 0x8e, 0xe2, 0xdc, 0xf1, 0x5f, 0x51, 0x54, 0x54, 0x4c, 0x5c, - 0xb9, 0x5c, 0xe2, 0x6a, 0xe7, 0x20, 0x36, 0x3a, 0x42, 0x47, 0x8e, 0xd3, 0x18, 0x32, 0x18, 0x0d, - 0x00, 0x4f, 0x87, 0x1b, 0x3f, 0xff, 0x14, 0x4b, 0x96, 0x7f, 0x80, 0x59, 0x7f, 0x9e, 0x87, 0xec, - 0xf4, 0x24, 0x92, 0xac, 0x48, 0x11, 0x53, 0x63, 0x6a, 0x6c, 0x18, 0x5e, 0x7d, 0xfb, 0x3d, 0x4c, - 0x98, 0x3c, 0x95, 0x38, 0xd7, 0x91, 0x70, 0x76, 0x73, 0xc7, 0x6b, 0x6f, 0x2d, 0x45, 0x5a, 0x46, - 0x1a, 0x7a, 0x0d, 0x1d, 0x41, 0xec, 0xf5, 0x0a, 0xdc, 0x39, 0x71, 0x0a, 0xfa, 0x92, 0x80, 0x56, - 0x51, 0x56, 0x1a, 0x72, 0x8a, 0x0a, 0x50, 0x52, 0x5e, 0x8c, 0xc5, 0xef, 0xae, 0x80, 0x67, 0xbf, - 0x41, 0xc6, 0xb4, 0x5b, 0x49, 0x6b, 0x74, 0x17, 0x4a, 0xcf, 0xc8, 0xc0, 0xd0, 0x61, 0x6a, 0xa9, - 0x30, 0x16, 0xd5, 0x1c, 0x1c, 0x70, 0x27, 0x36, 0xaf, 0xfb, 0x02, 0x96, 0x34, 0xb3, 0xb0, 0x04, - 0x83, 0x9b, 0x9b, 0x1b, 0x2a, 0x2a, 0xab, 0x30, 0xf0, 0x8e, 0x7b, 0x11, 0x1e, 0x9b, 0x80, 0x90, - 0xe8, 0x0b, 0xb8, 0x67, 0xfa, 0x6c, 0xd8, 0x75, 0xf7, 0xa4, 0x1b, 0xf2, 0x06, 0x31, 0x3e, 0x7e, - 0xfc, 0x66, 0x0d, 0x1e, 0x21, 0xb6, 0xca, 0xf1, 0x90, 0xb3, 0x98, 0xf3, 0xd8, 0xf3, 0xd8, 0xb2, - 0x71, 0x2d, 0x01, 0xfe, 0xae, 0xd2, 0x28, 0x63, 0x5e, 0x8c, 0x06, 0x20, 0x3c, 0xe4, 0x77, 0x14, - 0xe7, 0xe5, 0xe2, 0x18, 0x09, 0xab, 0x32, 0x27, 0xae, 0xb0, 0xb8, 0x14, 0x35, 0xce, 0xdd, 0x51, - 0x4e, 0x83, 0x58, 0x55, 0x59, 0x84, 0x43, 0xbf, 0x1c, 0x80, 0xa3, 0xef, 0x70, 0xe4, 0x56, 0xd7, - 0xc0, 0xbe, 0x97, 0x37, 0xcd, 0x2d, 0x12, 0x7c, 0x6c, 0x9d, 0x91, 0x4a, 0x42, 0x34, 0x4e, 0xd4, - 0xcd, 0x98, 0x3b, 0xed, 0x4c, 0x5c, 0xea, 0x33, 0xe1, 0x11, 0x98, 0x3c, 0x61, 0x12, 0xc9, 0xe7, - 0x79, 0xa2, 0x57, 0x2f, 0xcf, 0x56, 0x73, 0xa7, 0x8d, 0x06, 0xa0, 0x86, 0x58, 0xe7, 0xa9, 0x29, - 0xc9, 0xa8, 0x25, 0x19, 0x0d, 0x9e, 0xf8, 0x32, 0x73, 0xf3, 0x10, 0x12, 0xfe, 0x07, 0xc9, 0x6d, - 0xd4, 0xc0, 0x7f, 0xfc, 0xfd, 0xb0, 0xe9, 0x3b, 0x04, 0x87, 0x7f, 0xde, 0xcb, 0xbc, 0x69, 0x35, - 0x22, 0x69, 0xd1, 0xaa, 0xa2, 0x9b, 0x99, 0xcc, 0xb4, 0xcb, 0xc4, 0xf0, 0xaa, 0x80, 0x8d, 0xad, - 0x2d, 0xa6, 0xcf, 0x7f, 0x19, 0xa3, 0x07, 0x7b, 0xe3, 0xec, 0xcf, 0x3f, 0xd0, 0xec, 0x54, 0x8e, - 0x69, 0x0f, 0x3c, 0x62, 0x0c, 0xd2, 0x75, 0xd2, 0x1a, 0x3d, 0x8d, 0xc6, 0xc5, 0xc5, 0xa2, 0xb8, - 0x30, 0x1f, 0x77, 0x8d, 0x1e, 0x27, 0x0a, 0x3a, 0x7c, 0xf0, 0x20, 0x7e, 0x3c, 0x7a, 0x1c, 0x6e, - 0xbd, 0x7c, 0x30, 0x7c, 0xc4, 0x30, 0x62, 0xb1, 0x9f, 0xa3, 0x1d, 0x81, 0x9a, 0xd7, 0xcf, 0x5b, - 0x06, 0x66, 0xa9, 0x94, 0x91, 0x88, 0x8d, 0xb3, 0xbd, 0x3d, 0x9c, 0xbb, 0xb8, 0xe1, 0x4a, 0x7a, - 0x0a, 0xca, 0x8a, 0x0b, 0xa1, 0x32, 0xab, 0x47, 0xf7, 0x9e, 0xbd, 0xb1, 0x68, 0xd1, 0x22, 0x9d, - 0x06, 0x19, 0xeb, 0x31, 0x9a, 0x02, 0x83, 0x07, 0x0f, 0xc1, 0x82, 0xf9, 0x73, 0x05, 0x00, 0x3c, - 0xa0, 0x7f, 0xfe, 0xf7, 0x66, 0x0c, 0xb9, 0x7b, 0x26, 0xea, 0xa9, 0xd1, 0x11, 0xe7, 0x42, 0x85, - 0x08, 0xb3, 0x8e, 0x40, 0x17, 0x11, 0xa2, 0x8a, 0xe4, 0x52, 0x1e, 0x7e, 0x68, 0x36, 0x9c, 0x48, - 0x98, 0xba, 0xa4, 0x30, 0x1b, 0x6e, 0x2c, 0xd4, 0x4e, 0x80, 0x95, 0x97, 0x11, 0x4b, 0x9e, 0xca, - 0xd0, 0x17, 0x7b, 0x36, 0x06, 0x08, 0xa3, 0x01, 0x60, 0x8c, 0xbe, 0xfa, 0xce, 0x32, 0xac, 0xfe, - 0x68, 0x05, 0xba, 0xf5, 0xf1, 0x46, 0x15, 0x2c, 0x50, 0x43, 0x97, 0x1d, 0xc5, 0xb9, 0xf9, 0xa2, - 0x5e, 0x96, 0xca, 0xe1, 0xbd, 0x8e, 0xec, 0x98, 0x0a, 0x7c, 0xd9, 0x91, 0x9f, 0x16, 0x8f, 0x6a, - 0x62, 0xad, 0x5f, 0x22, 0x25, 0x81, 0xec, 0xbc, 0x6c, 0x5a, 0x37, 0xac, 0xa8, 0xe1, 0x66, 0x18, - 0x32, 0xc4, 0xb7, 0x4d, 0x00, 0x18, 0xdd, 0x85, 0xe4, 0x86, 0x25, 0x26, 0x5e, 0xc4, 0xa7, 0x4b, - 0x5f, 0x47, 0xcf, 0x81, 0x7e, 0xb0, 0xea, 0xd5, 0x0f, 0xe5, 0xcc, 0x99, 0xd6, 0xb4, 0x5b, 0x5c, - 0x6f, 0x28, 0x30, 0xd0, 0x18, 0x28, 0x2b, 0xa3, 0x95, 0x37, 0x01, 0x3e, 0xde, 0x3e, 0x48, 0xb8, - 0x18, 0x4f, 0xdd, 0xe8, 0x32, 0xcb, 0x1f, 0x89, 0x59, 0xe9, 0x1c, 0x51, 0xad, 0xb5, 0xd7, 0x4b, - 0xdc, 0x16, 0xa3, 0x29, 0x20, 0x03, 0x30, 0x60, 0xc0, 0x20, 0xac, 0xfb, 0x7e, 0x0f, 0x7e, 0xd8, - 0xb9, 0x03, 0x49, 0xf9, 0xa5, 0xe2, 0x72, 0x43, 0xdd, 0x66, 0x05, 0x0a, 0x4d, 0x52, 0xf5, 0x0d, - 0x4d, 0x52, 0xc2, 0x05, 0xe4, 0xd0, 0x8d, 0x65, 0x25, 0xdd, 0x11, 0xa8, 0x68, 0xca, 0x75, 0x74, - 0x72, 0x42, 0x57, 0x0f, 0xf7, 0x36, 0x35, 0xbe, 0x4d, 0x00, 0x70, 0x66, 0xee, 0x4e, 0xee, 0x74, - 0x07, 0x9c, 0x90, 0x53, 0x24, 0x04, 0xba, 0xd4, 0x14, 0xb8, 0x06, 0x00, 0x53, 0x82, 0xc4, 0xb1, - 0x68, 0xba, 0xad, 0x83, 0x05, 0x5d, 0x29, 0x59, 0xd0, 0xf5, 0x92, 0xbb, 0xab, 0x1b, 0x5d, 0x33, - 0xa9, 0xf0, 0xf4, 0xbc, 0xd9, 0x98, 0x72, 0xff, 0x54, 0x0d, 0x90, 0xad, 0x7f, 0xb4, 0x9a, 0x02, - 0x72, 0x95, 0xd4, 0x07, 0x49, 0xae, 0xb1, 0x4e, 0xdc, 0x56, 0xaa, 0xbb, 0xfe, 0x35, 0x00, 0x38, - 0x0d, 0x8f, 0x09, 0x07, 0x6a, 0x74, 0xd7, 0x3e, 0x7d, 0xc5, 0x36, 0x9a, 0x45, 0xa7, 0x2d, 0x2d, - 0xad, 0x90, 0x91, 0xc3, 0xb2, 0xd9, 0x6d, 0x77, 0x6d, 0x06, 0x80, 0x9b, 0xdb, 0x40, 0xa7, 0x29, - 0xde, 0x69, 0xf2, 0xe0, 0x15, 0xcd, 0x17, 0xff, 0x1a, 0xc4, 0x3b, 0x5f, 0xf0, 0x15, 0x91, 0x20, - 0xb9, 0xef, 0xc0, 0x01, 0xe2, 0x46, 0xd2, 0x86, 0xee, 0xc7, 0x9c, 0x1d, 0x9d, 0x70, 0xe9, 0x62, - 0x62, 0xdb, 0x5b, 0x4f, 0x25, 0xb4, 0x19, 0x00, 0x96, 0x76, 0xaf, 0xa5, 0x5f, 0x16, 0xed, 0x77, - 0x64, 0x46, 0xbb, 0x9a, 0x12, 0x54, 0x38, 0xed, 0x50, 0xdd, 0xba, 0x75, 0x15, 0x8b, 0x5a, 0xfa, - 0xe5, 0x64, 0xbc, 0xf4, 0xd4, 0x7c, 0x94, 0x95, 0x94, 0x62, 0xd7, 0xc1, 0xa3, 0x70, 0xa3, 0x2b, - 0xd6, 0xf6, 0x70, 0x6d, 0x06, 0x40, 0x65, 0x6d, 0x89, 0x6a, 0xda, 0xfb, 0x88, 0x2b, 0x56, 0x0d, - 0x05, 0x18, 0x10, 0xf5, 0x22, 0x26, 0x5e, 0xa8, 0x1b, 0x49, 0xb0, 0xb5, 0xb1, 0x86, 0x0b, 0xdd, - 0x4c, 0x3a, 0x38, 0x38, 0x50, 0x77, 0xa3, 0x31, 0x61, 0x46, 0xd3, 0x6d, 0x3b, 0xb8, 0x56, 0x4f, - 0xa3, 0x72, 0xdd, 0xdc, 0xd0, 0xff, 0x99, 0x3d, 0x97, 0x4e, 0x58, 0x3c, 0xaf, 0x6b, 0xf0, 0xa1, - 0x86, 0x40, 0x5c, 0x6a, 0xf3, 0xde, 0x87, 0x01, 0xa8, 0x2e, 0x2f, 0xa5, 0x15, 0xa3, 0x01, 0x35, - 0xb4, 0xa8, 0x55, 0x56, 0xd5, 0x61, 0xf9, 0xfb, 0xef, 0x62, 0xb0, 0xef, 0x60, 0xb9, 0x98, 0x56, - 0x3f, 0x8d, 0x07, 0x80, 0xba, 0x8b, 0x3e, 0xf7, 0x80, 0x57, 0xde, 0xb5, 0xeb, 0xd7, 0x23, 0x3a, - 0xfa, 0x0f, 0x94, 0xd0, 0x7a, 0xc0, 0xab, 0xab, 0x70, 0x34, 0x16, 0xe4, 0x35, 0x41, 0xa2, 0xc1, - 0x6c, 0x61, 0x41, 0xbb, 0xd7, 0xc1, 0x83, 0xb1, 0xf0, 0x95, 0x57, 0x68, 0x43, 0xe7, 0xdc, 0xea, - 0x46, 0x6b, 0x67, 0x34, 0x1e, 0x00, 0xed, 0xdc, 0x37, 0xc1, 0xbb, 0xd1, 0x07, 0x9a, 0x9b, 0xa0, - 0xcd, 0x3a, 0x4d, 0xe8, 0x04, 0x40, 0x07, 0x1d, 0x26, 0xf0, 0xb4, 0x69, 0x1a, 0xe5, 0xad, 0x04, - 0xaf, 0x03, 0x86, 0x36, 0x63, 0x74, 0x85, 0x44, 0xfc, 0x20, 0xb5, 0x2a, 0xc3, 0xf8, 0xf1, 0xe3, - 0xc5, 0xd6, 0xa3, 0xdd, 0x61, 0xa4, 0x69, 0xb0, 0x55, 0xae, 0xa0, 0xa0, 0x80, 0xd7, 0x5b, 0x29, - 0x33, 0x33, 0xd3, 0x60, 0x7e, 0x8e, 0x97, 0x7f, 0x21, 0x21, 0x21, 0x06, 0xd3, 0xb5, 0x25, 0xa2, - 0xd5, 0x14, 0x70, 0xa5, 0xf3, 0x2d, 0x55, 0xdc, 0x2c, 0x42, 0xe5, 0x78, 0xa6, 0x14, 0xff, 0x6e, - 0x84, 0x6b, 0x34, 0x88, 0xf9, 0x74, 0xa4, 0x5d, 0x21, 0xcb, 0xbf, 0x69, 0xfb, 0xb9, 0x11, 0x74, - 0x01, 0xae, 0x84, 0x7d, 0xf9, 0x65, 0x63, 0x4d, 0x8b, 0x5f, 0x7e, 0xf9, 0x85, 0xc4, 0xca, 0xec, - 0xc4, 0x41, 0x65, 0xef, 0xde, 0xbd, 0x8d, 0xda, 0x5d, 0x53, 0x53, 0x03, 0x47, 0x62, 0x6e, 0xc9, - 0xe5, 0xea, 0x4b, 0xb2, 0xe7, 0xe6, 0xe6, 0x8a, 0x6e, 0x29, 0xc7, 0x4f, 0x22, 0xf9, 0x52, 0x83, - 0x4e, 0x9f, 0x7c, 0x8f, 0x3d, 0xf6, 0x98, 0x20, 0xfb, 0xd8, 0xb1, 0x63, 0x45, 0xd4, 0x2b, 0xaf, - 0xbc, 0x22, 0xfc, 0xd3, 0xa6, 0x4d, 0x53, 0x92, 0x1e, 0x3e, 0x7c, 0x58, 0x62, 0x3f, 0x15, 0x2a, - 0xad, 0x5c, 0xb9, 0x52, 0x09, 0xe7, 0x97, 0xb5, 0x6b, 0xd7, 0x8a, 0x70, 0x95, 0x4a, 0x25, 0x51, - 0xc5, 0xe2, 0x9d, 0xd3, 0x69, 0x77, 0x21, 0xf6, 0x93, 0xf4, 0x96, 0x14, 0x1a, 0x1a, 0x2a, 0x7d, - 0xf8, 0xe1, 0x87, 0x22, 0x0d, 0xb1, 0x63, 0x44, 0x39, 0xda, 0xf7, 0xca, 0x6b, 0xd6, 0xac, 0x91, - 0xe6, 0xcf, 0x9f, 0xaf, 0x94, 0xa7, 0x53, 0x91, 0xc6, 0xc3, 0xdd, 0xa0, 0x91, 0xe3, 0x0a, 0x6c, - 0x6d, 0x6d, 0x45, 0xf8, 0xec, 0xd9, 0xb3, 0x45, 0x01, 0x8d, 0x12, 0x51, 0x40, 0x53, 0x00, 0x70, - 0x18, 0xff, 0x64, 0xb7, 0x7b, 0xf7, 0x6e, 0xe1, 0x97, 0x01, 0x90, 0x11, 0xa2, 0x7d, 0x4b, 0x3f, - 0x71, 0xe2, 0x44, 0x25, 0xcf, 0xf0, 0xe1, 0xc3, 0xc5, 0xbb, 0xf6, 0x25, 0xf8, 0x9c, 0x39, 0x73, - 0x44, 0x98, 0x7c, 0xf1, 0x2d, 0x97, 0xcd, 0xcf, 0x46, 0x5d, 0x88, 0x2a, 0xc7, 0x86, 0x0d, 0x1b, - 0x84, 0xcc, 0x0f, 0x6f, 0x09, 0xb6, 0x6f, 0xdf, 0x8e, 0x4f, 0x3e, 0xf9, 0x84, 0x83, 0x5b, 0xe5, - 0xf4, 0xbb, 0x47, 0x6c, 0x6c, 0xac, 0x28, 0xe7, 0xc7, 0x1f, 0x7f, 0x84, 0xfc, 0xe3, 0x0d, 0xde, - 0x33, 0xcf, 0x3c, 0x23, 0xc2, 0xe9, 0xa6, 0x5f, 0x3c, 0xb5, 0x0f, 0xfa, 0xac, 0xf6, 0xcb, 0x8e, - 0x25, 0xbc, 0x1a, 0x39, 0x6d, 0x68, 0xb4, 0xdf, 0x29, 0xa1, 0x64, 0x6f, 0x6f, 0xaf, 0x60, 0x46, - 0x3b, 0x4e, 0x7e, 0xe7, 0x34, 0xfa, 0x5d, 0x88, 0xfa, 0xad, 0xc8, 0xc3, 0xb7, 0xec, 0xec, 0x64, - 0x71, 0x04, 0x99, 0x02, 0xac, 0x07, 0xc1, 0xf9, 0xb8, 0x6b, 0xc8, 0x8e, 0x05, 0x39, 0xba, 0x77, - 0xef, 0x2e, 0xbc, 0x4b, 0x97, 0x2e, 0x15, 0xf1, 0x8f, 0x3f, 0xfe, 0xb8, 0x1c, 0x2d, 0xfc, 0x9c, - 0xa7, 0x29, 0xd7, 0x74, 0x28, 0xa5, 0x94, 0xc7, 0xc2, 0x82, 0x05, 0x0b, 0x74, 0xf2, 0x9d, 0x39, - 0x73, 0x46, 0x29, 0x90, 0x0b, 0x95, 0x7f, 0xfd, 0xfa, 0xf5, 0x13, 0xe9, 0xca, 0xca, 0xca, 0x94, - 0x30, 0x8e, 0xa3, 0x13, 0x98, 0xe2, 0x97, 0x0b, 0xba, 0xef, 0xbe, 0xfb, 0x94, 0x30, 0x39, 0xbf, - 0x0c, 0x00, 0xa7, 0x19, 0x30, 0x60, 0x40, 0xa3, 0x78, 0x9a, 0x18, 0xe4, 0xec, 0x3a, 0x4f, 0x83, - 0x00, 0x70, 0xaa, 0x43, 0x87, 0x0e, 0xe9, 0x24, 0x36, 0xc6, 0xc3, 0xe2, 0x33, 0x69, 0x69, 0x69, - 0xcd, 0x66, 0x09, 0x0f, 0x0f, 0x97, 0x18, 0x21, 0xd4, 0x55, 0x9b, 0x4c, 0x17, 0x1c, 0x1c, 0x2c, - 0x34, 0x50, 0x9a, 0x8c, 0xd4, 0x04, 0x76, 0xee, 0x46, 0xa9, 0x0b, 0x98, 0xd4, 0x35, 0x39, 0x0b, - 0x99, 0xb4, 0x45, 0x46, 0x56, 0xde, 0x09, 0x80, 0x91, 0x08, 0x6b, 0xf7, 0xe4, 0x9d, 0x14, 0x68, - 0x77, 0x94, 0x1a, 0x59, 0xe0, 0x2d, 0x4f, 0x81, 0x5b, 0x7e, 0x1d, 0x30, 0x92, 0x60, 0x37, 0x5d, - 0xf2, 0x5b, 0xbe, 0x07, 0xdd, 0x74, 0x18, 0x35, 0xb2, 0x41, 0x9d, 0x04, 0x30, 0x12, 0x61, 0xed, - 0x9d, 0xbc, 0xd5, 0x2c, 0x89, 0xf6, 0x6e, 0x48, 0x7b, 0x94, 0x47, 0xdb, 0x6b, 0x30, 0xb7, 0x20, - 0x92, 0xf4, 0x5b, 0xe2, 0xff, 0x38, 0x8f, 0xab, 0x99, 0x29, 0xc4, 0xb4, 0x6a, 0x80, 0x25, 0xab, - 0x4b, 0xd1, 0x75, 0x28, 0x2b, 0xbc, 0xd5, 0x54, 0x55, 0x88, 0xcb, 0x8a, 0x9e, 0xa4, 0xd8, 0x39, - 0x74, 0xd8, 0x48, 0x0c, 0xf1, 0xf3, 0x17, 0xba, 0x60, 0xcc, 0x3d, 0x30, 0x85, 0xfb, 0x8f, 0x58, - 0x03, 0xf8, 0xdc, 0x7e, 0x81, 0xac, 0x36, 0x1d, 0xda, 0xb7, 0x1b, 0x52, 0x5d, 0x95, 0x50, 0xc4, - 0xe3, 0xdb, 0xae, 0x41, 0x43, 0xfd, 0x90, 0x4a, 0xda, 0xb3, 0xf9, 0xb9, 0x57, 0xc5, 0x0d, 0x2a, - 0x13, 0xa2, 0x47, 0x4f, 0x4f, 0x38, 0xd3, 0x7d, 0x5d, 0x66, 0x72, 0x12, 0xcc, 0xea, 0x49, 0xf3, - 0xaa, 0xa6, 0x1a, 0xb5, 0xc4, 0x16, 0xb8, 0x9f, 0x44, 0x1d, 0xfc, 0x02, 0x02, 0xda, 0x74, 0x5f, - 0xdd, 0x1a, 0x02, 0xde, 0xf2, 0x04, 0x28, 0x20, 0x3b, 0x2c, 0xdf, 0x6f, 0xda, 0x40, 0x36, 0x41, - 0x6a, 0x30, 0xff, 0xb9, 0x05, 0x38, 0x73, 0xea, 0x38, 0xbe, 0xfe, 0xf2, 0x0b, 0xf8, 0xf6, 0x1b, - 0x48, 0x42, 0x61, 0x0e, 0x64, 0xa0, 0xe4, 0x02, 0x6a, 0xea, 0xaa, 0x49, 0xe3, 0xd7, 0x9e, 0x2e, - 0x89, 0x00, 0x1b, 0x6b, 0x15, 0x7a, 0xf7, 0xe8, 0x8d, 0xda, 0xca, 0x32, 0x14, 0x94, 0x14, 0x21, - 0x68, 0xde, 0x7c, 0xf8, 0x0e, 0x09, 0xc0, 0x57, 0xab, 0x3e, 0xa1, 0x5b, 0x60, 0x5b, 0x3c, 0x49, - 0x0a, 0xb9, 0x2c, 0x2d, 0xd4, 0x51, 0xee, 0xa6, 0x23, 0x00, 0xf3, 0xb9, 0x99, 0x1b, 0xa4, 0xcd, - 0x11, 0x32, 0x84, 0x8c, 0x52, 0x12, 0x5e, 0xf8, 0x6a, 0xcd, 0x2a, 0x12, 0xd6, 0x1c, 0x8a, 0x00, - 0x52, 0xc1, 0x5e, 0xb1, 0xec, 0x4d, 0x24, 0x5f, 0x4a, 0xa0, 0x1b, 0xb8, 0x2a, 0xe2, 0x68, 0x55, - 0x23, 0xd0, 0x7f, 0x38, 0x89, 0x1b, 0x76, 0xc5, 0x05, 0x92, 0x0f, 0xc8, 0x27, 0xd9, 0x1a, 0x96, - 0x97, 0xec, 0xef, 0xd3, 0x9f, 0xf4, 0x0d, 0x2b, 0x10, 0x97, 0x10, 0x07, 0x73, 0x2b, 0x4b, 0xb8, - 0x38, 0x39, 0xc0, 0xc5, 0xbd, 0x1b, 0x96, 0x2c, 0xfb, 0x0c, 0x1b, 0x56, 0x7f, 0x4e, 0x56, 0xc5, - 0xf2, 0xc9, 0xd4, 0xe3, 0x7b, 0x42, 0x24, 0xc5, 0x50, 0xbd, 0xed, 0x19, 0x6e, 0x32, 0x02, 0x14, - 0xd3, 0x45, 0x71, 0x64, 0x78, 0x18, 0xd9, 0xe3, 0xb9, 0x40, 0x06, 0x80, 0x2e, 0xc1, 0x82, 0xae, - 0xee, 0xbb, 0x93, 0x5d, 0x18, 0x47, 0x07, 0x47, 0x61, 0xe1, 0x26, 0x3b, 0xfb, 0x2a, 0x4a, 0x48, - 0xa0, 0xa8, 0xab, 0x47, 0x57, 0x78, 0xf5, 0x1b, 0x80, 0xc1, 0xb7, 0x07, 0x92, 0xc2, 0x65, 0x3f, - 0x1d, 0xd8, 0x43, 0xce, 0x9c, 0x42, 0x44, 0x58, 0x28, 0x49, 0x4a, 0x05, 0xe1, 0xe3, 0x15, 0xef, - 0x21, 0xea, 0x7c, 0x18, 0xc9, 0x34, 0xf0, 0x5c, 0xde, 0x40, 0x92, 0x86, 0x35, 0x42, 0x14, 0x66, - 0xc4, 0x9d, 0xe3, 0xd0, 0xc5, 0xc7, 0x97, 0x64, 0x3b, 0xcd, 0x60, 0x49, 0xb7, 0xed, 0x15, 0xb9, - 0x99, 0x88, 0x8f, 0x3c, 0x8d, 0x92, 0xb2, 0x62, 0x61, 0x89, 0x80, 0xe7, 0x7e, 0xbe, 0x23, 0xf6, - 0xea, 0x7f, 0x1b, 0x16, 0xbd, 0xf9, 0x1e, 0x36, 0xaf, 0x59, 0x89, 0x6e, 0x3d, 0x7b, 0xe1, 0x09, - 0x1a, 0x4d, 0x1d, 0xe1, 0x3a, 0x9c, 0x00, 0xb1, 0x71, 0x71, 0xf8, 0x85, 0x2c, 0xf1, 0x65, 0x5c, - 0x4e, 0x84, 0xab, 0xab, 0x8b, 0x30, 0x71, 0x38, 0x3d, 0xe8, 0xcf, 0xb8, 0x3d, 0xa0, 0xb1, 0x29, - 0x27, 0xbe, 0xd9, 0x59, 0x4b, 0x92, 0x91, 0x16, 0x34, 0xaf, 0x5f, 0x25, 0xbb, 0x76, 0x2a, 0x12, - 0x51, 0xbe, 0xeb, 0x9e, 0xfb, 0x30, 0x6d, 0xc6, 0x4c, 0x71, 0x23, 0x74, 0xf4, 0xd0, 0x01, 0x44, - 0x9e, 0x39, 0x41, 0x97, 0xe5, 0xe6, 0x42, 0x4a, 0x80, 0xe5, 0x31, 0x78, 0x21, 0x6e, 0xa0, 0x05, - 0xa0, 0xa4, 0xb4, 0x04, 0xb6, 0xbd, 0xfa, 0xa2, 0xc2, 0xdc, 0x0e, 0x25, 0x57, 0xd3, 0x31, 0x6e, - 0xfc, 0xbd, 0x34, 0x3a, 0x12, 0x91, 0x45, 0xf2, 0x4c, 0x1e, 0x24, 0x68, 0x65, 0x5d, 0xc6, 0xac, - 0x7b, 0x2b, 0x16, 0x61, 0x62, 0x66, 0x25, 0xb1, 0xf8, 0xf9, 0xd6, 0xd8, 0x52, 0xb0, 0x18, 0xbb, - 0xd2, 0x3a, 0x31, 0xff, 0xa5, 0xd7, 0x3a, 0x02, 0xff, 0x6d, 0x17, 0x91, 0x68, 0x69, 0x2b, 0x79, - 0x77, 0xb2, 0x81, 0xee, 0xc0, 0xf3, 0x68, 0x67, 0xf2, 0xf8, 0xb3, 0x2f, 0x82, 0x0d, 0x13, 0x25, - 0x26, 0x5c, 0xc4, 0xde, 0x1d, 0xff, 0xc6, 0xe1, 0xbd, 0x3b, 0x49, 0xfe, 0x23, 0x07, 0x77, 0xdf, - 0x7b, 0xaf, 0x20, 0x08, 0x97, 0x19, 0x4f, 0x32, 0x20, 0xfb, 0x77, 0x6d, 0x43, 0x3d, 0x89, 0x93, - 0x7a, 0xf4, 0xf3, 0xc5, 0xc2, 0xa5, 0xff, 0x10, 0xc2, 0x30, 0x87, 0x0f, 0xfc, 0x8c, 0x37, 0x5e, - 0x7e, 0x0e, 0x73, 0x9f, 0x78, 0x86, 0xe6, 0x6a, 0x77, 0xd8, 0x38, 0xb9, 0x62, 0xca, 0xcc, 0x20, - 0x2c, 0x25, 0xe3, 0x5f, 0x31, 0xd1, 0x91, 0xa8, 0x22, 0x3b, 0x9c, 0x36, 0xb6, 0x0e, 0x98, 0x10, - 0xf4, 0xbf, 0xe8, 0xd2, 0xdd, 0x07, 0x66, 0x95, 0xe5, 0x28, 0x2d, 0xb2, 0xc5, 0x8e, 0x1f, 0xb6, - 0xc3, 0xbd, 0x7b, 0x4f, 0x58, 0x35, 0xd4, 0xe0, 0x44, 0xf0, 0x7e, 0x94, 0x55, 0x94, 0xd0, 0x7a, - 0x60, 0x23, 0xa6, 0x3a, 0x6b, 0xb2, 0xa4, 0xd0, 0x7f, 0x90, 0x1f, 0x5e, 0x7f, 0x7b, 0x19, 0xbe, - 0xdb, 0xb0, 0x16, 0x2e, 0xbc, 0x82, 0x77, 0x90, 0xeb, 0x90, 0x11, 0xc0, 0xc8, 0x5f, 0xf5, 0xcf, - 0x95, 0xa8, 0x26, 0x81, 0xfb, 0xb7, 0xfe, 0xef, 0x1f, 0x3a, 0xf3, 0x7b, 0x16, 0x09, 0x2f, 0x6f, - 0xd9, 0xb4, 0x1e, 0x12, 0x09, 0x71, 0xf6, 0x19, 0x70, 0x1b, 0x66, 0x3c, 0xf4, 0x30, 0x22, 0xc2, - 0x23, 0x71, 0xea, 0xc8, 0xcf, 0x42, 0x26, 0x72, 0xfc, 0xd4, 0x99, 0xb8, 0x9f, 0x24, 0xb2, 0x65, - 0xc7, 0x3d, 0x3c, 0xf6, 0x8f, 0x68, 0x6c, 0xfb, 0x6e, 0x33, 0x86, 0xdf, 0x39, 0x1a, 0x31, 0x64, - 0xaf, 0xf2, 0x81, 0x47, 0xe6, 0x90, 0xa1, 0x07, 0x27, 0x3c, 0xfd, 0xf8, 0x1c, 0x58, 0x3a, 0xb8, - 0x22, 0x70, 0xfc, 0x14, 0xda, 0x76, 0x9a, 0x8b, 0x6d, 0xa7, 0x19, 0x8d, 0x0e, 0x2b, 0x6b, 0x2b, - 0x21, 0xb1, 0x1d, 0x1f, 0x7e, 0x06, 0xaa, 0x0a, 0x9e, 0xd6, 0xdc, 0x11, 0x4d, 0x8b, 0x33, 0xdb, - 0x5c, 0xb0, 0x55, 0xd1, 0x68, 0x20, 0x42, 0x6c, 0xfc, 0x76, 0x27, 0xa2, 0xff, 0x88, 0x45, 0xc8, - 0xd1, 0xfd, 0x78, 0x76, 0xd1, 0xdb, 0xe8, 0xde, 0xa3, 0xa7, 0x5c, 0xe5, 0x0d, 0x7d, 0x76, 0x08, - 0x01, 0x8e, 0x90, 0x39, 0xd9, 0xe0, 0xc3, 0xfb, 0x31, 0x6b, 0xde, 0x13, 0x18, 0x34, 0x84, 0xc4, - 0x52, 0x68, 0x37, 0xc2, 0x5c, 0x7f, 0x79, 0xe7, 0x4d, 0x26, 0x1b, 0x71, 0xfc, 0xd4, 0x69, 0xd4, - 0x5b, 0xa9, 0xc8, 0x4a, 0x09, 0x84, 0xed, 0xce, 0x82, 0xd4, 0x8b, 0x98, 0x4c, 0x32, 0xf8, 0x93, - 0xa7, 0x4d, 0x17, 0x37, 0x80, 0xa5, 0x15, 0x55, 0x08, 0xbb, 0x98, 0x8c, 0xf2, 0x7a, 0x0b, 0x38, - 0xd2, 0xb5, 0x28, 0xd9, 0x4d, 0x12, 0x53, 0x0f, 0x8b, 0xbf, 0xb0, 0x71, 0x16, 0x6b, 0x92, 0x1e, - 0x49, 0x23, 0xe9, 0xf3, 0xac, 0xcc, 0x34, 0xd8, 0x68, 0x90, 0x6a, 0x4e, 0x06, 0x2a, 0x2c, 0x48, - 0x24, 0xac, 0x9c, 0x16, 0xeb, 0xe3, 0xbb, 0xb7, 0x20, 0xe2, 0xd4, 0x61, 0xb8, 0x7b, 0x74, 0xc7, - 0xe8, 0x11, 0x81, 0x70, 0x76, 0xb0, 0x47, 0x5c, 0x52, 0x32, 0x86, 0xdf, 0x35, 0x0e, 0xaf, 0x2c, - 0x7a, 0x83, 0x2c, 0xdd, 0xed, 0x05, 0x13, 0xe8, 0xb9, 0xc5, 0x4b, 0xe0, 0xd9, 0xc7, 0xeb, 0x86, - 0x22, 0x5d, 0xbb, 0xf0, 0x0e, 0x21, 0xc0, 0xce, 0xed, 0xdb, 0x10, 0xf5, 0xfb, 0x49, 0xd8, 0x58, - 0x59, 0x93, 0x78, 0x65, 0xbd, 0x98, 0xa7, 0xb9, 0x11, 0xbc, 0x7f, 0x67, 0x31, 0x65, 0x4b, 0xd7, - 0x6e, 0xb8, 0x9c, 0x57, 0x02, 0x4b, 0x42, 0xa6, 0x9f, 0xff, 0x30, 0x44, 0x87, 0x87, 0xa2, 0x9e, - 0xe6, 0x7b, 0x73, 0xb2, 0xce, 0x6b, 0x59, 0x53, 0x81, 0xb1, 0x0f, 0xcd, 0xc5, 0xe0, 0xc0, 0x61, - 0xb8, 0x9c, 0x98, 0x80, 0xcb, 0x49, 0x97, 0x85, 0x40, 0x95, 0xf6, 0xc1, 0x89, 0xb2, 0x09, 0x22, - 0x55, 0x14, 0x17, 0x91, 0xc1, 0xea, 0x04, 0xda, 0xdd, 0x58, 0x93, 0xa5, 0x68, 0x67, 0x61, 0xfa, - 0x84, 0x89, 0x60, 0x45, 0x7e, 0x7b, 0x92, 0xd1, 0xce, 0xc9, 0x48, 0x45, 0x02, 0x69, 0x8f, 0xb8, - 0x39, 0x3b, 0xa1, 0xbb, 0xb3, 0x3d, 0xdc, 0x5c, 0xc8, 0x02, 0xb0, 0x9d, 0x13, 0x0a, 0x0a, 0xf2, - 0x10, 0x38, 0x6a, 0x1c, 0x66, 0x3e, 0x4c, 0x23, 0xa8, 0x15, 0xca, 0x47, 0xda, 0x08, 0x35, 0xf6, - 0xbd, 0x43, 0x4e, 0xc2, 0x96, 0x74, 0x3f, 0x5e, 0x49, 0x5b, 0xc3, 0xfb, 0xe8, 0xb0, 0x33, 0x76, - 0xdc, 0x3d, 0xd7, 0x64, 0xa0, 0xa8, 0xb5, 0x2c, 0x5a, 0xc1, 0x23, 0xa4, 0xf4, 0xd8, 0x49, 0xe4, - 0x16, 0x16, 0x63, 0xef, 0x9e, 0x9d, 0xb0, 0xb6, 0x73, 0xc4, 0xd0, 0x11, 0xbe, 0x18, 0x33, 0x7e, - 0x3c, 0xec, 0x1d, 0xed, 0x71, 0x81, 0xa6, 0x9c, 0x9f, 0x76, 0xec, 0xa4, 0x59, 0x45, 0x7d, 0xc9, - 0x2f, 0x90, 0xcf, 0x58, 0xd7, 0x72, 0x1c, 0x56, 0x57, 0x5b, 0x4d, 0x8b, 0x73, 0x8d, 0xd8, 0x45, - 0x99, 0x93, 0x99, 0x16, 0x1b, 0x5a, 0x94, 0x2d, 0xe9, 0x59, 0x4e, 0xf2, 0xe6, 0x39, 0x39, 0x57, - 0x89, 0x20, 0x36, 0xf0, 0x1b, 0x33, 0x09, 0x56, 0x15, 0xa4, 0xaa, 0x40, 0x46, 0x0a, 0xeb, 0xad, - 0x7b, 0x60, 0xfc, 0x8c, 0x07, 0x11, 0x38, 0x7c, 0xa4, 0x56, 0x49, 0x1d, 0xfb, 0xda, 0x21, 0x04, - 0x98, 0x3a, 0x6d, 0x06, 0x22, 0x49, 0xd3, 0x20, 0xf4, 0xe4, 0x09, 0x41, 0x00, 0x6d, 0x79, 0x16, - 0x36, 0xa9, 0x74, 0x2e, 0xf8, 0x04, 0x32, 0xa3, 0xce, 0xc2, 0xaa, 0xab, 0x17, 0x66, 0x3d, 0xf5, - 0x12, 0xa9, 0x0f, 0x79, 0x22, 0x23, 0xe5, 0x32, 0xa2, 0xce, 0xfd, 0x2e, 0xb4, 0x12, 0xb8, 0x17, - 0x9b, 0x6b, 0x58, 0x05, 0xac, 0xa5, 0xa0, 0x83, 0x7a, 0x75, 0xf7, 0xa7, 0x11, 0x60, 0x2e, 0x6e, - 0xb3, 0x7b, 0xf7, 0xe9, 0x8f, 0x3b, 0xc8, 0xec, 0x92, 0x03, 0x11, 0xce, 0x82, 0xe4, 0x24, 0x39, - 0xbc, 0x24, 0x3f, 0x0b, 0xf6, 0x16, 0x75, 0xb0, 0xe3, 0xc3, 0x18, 0x9f, 0xc6, 0xa8, 0x2c, 0x47, - 0x12, 0x72, 0xcb, 0x48, 0xcf, 0x20, 0x02, 0xd9, 0x8a, 0x11, 0xa9, 0x3d, 0xa2, 0x3a, 0x92, 0x04, - 0x1d, 0x32, 0x05, 0x31, 0x40, 0xa5, 0xb4, 0x2d, 0xfc, 0xe2, 0x93, 0x0f, 0x49, 0x3d, 0xa9, 0x1a, - 0x73, 0x9f, 0x7e, 0x09, 0x3e, 0xde, 0x5e, 0x60, 0xed, 0xa1, 0x6f, 0xbe, 0x5c, 0x83, 0x2b, 0xa9, - 0x97, 0xd0, 0xd3, 0x7f, 0x14, 0x3c, 0x7d, 0xfd, 0x68, 0x0e, 0xcf, 0x40, 0x49, 0x51, 0x11, 0xcc, - 0x69, 0x4e, 0x67, 0xfe, 0x8d, 0xda, 0x26, 0x8b, 0x06, 0xe5, 0xfc, 0x60, 0x42, 0x68, 0x7a, 0x3f, - 0x2f, 0xc8, 0xea, 0x85, 0x44, 0x3d, 0x32, 0xf2, 0xc9, 0x2e, 0x96, 0x17, 0x99, 0xcc, 0x09, 0x7a, - 0xe4, 0x61, 0xd8, 0x92, 0x68, 0xbc, 0xb9, 0xb9, 0x05, 0xad, 0x0f, 0x16, 0x48, 0x4b, 0x8c, 0x47, - 0x2e, 0xed, 0xbe, 0xd8, 0x06, 0x10, 0x13, 0x93, 0x91, 0xcd, 0xd2, 0x27, 0xa5, 0xc5, 0x25, 0x74, - 0x42, 0x56, 0xe1, 0xf6, 0xdb, 0xfd, 0x95, 0xdd, 0x57, 0x47, 0x22, 0x9f, 0xeb, 0xea, 0x30, 0x02, - 0x70, 0x65, 0x8c, 0xb0, 0xa8, 0xf3, 0x91, 0xd8, 0xf2, 0xd5, 0x3a, 0x74, 0x71, 0xb0, 0x15, 0xbb, - 0x90, 0x22, 0x42, 0x76, 0x17, 0xaf, 0x41, 0x70, 0xa6, 0x9e, 0x5b, 0x4d, 0xd2, 0x99, 0xe5, 0x64, - 0x34, 0x46, 0xb6, 0x8a, 0xc3, 0x88, 0x16, 0x38, 0xe7, 0xcc, 0xe4, 0x64, 0x91, 0x4d, 0xb5, 0x4f, - 0xf3, 0x5f, 0x43, 0x04, 0x46, 0x36, 0x1b, 0xa3, 0x49, 0xf9, 0x23, 0x12, 0x36, 0xa4, 0x83, 0x66, - 0x47, 0x82, 0xe5, 0x3c, 0xd2, 0xb8, 0xac, 0x2c, 0xd2, 0xf1, 0xc9, 0xa5, 0x38, 0x1b, 0x92, 0x92, - 0x67, 0xd1, 0x67, 0x3e, 0x65, 0xf3, 0xd4, 0xc4, 0xd4, 0x7b, 0xe6, 0xd9, 0x67, 0x30, 0x63, 0x06, - 0xe9, 0xbd, 0x75, 0xf0, 0xdc, 0x2f, 0xc3, 0xd0, 0x21, 0x53, 0x90, 0x5c, 0x19, 0xf7, 0xbc, 0x00, - 0xd2, 0xd8, 0xf2, 0x5f, 0xbd, 0x81, 0x6c, 0xaa, 0x97, 0x22, 0x34, 0xe4, 0x0c, 0x19, 0xdc, 0x3f, - 0x48, 0xe6, 0xb7, 0x92, 0x61, 0xe1, 0x4a, 0x22, 0xd5, 0x36, 0x76, 0x84, 0xb0, 0x7a, 0xf5, 0x1a, - 0xa1, 0xe9, 0xf4, 0x9c, 0x57, 0xfd, 0x4a, 0xe8, 0x97, 0x3b, 0xbc, 0xa6, 0x40, 0x65, 0x04, 0x70, - 0x02, 0xfa, 0x35, 0x90, 0x1e, 0x52, 0x83, 0x15, 0x59, 0x7c, 0xa3, 0x83, 0x94, 0x9b, 0xbb, 0xbb, - 0xd8, 0x5e, 0x72, 0x8f, 0xaf, 0xa6, 0xd3, 0x76, 0x35, 0xe9, 0x1c, 0xa9, 0x48, 0xdf, 0x88, 0x91, - 0xce, 0x32, 0xb7, 0x6c, 0xab, 0xac, 0x92, 0x76, 0x52, 0x0e, 0x34, 0x2d, 0x99, 0x0a, 0xf9, 0x0c, - 0x46, 0x87, 0x8e, 0x00, 0xae, 0xb0, 0x29, 0x77, 0x22, 0x38, 0x18, 0x61, 0x71, 0x17, 0x50, 0x55, - 0x4f, 0x6a, 0x40, 0x84, 0x14, 0xa2, 0x80, 0x1a, 0xeb, 0x9a, 0xd9, 0x86, 0x15, 0xb8, 0x18, 0xc7, - 0xe4, 0x15, 0x8e, 0x09, 0xa1, 0x38, 0xf2, 0x70, 0x38, 0xcf, 0xf5, 0xcc, 0x6a, 0x8e, 0x0e, 0xff, - 0x1d, 0xb9, 0xa4, 0xd0, 0xc8, 0x06, 0x0f, 0x2d, 0xa8, 0x97, 0xf3, 0x3a, 0x20, 0x0a, 0xa3, 0x44, - 0xd6, 0xb4, 0x1b, 0x72, 0xa2, 0xed, 0xe7, 0x8c, 0xa9, 0x93, 0x31, 0x93, 0x4e, 0xd3, 0x2c, 0x20, - 0xed, 0xe2, 0xe2, 0x62, 0x52, 0x02, 0x74, 0xe8, 0x08, 0x50, 0x90, 0xa6, 0xf7, 0xc2, 0xfa, 0x88, - 0xb5, 0xb5, 0xf5, 0x64, 0x49, 0x99, 0x50, 0xcd, 0xc8, 0xe7, 0x1f, 0x3b, 0x41, 0x07, 0x35, 0xf2, - 0x99, 0x02, 0x9a, 0x37, 0x75, 0x9c, 0x42, 0x04, 0x0a, 0xe5, 0x75, 0x81, 0xf2, 0xd0, 0x4a, 0x40, - 0x73, 0xbe, 0x25, 0x6a, 0xe9, 0xdd, 0x42, 0x50, 0x8c, 0xfd, 0x34, 0xdd, 0xd0, 0xf4, 0xc2, 0xd3, - 0x11, 0x13, 0xc4, 0x52, 0x65, 0x27, 0x90, 0xce, 0x22, 0x96, 0x37, 0x83, 0xbb, 0x29, 0x08, 0xc0, - 0x53, 0x02, 0x9f, 0x0f, 0xd8, 0xa2, 0x9b, 0x50, 0x9a, 0xd0, 0x10, 0xe0, 0x5a, 0x4f, 0x57, 0xb0, - 0xad, 0x8b, 0x33, 0x26, 0x8a, 0x48, 0x44, 0x44, 0xa0, 0x77, 0x6b, 0x95, 0x0a, 0x7f, 0xba, 0x67, - 0x92, 0x50, 0x89, 0xac, 0xa7, 0xc2, 0xb8, 0x87, 0x73, 0x38, 0x8b, 0xf8, 0x5b, 0x10, 0x21, 0xc4, - 0x30, 0x22, 0x7f, 0x58, 0x6c, 0x22, 0x02, 0xfc, 0x53, 0xe0, 0xe5, 0xe5, 0xad, 0x5b, 0x9e, 0x09, - 0x7c, 0x37, 0x09, 0x01, 0xd4, 0xc6, 0xce, 0xea, 0x6a, 0x1b, 0x50, 0x40, 0x9f, 0xc8, 0xa8, 0x22, - 0xc5, 0x6e, 0x81, 0x39, 0x0d, 0x42, 0xb8, 0x83, 0xcb, 0xc8, 0x23, 0xfc, 0x09, 0x0f, 0x8f, 0x14, - 0x4b, 0x9a, 0x52, 0x5c, 0x69, 0xae, 0xe7, 0x45, 0x95, 0x0f, 0x75, 0x15, 0xe5, 0xb5, 0xb4, 0x88, - 0x97, 0x22, 0x3f, 0x3f, 0x0f, 0xb5, 0xb4, 0xeb, 0xf2, 0xed, 0xef, 0x03, 0x57, 0x9a, 0x62, 0xb2, - 0x49, 0x37, 0xf5, 0x6a, 0x61, 0x09, 0x11, 0x88, 0xec, 0xf1, 0x91, 0xd6, 0x8b, 0x8a, 0xb4, 0x3a, - 0x79, 0xd4, 0xdd, 0x0c, 0xee, 0xa6, 0x20, 0x40, 0x2d, 0x69, 0xd0, 0x94, 0x14, 0x17, 0xc3, 0x8c, - 0x0e, 0x4a, 0x3c, 0x5d, 0xd8, 0xd2, 0xfc, 0xad, 0xee, 0xd9, 0x6a, 0x14, 0xf1, 0x3b, 0xd3, 0x80, - 0x9d, 0xe8, 0xf0, 0xe4, 0x11, 0x53, 0x15, 0xcd, 0xfb, 0x0d, 0x34, 0x72, 0x04, 0x7d, 0x34, 0x08, - 0x2d, 0x25, 0x36, 0xb7, 0x05, 0x1d, 0xc6, 0xe6, 0xcc, 0x0e, 0x42, 0xaf, 0xde, 0x9e, 0xe2, 0x8a, - 0x92, 0x17, 0xdc, 0x18, 0x92, 0x4c, 0x3d, 0x75, 0x2e, 0x02, 0x55, 0xbc, 0x00, 0x13, 0xfb, 0x59, - 0x8c, 0x08, 0x75, 0x91, 0x26, 0xfd, 0x7f, 0x53, 0x10, 0x20, 0x90, 0x58, 0xd1, 0x07, 0x8f, 0x9d, - 0xa0, 0xcb, 0x90, 0x22, 0xfa, 0xa4, 0x4a, 0x03, 0x8d, 0x80, 0x0a, 0x42, 0x30, 0xe1, 0x45, 0xee, - 0xf9, 0x02, 0x45, 0x72, 0xdf, 0x57, 0xe3, 0x4b, 0x8c, 0x00, 0x42, 0xa4, 0x9d, 0x1d, 0xed, 0x6c, - 0xcc, 0x79, 0x04, 0xa9, 0x39, 0x98, 0xb6, 0x36, 0x56, 0xa4, 0x4e, 0x5e, 0x8b, 0xe3, 0x27, 0x83, - 0x71, 0xf7, 0xb8, 0x71, 0x74, 0xb1, 0xe2, 0x84, 0xb4, 0xf4, 0x74, 0x84, 0x86, 0x45, 0x90, 0x96, - 0x75, 0x2d, 0x2a, 0x4b, 0xcb, 0x70, 0xfb, 0x9d, 0x81, 0xf0, 0xd4, 0xd8, 0x4a, 0x34, 0x29, 0xf6, - 0x19, 0x44, 0xea, 0x5d, 0x6a, 0xc8, 0x4c, 0xdc, 0x12, 0xb6, 0x78, 0xf9, 0xe5, 0xc6, 0x8d, 0xd8, - 0x4f, 0x26, 0x6c, 0xa9, 0x51, 0xc4, 0x2a, 0xb6, 0x16, 0x97, 0x34, 0xbc, 0xb0, 0x32, 0x0b, 0xe2, - 0xda, 0x1e, 0x88, 0x1b, 0xaa, 0x6e, 0xb2, 0x39, 0x19, 0xd2, 0x30, 0x63, 0x2d, 0x71, 0xe1, 0xd5, - 0x10, 0x88, 0x1e, 0x75, 0xc4, 0xe5, 0xac, 0x25, 0xb6, 0x34, 0xdf, 0xae, 0xd5, 0x13, 0x6b, 0x99, - 0x17, 0x6f, 0x3e, 0x00, 0xfb, 0xf9, 0xfb, 0xe3, 0x89, 0x27, 0xe6, 0x83, 0x4c, 0xc1, 0x89, 0x69, - 0xcb, 0xc4, 0x20, 0x8b, 0xea, 0x6f, 0x1a, 0x02, 0xdc, 0x0c, 0xc8, 0x30, 0x45, 0x1b, 0x68, 0x6b, - 0xd0, 0xe9, 0x4c, 0x89, 0x81, 0x4e, 0x02, 0x98, 0x12, 0xfb, 0x54, 0x77, 0x27, 0x01, 0xfe, 0x9b, - 0x09, 0xc0, 0x8c, 0xb8, 0xff, 0x76, 0x67, 0x92, 0x11, 0xc0, 0xd2, 0x0e, 0xcc, 0x98, 0x63, 0x76, - 0x00, 0x3f, 0xe5, 0x8f, 0x41, 0x1a, 0x43, 0x0c, 0x52, 0x33, 0x15, 0x1f, 0x02, 0xe0, 0xfc, 0xfa, - 0x3f, 0x52, 0xdc, 0x32, 0xa6, 0x28, 0x93, 0xa6, 0x35, 0xc9, 0x39, 0x80, 0x35, 0x3d, 0xe9, 0x43, - 0x3b, 0xe0, 0xef, 0x05, 0xd2, 0x37, 0x72, 0xc0, 0x9f, 0x10, 0x32, 0xd6, 0xf5, 0x24, 0x19, 0x22, - 0x52, 0xb4, 0x04, 0x29, 0x5c, 0x8a, 0xed, 0x26, 0xd9, 0xb6, 0x05, 0x7f, 0x7f, 0x8a, 0x1d, 0x29, - 0xab, 0x19, 0x5b, 0x9c, 0xc9, 0xd2, 0xb7, 0x68, 0x1b, 0x4a, 0xdf, 0x45, 0xd4, 0xe9, 0xa5, 0xfc, - 0x95, 0x12, 0xed, 0x8f, 0x5b, 0xf2, 0x05, 0x79, 0x52, 0x52, 0x92, 0x72, 0x7a, 0x65, 0xd1, 0xbe, - 0x5e, 0xbd, 0x7a, 0x35, 0x09, 0x14, 0x7d, 0x3a, 0x09, 0xfc, 0xd1, 0x34, 0xd9, 0xf1, 0xc9, 0x97, - 0x4c, 0x30, 0x0b, 0x66, 0x99, 0x1c, 0x76, 0xbd, 0x27, 0xf3, 0x78, 0x52, 0x53, 0x53, 0x41, 0xda, - 0x7d, 0xe2, 0x62, 0x85, 0xd3, 0x33, 0x11, 0x49, 0xbd, 0x51, 0x64, 0x65, 0xa2, 0x30, 0x61, 0x0d, - 0x39, 0xb6, 0xfd, 0x9e, 0x90, 0x90, 0x00, 0xd6, 0xcb, 0xe4, 0x3c, 0x6c, 0x61, 0x7f, 0xc8, 0x90, - 0x21, 0xc4, 0x1b, 0xf2, 0x32, 0x94, 0x45, 0x27, 0x9c, 0xdb, 0xcf, 0x79, 0x49, 0x99, 0x8f, 0xc4, - 0x60, 0xaa, 0x44, 0xfb, 0xc9, 0x8a, 0x33, 0xd9, 0x03, 0xeb, 0xa1, 0x93, 0xae, 0x45, 0x1e, 0x3e, - 0x88, 0x35, 0xe7, 0xe6, 0xce, 0x9d, 0xcb, 0x27, 0x9c, 0x46, 0x3f, 0xd9, 0x6c, 0xf4, 0xaa, 0x55, - 0xab, 0x1a, 0xc5, 0x71, 0x7a, 0x52, 0x30, 0x6d, 0x54, 0x2c, 0x01, 0xd9, 0x64, 0x5a, 0x7d, 0x7d, - 0x51, 0xfd, 0x8c, 0xac, 0x89, 0x48, 0xca, 0xac, 0x4d, 0xe6, 0x6d, 0xaa, 0x6d, 0xac, 0x86, 0xac, - 0xef, 0x48, 0x87, 0x5a, 0xd8, 0xda, 0x6e, 0x2a, 0xbd, 0x76, 0x18, 0xe9, 0x77, 0x4b, 0x07, 0x0e, - 0x1c, 0xd0, 0xcf, 0x2e, 0x34, 0x22, 0x89, 0x75, 0x7d, 0xdd, 0x36, 0xb0, 0xed, 0xee, 0xaf, 0xbe, - 0xfa, 0xaa, 0x51, 0x7e, 0x43, 0x01, 0xdc, 0x6b, 0x5b, 0xe4, 0xb4, 0x75, 0xaf, 0xb5, 0x2d, 0xac, - 0x73, 0x66, 0x56, 0xa4, 0x95, 0x81, 0x60, 0x3d, 0x53, 0x6d, 0x55, 0x65, 0x43, 0x85, 0xcb, 0x4a, - 0xb8, 0x9c, 0xaf, 0x39, 0x02, 0xb0, 0xd2, 0x2e, 0x4d, 0x59, 0x4a, 0xf9, 0xd4, 0xcb, 0xc4, 0x17, - 0x4b, 0xe5, 0x72, 0xa9, 0x27, 0x4b, 0xde, 0xde, 0xde, 0x4a, 0x3c, 0x97, 0x27, 0x2b, 0xf6, 0xca, - 0x69, 0xe8, 0xe3, 0xc2, 0x4a, 0x3c, 0xad, 0x17, 0xd2, 0xe9, 0xd3, 0xa7, 0xe5, 0x28, 0xe5, 0xc9, - 0x6a, 0xa9, 0xb2, 0x72, 0x31, 0x97, 0xb1, 0x70, 0xe1, 0x42, 0x25, 0x8e, 0xf5, 0x75, 0x65, 0xf8, - 0xf8, 0xf9, 0xfe, 0xfb, 0xef, 0x2b, 0x71, 0xf2, 0x0b, 0x13, 0x8d, 0xcb, 0x96, 0xd3, 0x8d, 0x1a, - 0x35, 0x4a, 0x8e, 0x6a, 0xf6, 0xd9, 0x62, 0x02, 0x70, 0x2f, 0xd4, 0xee, 0xc1, 0x6c, 0x02, 0x9f, - 0x1d, 0x4d, 0x05, 0x8a, 0x42, 0x30, 0xcd, 0xcb, 0x52, 0x53, 0x3a, 0xe1, 0x4d, 0xb5, 0xa0, 0xa5, - 0x04, 0xe0, 0xaf, 0xbe, 0xc9, 0x40, 0xf1, 0x33, 0x25, 0x25, 0xa5, 0x51, 0x71, 0xc5, 0xc5, 0xc5, - 0x3a, 0x69, 0xf4, 0x09, 0x30, 0x6e, 0xdc, 0x38, 0x9d, 0x78, 0xed, 0xf2, 0x0c, 0xbd, 0xcb, 0x96, - 0xe9, 0x49, 0xa8, 0x4c, 0xe2, 0x51, 0x21, 0xa7, 0xfb, 0xcb, 0x5f, 0xfe, 0xd2, 0xa8, 0x7e, 0x39, - 0x40, 0x7f, 0x36, 0x60, 0x5d, 0xe2, 0xeb, 0xb9, 0x16, 0xef, 0x82, 0x78, 0xa7, 0x41, 0x05, 0x92, - 0xd9, 0x4d, 0x77, 0x6a, 0x0b, 0xc0, 0x9f, 0x47, 0xdf, 0xb6, 0x6d, 0x1b, 0x5d, 0x68, 0xdf, 0x2e, - 0x16, 0x41, 0xde, 0xd1, 0xf0, 0x9c, 0xc8, 0x26, 0x1a, 0xda, 0xd3, 0xe9, 0xcf, 0xcb, 0x11, 0x11, - 0x11, 0x8d, 0x8a, 0xe7, 0x76, 0x35, 0xe7, 0xe8, 0x03, 0x78, 0x4a, 0x34, 0xaf, 0x4f, 0xbc, 0xa6, - 0x11, 0x62, 0x9a, 0xfd, 0xc9, 0x7a, 0xfb, 0xfc, 0x79, 0xee, 0x11, 0x23, 0x46, 0x28, 0xf9, 0xe9, - 0x5b, 0x0b, 0x42, 0x28, 0x4c, 0x09, 0xd0, 0x7a, 0xd1, 0x36, 0x2f, 0xc1, 0x97, 0xfe, 0xcc, 0x73, - 0xba, 0xae, 0xbb, 0x1e, 0x85, 0xf4, 0xe3, 0xb3, 0xb2, 0xb2, 0x74, 0x7a, 0x04, 0x55, 0x20, 0x3e, - 0x4e, 0xcc, 0x73, 0xac, 0x21, 0xc7, 0xa3, 0x62, 0xd6, 0xac, 0x59, 0xe2, 0x93, 0x84, 0xb4, 0x78, - 0x4b, 0xfc, 0xe3, 0xb9, 0x92, 0xf3, 0xf2, 0x8f, 0xe7, 0x56, 0x39, 0x9c, 0x08, 0x2a, 0xcc, 0x4e, - 0x68, 0x97, 0xa5, 0x3f, 0x05, 0xf0, 0x34, 0xf4, 0xdc, 0x73, 0xcf, 0x49, 0x2f, 0xbe, 0xf8, 0xa2, - 0xe4, 0xe9, 0xe9, 0xa9, 0x94, 0x23, 0x97, 0x47, 0x8b, 0xaa, 0xb4, 0x75, 0xeb, 0x56, 0xed, 0x22, - 0xa4, 0xa7, 0x9f, 0x7e, 0x5a, 0x27, 0x1d, 0x7f, 0xcb, 0x98, 0xdb, 0xc4, 0x1f, 0x99, 0x60, 0xab, - 0x12, 0xac, 0xae, 0x2f, 0xe7, 0xe7, 0x27, 0xa7, 0x97, 0x1d, 0x2d, 0xb4, 0xe2, 0x5b, 0x0e, 0xda, - 0xf1, 0xbc, 0x06, 0xb2, 0xf5, 0x88, 0x37, 0xdf, 0x7c, 0x53, 0xe2, 0xe9, 0x46, 0x3b, 0x8e, 0xcb, - 0xbe, 0x9e, 0xa6, 0xbd, 0x5c, 0x76, 0x8b, 0xa7, 0x20, 0x39, 0x03, 0x3f, 0x13, 0x13, 0x13, 0x25, - 0x32, 0x1e, 0x25, 0x2a, 0x65, 0x64, 0x34, 0x87, 0x7c, 0x4e, 0x4f, 0xbb, 0x0e, 0xf1, 0xe1, 0x09, - 0xda, 0xf1, 0xe8, 0x34, 0x54, 0xbb, 0xd1, 0xf2, 0x3b, 0x8d, 0x24, 0xf1, 0xb1, 0x49, 0xce, 0xa7, - 0xed, 0xe8, 0x43, 0x77, 0xd2, 0xb2, 0x65, 0xcb, 0x74, 0xe6, 0x69, 0xce, 0xc3, 0x84, 0x3b, 0x7a, - 0xf4, 0xa8, 0x98, 0x97, 0xe5, 0x39, 0x98, 0xbf, 0xe6, 0xb1, 0x7a, 0xf5, 0x6a, 0xed, 0xec, 0xca, - 0xfb, 0xae, 0x5d, 0xbb, 0x0c, 0x2e, 0xc6, 0x6c, 0x47, 0xe4, 0xd5, 0x57, 0x5f, 0x95, 0x64, 0x63, - 0x11, 0x4a, 0x26, 0xcd, 0x0b, 0x77, 0x24, 0x26, 0x18, 0xcd, 0x02, 0x8d, 0xe0, 0xe0, 0xf5, 0xe3, - 0xf9, 0xe7, 0x9f, 0x97, 0xe4, 0x0f, 0x7a, 0xe8, 0xe7, 0x35, 0xe4, 0x6f, 0xd1, 0x36, 0x94, 0x00, - 0xed, 0x74, 0x37, 0x08, 0x03, 0x2d, 0x5e, 0x03, 0x6e, 0x50, 0xfd, 0xff, 0xf5, 0xc5, 0x76, 0x12, - 0xc0, 0xc4, 0x5d, 0xa0, 0x93, 0x00, 0x9d, 0x04, 0x30, 0x31, 0x06, 0x4c, 0x5c, 0x7d, 0xe7, 0x08, - 0xe8, 0x24, 0x80, 0x89, 0x31, 0x60, 0xe2, 0xea, 0x3b, 0x47, 0x40, 0x27, 0x01, 0x4c, 0x8c, 0x01, - 0x13, 0x57, 0xff, 0xff, 0x2d, 0xb1, 0x75, 0xfd, 0xe9, 0xfe, 0xa1, 0x6c, 0x00, 0x00, 0x00, 0x00, - 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXXMLIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x30, 0x3a, 0x30, 0x32, 0x3a, 0x30, 0x39, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x9d, - 0x3c, 0x78, 0xe3, 0x00, 0x00, 0x05, 0x7c, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x58, 0x59, - 0x4c, 0x1b, 0x57, 0x14, 0xc5, 0x0b, 0xbb, 0xc1, 0x26, 0xa2, 0x31, 0x56, 0x58, 0x4c, 0xb1, 0x1b, - 0x37, 0x15, 0x8e, 0x42, 0x05, 0x94, 0x25, 0x88, 0x25, 0x6c, 0x05, 0x52, 0x14, 0x0a, 0xfd, 0xa8, - 0x08, 0x1f, 0x91, 0xe0, 0x83, 0x02, 0xa2, 0x2a, 0x6a, 0xfb, 0xd3, 0x82, 0x00, 0x15, 0x3e, 0x8a, - 0x8a, 0x10, 0x42, 0x42, 0x4a, 0xbf, 0x10, 0x12, 0x84, 0x06, 0xd5, 0x12, 0x15, 0x5b, 0x49, 0x0a, - 0x51, 0x31, 0x34, 0xdd, 0x00, 0xa5, 0xb5, 0x4d, 0x42, 0x83, 0xa1, 0x24, 0x0a, 0xc4, 0x94, 0x60, - 0x03, 0xb6, 0xb1, 0x7b, 0x9d, 0x57, 0xdc, 0x67, 0x9b, 0x24, 0xe3, 0x19, 0x3b, 0x08, 0x69, 0x46, - 0x23, 0xfb, 0xbe, 0xf3, 0xee, 0xbd, 0xef, 0xdc, 0x7b, 0xdf, 0x32, 0x33, 0x0c, 0xb3, 0xd9, 0xec, - 0x71, 0x9c, 0x2f, 0xe6, 0x71, 0x26, 0x6f, 0xe1, 0x4e, 0x07, 0x70, 0xd4, 0x15, 0xa4, 0x2b, 0x40, - 0x57, 0x80, 0x62, 0x06, 0xe8, 0x29, 0x44, 0x31, 0x81, 0x94, 0xcd, 0xe9, 0x0a, 0x50, 0x4e, 0x21, - 0x45, 0x07, 0x74, 0x05, 0x28, 0x26, 0x90, 0xb2, 0x39, 0x5d, 0x81, 0xc3, 0x52, 0xa8, 0xff, 0x67, - 0xdb, 0x11, 0x36, 0xea, 0x76, 0x3d, 0x4c, 0xae, 0x7f, 0xf2, 0x75, 0x71, 0x05, 0x36, 0x15, 0xcb, - 0xb7, 0x9b, 0xbe, 0x1e, 0x2e, 0xfe, 0xd4, 0x31, 0x80, 0xf5, 0xdf, 0x94, 0xdf, 0x15, 0x7d, 0xac, - 0xec, 0x19, 0x36, 0x3c, 0xd1, 0x39, 0xf6, 0x92, 0x46, 0xd8, 0xa4, 0x2d, 0x6d, 0x0c, 0x4d, 0xe6, - 0xd5, 0x1f, 0x7e, 0x51, 0xf5, 0x8d, 0xad, 0xff, 0xae, 0x02, 0x9c, 0xe5, 0xed, 0x69, 0xd3, 0x7b, - 0xd0, 0xd0, 0x3d, 0xd8, 0x98, 0xeb, 0xbc, 0x76, 0xe7, 0xaa, 0x2c, 0x3c, 0x37, 0x41, 0x5c, 0x72, - 0x21, 0x40, 0x28, 0x38, 0xe8, 0x21, 0xff, 0x4f, 0x35, 0x00, 0xc3, 0x96, 0x76, 0x49, 0x36, 0xb5, - 0xf8, 0xcd, 0x04, 0x90, 0x23, 0xc8, 0xc2, 0xb8, 0xbb, 0x77, 0x6f, 0xf0, 0x26, 0xdc, 0xfc, 0xb8, - 0x33, 0xa2, 0x92, 0x4c, 0x41, 0x92, 0x94, 0xa0, 0xe1, 0xa1, 0x6a, 0xe4, 0x03, 0xd8, 0x5a, 0xfa, - 0x7b, 0xb1, 0x7f, 0x7c, 0x79, 0x58, 0x0e, 0x84, 0x70, 0xd7, 0xbe, 0xc1, 0x3c, 0x61, 0x7e, 0x32, - 0x8e, 0x20, 0x99, 0x2b, 0x0a, 0x8b, 0xc8, 0x49, 0x58, 0xb9, 0xf9, 0xf3, 0xfe, 0xae, 0x1e, 0x21, - 0x0f, 0x67, 0xef, 0xc0, 0xcd, 0x09, 0xe3, 0x8b, 0xde, 0x4d, 0x07, 0x13, 0xb6, 0x9f, 0x8f, 0xa3, - 0xd5, 0x0b, 0x11, 0x86, 0xd3, 0xaf, 0x94, 0x66, 0xf3, 0xda, 0x8f, 0xf3, 0x8b, 0xfd, 0x63, 0x30, - 0x36, 0xee, 0x9d, 0xc9, 0x66, 0x0b, 0x92, 0xa5, 0xc2, 0xfc, 0xf3, 0x82, 0x84, 0x68, 0x0f, 0x26, - 0x03, 0xef, 0xc2, 0x65, 0xc3, 0xf6, 0x8e, 0x7a, 0x54, 0x0e, 0x45, 0xd3, 0x28, 0xee, 0xe3, 0xb8, - 0xa7, 0xbf, 0xaf, 0x30, 0x2f, 0x49, 0x54, 0x9c, 0xe1, 0x1f, 0x7a, 0x12, 0xc7, 0x5f, 0x28, 0x3b, - 0x1d, 0xc0, 0xad, 0x0f, 0xbf, 0x7a, 0x30, 0x3d, 0x8f, 0xfb, 0xe5, 0x46, 0x85, 0x42, 0xfe, 0x20, - 0xbb, 0x5e, 0x3c, 0x0e, 0x8e, 0x3f, 0x5f, 0xde, 0x54, 0x2e, 0x43, 0x18, 0x10, 0x8c, 0x1e, 0x5b, - 0xd3, 0x0c, 0x06, 0xe3, 0xcd, 0x4f, 0xca, 0x84, 0x17, 0xcf, 0x3f, 0xdf, 0x16, 0xef, 0x75, 0x7a, - 0x0a, 0xe9, 0x37, 0xff, 0xdf, 0x22, 0x4f, 0xa5, 0xc6, 0x48, 0x2e, 0xe7, 0x05, 0xbd, 0x2e, 0xc4, - 0x3d, 0x12, 0x94, 0x79, 0xaf, 0x85, 0x9f, 0xfb, 0xe8, 0xfd, 0xb3, 0x55, 0x25, 0x30, 0xa9, 0xfe, - 0xb8, 0x2a, 0x7b, 0xa2, 0x7e, 0x08, 0x86, 0x30, 0x1d, 0x76, 0x35, 0x5b, 0x04, 0x3d, 0x20, 0x35, - 0xa7, 0x03, 0xc0, 0xbd, 0xaf, 0xdd, 0x9a, 0x63, 0x30, 0x98, 0x91, 0x85, 0x29, 0xfc, 0xb8, 0x37, - 0x70, 0x9c, 0xa0, 0x6c, 0xda, 0x33, 0xa8, 0xbf, 0xff, 0x69, 0x49, 0x36, 0x89, 0xd8, 0x13, 0xb4, - 0xb2, 0x53, 0x73, 0x3a, 0x80, 0xc8, 0x77, 0x52, 0x20, 0x49, 0x68, 0xcf, 0x31, 0x19, 0x8d, 0x2b, - 0x37, 0x6e, 0xc3, 0xed, 0x2f, 0x08, 0x06, 0x1c, 0x26, 0xb1, 0x4f, 0x30, 0xcf, 0x6e, 0x80, 0x43, - 0x9b, 0x68, 0xfe, 0x2c, 0x8f, 0xc8, 0x0d, 0xdb, 0x36, 0x67, 0xc2, 0x2b, 0xe7, 0x4e, 0x3b, 0x9b, - 0x0b, 0xa7, 0xd7, 0x80, 0x85, 0x90, 0xed, 0xae, 0x6f, 0xa5, 0xc8, 0x64, 0xb3, 0x04, 0x89, 0x52, - 0x88, 0x24, 0xe4, 0xad, 0xc3, 0xd7, 0x31, 0x1c, 0xc6, 0xea, 0xd1, 0x99, 0x7b, 0xdf, 0x4e, 0x6a, - 0xfe, 0xfc, 0xcb, 0x6a, 0x05, 0x02, 0xd3, 0x93, 0x1d, 0x9e, 0x15, 0x2f, 0x2a, 0xb9, 0x00, 0xf3, - 0x0a, 0xc7, 0x89, 0xc8, 0xa4, 0x02, 0x38, 0x70, 0xbc, 0xa9, 0xb8, 0xaf, 0xea, 0x1b, 0x57, 0x8f, - 0xcf, 0x9a, 0x0c, 0xc6, 0x03, 0xcc, 0xf2, 0xcf, 0x09, 0x3d, 0x99, 0x73, 0xed, 0x0b, 0x1c, 0x01, - 0xf9, 0xf1, 0xc2, 0xdd, 0xc9, 0xaa, 0x2f, 0xed, 0xf6, 0x5c, 0x9f, 0x13, 0xdc, 0xa8, 0x4b, 0xa9, - 0xaf, 0x5e, 0x4a, 0xf5, 0x0e, 0x0a, 0xb4, 0xd3, 0x27, 0xd8, 0x74, 0x7a, 0x0a, 0xe1, 0x7e, 0x79, - 0xa7, 0x23, 0x62, 0x3f, 0xbb, 0x22, 0xfd, 0xa0, 0xf8, 0x2e, 0x1c, 0x4c, 0xd7, 0x6f, 0xec, 0x3e, - 0xfe, 0x6f, 0xfd, 0xed, 0x3c, 0xd2, 0xe0, 0x6a, 0x48, 0xd6, 0x6f, 0x69, 0x71, 0xf6, 0x41, 0x92, - 0x08, 0x71, 0x49, 0x66, 0x58, 0x66, 0x1c, 0x83, 0xcd, 0x72, 0x54, 0x26, 0x8e, 0x50, 0x0a, 0x00, - 0x0d, 0xe3, 0x7d, 0x22, 0xf0, 0xcc, 0x95, 0x8b, 0x92, 0xcb, 0x6f, 0xab, 0xc7, 0x66, 0xe1, 0x68, - 0xb3, 0xdb, 0xe0, 0xed, 0xa8, 0x30, 0x58, 0xcc, 0x53, 0x29, 0x31, 0xa2, 0xf7, 0x2e, 0x04, 0x9f, - 0x15, 0xdb, 0x75, 0x91, 0x6c, 0xc2, 0xce, 0xe5, 0xda, 0xeb, 0xd1, 0xaf, 0x8a, 0x99, 0xcf, 0xbb, - 0x1d, 0x7d, 0x02, 0x3e, 0xd7, 0xd1, 0xaf, 0x5d, 0x5b, 0x77, 0xec, 0xa2, 0x82, 0x50, 0x5a, 0x03, - 0x24, 0x73, 0xe6, 0x52, 0x33, 0x17, 0x3f, 0x4e, 0xbb, 0x94, 0x1b, 0x21, 0x67, 0x74, 0x00, 0x84, - 0xd2, 0xe4, 0x46, 0x25, 0xba, 0x02, 0x6e, 0x4c, 0x2e, 0x21, 0xd7, 0x74, 0x05, 0x08, 0xa5, 0xc9, - 0x8d, 0x4a, 0xc7, 0xbe, 0x02, 0x2e, 0x78, 0x94, 0x20, 0x9d, 0xde, 0xfd, 0xfd, 0x7d, 0x38, 0x83, - 0xc1, 0x9c, 0xcd, 0x26, 0x4f, 0xe3, 0xc8, 0x2a, 0x50, 0x5d, 0x5d, 0xed, 0xe5, 0xe5, 0xe5, 0xf9, - 0xf4, 0x6a, 0x6f, 0x6f, 0x27, 0x9d, 0x85, 0x23, 0x0b, 0x20, 0x32, 0x32, 0x32, 0x2a, 0x2a, 0xca, - 0xd7, 0xd7, 0x17, 0xa8, 0x6b, 0xb5, 0xda, 0xe3, 0x17, 0x40, 0x6d, 0x6d, 0xad, 0x52, 0xa9, 0xcc, - 0xc8, 0xc8, 0x20, 0x4d, 0x1d, 0x19, 0x92, 0xa9, 0xc0, 0xf4, 0xf4, 0x74, 0x7a, 0x7a, 0x7a, 0x7c, - 0x7c, 0x7c, 0x72, 0x72, 0xf2, 0xd4, 0xd4, 0xd4, 0xc8, 0xc8, 0x48, 0x62, 0x62, 0x22, 0x34, 0x8b, - 0x8a, 0x8a, 0x76, 0x76, 0x76, 0x64, 0x32, 0x59, 0x52, 0x52, 0x52, 0x5a, 0x5a, 0x5a, 0x67, 0x67, - 0x27, 0x9f, 0xcf, 0x17, 0x8b, 0xc5, 0xbd, 0xbd, 0xbd, 0x31, 0x31, 0x31, 0x21, 0x21, 0x21, 0xf5, - 0xf5, 0xf5, 0x7b, 0x7b, 0x36, 0x1f, 0x91, 0x28, 0xb2, 0xb7, 0x98, 0x93, 0x78, 0x94, 0x6d, 0x69, - 0x69, 0xb1, 0x0e, 0xdc, 0xd4, 0xd4, 0x54, 0x57, 0x57, 0x67, 0x6d, 0xaa, 0x54, 0xaa, 0xaa, 0xaa, - 0x2a, 0x6b, 0xd3, 0x51, 0x80, 0x60, 0xf0, 0x11, 0xf3, 0xf3, 0xf3, 0x41, 0xa7, 0xb9, 0xb9, 0x19, - 0x07, 0x9d, 0x92, 0xc9, 0x54, 0xa0, 0xa6, 0xa6, 0x66, 0x70, 0x70, 0x90, 0xc7, 0xb3, 0xbc, 0xbf, - 0x4b, 0xa5, 0x52, 0x89, 0x44, 0x02, 0x42, 0x6e, 0x6e, 0xee, 0xcc, 0xcc, 0x8c, 0x48, 0x24, 0x6a, - 0x6c, 0x6c, 0x84, 0x6a, 0x00, 0x52, 0x5a, 0x5a, 0x3a, 0x3e, 0x3e, 0x0e, 0x02, 0x5c, 0x43, 0x43, - 0x43, 0xe5, 0xe5, 0xe5, 0x20, 0xcc, 0xcf, 0xdb, 0x7c, 0x53, 0x7a, 0xda, 0x49, 0xe9, 0x87, 0xcc, - 0xfe, 0xe5, 0xe3, 0xe3, 0x53, 0x58, 0x58, 0xc8, 0xe5, 0x72, 0xb3, 0xb3, 0xb3, 0xcb, 0xca, 0xca, - 0x74, 0x3a, 0x5d, 0x74, 0x74, 0x74, 0x5f, 0x5f, 0x5f, 0x40, 0x40, 0x00, 0x70, 0x01, 0x1c, 0x66, - 0x0b, 0x08, 0x79, 0x79, 0x79, 0xb1, 0xb1, 0xb1, 0x20, 0xc0, 0x4e, 0x93, 0x95, 0x95, 0xb5, 0xb2, - 0xb2, 0x02, 0xb2, 0x46, 0x73, 0xc8, 0xdb, 0x26, 0xe0, 0xa4, 0x2f, 0x32, 0x15, 0x40, 0x83, 0xc1, - 0x2c, 0x6f, 0x68, 0x68, 0x00, 0x42, 0x30, 0xad, 0x3b, 0x3a, 0x3a, 0x10, 0x7b, 0x9c, 0x87, 0x9f, - 0x9f, 0x1f, 0x7c, 0x69, 0x03, 0x04, 0x02, 0x80, 0x9d, 0x1e, 0xc9, 0x26, 0x93, 0x09, 0xd7, 0xa1, - 0x2e, 0x93, 0x0f, 0x00, 0x32, 0xda, 0xd5, 0xd5, 0x05, 0xd5, 0x00, 0x12, 0x15, 0x15, 0x15, 0x1b, - 0x1b, 0x44, 0xbf, 0x4e, 0x53, 0x27, 0x8d, 0x7b, 0x20, 0x19, 0x00, 0xd0, 0xcd, 0xc9, 0xc9, 0x59, - 0x5d, 0x5d, 0x1d, 0x18, 0x18, 0xa8, 0xac, 0xac, 0x54, 0x28, 0x14, 0x05, 0x05, 0x05, 0xd6, 0xed, - 0x1c, 0x56, 0x21, 0x8c, 0x81, 0x7e, 0xf1, 0xc1, 0x70, 0x19, 0x4a, 0x61, 0x34, 0x1a, 0x91, 0x0e, - 0x2e, 0xe3, 0x3a, 0x84, 0x64, 0xa7, 0x96, 0x3c, 0x52, 0x86, 0xa5, 0x89, 0x12, 0x0f, 0xc7, 0x90, - 0x5c, 0x2e, 0x6f, 0x6d, 0x6d, 0x45, 0x23, 0x41, 0x73, 0x62, 0x62, 0xa2, 0xad, 0xad, 0x0d, 0xcd, - 0x96, 0xc0, 0xc0, 0xc0, 0x85, 0x85, 0x05, 0xd4, 0x05, 0x4b, 0xbc, 0xbb, 0xbb, 0x1b, 0x64, 0x16, - 0x8b, 0xd5, 0xd3, 0xd3, 0x03, 0x26, 0x8e, 0x8f, 0x0f, 0x1c, 0x0e, 0x67, 0x74, 0x74, 0xd4, 0x59, - 0x3e, 0x64, 0x2a, 0x00, 0xfc, 0xe0, 0x29, 0x00, 0xd8, 0x80, 0x00, 0x59, 0xd4, 0xeb, 0xf5, 0x88, - 0xb1, 0x15, 0x64, 0x32, 0x2d, 0x6e, 0x81, 0x22, 0x5c, 0xe8, 0xac, 0x05, 0x04, 0x2d, 0x12, 0x08, - 0x00, 0x28, 0x82, 0x3e, 0x32, 0x41, 0xe1, 0xa1, 0x5f, 0x47, 0x04, 0xef, 0x7d, 0x96, 0x4c, 0x7f, - 0x95, 0x78, 0x56, 0x66, 0x5e, 0x16, 0x4e, 0x66, 0x0a, 0xbd, 0x2c, 0x6e, 0x84, 0xc6, 0xa1, 0x03, - 0x20, 0x94, 0x26, 0x37, 0x2a, 0xd1, 0x15, 0x70, 0x63, 0x72, 0x09, 0xb9, 0xa6, 0x2b, 0x40, 0x28, - 0x4d, 0x6e, 0x54, 0xa2, 0x2b, 0xe0, 0xc6, 0xe4, 0x12, 0x72, 0x4d, 0x57, 0x80, 0x50, 0x9a, 0xdc, - 0xa8, 0xf4, 0x2f, 0x8a, 0xf9, 0x6c, 0x7c, 0x9d, 0x47, 0x95, 0x15, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXXMLIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0e, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x1d, 0x69, 0x74, 0x54, 0xd5, 0xf9, 0x9b, 0xcc, 0x64, 0x9f, 0xec, 0x54, 0x16, 0x13, 0xb6, 0x20, - 0x02, 0x0a, 0x28, 0x2a, 0x04, 0xb1, 0x2d, 0x50, 0x6c, 0x2d, 0x16, 0xb4, 0x28, 0x76, 0x53, 0xaa, - 0xb5, 0x96, 0x9e, 0x23, 0x15, 0x0a, 0x47, 0xa4, 0x2d, 0x82, 0x4b, 0xed, 0xb1, 0xd5, 0x42, 0x6b, - 0x51, 0xb1, 0x0b, 0xf0, 0xc3, 0x96, 0xd3, 0x5a, 0x2c, 0x16, 0x5a, 0x6c, 0xd5, 0x42, 0x85, 0xb0, - 0x06, 0x01, 0x29, 0x90, 0xb0, 0x19, 0x16, 0xc3, 0x96, 0xc9, 0x64, 0x9b, 0x2c, 0x93, 0x99, 0x79, - 0xfd, 0xbe, 0x1b, 0xef, 0xcd, 0xbc, 0x37, 0xf3, 0xde, 0xcc, 0x7b, 0x33, 0xef, 0x91, 0xe0, 0x7b, - 0xe7, 0x24, 0xef, 0xdb, 0xee, 0x77, 0xbf, 0xe5, 0x2e, 0x6f, 0xb9, 0xef, 0x8e, 0x43, 0xc2, 0x03, - 0x74, 0x1c, 0x29, 0x3a, 0x64, 0x99, 0x68, 0xe2, 0x05, 0x6a, 0xb7, 0x8d, 0x65, 0x9a, 0xa4, 0xa0, - 0x8f, 0x9d, 0x39, 0x2e, 0x2c, 0x21, 0x1f, 0xf8, 0x71, 0x69, 0xeb, 0x2d, 0x1c, 0x94, 0xd4, 0x60, - 0x07, 0x49, 0x88, 0xd2, 0x08, 0x84, 0xda, 0x6a, 0x20, 0x25, 0xa3, 0x5f, 0x38, 0x49, 0x06, 0x47, - 0x14, 0x90, 0x71, 0xa3, 0x20, 0x89, 0x3b, 0xad, 0x54, 0xea, 0x70, 0x38, 0x64, 0xa4, 0x88, 0x1a, - 0xb8, 0x00, 0x3f, 0xcb, 0xa4, 0x11, 0x31, 0xdf, 0x07, 0xf3, 0x6b, 0x88, 0x70, 0x5a, 0xe9, 0xa4, - 0x12, 0x97, 0x15, 0x08, 0xfa, 0x8e, 0x81, 0x14, 0x68, 0x60, 0x32, 0xde, 0x8a, 0xaf, 0x82, 0x67, - 0xfb, 0x6d, 0x4a, 0x79, 0x00, 0xde, 0x78, 0x3c, 0x3b, 0x26, 0x71, 0x50, 0x76, 0x6e, 0xad, 0xf9, - 0xb3, 0x0c, 0x17, 0x05, 0xc2, 0xa9, 0xbc, 0xe1, 0x79, 0x76, 0x7d, 0x39, 0x9c, 0xcc, 0xe0, 0xee, - 0x1e, 0x25, 0x1e, 0x92, 0x8a, 0x8a, 0x0a, 0x18, 0x36, 0x6c, 0x18, 0x47, 0x65, 0x67, 0xf3, 0x7d, - 0xd0, 0x5d, 0x83, 0xcc, 0xbe, 0x38, 0x10, 0x59, 0xcb, 0x88, 0x43, 0x5e, 0xb7, 0x88, 0xa1, 0x0a, - 0x22, 0x86, 0x36, 0xad, 0x6a, 0x23, 0x9a, 0xd6, 0x27, 0x04, 0x6a, 0x7d, 0xde, 0x0f, 0xbe, 0x11, - 0xc1, 0xe6, 0xad, 0x32, 0x9c, 0x41, 0x34, 0xdf, 0x47, 0xbf, 0x0e, 0x27, 0x09, 0x38, 0x6a, 0xd3, - 0xe6, 0x5c, 0x2a, 0xe8, 0xd9, 0xf9, 0x45, 0x8e, 0xca, 0xc6, 0x5a, 0x4e, 0x24, 0x99, 0xc6, 0x23, - 0x8b, 0x38, 0x1a, 0x71, 0xd6, 0xac, 0x20, 0x5c, 0xba, 0xae, 0xe2, 0x5e, 0x29, 0xd4, 0xe1, 0x0d, - 0x27, 0xc5, 0x05, 0x77, 0xef, 0x56, 0x54, 0x5d, 0x5d, 0x0d, 0x9b, 0x37, 0x6f, 0xd6, 0x4a, 0x71, - 0xd7, 0x78, 0x14, 0xcd, 0x5f, 0x2c, 0xc9, 0xc8, 0xd7, 0x5f, 0x7f, 0xbd, 0xf4, 0xec, 0xb3, 0xcf, - 0x4a, 0x03, 0x07, 0x0e, 0xa4, 0x69, 0x8d, 0xfd, 0x71, 0x79, 0x2e, 0xc3, 0x71, 0xe5, 0x59, 0x33, - 0x07, 0x54, 0x78, 0xf7, 0xee, 0xdd, 0x42, 0x29, 0x57, 0x7e, 0xed, 0xb5, 0xd7, 0x4a, 0x4f, 0x3d, - 0xf5, 0x94, 0x8c, 0xae, 0x54, 0xcc, 0xf1, 0xee, 0x9d, 0x03, 0xf4, 0x28, 0xe6, 0xd1, 0xf3, 0x3d, - 0x30, 0x34, 0x16, 0xc5, 0x8c, 0x4b, 0x98, 0xc0, 0xa7, 0xb0, 0x82, 0x40, 0xd3, 0x41, 0x68, 0x3e, - 0xba, 0x24, 0x2c, 0x08, 0x31, 0x40, 0xde, 0x21, 0xa2, 0x9d, 0x69, 0xa4, 0xc4, 0xb1, 0x5f, 0xc6, - 0x22, 0x1a, 0x3b, 0x42, 0xed, 0x6c, 0x74, 0xf5, 0x7b, 0x77, 0xca, 0xf8, 0x4a, 0x24, 0x6a, 0x4f, - 0x6e, 0xfd, 0xf8, 0x4f, 0x51, 0x87, 0x66, 0x2a, 0x5c, 0xbb, 0xad, 0x4c, 0xa6, 0xa3, 0xe1, 0xe0, - 0xa3, 0xaa, 0xb2, 0x24, 0x18, 0xb5, 0x02, 0xb2, 0xd2, 0x57, 0xfd, 0xb2, 0x4c, 0x11, 0x21, 0xc2, - 0x7a, 0x05, 0x87, 0x79, 0x5a, 0x3e, 0x5e, 0x41, 0xed, 0x44, 0xa3, 0x56, 0x40, 0xac, 0xe6, 0x13, - 0x2f, 0x46, 0x28, 0x54, 0x56, 0x50, 0x57, 0x71, 0x4f, 0x84, 0x8c, 0xb2, 0x16, 0xd5, 0x0a, 0xb8, - 0x60, 0x6d, 0xf9, 0xad, 0x0c, 0xac, 0x8d, 0x62, 0x61, 0x47, 0xd3, 0x61, 0x2e, 0xa6, 0x7a, 0x8e, - 0xd9, 0x0f, 0x8a, 0x6e, 0x2d, 0x67, 0xcd, 0x44, 0x0a, 0x05, 0x22, 0x9a, 0x8b, 0xcb, 0x3d, 0x3c, - 0x82, 0xa6, 0x24, 0xd8, 0x63, 0x91, 0x32, 0x22, 0x11, 0x78, 0xcc, 0x1c, 0x44, 0x94, 0x08, 0x23, - 0xc4, 0x9c, 0x8f, 0x51, 0x36, 0xa1, 0x0a, 0x36, 0x6e, 0xdc, 0x18, 0x56, 0x5d, 0x74, 0x50, 0xb5, - 0x82, 0x79, 0xf3, 0xe6, 0x41, 0x6e, 0x6e, 0x2e, 0xd0, 0x3d, 0xde, 0xd9, 0xb3, 0x67, 0xd9, 0x79, - 0xcc, 0x98, 0x31, 0x40, 0x74, 0x97, 0xcb, 0x15, 0x5d, 0x5b, 0x34, 0xaa, 0x6a, 0x03, 0x46, 0x86, - 0xdb, 0xed, 0x96, 0xe6, 0xce, 0x9d, 0xcb, 0x44, 0xb0, 0xac, 0xf4, 0xc6, 0x1b, 0x6f, 0x08, 0x98, - 0x80, 0xf9, 0xf3, 0xe7, 0x33, 0x5c, 0xeb, 0x9f, 0x6a, 0x47, 0x23, 0x85, 0xfc, 0x8f, 0xae, 0x22, - 0x78, 0x05, 0x9c, 0x96, 0x97, 0x97, 0x27, 0xf8, 0xa7, 0x4f, 0x9f, 0x56, 0xad, 0xc3, 0xee, 0x07, - 0x18, 0x31, 0xed, 0x43, 0xb5, 0x15, 0x69, 0x17, 0x8b, 0x9f, 0x6b, 0x7a, 0x0e, 0xe2, 0x37, 0xc5, - 0x98, 0xa4, 0xe9, 0x11, 0x32, 0x66, 0x56, 0xfc, 0xa5, 0x6c, 0x07, 0xe2, 0x8f, 0x95, 0x39, 0x92, - 0x96, 0x65, 0x20, 0xd4, 0x5e, 0x63, 0x8a, 0x07, 0x09, 0x3b, 0xd0, 0x54, 0xb5, 0x18, 0x62, 0x3d, - 0xb6, 0xf0, 0x94, 0x8f, 0x87, 0xba, 0x3d, 0x77, 0xcb, 0x1c, 0xa0, 0x32, 0x0d, 0x07, 0xbf, 0x2f, - 0xa3, 0x19, 0x41, 0x0c, 0x8d, 0x42, 0xde, 0x8a, 0xe9, 0x10, 0x6c, 0x3b, 0xcf, 0xea, 0x73, 0x97, - 0x2e, 0x84, 0x8c, 0xbe, 0xf7, 0xaa, 0xd6, 0xed, 0xad, 0xb8, 0x1b, 0x65, 0x6b, 0xa0, 0x68, 0xfc, - 0x16, 0x70, 0x38, 0xb3, 0x64, 0x72, 0x7e, 0xcf, 0x16, 0x68, 0x3c, 0xb2, 0x90, 0xd1, 0x52, 0x5c, - 0x39, 0x50, 0x58, 0xf6, 0x9e, 0x8c, 0x1f, 0x0f, 0x12, 0xb7, 0x03, 0x9e, 0xf2, 0x32, 0x9c, 0x57, - 0x43, 0x4c, 0x67, 0xd1, 0xb8, 0x4d, 0xe0, 0x48, 0x2d, 0x8a, 0xa9, 0xbf, 0xa9, 0xea, 0x27, 0xd0, - 0x7e, 0xe9, 0x1d, 0xc8, 0x1f, 0xfd, 0x7b, 0x70, 0xe5, 0x8c, 0xd2, 0x94, 0x97, 0x82, 0x2d, 0x50, - 0xb7, 0x73, 0x0a, 0xd6, 0xd1, 0x79, 0x6d, 0xda, 0xeb, 0xb6, 0xdd, 0x9a, 0xf2, 0x9c, 0x19, 0xb7, - 0x03, 0x54, 0x20, 0xd0, 0xf4, 0x3f, 0xa8, 0x3f, 0xf0, 0x1d, 0x5e, 0x16, 0x0a, 0xc6, 0xac, 0x05, - 0x67, 0x56, 0xa9, 0xc0, 0xc3, 0x81, 0xb6, 0x73, 0x7f, 0x01, 0xbc, 0xf4, 0x87, 0xec, 0x81, 0x73, - 0x20, 0xb3, 0x78, 0x56, 0x38, 0x4b, 0x06, 0x87, 0xfc, 0x97, 0xa0, 0x6e, 0xf7, 0x9d, 0x82, 0x96, - 0x3b, 0xe2, 0x05, 0x48, 0x2b, 0xfc, 0xbc, 0xc0, 0x63, 0x01, 0xba, 0x1c, 0x50, 0x2a, 0xf3, 0xee, - 0x99, 0x06, 0xc1, 0xf6, 0x0b, 0x8c, 0x9c, 0x3f, 0xea, 0x35, 0x70, 0xe5, 0xde, 0xc8, 0xe0, 0x40, - 0x73, 0x25, 0xd4, 0xef, 0x9f, 0x05, 0xe9, 0x45, 0x9f, 0x85, 0x9c, 0xe1, 0xbf, 0x54, 0x16, 0x83, - 0x90, 0xbf, 0x16, 0x8d, 0x9e, 0xca, 0xe8, 0x29, 0x2e, 0x37, 0x36, 0x9d, 0x77, 0x10, 0x76, 0x46, - 0xc8, 0xc5, 0x43, 0x48, 0xc8, 0x81, 0xa8, 0x15, 0x84, 0xda, 0xa1, 0x76, 0xfb, 0x67, 0x21, 0x25, - 0xad, 0x17, 0x14, 0x8e, 0xfd, 0x67, 0x54, 0x91, 0x64, 0x12, 0x93, 0xef, 0x00, 0x5a, 0xe7, 0xaf, - 0x7d, 0x0f, 0xd2, 0x7a, 0x7d, 0x21, 0x99, 0x76, 0xaa, 0xea, 0x32, 0xc5, 0x01, 0xd5, 0xda, 0x4c, - 0x60, 0x24, 0x3c, 0x0f, 0x98, 0x60, 0x93, 0x2e, 0x95, 0x3d, 0xde, 0x01, 0x1d, 0xb7, 0x6f, 0xba, - 0x02, 0x13, 0x53, 0x38, 0xfc, 0x8d, 0x21, 0xde, 0x70, 0xc5, 0x94, 0x57, 0x13, 0x30, 0x94, 0x81, - 0xb4, 0xb4, 0x34, 0x76, 0x1b, 0xeb, 0x74, 0x3a, 0x21, 0x10, 0x08, 0x30, 0x98, 0x0c, 0x5a, 0xbf, - 0x7e, 0x3d, 0x14, 0x15, 0x15, 0x31, 0x7c, 0xd6, 0xac, 0x59, 0xec, 0x3c, 0x63, 0xc6, 0x0c, 0xc1, - 0x7f, 0xff, 0xfd, 0xf7, 0x85, 0x1d, 0x64, 0x34, 0xde, 0x95, 0x0a, 0xdc, 0x30, 0xa0, 0x7a, 0xbb, - 0x19, 0x83, 0x71, 0xe1, 0xc2, 0x05, 0x76, 0xd7, 0x8a, 0x4e, 0x48, 0x23, 0x46, 0x8c, 0x90, 0x49, - 0xa3, 0x31, 0xd2, 0xb6, 0x6d, 0xdb, 0xd8, 0x6d, 0x34, 0xc1, 0x74, 0xf0, 0x3b, 0xdf, 0x70, 0x41, - 0xba, 0xad, 0xe6, 0xfc, 0x70, 0xba, 0x1e, 0xd8, 0x50, 0x06, 0x28, 0x5a, 0x43, 0x87, 0x0e, 0x85, - 0x9c, 0x9c, 0x1c, 0x38, 0x74, 0xe8, 0x10, 0x1c, 0x3e, 0x7c, 0x18, 0x16, 0x2f, 0x5e, 0x4c, 0x64, - 0x71, 0xa4, 0xa7, 0xa7, 0x0b, 0xd8, 0x4c, 0xc0, 0x1e, 0x46, 0xcd, 0x8c, 0x6e, 0x3c, 0xba, 0x0d, - 0x37, 0xa1, 0x78, 0x94, 0x5b, 0x21, 0x63, 0x3b, 0x60, 0x45, 0x94, 0xb5, 0xea, 0xb0, 0x3b, 0xb1, - 0x56, 0x74, 0xac, 0xe0, 0xd9, 0x7d, 0xc0, 0x8a, 0x28, 0x6b, 0xd5, 0x61, 0x67, 0x40, 0x2b, 0x3a, - 0x56, 0xf0, 0xec, 0x0c, 0x58, 0x11, 0x65, 0xad, 0x3a, 0xec, 0x0c, 0x68, 0x45, 0x87, 0xf3, 0x82, - 0xbe, 0x2a, 0x0e, 0x26, 0xfd, 0x6c, 0xc9, 0x4c, 0xcc, 0x1f, 0xfe, 0xc6, 0xfb, 0xb8, 0x50, 0x8f, - 0x97, 0x09, 0x35, 0x21, 0xa9, 0xc3, 0xc3, 0x9e, 0x4c, 0xb7, 0x9c, 0x7a, 0x55, 0xb5, 0xce, 0x50, - 0xfb, 0x39, 0xc6, 0x4b, 0xcd, 0xbb, 0x41, 0xc8, 0xb4, 0x5f, 0xfa, 0x17, 0x2b, 0x17, 0x6c, 0xad, - 0x16, 0x34, 0xa3, 0x80, 0xe1, 0x9b, 0xfa, 0x86, 0x0f, 0x1f, 0x86, 0x8e, 0xc6, 0x83, 0xac, 0x5e, - 0x5c, 0xfa, 0xa6, 0x5a, 0x7f, 0xfd, 0xbe, 0x6f, 0x31, 0x5e, 0xde, 0xc8, 0x95, 0x42, 0x26, 0xd8, - 0x7a, 0x8a, 0xc1, 0xde, 0xbd, 0xf7, 0x81, 0x33, 0xb3, 0x04, 0x0a, 0x6e, 0x5a, 0x27, 0x78, 0x7a, - 0x01, 0xdd, 0x4d, 0xc8, 0x5f, 0xb7, 0x15, 0x1a, 0x0f, 0x2f, 0x60, 0xf5, 0x74, 0x3e, 0x12, 0x7f, - 0x17, 0x61, 0xf9, 0xe2, 0xe5, 0x2e, 0x23, 0x42, 0x18, 0xe9, 0x32, 0xe8, 0x7c, 0xfe, 0xf9, 0x9f, - 0x2e, 0xf2, 0x27, 0x90, 0xec, 0x31, 0xfd, 0x90, 0x45, 0x90, 0xd1, 0x67, 0x46, 0x84, 0x4c, 0x2c, - 0x82, 0x0e, 0x07, 0x42, 0xe0, 0xd9, 0x31, 0x19, 0xe8, 0x31, 0x38, 0x1d, 0xf9, 0xa3, 0x7e, 0x87, - 0x0f, 0x73, 0x47, 0x6b, 0xea, 0x6f, 0xf8, 0xf0, 0xbb, 0x98, 0xa5, 0x0f, 0xa1, 0xf0, 0x96, 0xb7, - 0x20, 0x25, 0xbd, 0x6f, 0x54, 0x59, 0xca, 0x86, 0x77, 0xef, 0x4c, 0xc6, 0x73, 0x38, 0x5c, 0xf8, - 0x1e, 0x01, 0x1d, 0x4d, 0xc9, 0x88, 0x2a, 0x1b, 0x8d, 0x18, 0x57, 0x1f, 0x68, 0x39, 0xb5, 0x92, - 0x45, 0x92, 0x8c, 0x4f, 0xff, 0xcc, 0x97, 0x80, 0x3a, 0x63, 0x2c, 0xe3, 0xa9, 0x32, 0x32, 0x9e, - 0x0e, 0x35, 0xe3, 0x89, 0xe7, 0xcc, 0x1c, 0xc0, 0xf4, 0x65, 0x15, 0xdf, 0xcf, 0xde, 0x0d, 0xd4, - 0x6e, 0xff, 0x1c, 0x34, 0x55, 0x2e, 0x22, 0x56, 0x5c, 0x47, 0x5c, 0x0e, 0xa4, 0xa4, 0x5f, 0x25, - 0x94, 0xf9, 0x3d, 0x9b, 0x69, 0x4d, 0xbe, 0xc0, 0xd5, 0x80, 0x96, 0xea, 0xdf, 0x30, 0x56, 0xee, - 0xb0, 0x9f, 0xaa, 0x89, 0x84, 0xd1, 0x43, 0xd0, 0x76, 0xfe, 0x2d, 0x81, 0x3b, 0x33, 0xae, 0x16, - 0x70, 0x2c, 0x40, 0x47, 0x13, 0x02, 0x68, 0x38, 0xf0, 0x20, 0xe0, 0x52, 0x21, 0xa6, 0x33, 0x35, - 0x6f, 0x0c, 0x84, 0x77, 0x4c, 0x65, 0x45, 0xf1, 0x0e, 0x9d, 0xf4, 0x8e, 0xad, 0xfd, 0xd2, 0xbf, - 0x59, 0x71, 0x32, 0xbc, 0xe0, 0xe6, 0xbf, 0x29, 0x55, 0x69, 0xe2, 0xba, 0x1c, 0x20, 0x4d, 0x52, - 0xb0, 0x19, 0x5f, 0x05, 0xdd, 0x8e, 0xe9, 0x0e, 0x32, 0xc5, 0x39, 0xd7, 0x2c, 0x86, 0xf4, 0xde, - 0xd3, 0x65, 0x95, 0xf8, 0xeb, 0xfe, 0x8b, 0x1d, 0xfd, 0x71, 0xc8, 0xec, 0x37, 0x13, 0xb2, 0x07, - 0x3f, 0x2e, 0xe3, 0x71, 0xa4, 0xc3, 0xbb, 0x1d, 0x1a, 0x0e, 0xcd, 0xe3, 0x28, 0xf6, 0x93, 0x0d, - 0xd8, 0xd4, 0x7a, 0x0b, 0x3c, 0x5e, 0x40, 0xb7, 0x03, 0x5c, 0xb1, 0xbf, 0xf6, 0x5d, 0x68, 0xac, - 0xfc, 0x31, 0x43, 0xe9, 0xb1, 0x62, 0xd1, 0x84, 0x5d, 0x9c, 0xc5, 0xc6, 0x78, 0x42, 0xd4, 0x26, - 0x2e, 0x0f, 0xbe, 0x00, 0x91, 0xf0, 0x45, 0x08, 0x1d, 0xee, 0xc1, 0x0b, 0x20, 0xa3, 0xdf, 0xd7, - 0x18, 0x6c, 0xe8, 0x9f, 0x9e, 0xc7, 0x78, 0xd1, 0x64, 0x71, 0x48, 0x95, 0x02, 0x2d, 0xd5, 0x82, - 0x15, 0x6c, 0xbf, 0xc8, 0x96, 0xbb, 0x79, 0xf7, 0xdd, 0x2f, 0x68, 0x4a, 0x20, 0x14, 0x68, 0x96, - 0xea, 0xf7, 0x3f, 0xa8, 0x24, 0x1b, 0xc2, 0x0d, 0x67, 0x40, 0x2d, 0x5a, 0x75, 0xbb, 0x6e, 0x87, - 0x50, 0x47, 0x03, 0xf4, 0x9a, 0xb0, 0x1d, 0xa7, 0x07, 0xc3, 0xf3, 0xa4, 0x9a, 0xfa, 0x08, 0x7a, - 0x5c, 0xa3, 0x50, 0x44, 0x29, 0x0d, 0x02, 0x19, 0xef, 0x48, 0xc1, 0xe7, 0xa2, 0x16, 0x18, 0x4f, - 0x66, 0x24, 0x3d, 0x03, 0xb4, 0x14, 0x2b, 0xd4, 0x76, 0x06, 0xe7, 0xa2, 0xfe, 0x1a, 0x6e, 0x26, - 0x8f, 0x65, 0x82, 0x03, 0xc9, 0x33, 0x2e, 0x1e, 0x4d, 0x49, 0x6f, 0x42, 0xf1, 0x54, 0x9a, 0x4c, - 0x19, 0xdb, 0x81, 0x64, 0x46, 0xd3, 0x88, 0x2e, 0x3b, 0x03, 0x46, 0xa2, 0x96, 0xcc, 0x32, 0xe6, - 0xcf, 0x34, 0x2a, 0xd6, 0xf2, 0xa5, 0xc5, 0xf8, 0x82, 0x10, 0x7a, 0xf7, 0xd6, 0x7f, 0x0d, 0x24, - 0xd4, 0x1a, 0x9a, 0xbf, 0x13, 0x2c, 0x84, 0x2b, 0x8c, 0xd9, 0xdb, 0x49, 0x34, 0x42, 0xba, 0xe3, - 0x8e, 0x3b, 0x12, 0xd2, 0x76, 0x59, 0xfa, 0xc0, 0xf2, 0xe5, 0xcb, 0xf1, 0x6a, 0x96, 0x7c, 0x48, - 0xfc, 0xd0, 0xed, 0xc0, 0x86, 0x0d, 0x1b, 0xc4, 0x8b, 0xeb, 0x75, 0xeb, 0xd6, 0x41, 0x49, 0x49, - 0x09, 0xc3, 0x53, 0x53, 0x53, 0xa1, 0xa5, 0xa5, 0x85, 0xc1, 0xc3, 0x87, 0x0f, 0x17, 0x32, 0xfc, - 0x45, 0x37, 0xae, 0x86, 0x4e, 0xdc, 0xda, 0x68, 0x1a, 0xf4, 0xe6, 0xaf, 0xa6, 0xa6, 0x46, 0xc2, - 0x77, 0xc4, 0xac, 0x09, 0xe0, 0x67, 0x6b, 0xd2, 0xcc, 0x99, 0x33, 0x19, 0x3c, 0x67, 0xce, 0x1c, - 0xa6, 0x2a, 0x3f, 0x3f, 0x9f, 0xe1, 0xab, 0x56, 0xad, 0x62, 0x67, 0xac, 0x53, 0x7a, 0xe6, 0x99, - 0x67, 0x18, 0x1c, 0x0c, 0x06, 0x65, 0xd5, 0x11, 0x2f, 0xd1, 0x26, 0x44, 0xa9, 0x34, 0x74, 0x70, - 0x27, 0xc8, 0x08, 0x8f, 0xc7, 0x23, 0x74, 0x8c, 0x1d, 0x3b, 0x96, 0x19, 0x4b, 0x84, 0x70, 0x03, - 0x09, 0x3e, 0x7a, 0xf4, 0xa8, 0x90, 0x53, 0xf2, 0x65, 0x0c, 0x1d, 0x88, 0xee, 0x26, 0x84, 0x86, - 0xb0, 0x63, 0xf5, 0xea, 0xd5, 0x1c, 0x84, 0xc2, 0xc2, 0x42, 0x01, 0x2b, 0x01, 0xb3, 0xdf, 0xd8, - 0x1b, 0x72, 0x60, 0xcf, 0x9e, 0x3d, 0x30, 0x61, 0xc2, 0x04, 0xd8, 0xb7, 0x6f, 0x9f, 0x58, 0xdc, - 0xa1, 0x34, 0xdc, 0x32, 0x5c, 0x47, 0xb6, 0x98, 0xe8, 0xda, 0xb5, 0x6b, 0x59, 0xd3, 0x40, 0x03, - 0xa5, 0xb7, 0xdf, 0x7e, 0x5b, 0xc0, 0x84, 0x1f, 0x3f, 0x7e, 0x5c, 0xe0, 0x8f, 0x3d, 0xf6, 0x98, - 0x80, 0x1b, 0x1b, 0x1b, 0x05, 0x4c, 0x4a, 0x48, 0x36, 0xda, 0x9f, 0x5e, 0x5b, 0x48, 0xde, 0xbe, - 0x9c, 0xc6, 0x48, 0x5e, 0xd6, 0xc3, 0x50, 0x1f, 0xb8, 0xac, 0x16, 0x2b, 0x2a, 0xb7, 0x1d, 0x50, - 0x04, 0xc4, 0x72, 0xd4, 0xce, 0x80, 0xe5, 0x21, 0x57, 0x54, 0x68, 0x67, 0x40, 0x11, 0x10, 0xcb, - 0xd1, 0x1e, 0x3f, 0x91, 0x59, 0x1e, 0xb1, 0x24, 0x57, 0xd8, 0xe3, 0xbb, 0x40, 0x92, 0xe3, 0x61, - 0xb9, 0x3a, 0x3b, 0x01, 0x96, 0x87, 0x5c, 0x5e, 0xa1, 0x9d, 0x00, 0x79, 0x3c, 0x2c, 0xc7, 0xec, - 0x04, 0x58, 0x1e, 0x72, 0x79, 0x85, 0x76, 0x02, 0xe4, 0xf1, 0xb0, 0x1c, 0xb3, 0x13, 0x60, 0x79, - 0xc8, 0xe5, 0x15, 0xda, 0x09, 0x90, 0xc7, 0xc3, 0x72, 0xcc, 0x4e, 0x80, 0xe5, 0x21, 0x97, 0x57, - 0x78, 0xd9, 0x5e, 0x8d, 0xc9, 0xcd, 0x48, 0x0e, 0xd6, 0x70, 0xe0, 0x21, 0xa0, 0x6f, 0xb0, 0xd3, - 0x8a, 0x26, 0xe2, 0xc7, 0xe3, 0xf7, 0x83, 0xcb, 0x7d, 0x5d, 0x72, 0x14, 0x9b, 0xa8, 0xa5, 0x5b, - 0xf4, 0x80, 0x8e, 0xfa, 0x5d, 0xd0, 0x48, 0x6b, 0xb6, 0x24, 0xbf, 0x61, 0x57, 0x9b, 0x2a, 0x7f, - 0x84, 0x8b, 0xe0, 0x0e, 0xe1, 0x6b, 0x9a, 0x20, 0xb4, 0xe3, 0x67, 0xd8, 0x6a, 0x9b, 0x26, 0x35, - 0x1f, 0x5d, 0x0a, 0xed, 0x17, 0x63, 0xef, 0x88, 0x64, 0xd8, 0x10, 0x9d, 0x05, 0x2f, 0xd3, 0xa3, - 0x08, 0x09, 0x97, 0x26, 0xbe, 0x09, 0x2d, 0xd5, 0x2f, 0x03, 0x2e, 0xd9, 0x12, 0x26, 0x3b, 0x52, - 0x5c, 0x90, 0x7f, 0xc3, 0xeb, 0xb8, 0x3d, 0xc2, 0x60, 0x41, 0x8b, 0x07, 0xf0, 0x7d, 0xf4, 0x2b, - 0xc0, 0x7d, 0xdf, 0x84, 0x68, 0xee, 0xf0, 0x5f, 0xb0, 0x5e, 0x20, 0x08, 0x08, 0x48, 0x81, 0x46, - 0xf0, 0x7e, 0x70, 0x1f, 0xee, 0x42, 0x50, 0x27, 0xc8, 0x8e, 0x94, 0x54, 0xb6, 0xcd, 0x42, 0x56, - 0xc9, 0x43, 0xb8, 0xda, 0x28, 0x4d, 0xd0, 0xad, 0x04, 0xac, 0x4b, 0x00, 0xae, 0x2f, 0x6d, 0x39, - 0xfd, 0x5b, 0x0c, 0xd4, 0x5a, 0xd6, 0x4a, 0xc3, 0x9d, 0x74, 0xb9, 0x87, 0x81, 0x7b, 0xc8, 0x13, - 0x86, 0x86, 0x8c, 0xb6, 0x9a, 0xb5, 0xd0, 0x7c, 0x72, 0xb9, 0x50, 0xe7, 0x1e, 0x3c, 0x1f, 0x17, - 0x0e, 0x7e, 0x5d, 0xe0, 0x4a, 0x20, 0xd4, 0xf6, 0x31, 0xca, 0xbf, 0x00, 0xfe, 0x3a, 0x5c, 0x06, - 0xa7, 0x38, 0x68, 0x21, 0xaf, 0x7b, 0xf0, 0x0f, 0x71, 0xa3, 0x0f, 0xf5, 0xf7, 0x7c, 0x8a, 0x22, - 0x09, 0xa3, 0xa6, 0x26, 0x20, 0xe4, 0xbf, 0x08, 0x3e, 0xdc, 0xd0, 0xa3, 0x1d, 0xb7, 0x4d, 0x09, - 0x3f, 0x68, 0x65, 0x66, 0xfa, 0x55, 0x77, 0xe2, 0x46, 0x1f, 0x3f, 0x40, 0x67, 0x0b, 0xc2, 0x59, - 0xba, 0x60, 0x5a, 0x38, 0xdc, 0x78, 0xe4, 0x09, 0x51, 0x26, 0xf3, 0xea, 0x6f, 0x42, 0xf6, 0xa0, - 0xae, 0xe5, 0xa7, 0x82, 0xa1, 0x06, 0xe0, 0x6a, 0xcf, 0x96, 0x33, 0x7f, 0xc0, 0x46, 0xf1, 0x3a, - 0xae, 0xfc, 0x94, 0xef, 0xd0, 0x97, 0x9a, 0x3b, 0x12, 0xdc, 0xa5, 0x8b, 0xc0, 0x99, 0x7d, 0x8d, - 0x5a, 0xe9, 0xa4, 0xd0, 0x93, 0x9e, 0x80, 0x40, 0xf3, 0x11, 0x68, 0x3e, 0xfe, 0x33, 0x9c, 0x0c, - 0xe5, 0x1f, 0x9a, 0xa4, 0xb8, 0xb2, 0x21, 0xab, 0xff, 0xf7, 0xb0, 0x75, 0xde, 0x87, 0x86, 0x1b, - 0xdb, 0x78, 0x24, 0xdc, 0xe3, 0x40, 0xf3, 0x61, 0xdc, 0xf0, 0xe4, 0x41, 0x41, 0x4a, 0xef, 0x35, - 0x19, 0x72, 0x86, 0x3d, 0x2f, 0x70, 0x23, 0x00, 0x2d, 0xdf, 0xf5, 0x7d, 0xb4, 0x1c, 0x37, 0x58, - 0xb9, 0x24, 0x2b, 0xee, 0xcc, 0xe8, 0x83, 0x6b, 0x8e, 0x17, 0xe2, 0x2e, 0x2f, 0xb7, 0xc9, 0xe8, - 0xc9, 0x40, 0x92, 0x9a, 0x80, 0xfa, 0xfd, 0x0f, 0x44, 0x04, 0xde, 0x85, 0xe3, 0x79, 0xee, 0x88, - 0x17, 0x71, 0xdd, 0x65, 0x71, 0x32, 0xec, 0x65, 0x3a, 0xa8, 0x67, 0x79, 0x71, 0x87, 0x25, 0xbe, - 0x77, 0x4f, 0x6a, 0xce, 0x75, 0x90, 0x37, 0x7a, 0x75, 0xd2, 0xf4, 0x4b, 0x81, 0x7a, 0x68, 0xaa, - 0x5a, 0x02, 0xb8, 0x09, 0xa9, 0x4c, 0x27, 0xcd, 0x51, 0x45, 0xb7, 0x46, 0x0e, 0x5d, 0x32, 0x21, - 0x9d, 0x48, 0x52, 0x13, 0x40, 0x75, 0x4b, 0x1d, 0x75, 0xe0, 0xab, 0x5e, 0x81, 0x57, 0x1a, 0xff, - 0xa0, 0x85, 0x23, 0x32, 0x73, 0x9c, 0xb8, 0x1a, 0x3d, 0x7b, 0xd0, 0x5c, 0xdc, 0x28, 0x66, 0x8a, - 0x8c, 0xae, 0x0b, 0x09, 0xb5, 0xe2, 0x56, 0x3e, 0x5f, 0xc1, 0xc9, 0xbb, 0x89, 0x15, 0x23, 0x9d, - 0x05, 0xb7, 0xac, 0x47, 0x38, 0xb1, 0x5e, 0x15, 0x68, 0xdc, 0x87, 0xfb, 0x1f, 0xbd, 0x00, 0x01, - 0xdf, 0xf1, 0x08, 0x73, 0xd2, 0x0a, 0xca, 0xb0, 0x07, 0x2c, 0x60, 0x1f, 0x67, 0x44, 0x30, 0x13, - 0x24, 0x24, 0x3d, 0x01, 0x72, 0x7b, 0x24, 0x68, 0xbf, 0xf0, 0x77, 0x4c, 0xc8, 0x2b, 0xb8, 0xfe, - 0xdb, 0x2b, 0x63, 0x39, 0x1c, 0x4e, 0xb6, 0x15, 0x57, 0xd6, 0x80, 0xd9, 0xb8, 0xd5, 0x96, 0x5b, - 0xc6, 0x53, 0x47, 0x24, 0xfc, 0xbc, 0xe6, 0x1e, 0x08, 0xb6, 0x9e, 0x65, 0x22, 0x0e, 0x67, 0x26, - 0x7e, 0x66, 0xb0, 0x11, 0x57, 0x65, 0xe7, 0xa8, 0x17, 0x51, 0xe3, 0xe0, 0xce, 0x57, 0xad, 0x1f, - 0xff, 0x11, 0xe7, 0x80, 0x55, 0xf8, 0x09, 0x44, 0xab, 0x4c, 0xca, 0xe1, 0xcc, 0x80, 0xac, 0xe2, - 0x6f, 0xe3, 0x15, 0xd2, 0x03, 0xa6, 0x5f, 0x1d, 0x99, 0x9c, 0x00, 0x99, 0x5f, 0x10, 0x6c, 0x39, - 0x09, 0x3e, 0xba, 0x02, 0xa9, 0xdf, 0x2b, 0x67, 0x20, 0x96, 0x9a, 0x33, 0x02, 0xb2, 0x4b, 0x1f, - 0xd7, 0xbc, 0x12, 0xa2, 0x4d, 0xdc, 0x3a, 0x1a, 0x3e, 0x60, 0x65, 0x69, 0x22, 0x2f, 0xb8, 0xe9, - 0xaf, 0x38, 0xb4, 0x95, 0x44, 0xe8, 0x52, 0x23, 0x74, 0x5e, 0x01, 0x2d, 0xc3, 0x2b, 0xa0, 0xad, - 0x11, 0x22, 0xae, 0xec, 0x52, 0xd6, 0xca, 0x53, 0xf3, 0x6e, 0x8e, 0xe0, 0x99, 0x49, 0xb0, 0x34, - 0x01, 0x32, 0x47, 0xd8, 0x15, 0xc8, 0xea, 0x4f, 0xae, 0x40, 0x3a, 0x6f, 0xc0, 0x52, 0xf3, 0x6e, - 0xc4, 0xaf, 0x88, 0x5e, 0x93, 0x89, 0x71, 0x84, 0x6e, 0xa0, 0xda, 0x2e, 0x6e, 0xe2, 0x28, 0xca, - 0xbd, 0x0a, 0xa9, 0x79, 0x37, 0x09, 0x3c, 0x1e, 0xc0, 0x77, 0xe2, 0x79, 0x68, 0x3d, 0xf7, 0x26, - 0x13, 0x65, 0x57, 0x62, 0xbd, 0xa7, 0x41, 0xf6, 0x80, 0x47, 0x13, 0xba, 0x12, 0x8b, 0xa7, 0x5e, - 0x2d, 0x99, 0xcb, 0x97, 0x00, 0x85, 0x55, 0x5a, 0x3f, 0x0d, 0xd3, 0x72, 0xea, 0x15, 0x1c, 0x2a, - 0xd6, 0x88, 0x12, 0x39, 0x43, 0x97, 0xb2, 0xcb, 0x58, 0x41, 0xd0, 0x01, 0xd0, 0x87, 0xa8, 0x5a, - 0x1f, 0xe1, 0xe9, 0x50, 0x95, 0x14, 0xd1, 0x6e, 0x93, 0x00, 0x35, 0x6f, 0xda, 0xce, 0xaf, 0xc3, - 0xcb, 0xda, 0x9f, 0x0b, 0x76, 0x36, 0xce, 0x19, 0x99, 0x25, 0x0f, 0x0b, 0xbc, 0xa7, 0x03, 0xdd, - 0xe2, 0x59, 0x90, 0x7a, 0x10, 0x43, 0xb8, 0x58, 0xd9, 0x89, 0x57, 0x1f, 0x9d, 0x9f, 0x0e, 0x65, - 0xf4, 0xb9, 0xfb, 0x8a, 0x0a, 0x3e, 0xf9, 0xdd, 0xed, 0x7b, 0x80, 0x7a, 0x72, 0xae, 0x0c, 0x4e, - 0x37, 0xef, 0x01, 0x57, 0x46, 0x90, 0xb5, 0xbc, 0xb0, 0x13, 0xa0, 0x15, 0x1d, 0x0b, 0x78, 0x76, - 0x02, 0x2c, 0x08, 0xb2, 0x56, 0x15, 0x76, 0x02, 0xb4, 0xa2, 0x63, 0x01, 0xcf, 0x4e, 0x80, 0x05, - 0x41, 0xd6, 0xaa, 0xc2, 0x4e, 0x80, 0x56, 0x74, 0x2c, 0xe0, 0x7d, 0xaa, 0x12, 0xb0, 0x62, 0xc5, - 0x0a, 0xf1, 0x11, 0x24, 0x3d, 0x8a, 0xe0, 0x7f, 0x77, 0xdd, 0x75, 0x97, 0x05, 0xa1, 0x8e, 0x5e, - 0xc5, 0x15, 0xb5, 0x2a, 0x22, 0xba, 0x8b, 0x5d, 0xd4, 0x69, 0xd3, 0xa6, 0xb1, 0x5f, 0x16, 0x3a, - 0x71, 0xe2, 0x04, 0x1c, 0x38, 0x70, 0x00, 0x8e, 0x1d, 0x3b, 0xc6, 0x98, 0x7e, 0xbf, 0xf1, 0xc5, - 0x00, 0x5d, 0xda, 0x8d, 0x41, 0x96, 0xdd, 0x88, 0x35, 0x37, 0x37, 0xc3, 0xc9, 0x93, 0x27, 0x85, - 0x95, 0xf4, 0x95, 0x36, 0xff, 0x52, 0xbb, 0xa3, 0xa3, 0x03, 0x2a, 0x2b, 0x2b, 0xc5, 0xfb, 0x83, - 0x41, 0x83, 0x06, 0xb1, 0x1d, 0x93, 0x49, 0x98, 0x78, 0x55, 0x55, 0x55, 0x10, 0x0a, 0x85, 0x80, - 0xd3, 0xb7, 0x6e, 0xdd, 0x0a, 0x7b, 0xf7, 0xee, 0x85, 0xd2, 0xd2, 0x52, 0x98, 0x3a, 0x75, 0x2a, - 0xd0, 0xfe, 0xd6, 0xe5, 0xe5, 0xe5, 0x40, 0x3f, 0xab, 0x8a, 0x5f, 0xcb, 0xc2, 0xa4, 0x49, 0x93, - 0xa0, 0x7f, 0x7f, 0xed, 0x8d, 0x37, 0x16, 0x2c, 0x58, 0x00, 0xcb, 0x96, 0x2d, 0x63, 0xf6, 0xe0, - 0x17, 0xb3, 0xb0, 0x69, 0x53, 0xd7, 0x83, 0x3e, 0x61, 0xa4, 0x15, 0x80, 0x91, 0xcf, 0x13, 0xf5, - 0x96, 0x79, 0xfa, 0xe9, 0xa7, 0xa3, 0x7e, 0x1a, 0xf9, 0xe4, 0x93, 0x4f, 0x4a, 0xe7, 0xcf, 0x9f, - 0x8f, 0xca, 0x5b, 0xba, 0x74, 0xa9, 0x84, 0x2d, 0x34, 0x2a, 0x0f, 0xe3, 0x12, 0x93, 0x3e, 0x71, - 0xe2, 0x44, 0x4d, 0x33, 0xf9, 0x9e, 0xdc, 0xa4, 0x2b, 0xd1, 0x4f, 0x96, 0x35, 0x2b, 0x8a, 0xc1, - 0xb4, 0x64, 0x0e, 0x58, 0xb2, 0x64, 0x09, 0x6b, 0xdd, 0x5e, 0xaf, 0x17, 0x46, 0x8f, 0x1e, 0x2d, - 0xda, 0xd5, 0x99, 0x33, 0x67, 0x00, 0x7f, 0x04, 0x54, 0xfc, 0xc0, 0x58, 0x59, 0x59, 0x19, 0x50, - 0x4f, 0x41, 0x9b, 0x01, 0x7f, 0x04, 0x14, 0x86, 0x0c, 0x19, 0xc2, 0x60, 0xfc, 0x84, 0x5a, 0x94, - 0x79, 0xe9, 0xa5, 0x97, 0x18, 0x8d, 0xce, 0xfc, 0xe8, 0xd3, 0xa7, 0x0f, 0xa3, 0x51, 0x2f, 0xe1, - 0x1f, 0xb6, 0x6f, 0xd9, 0xb2, 0x05, 0x70, 0xf3, 0x74, 0x2e, 0xd2, 0x6d, 0xcf, 0x96, 0x24, 0x80, - 0x7b, 0x4f, 0xc3, 0xc3, 0xfe, 0xfd, 0xfb, 0xe1, 0xd4, 0xa9, 0x53, 0x50, 0x5c, 0x5c, 0x0c, 0x6b, - 0xd6, 0xac, 0x81, 0xe9, 0xd3, 0xa7, 0x03, 0x7d, 0xd2, 0x4d, 0xc9, 0xd8, 0xb1, 0x63, 0x07, 0x64, - 0x67, 0x67, 0x73, 0xf1, 0xa8, 0xe7, 0xf1, 0xe3, 0xc7, 0x33, 0x7a, 0xdf, 0xbe, 0x7d, 0x05, 0x7f, - 0xdc, 0xb8, 0x71, 0x0c, 0xa6, 0x49, 0x95, 0x92, 0xc1, 0x0f, 0xfc, 0x48, 0x99, 0x83, 0xdd, 0xf6, - 0x6c, 0x69, 0x02, 0x28, 0x0a, 0x3b, 0x77, 0xee, 0x84, 0x91, 0x23, 0x47, 0xb2, 0xc9, 0xb0, 0x5f, - 0xbf, 0x7e, 0x30, 0x60, 0xc0, 0x00, 0xf0, 0xf9, 0x7c, 0x6c, 0xeb, 0x86, 0x85, 0x0b, 0x17, 0x76, - 0xdb, 0x40, 0x99, 0x66, 0x58, 0x8c, 0x21, 0x2a, 0x29, 0x6c, 0xfa, 0x1d, 0x85, 0xc9, 0x93, 0x27, - 0x4b, 0xf8, 0xa3, 0x10, 0x62, 0xec, 0xc6, 0x96, 0x2c, 0xe1, 0x90, 0x24, 0xe1, 0x3e, 0x19, 0xd2, - 0x94, 0x29, 0x53, 0x04, 0x1d, 0x1d, 0x95, 0x70, 0x72, 0x95, 0x56, 0xae, 0x5c, 0x29, 0xe1, 0x90, - 0xc2, 0xb6, 0xa4, 0x08, 0x2f, 0x87, 0xbf, 0x5d, 0x2e, 0xe1, 0x8f, 0x44, 0x88, 0xdf, 0x5d, 0x20, - 0xf9, 0xcc, 0xcc, 0x4c, 0x69, 0xf6, 0xec, 0xd9, 0xcc, 0x56, 0xfe, 0x1b, 0x0c, 0x44, 0x1f, 0x35, - 0x6a, 0x94, 0x84, 0x7b, 0x12, 0x30, 0xfa, 0x73, 0xcf, 0x3d, 0x27, 0xe1, 0x5e, 0x1c, 0x12, 0xf6, - 0x3c, 0xf6, 0x47, 0x3f, 0x87, 0x48, 0x32, 0xf4, 0x97, 0x91, 0x91, 0x21, 0xe8, 0x54, 0xf7, 0x23, - 0x8f, 0x3c, 0x92, 0x14, 0xbf, 0xe3, 0x51, 0x62, 0xc9, 0x65, 0x28, 0x5d, 0xc9, 0xd0, 0xf8, 0x4f, - 0x67, 0x7e, 0x34, 0x34, 0x34, 0x00, 0xee, 0xe1, 0xc1, 0x50, 0xe2, 0x85, 0x1f, 0xf5, 0xf5, 0xf5, - 0x40, 0x7f, 0xe8, 0x00, 0x1b, 0xc7, 0xc3, 0xcb, 0x11, 0x9d, 0xe6, 0x09, 0x1a, 0x6a, 0xe8, 0x57, - 0x3e, 0xe8, 0x12, 0x92, 0xfe, 0x70, 0x32, 0x67, 0x2a, 0x68, 0x13, 0x14, 0xba, 0x6a, 0xa2, 0xa3, - 0xae, 0xae, 0x8e, 0xc9, 0x12, 0x8c, 0xdb, 0x72, 0xb0, 0x5e, 0xd7, 0xd4, 0xd4, 0xb9, 0x9a, 0x82, - 0x68, 0xfc, 0x68, 0x6b, 0x6b, 0x63, 0x3c, 0xc2, 0x49, 0xe7, 0xb9, 0x73, 0x9d, 0xdb, 0xb7, 0x72, - 0xbe, 0x99, 0x67, 0xcb, 0x2e, 0x43, 0xcd, 0x74, 0xa2, 0x27, 0xeb, 0xb6, 0x7c, 0x0e, 0xe8, 0xc9, - 0xc1, 0x32, 0xc3, 0x76, 0x3b, 0x01, 0x66, 0x44, 0x55, 0x87, 0x4e, 0x3b, 0x01, 0x3a, 0x82, 0x65, - 0x86, 0xa8, 0x9d, 0x00, 0x33, 0xa2, 0xaa, 0x43, 0xa7, 0x9d, 0x00, 0x1d, 0xc1, 0x32, 0x43, 0xd4, - 0x4e, 0x80, 0x19, 0x51, 0xd5, 0xa1, 0xd3, 0x4e, 0x80, 0x8e, 0x60, 0x99, 0x21, 0x6a, 0x27, 0xc0, - 0x8c, 0xa8, 0xea, 0xd0, 0xf9, 0x7f, 0xbe, 0xc9, 0xb9, 0x8c, 0x96, 0x81, 0xf7, 0x5a, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXBinaryIcon2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x08, 0x02, 0x00, 0x00, 0x00, 0x25, 0x0b, 0xe6, - 0x89, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x04, 0x24, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, - 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, - 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x2f, - 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x64, 0x63, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x70, 0x75, 0x72, 0x6c, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x64, 0x63, 0x2f, 0x65, - 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x2f, 0x31, 0x2e, 0x31, 0x2f, 0x22, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, - 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, - 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, - 0x74, 0x3e, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, - 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, - 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, - 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, - 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, - 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x36, 0x34, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, - 0x64, 0x66, 0x3a, 0x42, 0x61, 0x67, 0x2f, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x3c, 0x2f, 0x64, 0x63, 0x3a, 0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3e, 0x0a, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x35, 0x2d, 0x30, 0x32, - 0x2d, 0x32, 0x31, 0x54, 0x32, 0x31, 0x3a, 0x30, 0x32, 0x3a, 0x38, 0x31, 0x3c, 0x2f, 0x78, 0x6d, - 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, - 0x6f, 0x72, 0x20, 0x33, 0x2e, 0x33, 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xce, - 0xc3, 0x0a, 0xd6, 0x00, 0x00, 0x05, 0xc2, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x59, 0x6f, - 0x48, 0x64, 0x55, 0x14, 0x3f, 0x33, 0xe3, 0x8c, 0x63, 0xce, 0x44, 0x6e, 0x5b, 0xae, 0xd9, 0x22, - 0xa8, 0x59, 0xae, 0x08, 0x91, 0x9a, 0x1b, 0xea, 0x87, 0x30, 0xd1, 0x45, 0x03, 0x29, 0x58, 0x61, - 0x2b, 0xe9, 0x93, 0x89, 0x84, 0x44, 0x11, 0x51, 0x7d, 0x0b, 0x4a, 0x21, 0xb2, 0xed, 0x8b, 0xfa, - 0x29, 0xa8, 0x2c, 0xf1, 0x83, 0x4a, 0x1b, 0xad, 0x6c, 0x61, 0x05, 0x9b, 0xc9, 0x36, 0xba, 0x9b, - 0xe8, 0x1a, 0xa2, 0x28, 0xfe, 0xd7, 0x36, 0xf3, 0xcf, 0x6c, 0x3a, 0xce, 0x8c, 0x33, 0x9d, 0x3b, - 0xf7, 0xcd, 0x9d, 0xf7, 0xe6, 0xcd, 0xcc, 0xfb, 0x3b, 0xc4, 0xc2, 0xbb, 0x1f, 0xc6, 0x73, 0xcf, - 0xfd, 0x9d, 0xdf, 0xb9, 0xe7, 0x9c, 0xfb, 0xe7, 0x71, 0x35, 0x05, 0x83, 0x41, 0xb8, 0x97, 0x9b, - 0xf9, 0x5e, 0x9e, 0x3c, 0x99, 0xbb, 0x11, 0xc0, 0xff, 0x5d, 0x41, 0xa3, 0x02, 0x46, 0x05, 0x34, - 0x66, 0xc0, 0x58, 0x42, 0x1a, 0x13, 0xa8, 0xd9, 0x5c, 0x46, 0x05, 0x0e, 0xff, 0x82, 0xe0, 0x89, - 0x66, 0x47, 0x3c, 0x02, 0x5d, 0x09, 0x53, 0x78, 0xc4, 0x42, 0x71, 0x67, 0x16, 0x7e, 0x7a, 0x13, - 0xb6, 0x26, 0xe0, 0x68, 0x07, 0x52, 0xec, 0x70, 0xfa, 0x1c, 0x94, 0xbc, 0x01, 0x45, 0xaf, 0x08, - 0x41, 0xbc, 0x1e, 0x06, 0x39, 0xf0, 0x1c, 0x78, 0xdd, 0x60, 0x3f, 0x05, 0x17, 0x7f, 0xe0, 0x0d, - 0x84, 0x45, 0xa5, 0x84, 0xb3, 0x7d, 0x30, 0x71, 0x99, 0x18, 0x9f, 0x7f, 0x17, 0x0a, 0x5e, 0x0c, - 0xb3, 0x44, 0xff, 0x8d, 0x13, 0x00, 0x1a, 0x5f, 0x7b, 0x0d, 0x7c, 0x87, 0x1c, 0xdc, 0xef, 0x81, - 0xad, 0x9b, 0xf0, 0x7d, 0x33, 0x2c, 0xff, 0x08, 0x17, 0x3e, 0x07, 0x53, 0x2c, 0xab, 0xc5, 0xab, - 0xb0, 0xf2, 0x0b, 0xc1, 0xa7, 0x67, 0x72, 0x56, 0xfc, 0x3f, 0x8a, 0x09, 0x83, 0x30, 0xf9, 0x19, - 0x6c, 0x4d, 0x12, 0x8e, 0xc3, 0x3b, 0x7c, 0xa6, 0x28, 0x39, 0xd6, 0x12, 0x3a, 0xdc, 0x86, 0x6b, - 0x2d, 0xdc, 0xec, 0x6d, 0xe9, 0x90, 0xf3, 0x2c, 0x38, 0x1f, 0xe1, 0xcc, 0x66, 0xbe, 0x82, 0x99, - 0x2f, 0xa2, 0x28, 0x48, 0x77, 0x7d, 0x0c, 0xae, 0xbe, 0x1a, 0x43, 0x4f, 0x55, 0x4a, 0x09, 0x4f, - 0x3c, 0x84, 0x6d, 0x73, 0x22, 0x2e, 0x21, 0x6f, 0x20, 0x56, 0x2e, 0x7f, 0xff, 0x18, 0x7c, 0x47, - 0x04, 0xe3, 0xcc, 0x86, 0x97, 0xc7, 0xc1, 0x79, 0x96, 0xec, 0x81, 0x2b, 0x4d, 0x30, 0x37, 0x48, - 0x94, 0xe3, 0x1f, 0x42, 0x51, 0x33, 0x98, 0xad, 0x44, 0x9e, 0xfd, 0x1a, 0xb6, 0x27, 0x61, 0xfd, - 0x37, 0xd8, 0xb8, 0x41, 0xba, 0xf1, 0x9a, 0x4c, 0xc2, 0xbb, 0xeb, 0x70, 0xab, 0x1b, 0xdc, 0xab, - 0xb0, 0xf0, 0x1d, 0x78, 0xf6, 0xe2, 0x91, 0x45, 0xe9, 0x45, 0x15, 0x08, 0x78, 0xe1, 0x56, 0x0f, - 0x07, 0x2a, 0x7f, 0x87, 0xcc, 0x1e, 0x9b, 0xc9, 0x02, 0xd5, 0x97, 0xc1, 0x6c, 0x21, 0xf2, 0xde, - 0x12, 0x2c, 0x5c, 0x21, 0x02, 0xb6, 0xdb, 0x5f, 0x82, 0xeb, 0x53, 0x89, 0xd9, 0xcb, 0x27, 0x3c, - 0x58, 0x81, 0xf1, 0x8f, 0x00, 0x8b, 0x2c, 0x7b, 0xf6, 0x38, 0x05, 0x51, 0x00, 0xee, 0xb5, 0xc8, - 0xd2, 0xcf, 0xbd, 0x10, 0x9a, 0x66, 0xe8, 0xc7, 0xf1, 0x28, 0x3c, 0x54, 0xcc, 0x75, 0xff, 0x99, - 0x8b, 0xe8, 0x25, 0x25, 0xdd, 0x09, 0x85, 0x1e, 0x45, 0x4b, 0x08, 0xd3, 0x40, 0x1b, 0xe6, 0xfb, - 0x81, 0x3c, 0x01, 0xf8, 0xd4, 0xe3, 0xb0, 0xfd, 0x07, 0xd1, 0x30, 0xcc, 0xf3, 0xdf, 0x80, 0xff, - 0x98, 0xc3, 0xb8, 0x3e, 0x01, 0x57, 0x97, 0x00, 0x4f, 0x3b, 0x0c, 0x2c, 0x49, 0x78, 0xa6, 0x04, - 0xda, 0xd6, 0x23, 0x0c, 0xdd, 0xd9, 0x11, 0x39, 0xbe, 0x24, 0x0e, 0x60, 0x99, 0x03, 0xdb, 0xee, - 0xc7, 0xa5, 0x23, 0x30, 0xc4, 0xf3, 0x91, 0xb6, 0x83, 0x30, 0xc6, 0xfe, 0x60, 0x04, 0x60, 0x73, - 0x46, 0x64, 0xbe, 0xc4, 0xc0, 0x92, 0x84, 0x66, 0x1b, 0x38, 0xc2, 0xa7, 0x05, 0x9f, 0x21, 0xa1, - 0x2c, 0x5a, 0x42, 0x77, 0x37, 0x38, 0xbc, 0x59, 0x14, 0x1b, 0xd3, 0x30, 0x4c, 0x42, 0x6a, 0x6e, - 0x90, 0x81, 0x99, 0x39, 0xb3, 0x62, 0x1a, 0x86, 0x61, 0x43, 0xb2, 0x05, 0x51, 0x00, 0x16, 0x3b, - 0x67, 0x7b, 0xe2, 0x8d, 0x26, 0x61, 0x1a, 0x86, 0x89, 0x46, 0xc4, 0xea, 0x33, 0x30, 0x33, 0x67, - 0x28, 0xa6, 0x61, 0x18, 0x36, 0x24, 0x5b, 0x10, 0x05, 0x90, 0x8a, 0x2b, 0x27, 0xd4, 0x7c, 0xff, - 0x42, 0xd0, 0x2f, 0xe0, 0x39, 0x0e, 0x1f, 0x6d, 0x0c, 0x23, 0x18, 0x8e, 0xd3, 0x61, 0x60, 0xbd, - 0x08, 0x85, 0x7e, 0x44, 0x01, 0x64, 0x3c, 0xc6, 0x01, 0x02, 0x7e, 0x72, 0x62, 0xf2, 0xdb, 0xee, - 0x3c, 0xd7, 0x63, 0x18, 0xfe, 0x68, 0x3c, 0x99, 0x81, 0xf5, 0x22, 0x14, 0x3a, 0x12, 0x05, 0xf0, - 0xf0, 0x93, 0xc0, 0x96, 0xe6, 0xca, 0xcf, 0x11, 0x30, 0xde, 0xa6, 0x7f, 0xdf, 0xe6, 0xba, 0x67, - 0x4a, 0x23, 0x7a, 0x49, 0x49, 0x77, 0x42, 0xa1, 0x47, 0x51, 0x00, 0x78, 0x56, 0x9c, 0xbb, 0xc4, - 0x61, 0x6e, 0x74, 0x82, 0x3f, 0x74, 0x25, 0x63, 0x1f, 0x2f, 0x60, 0x7a, 0x62, 0xde, 0x77, 0x1a, - 0x9e, 0xb8, 0x28, 0x24, 0x49, 0xd8, 0xd3, 0x9d, 0x50, 0xe8, 0x4d, 0x74, 0xd4, 0xe0, 0xf0, 0x33, - 0xef, 0x93, 0x6f, 0x84, 0xc0, 0x09, 0x59, 0x42, 0x3d, 0x67, 0xc9, 0x74, 0xd7, 0xae, 0xc3, 0x9d, - 0x19, 0xce, 0xb0, 0xec, 0x2d, 0xb0, 0x3a, 0x84, 0x24, 0x52, 0x3d, 0xdd, 0x09, 0x79, 0x0e, 0x45, - 0x15, 0xc0, 0xb1, 0x8c, 0x02, 0x38, 0xff, 0x1e, 0x87, 0xc1, 0x6f, 0x69, 0xfc, 0xb2, 0x60, 0xb3, - 0xcf, 0x7a, 0x1a, 0x9e, 0x7a, 0x9d, 0x67, 0x2e, 0x4f, 0xd4, 0x9d, 0x90, 0xe7, 0x36, 0x56, 0x00, - 0x38, 0x5c, 0xf9, 0x01, 0xbc, 0xf0, 0x6d, 0xe4, 0x23, 0x14, 0x35, 0xd6, 0x34, 0x28, 0x7f, 0x1b, - 0x5e, 0xfa, 0x55, 0x71, 0xfa, 0xa9, 0x33, 0xdd, 0x09, 0xc3, 0x31, 0x98, 0x24, 0x9e, 0x16, 0xf1, - 0x8a, 0xd9, 0xf9, 0x93, 0x7c, 0x96, 0xe2, 0x61, 0x82, 0x9f, 0x74, 0xda, 0x9b, 0xde, 0x84, 0x52, - 0x01, 0x68, 0x9f, 0x71, 0x92, 0x19, 0xe2, 0x2c, 0xa1, 0x24, 0x7b, 0xd5, 0x91, 0xde, 0x08, 0x40, - 0xc7, 0x64, 0xaa, 0xa2, 0x32, 0x2a, 0xa0, 0x2a, 0x6d, 0x3a, 0x1a, 0x19, 0x15, 0xd0, 0x31, 0x99, - 0xaa, 0xa8, 0x8c, 0x0a, 0xa8, 0x4a, 0x9b, 0x8e, 0x46, 0x6a, 0x2a, 0x70, 0x12, 0x6a, 0x92, 0x93, - 0xf0, 0xfb, 0xfd, 0x5d, 0x5d, 0x5d, 0x43, 0x43, 0x43, 0x92, 0x48, 0x4d, 0x00, 0xfc, 0x16, 0x52, - 0xd4, 0xaa, 0xaa, 0xaa, 0xd0, 0x9f, 0xc9, 0x64, 0x1a, 0x1d, 0x1d, 0x4d, 0x6c, 0x38, 0x37, 0x47, - 0x9e, 0x8f, 0x72, 0x73, 0x73, 0x13, 0xc3, 0x34, 0x8e, 0x2a, 0xae, 0x40, 0x41, 0x41, 0x41, 0x4a, - 0x4a, 0x0a, 0x7a, 0x3d, 0x38, 0x38, 0x48, 0x9c, 0x39, 0x9b, 0xcd, 0x96, 0x9a, 0x9a, 0x9a, 0x9d, - 0x2d, 0xeb, 0x79, 0x27, 0x31, 0x55, 0xa2, 0x51, 0x15, 0x09, 0xc0, 0xa4, 0x22, 0xe3, 0xf0, 0xf0, - 0xb0, 0xa4, 0xad, 0xcf, 0xe7, 0x93, 0xc4, 0x68, 0x04, 0x28, 0xae, 0x00, 0x4b, 0xc6, 0xc6, 0xc6, - 0x46, 0x7b, 0x7b, 0x7b, 0x75, 0x75, 0x75, 0x6b, 0x6b, 0xeb, 0xd8, 0xd8, 0x18, 0xd3, 0x53, 0xa1, - 0xb9, 0xb9, 0xb9, 0xbc, 0xbc, 0xbc, 0xa2, 0xa2, 0xa2, 0xb2, 0xb2, 0x72, 0x6f, 0x2f, 0xfc, 0x9c, - 0x01, 0xb0, 0xbb, 0xbb, 0xdb, 0xd8, 0xd8, 0x88, 0x43, 0x6d, 0x6d, 0x6d, 0x83, 0x83, 0x83, 0xc5, - 0xc5, 0xc5, 0xe9, 0xe9, 0xe9, 0x75, 0x75, 0x75, 0x9b, 0x9b, 0x9b, 0x51, 0x0c, 0x72, 0xbb, 0x2a, - 0x12, 0x40, 0x2b, 0x80, 0xdb, 0x80, 0xf9, 0xb0, 0x58, 0x2c, 0x3d, 0x3d, 0x3d, 0x8c, 0xca, 0xed, - 0x76, 0xe3, 0x32, 0x63, 0xa3, 0x4b, 0x4b, 0x4b, 0x6c, 0x68, 0x62, 0x82, 0x7b, 0x34, 0x77, 0x3a, - 0x9d, 0x7c, 0x4c, 0x53, 0x53, 0x13, 0xc3, 0x28, 0x12, 0x40, 0x11, 0x9a, 0x82, 0x69, 0x00, 0x38, - 0x69, 0x4c, 0x73, 0x77, 0x77, 0x77, 0x5e, 0x1e, 0x79, 0x42, 0x4d, 0x4b, 0x4b, 0x5b, 0x5e, 0x5e, - 0x66, 0x6c, 0xd3, 0xd3, 0xd3, 0x03, 0x03, 0x03, 0x34, 0x06, 0x7e, 0x00, 0x08, 0xe8, 0xeb, 0xeb, - 0xa3, 0xfa, 0xda, 0xda, 0x5a, 0x8c, 0xa7, 0xa5, 0xa5, 0x05, 0xbb, 0x58, 0x07, 0x66, 0xab, 0x48, - 0x50, 0x1f, 0x00, 0xcb, 0xd9, 0xfc, 0x3c, 0xf7, 0x5e, 0xd4, 0xd9, 0xd9, 0xc9, 0xf7, 0x7d, 0x74, - 0xc4, 0xbd, 0x68, 0x44, 0x05, 0x30, 0x35, 0x35, 0x45, 0x03, 0x70, 0xb9, 0x5c, 0x88, 0x9f, 0x9c, - 0x0c, 0xfd, 0x1b, 0x06, 0x60, 0x7f, 0x7f, 0x9f, 0x6f, 0x2e, 0x53, 0x56, 0xbf, 0x07, 0x1a, 0x1a, - 0x1a, 0xe8, 0x3c, 0xf2, 0xf3, 0xf3, 0x0b, 0x0b, 0x0b, 0x51, 0xa6, 0xe7, 0x26, 0x55, 0xca, 0xf9, - 0x2d, 0x29, 0x29, 0x41, 0x58, 0x4e, 0x4e, 0x0e, 0x05, 0x7b, 0x3c, 0x1e, 0x39, 0x56, 0x51, 0x18, - 0xf5, 0x01, 0x60, 0x5e, 0x29, 0x97, 0xd7, 0xeb, 0x5d, 0x5b, 0x5b, 0x43, 0xd9, 0x6e, 0x0f, 0xbf, - 0xab, 0x46, 0x39, 0x89, 0xd3, 0xa5, 0xbb, 0x88, 0xbf, 0x97, 0xe2, 0x00, 0x13, 0xa9, 0xd5, 0x07, - 0xd0, 0xdf, 0xdf, 0xbf, 0xba, 0xba, 0x8a, 0x85, 0xee, 0xed, 0xed, 0xc5, 0x5d, 0x8b, 0x4e, 0x4a, - 0x4b, 0x23, 0x2f, 0x76, 0x78, 0x59, 0xe3, 0x4d, 0x4c, 0x3d, 0xf3, 0x65, 0xd4, 0xa0, 0x09, 0xd5, - 0x53, 0x21, 0x10, 0x08, 0xf0, 0xbb, 0x54, 0x56, 0xf0, 0x2b, 0x73, 0xa9, 0x31, 0x58, 0x4d, 0x4d, - 0x0d, 0x63, 0xc7, 0xab, 0x8a, 0x6e, 0x68, 0xd4, 0x14, 0x15, 0x15, 0x61, 0x29, 0x28, 0xac, 0xac, - 0xac, 0x8c, 0x61, 0x98, 0x80, 0x2b, 0xed, 0xf8, 0xf8, 0x18, 0x37, 0x7a, 0x46, 0x46, 0x06, 0x55, - 0xa2, 0x06, 0x4f, 0xd8, 0xac, 0xac, 0x2c, 0xda, 0xcd, 0xcc, 0xcc, 0xc4, 0xcb, 0x91, 0x39, 0x92, - 0x29, 0x28, 0xae, 0x80, 0xd9, 0x4c, 0x4c, 0x1c, 0x0e, 0x47, 0x47, 0x47, 0x07, 0x26, 0x6f, 0x71, - 0x71, 0x11, 0xd7, 0x40, 0x7d, 0x7d, 0xfd, 0xc8, 0xc8, 0x88, 0xd5, 0x6a, 0xa5, 0x53, 0xa1, 0x18, - 0x2a, 0xb3, 0x5f, 0x54, 0xe2, 0x9c, 0xb0, 0x8b, 0x61, 0x53, 0x25, 0xde, 0xd3, 0xc8, 0xc0, 0xef, - 0x52, 0x00, 0x33, 0x91, 0x23, 0x68, 0x7a, 0x56, 0xc1, 0x6d, 0xb7, 0xb0, 0xb0, 0x80, 0xbb, 0x10, - 0x0f, 0x75, 0x39, 0xce, 0x92, 0x81, 0xd1, 0x14, 0x40, 0x32, 0x26, 0xa4, 0x94, 0x53, 0xf1, 0x12, - 0x52, 0xea, 0x20, 0xd9, 0x78, 0x23, 0x80, 0x64, 0x67, 0x58, 0x8a, 0xdf, 0xa8, 0x80, 0x54, 0x86, - 0x92, 0x3d, 0x6e, 0x54, 0x20, 0xd9, 0x19, 0x96, 0xe2, 0x37, 0x2a, 0x20, 0x95, 0xa1, 0x64, 0x8f, - 0x1b, 0x15, 0x48, 0x76, 0x86, 0xa5, 0xf8, 0xff, 0x03, 0xf5, 0x1a, 0x5a, 0xe0, 0xcf, 0xeb, 0xd5, - 0xa2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXBinaryIcon3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x60, 0x08, 0x06, 0x00, 0x00, 0x01, 0x95, 0x9f, 0x47, - 0xae, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x60, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x00, 0x8a, 0xfb, 0x7d, 0x74, 0x00, 0x00, 0x0e, 0x68, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, - 0x5d, 0x09, 0x90, 0x15, 0xc5, 0x19, 0xfe, 0x39, 0xe4, 0x94, 0x1b, 0x24, 0xc8, 0x11, 0x8e, 0x04, - 0x90, 0x80, 0x18, 0x29, 0x54, 0x02, 0x05, 0x2b, 0x09, 0x87, 0x2b, 0x44, 0x70, 0x03, 0x16, 0xa9, - 0x84, 0xc2, 0x58, 0x20, 0x26, 0x9a, 0x22, 0xa1, 0xa2, 0x22, 0x11, 0x10, 0x22, 0x18, 0xc3, 0x12, - 0x23, 0x72, 0x54, 0x59, 0x31, 0x72, 0x48, 0x09, 0xca, 0x21, 0x97, 0x82, 0xc8, 0x11, 0x90, 0x2b, - 0x40, 0x10, 0x10, 0x50, 0x14, 0xd0, 0x05, 0x21, 0x28, 0xc7, 0x22, 0xb0, 0xdc, 0x93, 0xff, 0x9b, - 0x7e, 0x3d, 0xd3, 0x73, 0xbd, 0x37, 0x33, 0xef, 0xbd, 0x1d, 0x57, 0xe7, 0xaf, 0x7a, 0xd3, 0x7f, - 0xff, 0xfd, 0x1f, 0xdd, 0xfd, 0x77, 0xf7, 0xf4, 0xcc, 0x74, 0xf7, 0x2b, 0xa5, 0x31, 0x50, 0x00, - 0x28, 0x1d, 0x80, 0x57, 0x67, 0x4d, 0x43, 0xa0, 0xc5, 0x28, 0xa2, 0xae, 0x93, 0x84, 0x41, 0xe0, - 0x00, 0x84, 0x2a, 0xce, 0xa4, 0xb2, 0x7a, 0x82, 0xbc, 0xcc, 0x1b, 0x22, 0x31, 0x11, 0xde, 0x58, - 0x81, 0xa8, 0x57, 0x1b, 0x0b, 0xcd, 0xcc, 0xd2, 0xad, 0x0d, 0x88, 0x3a, 0x3e, 0x6f, 0x49, 0xa4, - 0xcb, 0x57, 0x89, 0x5e, 0xff, 0x8f, 0x85, 0x56, 0xea, 0x9b, 0x5c, 0x4b, 0x96, 0x9c, 0x12, 0x95, - 0x2a, 0x55, 0xca, 0x46, 0x11, 0x51, 0xb3, 0xd0, 0xb6, 0x64, 0xaf, 0x06, 0xe0, 0x29, 0x60, 0x93, - 0x37, 0xa2, 0xdf, 0xf8, 0x5a, 0xea, 0x3c, 0x51, 0xb4, 0x9d, 0x99, 0x9b, 0x89, 0x0a, 0x8b, 0x44, - 0xbe, 0xdf, 0xd8, 0x6e, 0xd2, 0x98, 0x22, 0x0a, 0xbd, 0xef, 0xb8, 0x48, 0xfc, 0xdf, 0x59, 0xa2, - 0x8f, 0xc6, 0x0a, 0x7c, 0xc4, 0x42, 0x11, 0xfe, 0xf9, 0x2d, 0x93, 0x06, 0x0a, 0x9a, 0x86, 0x0e, - 0xcd, 0x9f, 0x96, 0x98, 0xa6, 0xcd, 0xd8, 0xe4, 0x49, 0x2b, 0xe6, 0x5a, 0xf2, 0x6a, 0x0e, 0xa2, - 0x30, 0xe2, 0xea, 0xf0, 0xb4, 0x2a, 0x04, 0x5c, 0x8d, 0x43, 0x24, 0xfb, 0x65, 0x08, 0x6c, 0x41, - 0x2d, 0x8f, 0x1f, 0xdc, 0x51, 0x66, 0x3f, 0x42, 0x41, 0x78, 0x9c, 0x06, 0x30, 0x94, 0xa9, 0xc3, - 0x97, 0xd4, 0x76, 0x37, 0xd3, 0xd1, 0x24, 0x25, 0x48, 0x1e, 0x39, 0xcc, 0x49, 0xba, 0x8d, 0xcf, - 0x6a, 0x60, 0xcf, 0x17, 0x44, 0x47, 0xcf, 0x88, 0xa6, 0xb9, 0xf9, 0x49, 0x73, 0x8c, 0x84, 0xf0, - 0x17, 0x4c, 0x97, 0xf0, 0xf0, 0x6b, 0x44, 0x35, 0x2a, 0x09, 0xbe, 0x5f, 0xdd, 0xe9, 0xcd, 0xc7, - 0xfc, 0x56, 0x03, 0xad, 0x6f, 0x96, 0x2a, 0xc4, 0xa0, 0xdc, 0xac, 0x8e, 0x19, 0x57, 0xb1, 0x17, - 0xfa, 0x13, 0x9d, 0xbe, 0x20, 0x28, 0xb3, 0xb7, 0x10, 0xfd, 0x9d, 0xe3, 0x1e, 0xf0, 0x6d, 0x74, - 0xb2, 0x52, 0xd4, 0x35, 0x6b, 0xd6, 0x28, 0x31, 0x81, 0x56, 0xac, 0x58, 0xd1, 0x41, 0x4b, 0x4a, - 0x30, 0xc7, 0x14, 0x27, 0xc6, 0x82, 0x5a, 0xdf, 0xbe, 0x7d, 0x71, 0xff, 0xd6, 0x13, 0x47, 0x8e, - 0x1c, 0x69, 0xe0, 0x20, 0x80, 0x3e, 0x7e, 0xfc, 0x78, 0x0b, 0xcd, 0xae, 0xc5, 0x1c, 0xbf, 0x6c, - 0x29, 0x05, 0x05, 0x05, 0xba, 0x20, 0x94, 0x70, 0xff, 0xd7, 0x53, 0x81, 0xcb, 0x1f, 0x08, 0xc0, - 0x77, 0xee, 0xdc, 0x99, 0xd4, 0x40, 0xc9, 0x77, 0x72, 0xc9, 0x2f, 0x81, 0xb5, 0x27, 0xb3, 0xd7, - 0x32, 0x0d, 0xdf, 0x46, 0x03, 0x72, 0x18, 0xfe, 0xd7, 0x46, 0x6b, 0x6d, 0xa9, 0xc3, 0xf2, 0x95, - 0x6b, 0xe6, 0x90, 0x5e, 0x70, 0xda, 0x9b, 0x8f, 0x53, 0xac, 0xb3, 0x54, 0x28, 0x79, 0x83, 0x67, - 0xaa, 0x98, 0x80, 0x02, 0x7f, 0xf0, 0x27, 0xd6, 0xa1, 0x58, 0xaa, 0x6a, 0xfd, 0x8c, 0x39, 0xdb, - 0x00, 0x1f, 0x66, 0x23, 0x6a, 0x06, 0x24, 0x1f, 0x87, 0x4e, 0x1f, 0x40, 0xb9, 0x0a, 0x10, 0x96, - 0xd3, 0x19, 0x95, 0x6e, 0xc7, 0x3d, 0xf8, 0x9c, 0x06, 0xec, 0x82, 0x69, 0xc6, 0x9d, 0x06, 0x16, - 0xee, 0xf4, 0xa7, 0xf2, 0xda, 0x75, 0x7f, 0x7c, 0xb6, 0x31, 0x4e, 0xd3, 0x30, 0x69, 0xc3, 0xef, - 0xdd, 0xbd, 0xd6, 0x24, 0x75, 0x32, 0x87, 0x14, 0xc9, 0x57, 0x58, 0x94, 0x94, 0x2f, 0x1e, 0x2a, - 0x52, 0xfa, 0xc1, 0xe9, 0xe4, 0x94, 0x22, 0xc1, 0x18, 0x3c, 0x0d, 0x6c, 0xdc, 0x68, 0xeb, 0xc9, - 0xac, 0x77, 0xf9, 0xf2, 0xe5, 0xc1, 0xb4, 0x83, 0xdb, 0xda, 0x04, 0xcc, 0xd8, 0xf0, 0xe1, 0xc3, - 0xcd, 0x48, 0x1a, 0x98, 0x67, 0x09, 0x60, 0x5c, 0xce, 0xc7, 0x0f, 0x1f, 0x3e, 0x8c, 0x28, 0xb5, - 0x6f, 0xdf, 0x5e, 0x0f, 0x71, 0xe9, 0xda, 0xb5, 0xab, 0x91, 0x6e, 0x10, 0x5d, 0x90, 0xa4, 0x06, - 0x38, 0xe3, 0x28, 0x21, 0x35, 0x69, 0xd2, 0x44, 0x17, 0x1d, 0x35, 0x8a, 0xc7, 0x9d, 0x04, 0x8c, - 0x18, 0x31, 0x42, 0x4f, 0x7b, 0xe8, 0xa1, 0x87, 0x24, 0xc9, 0x3d, 0xf4, 0x2a, 0x3d, 0x73, 0x5b, - 0x66, 0x10, 0xdd, 0xbb, 0x77, 0x37, 0xe2, 0xb3, 0x66, 0xcd, 0x32, 0x70, 0xc9, 0xe7, 0xa5, 0x27, - 0xee, 0x68, 0xee, 0xf5, 0xae, 0x50, 0x93, 0x3a, 0x59, 0xe1, 0x0b, 0x8d, 0x66, 0xdd, 0x07, 0xa1, - 0x73, 0xe6, 0x53, 0x30, 0xeb, 0x35, 0xe4, 0x33, 0x1f, 0xa1, 0xd9, 0xe2, 0x02, 0x84, 0xae, 0xba, - 0x0c, 0x09, 0xfa, 0xf3, 0x00, 0x9e, 0x87, 0x5f, 0xdd, 0x44, 0xb4, 0x6a, 0x5f, 0x6a, 0xb3, 0x78, - 0xfd, 0xf8, 0xe5, 0x39, 0xa2, 0xa2, 0x2b, 0xde, 0xbc, 0x9f, 0x7c, 0x49, 0xf4, 0x8f, 0xd5, 0x44, - 0x3b, 0x0b, 0xbc, 0x79, 0x64, 0x4a, 0x0a, 0x7d, 0xc9, 0x3b, 0xf1, 0x83, 0x33, 0x88, 0x36, 0x7e, - 0x2a, 0x54, 0x0d, 0xef, 0x46, 0xb4, 0xeb, 0x28, 0xd1, 0xbb, 0x7b, 0x45, 0x7c, 0xed, 0x70, 0xa2, - 0x7a, 0xd5, 0xa4, 0x19, 0x11, 0x3e, 0xc9, 0x2f, 0xc9, 0x16, 0xfe, 0x57, 0xe0, 0x23, 0x73, 0x89, - 0x06, 0xde, 0x65, 0x4d, 0x97, 0x53, 0xd7, 0x72, 0x3c, 0x1b, 0x1e, 0xf7, 0x73, 0xa2, 0x17, 0xde, - 0x23, 0x3a, 0x56, 0x28, 0x78, 0xdc, 0x66, 0xa6, 0xa9, 0xf4, 0xb1, 0xa4, 0x75, 0x5e, 0xad, 0x9a, - 0xbb, 0xca, 0x93, 0x42, 0x99, 0x79, 0x55, 0xf9, 0xea, 0x8f, 0x88, 0x1e, 0xe1, 0xd7, 0x20, 0x39, - 0xf9, 0xe6, 0x74, 0x58, 0x66, 0x4c, 0x95, 0xb7, 0xe3, 0x53, 0xd7, 0x99, 0x94, 0xdd, 0x89, 0x7b, - 0x62, 0x9f, 0xdb, 0x88, 0xfa, 0x4e, 0x23, 0xda, 0x7b, 0x8c, 0x28, 0x77, 0x32, 0xcf, 0x27, 0x1e, - 0x13, 0x3c, 0x7e, 0xf4, 0x25, 0xb4, 0x79, 0x17, 0x40, 0x66, 0xde, 0x34, 0x2b, 0xb0, 0x8e, 0xcd, - 0xec, 0x14, 0xb3, 0x20, 0x48, 0xf1, 0x32, 0xbe, 0x86, 0x0b, 0x0e, 0xb0, 0x7b, 0xad, 0xe3, 0x0f, - 0x44, 0x01, 0x3e, 0xe5, 0x66, 0x25, 0x41, 0xad, 0x30, 0x2f, 0x7d, 0x09, 0x5e, 0xef, 0x3e, 0xd0, - 0xf9, 0x87, 0x52, 0x9d, 0x35, 0x7c, 0xe7, 0x43, 0x6b, 0xdc, 0x6f, 0x2c, 0xb7, 0xb5, 0xe0, 0x94, - 0x4d, 0x46, 0xca, 0x49, 0x7d, 0xea, 0x3b, 0x2a, 0x99, 0xe6, 0x23, 0xf4, 0x2e, 0x00, 0x84, 0xef, - 0x4d, 0x7c, 0x3c, 0x40, 0x2d, 0xa0, 0xbd, 0xa2, 0x4f, 0x3c, 0x3e, 0x5f, 0xa8, 0xdd, 0x32, 0xc2, - 0x87, 0x7a, 0x85, 0x05, 0x8f, 0x79, 0x65, 0xcb, 0x08, 0x42, 0xcb, 0xd1, 0x44, 0x78, 0xb6, 0xbc, - 0x63, 0x02, 0x51, 0xc1, 0x29, 0x41, 0x9b, 0x3f, 0x54, 0x61, 0xf6, 0x8f, 0x26, 0xef, 0xc4, 0xaa, - 0x9e, 0xf7, 0xf6, 0x13, 0x35, 0xa8, 0xc1, 0x4d, 0xa4, 0xae, 0x4a, 0x0d, 0x87, 0x63, 0x84, 0x7a, - 0x7b, 0x0f, 0x51, 0x97, 0xe6, 0x44, 0xb5, 0x2a, 0x87, 0xd3, 0x91, 0x90, 0xf2, 0x5f, 0x80, 0xb4, - 0xcc, 0x64, 0x4f, 0x38, 0x79, 0x13, 0xca, 0x9e, 0xdd, 0x8c, 0x69, 0x8e, 0x0b, 0x90, 0xb1, 0xaa, - 0x0c, 0xa9, 0x28, 0xb0, 0x07, 0x8e, 0x1c, 0x39, 0xe2, 0xeb, 0x69, 0x0f, 0xf9, 0x19, 0x36, 0x6c, - 0x98, 0xe3, 0x2b, 0x4e, 0xc8, 0x7c, 0x7a, 0x8b, 0x79, 0x3d, 0xac, 0x25, 0xa3, 0xe3, 0x99, 0x99, - 0x35, 0x6a, 0xf9, 0xf9, 0xf9, 0x7a, 0x58, 0xa7, 0x4e, 0x1d, 0xed, 0xd0, 0xa1, 0x43, 0x16, 0x91, - 0x0a, 0x15, 0x2a, 0x18, 0x0f, 0x86, 0x96, 0x04, 0x8e, 0x40, 0x16, 0xbf, 0x05, 0x0b, 0x16, 0x18, - 0xf8, 0x8a, 0x15, 0x2b, 0xec, 0x6c, 0xbe, 0xe2, 0x9e, 0x0f, 0xf6, 0xc9, 0xa4, 0x65, 0x01, 0x0a, - 0x0b, 0x0b, 0x0d, 0x36, 0x64, 0x08, 0x99, 0x56, 0x61, 0xf1, 0xe2, 0xc5, 0x7a, 0x06, 0x55, 0x1a, - 0xf0, 0x95, 0x2b, 0x57, 0xea, 0x74, 0xfe, 0x5a, 0xa0, 0x27, 0xe5, 0xe5, 0xe5, 0xb9, 0xf2, 0xe9, - 0x89, 0x29, 0x2e, 0x81, 0x9b, 0x10, 0x67, 0xd4, 0x80, 0x09, 0x13, 0xf8, 0x46, 0xc4, 0xb0, 0x6a, - 0xd5, 0x2a, 0x3d, 0x6c, 0xd6, 0xcc, 0x65, 0x9a, 0xa1, 0xa7, 0xb8, 0x5f, 0x72, 0x72, 0x72, 0xf4, - 0x84, 0xea, 0xd5, 0xab, 0xbb, 0x33, 0xf8, 0xa0, 0xa6, 0x7d, 0x1f, 0xd8, 0xb4, 0x69, 0x13, 0xb5, - 0x68, 0xd1, 0x82, 0x6a, 0xd6, 0xac, 0xe9, 0xc3, 0x5c, 0xe6, 0x59, 0xd2, 0x2e, 0x40, 0xe6, 0xb3, - 0x14, 0x4c, 0x63, 0x5a, 0x4d, 0x28, 0x98, 0xa9, 0xec, 0x70, 0xc7, 0x05, 0xc8, 0x4e, 0xbd, 0xfa, - 0xd7, 0x1a, 0xf7, 0x01, 0xff, 0x75, 0x95, 0x1d, 0xce, 0xb8, 0x0f, 0x64, 0xa7, 0x5e, 0xfd, 0x6b, - 0x8d, 0x3d, 0xe0, 0xbf, 0xae, 0xb2, 0xc3, 0x19, 0x7b, 0x20, 0x3b, 0xf5, 0xea, 0x5f, 0xeb, 0x77, - 0xc4, 0x03, 0x9b, 0x0e, 0x12, 0x4d, 0x59, 0x4b, 0x74, 0xc4, 0xf6, 0xfd, 0xdf, 0xad, 0xa2, 0xf0, - 0x62, 0x17, 0x3f, 0x2f, 0xc0, 0x77, 0xec, 0xa5, 0xbb, 0xc5, 0xfa, 0xd3, 0xf3, 0x97, 0xbd, 0xb8, - 0x4c, 0x7a, 0x0a, 0x7d, 0xc9, 0xef, 0xc4, 0x78, 0x7b, 0xfc, 0xc0, 0xcb, 0xa6, 0x32, 0x60, 0x37, - 0xf0, 0xcb, 0xa9, 0x3d, 0xa3, 0xad, 0x34, 0x19, 0xc3, 0xc3, 0x16, 0x5e, 0x5a, 0x01, 0xd4, 0xd7, - 0x83, 0x82, 0xc2, 0x2f, 0x74, 0xf9, 0x53, 0xea, 0x6c, 0x65, 0x1d, 0x1b, 0xe8, 0x6d, 0xea, 0x13, - 0xbd, 0xf9, 0xb0, 0xe4, 0xb0, 0x86, 0xa9, 0xf4, 0x31, 0x77, 0xf2, 0x26, 0x24, 0x33, 0x7f, 0x4b, - 0x3d, 0xf1, 0x36, 0x19, 0xea, 0xb1, 0x22, 0xe3, 0xb6, 0xbf, 0x58, 0x0d, 0x21, 0xf6, 0x39, 0xbf, - 0x61, 0x93, 0x99, 0x77, 0xa6, 0x12, 0x6d, 0xff, 0xcc, 0xcc, 0x7c, 0xff, 0x76, 0x44, 0x0f, 0x77, - 0x16, 0x5c, 0xbb, 0xf9, 0x8d, 0xf7, 0xb8, 0x65, 0x4e, 0x89, 0x54, 0xfa, 0x12, 0x12, 0xde, 0x2f, - 0x77, 0xff, 0xba, 0xc2, 0x54, 0xba, 0xe8, 0x11, 0x81, 0xf7, 0x63, 0xc3, 0xc8, 0x64, 0x91, 0xe2, - 0xfa, 0xf3, 0x97, 0x88, 0x6e, 0x7f, 0xd6, 0xe4, 0xf5, 0xc2, 0x06, 0xf1, 0x6b, 0x49, 0x00, 0xde, - 0xb9, 0x8e, 0xbb, 0x4f, 0xe0, 0xdf, 0xaf, 0x45, 0xf4, 0x14, 0xbf, 0x92, 0xc7, 0x3a, 0xbc, 0xa7, - 0xef, 0x15, 0x34, 0xbf, 0xfa, 0x04, 0x77, 0x12, 0x0f, 0x40, 0x29, 0xe0, 0xbe, 0xb6, 0x22, 0xc4, - 0x55, 0x5d, 0x7b, 0xfc, 0x76, 0xc0, 0x97, 0xbc, 0xf8, 0x50, 0x01, 0x18, 0xd5, 0x4b, 0x84, 0xb8, - 0xe6, 0xfd, 0xd8, 0xc4, 0x43, 0x62, 0xde, 0x1e, 0x90, 0x06, 0xdb, 0xda, 0x96, 0xc9, 0x48, 0x43, - 0xbb, 0x8e, 0x10, 0xdd, 0xf3, 0x23, 0xa2, 0xca, 0xe5, 0xcd, 0xf6, 0xbe, 0xf5, 0x30, 0xd1, 0xaf, - 0x5f, 0x91, 0x1c, 0xee, 0x61, 0x43, 0x7e, 0xbf, 0xea, 0x06, 0xe8, 0xd0, 0x95, 0xcb, 0x05, 0xd6, - 0x97, 0xbc, 0x0f, 0xc0, 0x50, 0x05, 0x56, 0xea, 0x06, 0x27, 0x93, 0x8c, 0x34, 0x6e, 0xfc, 0xa9, - 0x68, 0xa7, 0xce, 0xa7, 0xe2, 0x70, 0x4d, 0x4f, 0x5d, 0x80, 0xaf, 0x2f, 0xba, 0x0a, 0x52, 0x9d, - 0x2a, 0xee, 0xf4, 0xb0, 0xd4, 0x3a, 0x37, 0x86, 0x92, 0xf4, 0x2e, 0x00, 0x36, 0x17, 0x00, 0xbc, - 0xbe, 0xd4, 0xb4, 0x6f, 0xac, 0x27, 0x07, 0xbe, 0x60, 0xd4, 0x71, 0x83, 0x0a, 0x37, 0xb8, 0x51, - 0x53, 0xd2, 0xbc, 0x0b, 0xf0, 0x1b, 0xfe, 0x20, 0x01, 0x58, 0xf7, 0xb1, 0x08, 0x71, 0x95, 0xab, - 0x77, 0x81, 0xe7, 0xf0, 0xbb, 0xfd, 0x20, 0x80, 0xbe, 0x02, 0xf8, 0xe3, 0x1b, 0x22, 0xc4, 0x75, - 0xe2, 0xbb, 0x26, 0x1e, 0x12, 0xf3, 0x2e, 0xc0, 0xef, 0x72, 0x4c, 0x95, 0x3f, 0x7b, 0x81, 0xe8, - 0xe5, 0x0d, 0x44, 0x77, 0x3d, 0x27, 0x68, 0x58, 0xe7, 0x1c, 0x14, 0x5e, 0x1f, 0x2c, 0x24, 0x30, - 0xbe, 0x0f, 0x7f, 0x93, 0xe8, 0xb9, 0x77, 0x58, 0xe7, 0x7a, 0x41, 0x7b, 0xac, 0x6b, 0x50, 0x6d, - 0x06, 0xbf, 0x77, 0x01, 0xc0, 0xf2, 0xde, 0x1f, 0x04, 0x23, 0x3e, 0x03, 0x4d, 0x5c, 0x29, 0xf0, - 0x6a, 0x15, 0x89, 0xb0, 0x90, 0x3b, 0x28, 0x34, 0xbf, 0x89, 0x68, 0xc4, 0x3d, 0x42, 0x6a, 0xe9, - 0x2e, 0xf1, 0x89, 0x09, 0xb1, 0x6e, 0xad, 0x88, 0x1e, 0xcd, 0x11, 0xf4, 0x10, 0xd7, 0xe4, 0x53, - 0x09, 0xa9, 0xf0, 0xc8, 0x19, 0xa2, 0x1d, 0x9f, 0x8b, 0x61, 0x13, 0x53, 0x89, 0x74, 0xe1, 0x03, - 0x1e, 0x82, 0xcf, 0xf1, 0x0d, 0xd0, 0xed, 0x8b, 0x67, 0x40, 0xdd, 0xfe, 0x0a, 0x10, 0x50, 0x69, - 0x71, 0xb2, 0x27, 0x6f, 0x42, 0xc5, 0x99, 0x93, 0x90, 0xb6, 0xe2, 0x02, 0x84, 0xac, 0xb8, 0x8c, - 0x89, 0xc5, 0x1e, 0xc8, 0x58, 0x55, 0x86, 0x54, 0x14, 0x7b, 0x20, 0x64, 0xc5, 0x65, 0x4c, 0x2c, - 0xb0, 0x07, 0x8a, 0x8a, 0x8a, 0x08, 0x5b, 0x79, 0x4e, 0x9e, 0x3c, 0x99, 0x32, 0x13, 0xf8, 0xec, - 0x34, 0x63, 0x46, 0xe2, 0x49, 0x2c, 0x25, 0x77, 0x48, 0x86, 0x14, 0x1f, 0x01, 0x1d, 0xc9, 0x6c, - 0x86, 0x9f, 0xdc, 0x49, 0xeb, 0xd1, 0xa3, 0x87, 0x23, 0xcd, 0x4e, 0x00, 0xdf, 0xe0, 0xc1, 0x83, - 0xed, 0xe4, 0x8c, 0xc6, 0xbd, 0x9f, 0xc8, 0x3c, 0x2a, 0x84, 0xad, 0xfb, 0xfe, 0x78, 0x0d, 0xde, - 0x6c, 0x43, 0xe0, 0x26, 0x24, 0x33, 0x74, 0xf9, 0xf2, 0x65, 0xaa, 0x57, 0xaf, 0x9e, 0x5e, 0x98, - 0xfb, 0xef, 0xbf, 0x5f, 0x92, 0xf5, 0x70, 0xd7, 0xae, 0x5d, 0x3a, 0x1d, 0xeb, 0xbb, 0xc1, 0xa3, - 0xc2, 0xc0, 0x81, 0x03, 0xf5, 0xb4, 0x3e, 0x7d, 0xfa, 0x10, 0x7f, 0x57, 0xd6, 0x71, 0xfe, 0x50, - 0xae, 0xb2, 0x04, 0xc3, 0xc3, 0xf8, 0x93, 0x2d, 0xe8, 0xcd, 0xa8, 0x61, 0xc3, 0x86, 0x5a, 0xdb, - 0xb6, 0x6d, 0x75, 0xbc, 0x72, 0xe5, 0xca, 0x86, 0xaa, 0x73, 0xe7, 0xce, 0x69, 0xbd, 0x7a, 0xf5, - 0xd2, 0xe9, 0xd5, 0xaa, 0x55, 0x33, 0xe8, 0x40, 0xf0, 0x45, 0x5e, 0xca, 0xb7, 0x6b, 0xd7, 0x4e, - 0x6b, 0xd3, 0xa6, 0x8d, 0x1e, 0x9f, 0x3d, 0x7b, 0xb6, 0x85, 0xcf, 0x6f, 0x24, 0xd4, 0x97, 0x7a, - 0x64, 0xa0, 0x46, 0x8d, 0x1a, 0x86, 0x8d, 0xdc, 0xdc, 0x5c, 0x3d, 0x13, 0x57, 0xaf, 0x5e, 0x35, - 0x68, 0x40, 0xc0, 0x67, 0x2f, 0x80, 0xa4, 0x23, 0x4d, 0x02, 0xf0, 0xb0, 0x7d, 0x25, 0x74, 0x13, - 0xea, 0xd0, 0xa1, 0x03, 0xdb, 0x15, 0xd0, 0xb3, 0x67, 0x4f, 0x1d, 0xd9, 0xba, 0x75, 0xab, 0x24, - 0x05, 0x0e, 0x2f, 0x5d, 0xe2, 0xe9, 0x75, 0x18, 0x90, 0xb5, 0x10, 0x24, 0x64, 0x3b, 0x7a, 0xed, - 0x4a, 0x99, 0xd2, 0xa5, 0x4b, 0x5b, 0xe2, 0x92, 0x0e, 0x3e, 0xbf, 0x1e, 0xe0, 0xbe, 0x21, 0xc5, - 0x02, 0x85, 0xa6, 0x1f, 0x7d, 0x8a, 0xc9, 0xcc, 0x37, 0x68, 0xd0, 0x40, 0xcf, 0xb4, 0x8c, 0x8f, - 0x1e, 0x3d, 0xda, 0xd0, 0x20, 0x69, 0xf6, 0x10, 0x0c, 0xad, 0x5a, 0xb5, 0x32, 0xe4, 0x78, 0x39, - 0x8e, 0x81, 0x83, 0x77, 0xc7, 0x8e, 0x1d, 0x86, 0x0e, 0xbf, 0x48, 0x5a, 0x0f, 0x34, 0x17, 0x2e, - 0x5c, 0xa0, 0x6d, 0xdb, 0xb6, 0x51, 0xe7, 0xce, 0x89, 0xf7, 0x9c, 0x9c, 0x8b, 0xe2, 0x86, 0xb4, - 0x0a, 0x50, 0xdc, 0x99, 0x75, 0xb3, 0x17, 0xba, 0x13, 0xbb, 0x29, 0x8b, 0x82, 0x16, 0x17, 0x20, - 0x8a, 0x5a, 0x57, 0x6d, 0xc6, 0x1e, 0x50, 0x6b, 0x23, 0x0a, 0x3c, 0xf6, 0x40, 0x14, 0xb5, 0xae, - 0xda, 0x2c, 0xf1, 0xf7, 0x01, 0xb5, 0x30, 0x25, 0x11, 0x2f, 0xf1, 0x5d, 0xa0, 0x24, 0x56, 0xba, - 0x9a, 0xe7, 0xd8, 0x01, 0x6a, 0x6d, 0x44, 0x80, 0xc7, 0x0e, 0x88, 0xa0, 0xd2, 0x55, 0x93, 0xb1, - 0x03, 0xd4, 0xda, 0x88, 0x00, 0x8f, 0x1d, 0x10, 0x41, 0xa5, 0xab, 0x26, 0x63, 0x07, 0xa8, 0xb5, - 0x11, 0x01, 0x1e, 0x3b, 0x20, 0x82, 0x4a, 0x57, 0x4d, 0xc6, 0x0e, 0x50, 0x6b, 0x23, 0x02, 0x3c, - 0xf0, 0x87, 0x19, 0x47, 0x1e, 0xcf, 0xf2, 0x42, 0xae, 0x91, 0x8b, 0x88, 0x56, 0x26, 0xce, 0x08, - 0xb0, 0x33, 0x60, 0x41, 0xe2, 0xa4, 0x7e, 0x44, 0x21, 0x37, 0x6a, 0xeb, 0xfb, 0xaf, 0xa7, 0xad, - 0x33, 0xb5, 0xba, 0x9d, 0x31, 0x60, 0xa6, 0x3a, 0xb1, 0x55, 0xfb, 0x45, 0xfe, 0xce, 0x5c, 0x70, - 0xa6, 0x61, 0xed, 0x22, 0xf6, 0x67, 0xe3, 0x9c, 0x83, 0xb2, 0x21, 0xdb, 0x22, 0xf6, 0x87, 0xa7, - 0x91, 0xbf, 0xf0, 0x0e, 0xf8, 0x8c, 0x57, 0x0e, 0xf5, 0x9e, 0x42, 0x74, 0x89, 0xf7, 0x64, 0x27, - 0x83, 0xcf, 0xf8, 0x1b, 0x66, 0xde, 0x74, 0xc1, 0xf1, 0x24, 0x7f, 0x3d, 0x40, 0x81, 0xfd, 0x02, - 0xd6, 0x71, 0xc9, 0xa5, 0x50, 0x7e, 0x65, 0x24, 0x1f, 0x4e, 0x4d, 0xc5, 0x51, 0xab, 0xc9, 0x00, - 0x5f, 0x5e, 0x5e, 0x79, 0x5f, 0xfc, 0xea, 0x56, 0xe5, 0xbd, 0xe5, 0x8f, 0x89, 0xb5, 0x92, 0xc9, - 0x64, 0xd4, 0xb4, 0x74, 0xf2, 0x97, 0xd0, 0x13, 0xce, 0x01, 0x07, 0x4e, 0xf0, 0x11, 0xc3, 0x2f, - 0xa9, 0x59, 0xe1, 0x35, 0xc8, 0x0d, 0xf9, 0xc8, 0x8f, 0x41, 0x44, 0x15, 0x95, 0x15, 0x7b, 0x2f, - 0xad, 0x25, 0x9a, 0xbc, 0xda, 0xe4, 0xc3, 0xda, 0x32, 0x9c, 0x43, 0x3b, 0xec, 0xa7, 0x26, 0x0d, - 0x18, 0xd6, 0x30, 0xe7, 0x73, 0x65, 0x63, 0x21, 0xde, 0x21, 0x76, 0xd8, 0x07, 0x05, 0xd6, 0xf4, - 0xa0, 0xb1, 0xdf, 0xcf, 0x25, 0x5a, 0xf1, 0xa1, 0x29, 0x85, 0x96, 0xfe, 0xe2, 0x03, 0x44, 0xdd, - 0x79, 0x49, 0x98, 0x04, 0x1c, 0xa9, 0xf0, 0xcb, 0x7f, 0x9a, 0x67, 0x85, 0xe2, 0xe8, 0xdb, 0x8e, - 0x7f, 0x23, 0x7a, 0xff, 0x4f, 0x4e, 0x27, 0x64, 0x3a, 0x7f, 0x32, 0x0f, 0x1c, 0x86, 0xeb, 0x77, - 0x4f, 0xf1, 0x90, 0xa3, 0x42, 0xd3, 0xda, 0x44, 0x73, 0x79, 0x21, 0x9f, 0x5a, 0xf9, 0x48, 0xc7, - 0xfa, 0xb7, 0xdf, 0xf2, 0x4f, 0x05, 0x74, 0x57, 0xfb, 0xd1, 0x7d, 0x58, 0x19, 0x8c, 0xa3, 0x19, - 0x16, 0xed, 0x4c, 0xbf, 0xf2, 0xff, 0x7d, 0xc0, 0x5a, 0xf9, 0xb0, 0x8d, 0x21, 0x50, 0xad, 0x7c, - 0xd0, 0x70, 0x28, 0x07, 0x5a, 0x3c, 0x8e, 0x46, 0x91, 0x80, 0x75, 0xe0, 0xcf, 0x2c, 0x95, 0x31, - 0x33, 0xcc, 0x64, 0xfe, 0x4c, 0xad, 0x3a, 0xa6, 0x58, 0xb7, 0xa5, 0x78, 0x45, 0x31, 0xf4, 0x60, - 0xa9, 0xb4, 0x0a, 0xbd, 0x6e, 0x55, 0x63, 0x56, 0xbc, 0x37, 0xa7, 0x4d, 0x5d, 0x6b, 0xa5, 0x2d, - 0xfe, 0x80, 0x48, 0x5d, 0xc9, 0x89, 0x65, 0xa4, 0x7b, 0xc7, 0x58, 0x79, 0x10, 0xdb, 0x7a, 0x98, - 0x68, 0xd0, 0xab, 0xc0, 0xfc, 0x03, 0x74, 0xab, 0x50, 0x86, 0xdb, 0x98, 0x3c, 0x48, 0x44, 0xa5, - 0x03, 0xc7, 0xfa, 0xda, 0x6e, 0xb7, 0x10, 0x2d, 0xdb, 0x6d, 0xa6, 0x2c, 0x61, 0xfc, 0xf9, 0x3c, - 0x33, 0x0e, 0x2c, 0x93, 0xf9, 0xb3, 0x6a, 0x4e, 0x72, 0x9e, 0x8d, 0x8d, 0xd1, 0x88, 0xda, 0x4f, - 0x43, 0x41, 0x02, 0xc6, 0x4f, 0x2f, 0xb8, 0x99, 0x5b, 0x9a, 0x1d, 0x8e, 0x73, 0xf7, 0xb7, 0x03, - 0x2a, 0xca, 0x0e, 0x6e, 0x34, 0x3b, 0x8f, 0x3d, 0x7e, 0x8c, 0x87, 0x12, 0x15, 0x52, 0xad, 0xea, - 0xb6, 0x1f, 0x4f, 0x73, 0xfd, 0x3a, 0xd1, 0x89, 0xaf, 0x89, 0x6e, 0xaa, 0xa2, 0x6a, 0x21, 0x72, - 0xcb, 0x8b, 0x1b, 0xcd, 0x2a, 0x95, 0x32, 0xe6, 0x52, 0xea, 0x14, 0x32, 0x65, 0x78, 0x3c, 0xb5, - 0x03, 0xc6, 0x48, 0x2f, 0x70, 0x4b, 0x2b, 0x1d, 0xdc, 0xac, 0x97, 0x7a, 0x07, 0xdd, 0x9e, 0x3f, - 0x37, 0xfb, 0xaa, 0x90, 0x5b, 0x7a, 0x69, 0x97, 0x32, 0xaa, 0x32, 0x19, 0xc4, 0x83, 0xd7, 0x44, - 0xfd, 0x1a, 0x4e, 0xf3, 0x87, 0xf9, 0xc6, 0xe9, 0x05, 0x6e, 0x69, 0xf5, 0xab, 0x7b, 0x71, 0xa7, - 0x4f, 0xb7, 0xeb, 0xc6, 0xc6, 0x0c, 0x2c, 0x6b, 0xf6, 0x02, 0x7b, 0xfe, 0x70, 0x4f, 0xa8, 0x1d, - 0x6e, 0xef, 0x82, 0x97, 0x89, 0x64, 0xf4, 0xe0, 0x0e, 0xc0, 0x90, 0xd2, 0xbe, 0xb1, 0x55, 0xe7, - 0x72, 0x1e, 0x37, 0xbd, 0xce, 0x65, 0x7d, 0xcb, 0x36, 0x26, 0x43, 0x12, 0x47, 0x69, 0x65, 0x0b, - 0xdc, 0x74, 0xdb, 0xef, 0x0b, 0xd2, 0x36, 0x66, 0x5d, 0xeb, 0x3f, 0x91, 0x31, 0x11, 0xba, 0xc9, - 0x5b, 0x39, 0x32, 0x1a, 0x0b, 0xee, 0x00, 0x98, 0xc7, 0x4d, 0x4a, 0xdd, 0x80, 0x85, 0x31, 0xb3, - 0xe7, 0x8b, 0x44, 0xd8, 0xf1, 0xa5, 0xc2, 0xd8, 0x65, 0x44, 0xb3, 0x36, 0xab, 0x14, 0x3e, 0xd0, - 0xaa, 0x87, 0x73, 0x7c, 0xb5, 0x72, 0xa4, 0x17, 0xbb, 0xb3, 0x09, 0xd1, 0x2f, 0x6e, 0xb7, 0xea, - 0xc0, 0xcc, 0xe6, 0x35, 0xdb, 0xca, 0x25, 0x6c, 0x20, 0xc0, 0x39, 0xf9, 0x18, 0xf3, 0x25, 0x54, - 0xaf, 0xc4, 0x9b, 0xc2, 0x12, 0xbb, 0xd7, 0x24, 0x2d, 0xcb, 0x61, 0xf0, 0x59, 0x10, 0x32, 0x84, - 0x5e, 0xf0, 0xfe, 0xe3, 0x7c, 0x62, 0xd8, 0x64, 0x73, 0x13, 0x0d, 0xf6, 0x91, 0xa4, 0xda, 0xbe, - 0x97, 0xcf, 0xd3, 0x41, 0xdb, 0x5f, 0x94, 0x64, 0xa5, 0x7c, 0xcf, 0xf6, 0x21, 0x7d, 0x4b, 0x95, - 0xfa, 0x84, 0x3a, 0x96, 0x9d, 0x80, 0x9f, 0x17, 0x34, 0xe7, 0x83, 0xc2, 0x16, 0x0c, 0x15, 0x1b, - 0x43, 0xbd, 0x78, 0xb2, 0x40, 0x0f, 0xe7, 0x00, 0x64, 0x04, 0x27, 0x91, 0x61, 0xdf, 0x0c, 0x4e, - 0xff, 0x9b, 0xb4, 0x8a, 0x9f, 0x03, 0xb6, 0xf1, 0x58, 0x7b, 0xd1, 0x9a, 0x45, 0x6c, 0x4d, 0xb9, - 0x83, 0x5b, 0xe4, 0x78, 0xae, 0x90, 0xef, 0x25, 0x99, 0x29, 0x59, 0xa5, 0x32, 0x13, 0xc3, 0xc3, - 0x1e, 0x7e, 0xf8, 0xc3, 0x06, 0xbc, 0x2a, 0xf9, 0x98, 0x1f, 0x1e, 0xd5, 0xd6, 0x0e, 0x2b, 0xb5, - 0x78, 0xac, 0x7f, 0x34, 0x87, 0x1f, 0xc8, 0xee, 0xc8, 0x8c, 0xcd, 0x10, 0x5a, 0xe2, 0x8f, 0xf2, - 0x21, 0x2a, 0x2d, 0x93, 0x22, 0xe1, 0xee, 0x01, 0x99, 0xcc, 0xc1, 0x77, 0x5c, 0x57, 0xec, 0x80, - 0x88, 0x1b, 0x40, 0xec, 0x80, 0xd8, 0x01, 0x11, 0xd7, 0x40, 0xc4, 0xe6, 0xe3, 0x1e, 0x10, 0x3b, - 0x20, 0xe2, 0x1a, 0x88, 0xd8, 0x7c, 0xdc, 0x03, 0x62, 0x07, 0x84, 0xaf, 0x81, 0x2b, 0x57, 0xae, - 0x10, 0x76, 0xba, 0x94, 0x64, 0xc8, 0x7a, 0x0f, 0xb8, 0x78, 0xf1, 0x22, 0xf1, 0xb6, 0x38, 0x63, - 0xf3, 0x21, 0x36, 0x20, 0xf6, 0xef, 0xdf, 0x3f, 0xed, 0x3a, 0xe3, 0x83, 0x71, 0xa9, 0x5c, 0xb9, - 0x72, 0xc4, 0x7b, 0x04, 0x69, 0xc8, 0x90, 0x21, 0x69, 0xeb, 0x8b, 0x4a, 0x41, 0xd6, 0x1d, 0x80, - 0x1d, 0x9d, 0x13, 0x27, 0x4e, 0xa4, 0x96, 0x2d, 0x5b, 0x1a, 0x65, 0x3c, 0x7b, 0xd6, 0xf6, 0xd1, - 0xc4, 0x48, 0xf1, 0x8f, 0xf0, 0x7f, 0xeb, 0xe8, 0x7f, 0xe2, 0x83, 0x3f, 0xf2, 0x01, 0x5e, 0x52, - 0x21, 0xfc, 0xbb, 0xa0, 0x00, 0x25, 0xc6, 0x3f, 0x1a, 0xed, 0xdb, 0xb7, 0x8f, 0xf6, 0xef, 0xdf, - 0xef, 0x90, 0x3a, 0x71, 0xe2, 0x04, 0x5d, 0xbb, 0x76, 0xcd, 0xb1, 0x2d, 0xd7, 0xc1, 0x98, 0x20, - 0xa0, 0x47, 0x1d, 0x38, 0x70, 0x40, 0xe7, 0x5f, 0xb4, 0x88, 0xdf, 0xf1, 0x30, 0xd4, 0xad, 0x9b, - 0xfa, 0xc4, 0x7d, 0x1c, 0xe8, 0x7d, 0xea, 0x14, 0xbf, 0x30, 0x64, 0x68, 0xdc, 0xb8, 0x31, 0x55, - 0xad, 0x5a, 0x55, 0x8f, 0x6f, 0xd9, 0xb2, 0x45, 0xcf, 0x5b, 0xd3, 0xa6, 0x4d, 0xa9, 0x53, 0xa7, - 0x4e, 0x54, 0xbb, 0x76, 0x6d, 0x9d, 0xa7, 0xd8, 0x2e, 0x7e, 0xb7, 0x24, 0xa6, 0xcb, 0x27, 0xcf, - 0xd2, 0xe6, 0x82, 0x59, 0xb6, 0x47, 0xda, 0xe3, 0x55, 0xaa, 0x54, 0xd1, 0xe6, 0xce, 0x9d, 0xeb, - 0x6a, 0x6e, 0xde, 0xbc, 0x79, 0xae, 0xb2, 0x6e, 0xfb, 0x49, 0x55, 0x05, 0xdc, 0xfb, 0x2c, 0x72, - 0x5c, 0xc9, 0x5a, 0x99, 0x32, 0x65, 0x2c, 0x34, 0x99, 0x0f, 0x76, 0xa6, 0xc6, 0xf7, 0x15, 0x55, - 0x3c, 0xab, 0x78, 0xe0, 0xbd, 0xaa, 0x61, 0x73, 0x63, 0x77, 0xc0, 0x80, 0x01, 0x03, 0x34, 0x6e, - 0xcd, 0x86, 0xba, 0x69, 0xd3, 0xa6, 0x59, 0x2a, 0xa4, 0x77, 0xef, 0xde, 0x46, 0x9a, 0x1b, 0x22, - 0x0f, 0x3d, 0x47, 0xc5, 0xa5, 0x72, 0x00, 0xe4, 0xe5, 0x61, 0xe8, 0xb2, 0xa2, 0xd5, 0xed, 0xd5, - 0xd7, 0xaf, 0x5f, 0xd7, 0xb8, 0x57, 0x18, 0xf6, 0xc7, 0x8c, 0x19, 0xe3, 0x66, 0x32, 0x2b, 0xb4, - 0xac, 0xdf, 0x03, 0xb8, 0xc0, 0x0e, 0xe8, 0xd6, 0xad, 0x1b, 0xcd, 0x99, 0x33, 0x87, 0xca, 0x97, - 0x4f, 0x1c, 0xaa, 0xc5, 0x1c, 0x43, 0x87, 0x0e, 0x25, 0x3e, 0x2a, 0xdf, 0xe0, 0x5d, 0xb2, 0x64, - 0x89, 0x3e, 0xd4, 0x18, 0x84, 0x0c, 0x23, 0xec, 0x70, 0x43, 0x23, 0x26, 0x06, 0xf8, 0x87, 0x39, - 0x09, 0x07, 0x0f, 0x1e, 0x94, 0x68, 0xd6, 0xc3, 0x48, 0x1c, 0xb0, 0x67, 0xcf, 0x1e, 0xc2, 0x91, - 0x0d, 0x76, 0xd8, 0xbe, 0x7d, 0xbb, 0x41, 0x42, 0xa5, 0xf8, 0x19, 0xdb, 0x0d, 0x81, 0x80, 0x08, - 0x0f, 0x41, 0x16, 0x09, 0xd8, 0x8b, 0x04, 0xb2, 0xd2, 0xaf, 0x6c, 0x4a, 0x79, 0x9a, 0xa8, 0x0f, - 0x13, 0x5c, 0x40, 0xa3, 0x9b, 0x03, 0xe7, 0x9b, 0x9e, 0xf6, 0xc4, 0x13, 0x4f, 0x68, 0x3c, 0x2d, - 0xb5, 0x8c, 0xc9, 0x5c, 0x19, 0xda, 0xea, 0xd5, 0xab, 0x2d, 0x5a, 0xe6, 0xcf, 0x9f, 0xaf, 0xf1, - 0x7f, 0x22, 0x6a, 0xd8, 0xa6, 0x8f, 0x1f, 0xc6, 0x71, 0xa9, 0x0f, 0xfc, 0x92, 0xde, 0xa8, 0x51, - 0x23, 0xfd, 0xb8, 0x8a, 0xe3, 0xc7, 0x8f, 0x1b, 0xf2, 0xd3, 0xa7, 0x4f, 0xd7, 0x70, 0xbc, 0x85, - 0xe4, 0x47, 0x88, 0xe3, 0x2a, 0x36, 0x6f, 0xde, 0xac, 0xf1, 0x04, 0x40, 0xeb, 0xd7, 0xaf, 0x9f, - 0x56, 0xa9, 0x52, 0x25, 0x23, 0x9d, 0xff, 0xcd, 0x59, 0xc3, 0xff, 0x35, 0xd8, 0x4f, 0x90, 0x30, - 0x14, 0x66, 0x10, 0x29, 0x96, 0x59, 0xd0, 0xd1, 0xa3, 0x47, 0x09, 0xe7, 0xdd, 0x00, 0xf0, 0x57, - 0xd5, 0xeb, 0xd7, 0xaf, 0xa7, 0x29, 0x53, 0xa6, 0xd0, 0xcc, 0x99, 0x33, 0x69, 0xc3, 0x86, 0x0d, - 0x3a, 0x1d, 0x17, 0x3e, 0xcb, 0x80, 0xa6, 0x4e, 0x9d, 0x4a, 0x5d, 0xba, 0x74, 0x31, 0x68, 0x12, - 0xc1, 0xd4, 0x15, 0x33, 0x99, 0x63, 0xc7, 0x8e, 0x49, 0x92, 0x11, 0x72, 0x7d, 0xe8, 0x69, 0x20, - 0xa0, 0x25, 0xd7, 0xaa, 0x55, 0xcb, 0xd2, 0xc3, 0xce, 0x9c, 0x39, 0x43, 0xe7, 0xcf, 0x9f, 0x37, - 0xf8, 0x81, 0x9c, 0x3e, 0x7d, 0x5a, 0x7f, 0x88, 0xe3, 0xf1, 0x9f, 0xbe, 0xfa, 0xea, 0x2b, 0xc2, - 0x43, 0x9d, 0x04, 0xe0, 0xa0, 0x21, 0xcd, 0xde, 0x53, 0x24, 0x4f, 0xa6, 0xc2, 0xf8, 0x8b, 0x58, - 0xa6, 0x6a, 0x32, 0xa4, 0x9e, 0x48, 0xee, 0x01, 0x21, 0xf3, 0xfa, 0xad, 0x14, 0x8b, 0x1d, 0x10, - 0xb1, 0x5b, 0x63, 0x07, 0xc4, 0x0e, 0x88, 0xb8, 0x06, 0x22, 0x36, 0x1f, 0xf7, 0x80, 0xd8, 0x01, - 0x11, 0xd7, 0x40, 0xc4, 0xe6, 0xe3, 0x1e, 0x10, 0x3b, 0x20, 0xe2, 0x1a, 0x88, 0xd8, 0xfc, 0xff, - 0x01, 0xdc, 0xb2, 0xfe, 0x66, 0x57, 0x2f, 0x5a, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 -}; - - -#pragma mark - 3D Explorer Icons - -static const u_int8_t FLEXToggle2DIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x5d, 0x3f, 0x5b, - 0x66, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0xc8, 0xdf, 0xdc, 0x41, 0x00, 0x00, - 0x02, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x98, 0xcf, 0x2b, 0x44, 0x51, 0x14, 0xc7, - 0x3d, 0xbf, 0x86, 0x92, 0x8d, 0x3f, 0x60, 0xc4, 0xc2, 0xd6, 0x8f, 0xb2, 0x40, 0x2c, 0xc9, 0x46, - 0xcd, 0x82, 0x94, 0x7f, 0x40, 0x52, 0xca, 0x4a, 0x12, 0x4a, 0x76, 0xca, 0x42, 0xc9, 0xc6, 0xc6, - 0x02, 0x0b, 0x25, 0x8b, 0xd9, 0x48, 0xc6, 0xc6, 0x0e, 0x65, 0x37, 0x7e, 0x65, 0x83, 0x0d, 0x2b, - 0xbf, 0xc2, 0x68, 0x7c, 0x8e, 0x86, 0x5e, 0xd7, 0x79, 0x79, 0xca, 0xdc, 0xa1, 0xee, 0xa9, 0x6f, - 0xf7, 0x9e, 0x73, 0xcf, 0x7d, 0xe7, 0x7b, 0xce, 0xbb, 0xef, 0xbe, 0xfb, 0x5e, 0x5e, 0x1e, 0x92, - 0x4e, 0xa7, 0x63, 0x60, 0x1d, 0xac, 0x82, 0x26, 0xb1, 0xfd, 0x57, 0xf1, 0x48, 0xa0, 0x07, 0xf2, - 0x2b, 0xbe, 0x04, 0x52, 0xf4, 0x1b, 0x3d, 0xcf, 0x3b, 0xf0, 0xd9, 0x24, 0xe9, 0x32, 0xf4, 0x29, - 0xd0, 0x01, 0xf2, 0xfd, 0x63, 0x59, 0xec, 0xa7, 0xb9, 0x76, 0x02, 0x8c, 0xc2, 0xe7, 0x3a, 0x54, - 0x1c, 0x88, 0x6e, 0x02, 0x53, 0x66, 0xcd, 0xc9, 0x38, 0xf4, 0x9b, 0x4e, 0x16, 0xf5, 0x09, 0x93, - 0x4f, 0x90, 0x2e, 0x95, 0x7e, 0x51, 0x06, 0x35, 0xdb, 0x83, 0xe2, 0x67, 0xcb, 0x14, 0x3a, 0xb6, - 0x2c, 0xb9, 0x76, 0x58, 0xc5, 0xc1, 0xc7, 0x32, 0xba, 0xa7, 0x5f, 0xcf, 0x2d, 0x3e, 0xf2, 0xb3, - 0xc5, 0x2f, 0x82, 0x3e, 0x04, 0x72, 0xb1, 0xe4, 0x66, 0xe0, 0x73, 0xeb, 0xe7, 0x13, 0xd4, 0xf7, - 0x64, 0x00, 0xb2, 0xcd, 0x34, 0x7d, 0xe0, 0x09, 0xcc, 0x33, 0x39, 0x49, 0xeb, 0xc4, 0x55, 0xc0, - 0x55, 0xc0, 0x55, 0xc0, 0x55, 0xe0, 0xcf, 0x55, 0xe0, 0x7d, 0xdb, 0xd6, 0x58, 0xb1, 0x95, 0x17, - 0x61, 0x6f, 0x03, 0xc5, 0x20, 0xc1, 0x56, 0x1e, 0xfa, 0xe5, 0xa6, 0x5d, 0xcf, 0x96, 0x4d, 0x4d, - 0x88, 0x64, 0xca, 0x21, 0xb0, 0x03, 0x6a, 0x33, 0x44, 0xce, 0x68, 0x5b, 0x49, 0xea, 0x22, 0xa3, - 0x7f, 0x36, 0xf8, 0x46, 0x51, 0xba, 0x80, 0xbc, 0x78, 0x6d, 0xc9, 0x1e, 0x81, 0xb6, 0xe1, 0x23, - 0x67, 0xbd, 0xef, 0x05, 0x92, 0xe3, 0xc0, 0x94, 0x05, 0x73, 0x26, 0x0e, 0x51, 0x90, 0x32, 0x1d, - 0x2d, 0xe9, 0x23, 0x26, 0x1f, 0xd1, 0x3f, 0x8e, 0x3b, 0xe6, 0x58, 0x95, 0x69, 0x40, 0xaf, 0x56, - 0x6c, 0xf2, 0xa9, 0x51, 0xa0, 0xd8, 0x6d, 0x98, 0x5a, 0xb4, 0x20, 0x41, 0x09, 0x6d, 0x29, 0xce, - 0x9a, 0x6d, 0x03, 0xbf, 0x7d, 0xc5, 0x37, 0xdb, 0xa6, 0x1b, 0x02, 0xcc, 0x69, 0x41, 0x82, 0x9e, - 0x21, 0xb1, 0x4f, 0x83, 0x41, 0x20, 0x77, 0x60, 0x09, 0x0c, 0xb0, 0x66, 0xb5, 0x53, 0xb8, 0x9c, - 0x05, 0x2b, 0x19, 0xb7, 0xf9, 0x0c, 0x9d, 0xc3, 0x45, 0xce, 0x9d, 0x3f, 0x13, 0x88, 0xe6, 0x83, - 0xc2, 0x9f, 0xcd, 0x72, 0xde, 0xae, 0x02, 0xae, 0x02, 0xae, 0x02, 0xae, 0x02, 0xd9, 0xab, 0x80, - 0xfa, 0x1e, 0x0a, 0x0a, 0xc7, 0x16, 0xde, 0xcd, 0xd8, 0x24, 0xa8, 0x00, 0x6b, 0x60, 0x98, 0xf7, - 0x81, 0x7a, 0x68, 0xc5, 0xb7, 0x94, 0x71, 0x39, 0xd8, 0xda, 0x92, 0x3b, 0xb8, 0xbc, 0x86, 0x0e, - 0x06, 0xc1, 0x06, 0xf0, 0x0a, 0xfc, 0xf2, 0xe5, 0xff, 0x9d, 0x5c, 0x10, 0x87, 0x45, 0xf0, 0xec, - 0x77, 0xb4, 0xd0, 0xbf, 0x24, 0x86, 0xfc, 0x34, 0x0d, 0x27, 0x38, 0x8f, 0x29, 0xa4, 0x4e, 0xcd, - 0xd9, 0xf8, 0x48, 0xe2, 0xb9, 0x92, 0x64, 0xd0, 0x59, 0xce, 0xe4, 0x29, 0xfa, 0x95, 0x62, 0xd4, - 0x6c, 0x27, 0xf8, 0xa9, 0xcb, 0x50, 0x99, 0xff, 0xdb, 0xa6, 0xc3, 0xd0, 0xcf, 0x10, 0x25, 0x2f, - 0x21, 0xfa, 0x2e, 0xa8, 0xcb, 0xb0, 0x78, 0xa4, 0xed, 0x64, 0xdd, 0x26, 0x32, 0xfa, 0x67, 0x83, - 0x6f, 0x0d, 0x4a, 0x2f, 0x90, 0xff, 0xe1, 0xb6, 0xe4, 0x98, 0x40, 0xcb, 0xa1, 0x13, 0x12, 0x56, - 0x10, 0x8d, 0xd0, 0xc4, 0x80, 0x6c, 0x0a, 0x71, 0x92, 0x91, 0x0f, 0x3f, 0x27, 0xd9, 0xac, 0xc0, - 0x1b, 0xa1, 0x20, 0xca, 0x34, 0x04, 0xe9, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, - 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXToggle2DIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0xbf, 0x82, 0x4c, - 0xac, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xa7, 0x5a, 0xe9, 0x00, 0x00, - 0x03, 0x33, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, 0x9b, 0x4d, 0x88, 0x4e, 0x61, 0x14, 0xc7, - 0xe7, 0x1a, 0x5f, 0x65, 0xe3, 0x23, 0x8a, 0xed, 0x64, 0x61, 0x22, 0x5f, 0xc9, 0x57, 0xc8, 0x42, - 0x29, 0x0b, 0xe5, 0x63, 0x43, 0xd9, 0x20, 0x11, 0x29, 0x9b, 0xd9, 0xb3, 0xb0, 0xd5, 0xac, 0x24, - 0x42, 0xd9, 0x48, 0xb3, 0xf3, 0x11, 0x0d, 0x09, 0x35, 0x44, 0x61, 0x43, 0xde, 0xb1, 0x20, 0x29, - 0x43, 0xb2, 0x41, 0xa9, 0xe9, 0x7d, 0xfd, 0xce, 0x64, 0xa6, 0x3b, 0x6f, 0xf7, 0x39, 0xe7, 0xbe, - 0xf3, 0xbc, 0xf1, 0xdc, 0x9c, 0x53, 0xff, 0xee, 0xbd, 0xcf, 0xff, 0x39, 0xe7, 0x39, 0xe7, 0x7f, - 0xef, 0x7d, 0x6e, 0xf7, 0xb9, 0xef, 0x9b, 0x75, 0x60, 0x8d, 0x46, 0x63, 0x32, 0x9b, 0x3d, 0x60, - 0x35, 0xf8, 0x09, 0xfa, 0xb3, 0x2c, 0xbb, 0xcd, 0xd6, 0x2d, 0xa0, 0x40, 0x86, 0x68, 0xf3, 0xe0, - 0x6e, 0x81, 0x15, 0x4d, 0x7d, 0xae, 0x70, 0xbc, 0x0f, 0x01, 0x1b, 0x4d, 0xed, 0xe3, 0x0e, 0xf1, - 0x9f, 0x46, 0xc3, 0x32, 0x30, 0x73, 0x1c, 0x91, 0xe6, 0xc1, 0x0f, 0xd2, 0x7a, 0x4e, 0x4d, 0xb2, - 0x8d, 0x33, 0x0a, 0xef, 0x03, 0x21, 0x3b, 0xa6, 0x45, 0xc7, 0xa9, 0x0b, 0xbc, 0x0d, 0x39, 0x27, - 0xda, 0x3e, 0x44, 0x5e, 0x6b, 0xb4, 0xba, 0xca, 0x70, 0x72, 0xc5, 0xd5, 0xe9, 0x98, 0x05, 0x3a, - 0x3f, 0xe3, 0xec, 0xac, 0x0a, 0x70, 0x72, 0x8b, 0xf7, 0xc1, 0xed, 0x08, 0xf1, 0x09, 0xb7, 0xbf, - 0xa4, 0x2e, 0xb9, 0x4b, 0x26, 0x6c, 0x93, 0xf0, 0x0c, 0x89, 0x26, 0x41, 0xbb, 0x8c, 0xc8, 0xdd, - 0x06, 0x9f, 0x2a, 0xbd, 0x88, 0x93, 0xae, 0xd5, 0x6d, 0xe6, 0x2d, 0xc2, 0x0d, 0x2b, 0xbd, 0x5e, - 0x29, 0x9c, 0x50, 0x03, 0x06, 0x9f, 0x2a, 0xfd, 0xd8, 0x9a, 0xbb, 0xad, 0xc4, 0x45, 0xb8, 0x73, - 0x4a, 0xa7, 0x5e, 0x85, 0x13, 0xaa, 0x07, 0xdc, 0x33, 0xfa, 0xa4, 0x46, 0xbf, 0x20, 0xa1, 0x03, - 0xb1, 0x49, 0xc9, 0x1c, 0x37, 0x83, 0x20, 0x97, 0xc1, 0xce, 0x5c, 0x30, 0xb9, 0x0a, 0x4f, 0x72, - 0x56, 0x4e, 0xe5, 0xda, 0x82, 0xbb, 0xc4, 0x98, 0x0d, 0x59, 0x85, 0xa7, 0xea, 0x77, 0x6a, 0xfa, - 0x1c, 0x2c, 0xa4, 0x05, 0x62, 0xec, 0x3e, 0xa7, 0x78, 0x79, 0xd2, 0x08, 0xe4, 0x51, 0x7d, 0x9f, - 0x01, 0x06, 0x5b, 0x88, 0xe3, 0x5d, 0x5d, 0x01, 0x57, 0xc0, 0x15, 0x70, 0x05, 0x5c, 0x01, 0x57, - 0xc0, 0x15, 0x70, 0x05, 0x5c, 0x01, 0x57, 0xc0, 0x15, 0xf8, 0xa3, 0x00, 0x6f, 0x17, 0x53, 0x5d, - 0x8c, 0x92, 0x0a, 0x20, 0x96, 0xbc, 0xcf, 0x1e, 0x05, 0x35, 0x50, 0x07, 0x1f, 0xc0, 0x69, 0x20, - 0x2b, 0xbf, 0xff, 0xad, 0x8d, 0xbd, 0xab, 0x86, 0x14, 0x40, 0x20, 0x59, 0x21, 0x29, 0x5a, 0x09, - 0xbe, 0x43, 0xfb, 0x56, 0x6d, 0x79, 0x06, 0xdf, 0x29, 0xf4, 0x39, 0x02, 0xd6, 0x82, 0x2a, 0x08, - 0xfd, 0x89, 0x3c, 0x2f, 0x51, 0xd3, 0x13, 0xb6, 0x13, 0x37, 0x0a, 0x5f, 0x0a, 0xe4, 0x2a, 0x0b, - 0xd9, 0x6e, 0x2d, 0x3a, 0x4e, 0xd7, 0x42, 0x8e, 0x09, 0xb7, 0x0f, 0x93, 0xdb, 0x3a, 0xad, 0x2e, - 0xe1, 0x64, 0x3d, 0x4e, 0xb3, 0x0d, 0x90, 0xda, 0x55, 0xb9, 0x29, 0xe4, 0xcc, 0xe0, 0xf2, 0x11, - 0x68, 0x57, 0x88, 0x4f, 0xb8, 0xbd, 0x93, 0xdc, 0x0e, 0x59, 0xf9, 0x59, 0xc2, 0x49, 0x10, 0xcd, - 0x34, 0x7f, 0x8d, 0xd3, 0x62, 0xa6, 0xc0, 0x69, 0x17, 0xcb, 0x48, 0x7e, 0x56, 0x71, 0x0f, 0x8d, - 0x2a, 0x1e, 0x85, 0x78, 0xe6, 0x09, 0x99, 0x2f, 0xae, 0x87, 0xf8, 0x84, 0xdb, 0xe5, 0x73, 0xe8, - 0x05, 0x2b, 0x3f, 0x53, 0x59, 0x6e, 0x39, 0x59, 0x5a, 0x3f, 0x58, 0x10, 0xe8, 0x01, 0x6d, 0x9b, - 0x11, 0x48, 0xbe, 0x92, 0x15, 0x1a, 0xbe, 0xd3, 0x21, 0x4e, 0x80, 0x2a, 0x3d, 0x1c, 0xce, 0x53, - 0x93, 0xd4, 0x16, 0x67, 0x14, 0xdf, 0x09, 0x7a, 0xc0, 0x47, 0x20, 0xf6, 0x15, 0xf4, 0x02, 0x59, - 0x72, 0x77, 0x2b, 0xa3, 0x00, 0x62, 0x55, 0xe1, 0xbb, 0x42, 0x99, 0x52, 0xbc, 0x8f, 0x2b, 0xe0, - 0x0a, 0xb8, 0x02, 0xae, 0x80, 0x2b, 0xe0, 0x0a, 0xb8, 0x02, 0xae, 0x80, 0x2b, 0xe0, 0x0a, 0xb4, - 0xa2, 0x80, 0xf9, 0xae, 0x5a, 0x26, 0x18, 0x6f, 0x14, 0x73, 0xe8, 0xb7, 0x11, 0xcc, 0x07, 0xf2, - 0x33, 0xaa, 0x01, 0xde, 0xf7, 0xd4, 0xdf, 0x0e, 0xd3, 0xa7, 0xd2, 0x16, 0x2d, 0x1c, 0xa2, 0xc9, - 0x9a, 0x9b, 0x2c, 0x04, 0xcc, 0xca, 0x29, 0x71, 0x97, 0xfd, 0xbd, 0x88, 0x37, 0x94, 0x6b, 0x2b, - 0xdc, 0xc5, 0x5f, 0x72, 0x98, 0x0b, 0xa2, 0x73, 0x29, 0x1c, 0xa0, 0x7d, 0x8d, 0x75, 0xea, 0xf9, - 0xd2, 0x96, 0x70, 0x14, 0xbd, 0x04, 0xfc, 0x02, 0x45, 0x76, 0xc3, 0x1a, 0x04, 0xa7, 0xc3, 0xe0, - 0x5b, 0x91, 0x73, 0xa2, 0x6d, 0xb2, 0xc0, 0xb1, 0x5f, 0xea, 0x8a, 0x3a, 0xcb, 0x04, 0x09, 0x2d, - 0x39, 0x8d, 0x6a, 0xd6, 0xcd, 0x59, 0x7a, 0x3d, 0x7a, 0x90, 0xdf, 0xe2, 0xbb, 0x92, 0xe3, 0xa7, - 0x20, 0x2a, 0x87, 0x7c, 0xcc, 0xbf, 0xb4, 0x2f, 0xcb, 0x68, 0xcb, 0xad, 0x85, 0x4c, 0x2b, 0x97, - 0xc5, 0x46, 0x07, 0x8d, 0xb7, 0x96, 0xe5, 0x8d, 0xd0, 0xff, 0x8c, 0x16, 0xcd, 0xd6, 0xc7, 0x0a, - 0xf7, 0xce, 0x48, 0xff, 0xbd, 0xc2, 0xd7, 0x14, 0x2e, 0x75, 0x6a, 0x30, 0x56, 0xb8, 0xab, 0x4a, - 0x85, 0x6f, 0xe0, 0xe4, 0x09, 0x5b, 0x68, 0xdc, 0xc2, 0x37, 0x21, 0xe4, 0xdf, 0x3b, 0x55, 0xb3, - 0x8b, 0xe4, 0xde, 0x1f, 0x3d, 0xbf, 0x30, 0x57, 0x9d, 0xa1, 0xf2, 0xe3, 0x4d, 0xd5, 0xcb, 0xd3, - 0x67, 0x1b, 0x03, 0xc8, 0x1c, 0xa6, 0x1a, 0xfe, 0x72, 0x3b, 0x2f, 0x04, 0xd1, 0xb9, 0xa8, 0x03, - 0xc5, 0x93, 0x32, 0xb7, 0xd5, 0xa8, 0x69, 0xe4, 0x2f, 0x0c, 0x6d, 0x49, 0x96, 0xe2, 0xb7, 0x10, - 0x74, 0x3b, 0x58, 0x00, 0xe4, 0x2a, 0x3b, 0xcb, 0x00, 0x6d, 0xf9, 0x75, 0x37, 0xb1, 0xdc, 0x5c, - 0x01, 0x57, 0xa0, 0xe3, 0x37, 0x24, 0xed, 0x51, 0x75, 0x62, 0x2b, 0x68, 0x57, 0x00, 0x00, 0x00, - 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXToggle3DIcon2x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x00, 0x67, 0x8e, 0xe8, - 0xa6, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x4a, 0x2a, 0x28, 0x00, 0x00, - 0x03, 0xc8, 0x49, 0x44, 0x41, 0x54, 0x58, 0x09, 0xed, 0x99, 0x4b, 0x48, 0x55, 0x41, 0x18, 0xc7, - 0x3b, 0xa2, 0x62, 0x19, 0x16, 0xa6, 0x2d, 0xa4, 0x37, 0x62, 0x21, 0x51, 0x46, 0x90, 0x2d, 0x24, - 0x6a, 0x21, 0x2e, 0x5c, 0x45, 0x6e, 0x22, 0xdb, 0x18, 0xd5, 0x22, 0x03, 0x17, 0xad, 0x2c, 0x7b, - 0x50, 0x41, 0x04, 0xb6, 0xa9, 0x4d, 0x42, 0xf4, 0x2e, 0x89, 0x12, 0x8a, 0x5a, 0x64, 0x44, 0x2f, - 0x7a, 0xd0, 0x93, 0xca, 0x5c, 0x18, 0x24, 0xf4, 0xc2, 0xa4, 0x82, 0xa2, 0x0c, 0x33, 0xbb, 0xfd, - 0x3e, 0x61, 0x8e, 0xc7, 0x61, 0xc6, 0x73, 0xee, 0xbd, 0x73, 0x11, 0xc3, 0x0f, 0x7e, 0xdc, 0x99, - 0x6f, 0xe6, 0xfb, 0xbe, 0xff, 0x99, 0x33, 0x67, 0xee, 0xf1, 0xea, 0x8d, 0x73, 0x6c, 0xb1, 0x58, - 0x6c, 0x0a, 0x29, 0x2b, 0xa1, 0x10, 0x4e, 0x7a, 0x9e, 0xf7, 0xda, 0x71, 0x89, 0xe4, 0xd2, 0x21, - 0x70, 0x02, 0xec, 0x82, 0x1e, 0x50, 0xd6, 0x47, 0x23, 0x3f, 0xb9, 0xcc, 0x8e, 0xa2, 0x11, 0xe2, - 0xc1, 0x1a, 0x78, 0x07, 0x26, 0xab, 0x76, 0x54, 0x2a, 0xf1, 0x34, 0xa8, 0x5a, 0x02, 0xf7, 0x4c, - 0xea, 0xf0, 0xbd, 0x85, 0xd5, 0x89, 0x67, 0x77, 0x10, 0x89, 0x80, 0x02, 0x38, 0x0e, 0x7f, 0x41, - 0x37, 0xb9, 0xf5, 0x3b, 0x61, 0xbc, 0x83, 0x52, 0x89, 0xa5, 0xa0, 0x78, 0x16, 0x6c, 0x85, 0x1f, - 0x60, 0xb2, 0xb3, 0x38, 0xa7, 0x0f, 0x97, 0x9d, 0xf1, 0x0a, 0x38, 0x02, 0x4f, 0xa1, 0x01, 0xdc, - 0x5e, 0x10, 0x09, 0xab, 0xa0, 0x13, 0x4c, 0xf6, 0x04, 0x67, 0x59, 0x88, 0xc0, 0x62, 0xe6, 0xb4, - 0x1a, 0x82, 0xdd, 0x6c, 0x0f, 0x12, 0x97, 0xc0, 0x4d, 0x43, 0x01, 0x71, 0x75, 0xc1, 0x3a, 0x48, - 0xb3, 0x89, 0x64, 0x2c, 0x17, 0x0e, 0xc2, 0x1f, 0xd0, 0xad, 0x1f, 0x47, 0x9d, 0x2d, 0x36, 0x92, - 0x9f, 0x04, 0x53, 0xa1, 0x09, 0x24, 0x99, 0x6e, 0xbd, 0x38, 0xf6, 0x43, 0x8e, 0x2d, 0x19, 0x63, - 0xe9, 0x50, 0x0b, 0x5f, 0xc0, 0x64, 0xb7, 0x70, 0x96, 0xd8, 0xe2, 0x43, 0xfd, 0x04, 0x67, 0xc2, - 0x16, 0xf8, 0x06, 0x26, 0xbb, 0x84, 0x53, 0x0e, 0x73, 0xab, 0x31, 0x5e, 0x0e, 0x6d, 0xa6, 0x60, - 0x7c, 0x9d, 0x50, 0x65, 0x0d, 0x8e, 0x32, 0x40, 0x82, 0x4a, 0xe8, 0x00, 0x93, 0xbd, 0xc2, 0x59, - 0x3e, 0x5c, 0x1e, 0xc6, 0x0b, 0xe1, 0xa2, 0x29, 0x18, 0x9f, 0x3c, 0x80, 0xf2, 0x20, 0x66, 0x85, - 0xe4, 0x98, 0xc6, 0x9c, 0x46, 0x90, 0x7a, 0x72, 0xb1, 0x83, 0xe7, 0x30, 0x9d, 0x0c, 0x38, 0x0d, - 0x26, 0xfb, 0x8a, 0x73, 0x33, 0xa4, 0xdb, 0x0a, 0x30, 0x96, 0x03, 0xb2, 0x15, 0x64, 0x4b, 0xe8, - 0x26, 0x47, 0xd8, 0x09, 0x28, 0xb0, 0xc5, 0x8b, 0x9f, 0xf1, 0x6c, 0xd8, 0x0b, 0xbf, 0x20, 0x68, - 0x12, 0x3f, 0x77, 0x20, 0x96, 0x86, 0x1c, 0x13, 0xba, 0xc9, 0xe6, 0x3f, 0x04, 0xb9, 0xb6, 0x02, - 0x8c, 0xa5, 0x81, 0x3c, 0x4c, 0xf2, 0x50, 0x99, 0xec, 0x01, 0xce, 0x52, 0x5b, 0xbc, 0xf8, 0x19, - 0x97, 0x6f, 0xb6, 0xb5, 0xf0, 0x01, 0x6c, 0xd6, 0x30, 0x90, 0x83, 0x51, 0xfd, 0xa9, 0x7e, 0x88, - 0x6f, 0x7e, 0x48, 0x81, 0x32, 0xe6, 0xc8, 0xb1, 0x64, 0xb2, 0xf7, 0x38, 0xab, 0xc1, 0x0b, 0xc9, - 0x51, 0xca, 0x1c, 0xb9, 0x98, 0x30, 0x6b, 0x52, 0x42, 0x9f, 0x05, 0x66, 0xfe, 0xa4, 0x6d, 0x3d, - 0x84, 0x19, 0x9b, 0x01, 0xcd, 0x81, 0xf9, 0xc1, 0xa6, 0xdc, 0xb6, 0xdd, 0x90, 0x1d, 0x22, 0x50, - 0xbe, 0xd9, 0x64, 0x3b, 0xc8, 0x6d, 0x8d, 0x62, 0xcd, 0x4a, 0xe8, 0x8b, 0xc0, 0xec, 0x76, 0x53, - 0x11, 0xc6, 0x65, 0x1f, 0x6f, 0x83, 0xe0, 0xdb, 0x51, 0x20, 0x2c, 0x76, 0x8e, 0xce, 0x4c, 0x53, - 0xac, 0xf2, 0x31, 0x9e, 0x05, 0xf5, 0x20, 0x0f, 0x56, 0x3c, 0x66, 0x14, 0xda, 0xa6, 0x12, 0xab, - 0x4f, 0x32, 0x4e, 0x84, 0xfb, 0x96, 0xcc, 0x72, 0x37, 0x96, 0xa9, 0xb9, 0xb6, 0x4f, 0xe6, 0xac, - 0x82, 0x4e, 0x48, 0xc4, 0x9a, 0xad, 0xdf, 0x28, 0x5a, 0xc1, 0x1a, 0xfa, 0x4b, 0x35, 0x5f, 0x37, - 0xfd, 0x0d, 0xb0, 0x98, 0x97, 0xe3, 0xdb, 0xda, 0x98, 0xdf, 0x45, 0xd5, 0x42, 0xb8, 0x81, 0xe3, - 0x3c, 0xcc, 0xf2, 0x07, 0xe2, 0x6c, 0x58, 0x8f, 0x1c, 0x2d, 0xcf, 0x02, 0xad, 0x7f, 0x81, 0x7e, - 0x0d, 0x02, 0xbf, 0x6b, 0x7e, 0xbf, 0x8b, 0xb8, 0x3c, 0x3a, 0x7b, 0x60, 0x3d, 0x44, 0x5d, 0x10, - 0x3f, 0x5e, 0x6b, 0x78, 0x51, 0x85, 0xea, 0x0f, 0x47, 0xad, 0x4d, 0x24, 0x02, 0x33, 0x28, 0xb2, - 0x09, 0x76, 0xc0, 0x64, 0xad, 0x60, 0xc2, 0xdd, 0xa8, 0x42, 0xf5, 0x63, 0xe6, 0xb3, 0xa9, 0xa2, - 0xdc, 0x66, 0xfc, 0xa7, 0x60, 0xd8, 0xa3, 0xcd, 0x14, 0x1b, 0xe6, 0x8b, 0x2a, 0x34, 0x2c, 0x8f, - 0x1c, 0xdc, 0x8b, 0x98, 0x74, 0x07, 0xf4, 0xd5, 0x0f, 0x8d, 0x8d, 0x32, 0x21, 0xd9, 0xbd, 0x13, - 0xac, 0xd1, 0x98, 0x2a, 0x91, 0xe4, 0xf5, 0x9c, 0x08, 0x65, 0x35, 0x33, 0x49, 0xb6, 0x1c, 0x52, - 0x66, 0x4e, 0x84, 0xa2, 0x4e, 0xfe, 0x24, 0xd6, 0xf7, 0xb1, 0x53, 0xd1, 0xae, 0x84, 0xca, 0x8a, - 0xa6, 0xd4, 0x5c, 0x09, 0x4d, 0xa9, 0x48, 0x92, 0xbb, 0xd9, 0xa3, 0xa9, 0x56, 0x29, 0xf9, 0x47, - 0xcb, 0x8a, 0x8e, 0x09, 0x75, 0xbd, 0x1b, 0xc6, 0xf6, 0xa8, 0xeb, 0x15, 0xed, 0x1b, 0x2d, 0x0f, - 0x53, 0xb7, 0x12, 0xfa, 0xc6, 0xf5, 0x12, 0x38, 0xce, 0x77, 0x5d, 0x09, 0xbd, 0xea, 0x38, 0xb1, - 0xcb, 0x74, 0xd7, 0x48, 0x76, 0x45, 0x09, 0x6d, 0xa1, 0xa3, 0x56, 0xb5, 0xc7, 0x65, 0x95, 0x24, - 0x73, 0x1d, 0x26, 0x7e, 0x25, 0x2f, 0xe9, 0xfd, 0x03, 0xef, 0xa3, 0x34, 0x3e, 0xf1, 0x06, 0x54, - 0x8c, 0xb3, 0x08, 0x8c, 0x7f, 0x85, 0x26, 0x59, 0x30, 0xde, 0xf0, 0xc7, 0x04, 0xd4, 0xa1, 0xeb, - 0xae, 0x0a, 0xf4, 0x5f, 0x9c, 0x71, 0xf6, 0xe2, 0x7c, 0xa9, 0x06, 0xb4, 0xcf, 0x7e, 0xad, 0x9f, - 0xaa, 0x6e, 0x17, 0x89, 0xeb, 0xe1, 0x18, 0x7a, 0x62, 0xc1, 0x22, 0xea, 0xd6, 0x07, 0x7d, 0xa6, - 0xf6, 0x23, 0x93, 0xd3, 0xa1, 0x4f, 0x16, 0x69, 0x1f, 0x14, 0x21, 0xf0, 0xa8, 0x2e, 0x32, 0x72, - 0x1d, 0xb6, 0xc5, 0x3c, 0x08, 0x9a, 0x7f, 0x27, 0x24, 0x09, 0x03, 0xb3, 0x83, 0x83, 0x71, 0xb6, - 0x5b, 0x98, 0x3f, 0x27, 0xb2, 0x98, 0xb0, 0x89, 0x24, 0xdb, 0x0e, 0x1f, 0xa1, 0x15, 0x86, 0xdc, - 0x09, 0xfa, 0x89, 0x08, 0x7d, 0x4e, 0xdc, 0x8a, 0xb0, 0xba, 0x4e, 0xc7, 0xe3, 0x14, 0xda, 0xcd, - 0xfc, 0x8d, 0x30, 0xe4, 0x62, 0x9d, 0x0a, 0xb2, 0x25, 0xa3, 0x68, 0x3e, 0x84, 0xd9, 0x6f, 0x26, - 0x1c, 0x80, 0x49, 0xb6, 0x3c, 0x29, 0xf7, 0x53, 0x5c, 0x7e, 0xe3, 0xd4, 0x7f, 0x80, 0xc5, 0xe5, - 0xdb, 0x65, 0x5a, 0x72, 0xf4, 0x8d, 0xbc, 0x21, 0xe4, 0x8c, 0x2f, 0x6b, 0xb0, 0xd1, 0x4e, 0xb3, - 0x62, 0xe4, 0xd5, 0x05, 0x14, 0x20, 0x28, 0x0f, 0x64, 0xe5, 0xba, 0x40, 0x7e, 0x18, 0x96, 0xff, - 0x8f, 0x0e, 0x39, 0x1d, 0x02, 0xd3, 0xff, 0xdf, 0xe6, 0x3f, 0x87, 0x98, 0x3c, 0xc9, 0xe6, 0x6a, - 0x0b, 0xe2, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXToggle3DIcon3x[] = { - - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x48, 0x08, 0x06, 0x00, 0x00, 0x00, 0x41, 0x78, 0x2d, - 0xa6, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x08, 0x00, 0x01, - 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x03, 0xa0, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0xa0, 0x02, - 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3f, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x00, 0xd4, 0x17, 0xf4, 0xd7, 0x00, 0x00, - 0x05, 0xdb, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed, 0x9b, 0x6b, 0x88, 0x55, 0x55, 0x14, 0xc7, - 0xe7, 0xaa, 0x4d, 0x0f, 0xad, 0xc8, 0xc0, 0x40, 0x8b, 0xc8, 0x9a, 0x84, 0x94, 0x6a, 0xb4, 0x82, - 0x0c, 0x7a, 0x9a, 0x45, 0x61, 0xfa, 0x41, 0xac, 0xc0, 0x40, 0x89, 0x04, 0x7b, 0x88, 0x69, 0x85, - 0x86, 0x0a, 0x12, 0x98, 0x1f, 0xb4, 0xec, 0x21, 0x41, 0xd6, 0x87, 0x1e, 0x16, 0x15, 0x22, 0x96, - 0x54, 0x16, 0x95, 0xd4, 0x60, 0x94, 0x20, 0x41, 0x25, 0x43, 0x06, 0x62, 0x08, 0x9a, 0x4c, 0x96, - 0xe2, 0xa3, 0xb2, 0x71, 0xfa, 0xfd, 0xc7, 0xee, 0x78, 0xef, 0x3d, 0x8f, 0xbd, 0xf7, 0x79, 0xec, - 0x73, 0x9a, 0x99, 0x05, 0x3f, 0xe6, 0x9c, 0xbd, 0xd7, 0x5e, 0x6b, 0xfd, 0xef, 0xde, 0xe7, 0x71, - 0xef, 0x39, 0x53, 0x69, 0x2a, 0xd0, 0xba, 0xba, 0xba, 0x4e, 0x23, 0xfd, 0x0d, 0x30, 0x02, 0xda, - 0x2b, 0x95, 0xca, 0x96, 0x02, 0xcb, 0xf1, 0x93, 0x5a, 0xa2, 0x61, 0x01, 0xec, 0x83, 0x5a, 0x7b, - 0x9f, 0x9d, 0x81, 0x7e, 0xaa, 0x28, 0x20, 0x0b, 0xe2, 0xa6, 0xc2, 0x4e, 0x88, 0xb2, 0xd9, 0x05, - 0x94, 0x95, 0x6f, 0x4a, 0x94, 0x5e, 0x09, 0x9b, 0xa3, 0x14, 0xd7, 0xb4, 0xbf, 0x93, 0x6f, 0x25, - 0x1e, 0xa3, 0x23, 0x6a, 0x18, 0xbc, 0x0c, 0x9d, 0x35, 0x02, 0xa3, 0x36, 0x7f, 0xa2, 0xe3, 0x36, - 0x8f, 0xe5, 0xe5, 0x93, 0x0a, 0x11, 0xcd, 0x30, 0x1f, 0x0e, 0x80, 0xc9, 0xe4, 0xf3, 0x18, 0x9c, - 0x92, 0x4f, 0x35, 0x1e, 0xa3, 0x22, 0x62, 0x12, 0x68, 0x16, 0x4d, 0xa6, 0xd5, 0xb0, 0x06, 0x86, - 0x79, 0x2c, 0x2f, 0x9f, 0x54, 0x88, 0x18, 0x0d, 0x9f, 0x80, 0x8d, 0x7d, 0x89, 0x53, 0xab, 0x6b, - 0x25, 0x8c, 0x69, 0x81, 0x3b, 0x61, 0x2c, 0x14, 0x7f, 0x65, 0xa0, 0x88, 0xa1, 0xf0, 0x02, 0xfc, - 0x03, 0x26, 0xdb, 0x85, 0xc3, 0xb4, 0x04, 0xa2, 0x27, 0x33, 0xee, 0x9b, 0x86, 0xe0, 0x5b, 0xd9, - 0x1f, 0xee, 0x1a, 0x2b, 0x13, 0x7f, 0x12, 0x0f, 0x82, 0x47, 0x60, 0x3f, 0x98, 0xec, 0x30, 0x0e, - 0x4b, 0xe0, 0x74, 0x97, 0xe4, 0xf8, 0x8f, 0x81, 0x4f, 0x21, 0xca, 0xde, 0x76, 0x89, 0x97, 0x89, - 0x2f, 0x95, 0x4c, 0x84, 0x1f, 0xa3, 0x2a, 0x6a, 0x68, 0x5f, 0xcb, 0xfe, 0xf9, 0x2e, 0x89, 0xf1, - 0x3f, 0x17, 0x56, 0x83, 0x69, 0x35, 0xed, 0x77, 0x89, 0x9b, 0xca, 0x97, 0x62, 0x2e, 0x85, 0x0f, - 0xc0, 0xc6, 0xb4, 0x2c, 0xc7, 0xbb, 0x24, 0xc4, 0x5f, 0xab, 0x69, 0x0e, 0xd8, 0xac, 0xa6, 0xbf, - 0xf1, 0x5b, 0x01, 0x15, 0x97, 0x1c, 0xce, 0xbe, 0x24, 0x38, 0x1b, 0x56, 0x82, 0x12, 0x9a, 0x6c, - 0x0f, 0x0e, 0x33, 0xc1, 0xa9, 0x28, 0xfc, 0x5d, 0x56, 0x93, 0x26, 0xa0, 0xc5, 0x59, 0x88, 0xcb, - 0x00, 0x12, 0x0c, 0x80, 0x59, 0xd0, 0x78, 0x1f, 0x4e, 0x53, 0xc0, 0xfe, 0xa4, 0x65, 0x39, 0x9c, - 0xe9, 0x98, 0x43, 0x67, 0x70, 0xdb, 0xd5, 0xb4, 0x1d, 0xdf, 0xfc, 0x6f, 0x84, 0x48, 0x72, 0x23, - 0x7c, 0x07, 0x36, 0xb6, 0x1e, 0xa7, 0x8b, 0x1d, 0x45, 0x6b, 0x35, 0x69, 0xd9, 0xda, 0xac, 0x26, - 0x1d, 0x06, 0x3a, 0xb9, 0x0e, 0x72, 0xc9, 0xe1, 0xec, 0x4b, 0x82, 0x8b, 0x60, 0x1d, 0xd8, 0xd8, - 0xf7, 0x38, 0xdd, 0xe2, 0x92, 0x04, 0x7f, 0xad, 0xa6, 0x07, 0xe0, 0x57, 0x30, 0x99, 0x4e, 0x78, - 0x2f, 0xc2, 0x50, 0x97, 0x1c, 0xf2, 0x65, 0xcc, 0x10, 0x98, 0x0b, 0x1b, 0xa1, 0x1d, 0x34, 0x41, - 0x13, 0x43, 0xe3, 0xd0, 0xa1, 0x93, 0xcd, 0x42, 0x38, 0x0a, 0x26, 0xeb, 0xc0, 0xe1, 0x21, 0x70, - 0xba, 0xd1, 0xc0, 0xff, 0x7a, 0xd8, 0x06, 0x36, 0xa6, 0x4b, 0xdc, 0x98, 0xd0, 0x62, 0x63, 0x1a, - 0x19, 0x73, 0x06, 0xe8, 0xb2, 0xfa, 0x3b, 0x34, 0xda, 0x31, 0x1a, 0xa6, 0xd4, 0x0d, 0xa7, 0x41, - 0x9f, 0xd2, 0x96, 0x46, 0xcf, 0x90, 0x7d, 0x0d, 0x7e, 0x1e, 0xce, 0xa9, 0x0b, 0x60, 0xd8, 0xc1, - 0xff, 0x42, 0x78, 0x17, 0x6c, 0x6c, 0x07, 0x4e, 0x93, 0x0d, 0x21, 0x43, 0xbb, 0x19, 0x77, 0x0f, - 0xfc, 0x62, 0x48, 0xf2, 0x43, 0xdd, 0x60, 0x9c, 0xdf, 0x34, 0x0c, 0x50, 0xf7, 0x26, 0xb8, 0xac, - 0x6e, 0xa0, 0x61, 0x07, 0xff, 0xc1, 0xf0, 0x14, 0xd8, 0xac, 0x26, 0x7d, 0xc1, 0x79, 0x1c, 0x9a, - 0x0d, 0x61, 0x03, 0xdd, 0x8c, 0x19, 0x07, 0x6d, 0x60, 0x6b, 0x63, 0xbb, 0x83, 0xe0, 0xad, 0x65, - 0x72, 0x24, 0x66, 0x94, 0x66, 0x62, 0x52, 0x20, 0x63, 0x4c, 0x03, 0xfe, 0x15, 0x98, 0x0e, 0xbb, - 0xc1, 0x64, 0xfa, 0x82, 0xf3, 0x0a, 0x9c, 0x17, 0x13, 0x32, 0xb4, 0x4b, 0x63, 0xe0, 0x55, 0x38, - 0x0e, 0x2e, 0x36, 0xb5, 0x3b, 0x20, 0x23, 0x46, 0xc5, 0x8c, 0x7a, 0x9a, 0x3e, 0xa7, 0x99, 0xc0, - 0xff, 0x1a, 0xf8, 0x3a, 0x26, 0x66, 0x6d, 0xd7, 0x57, 0xec, 0x9c, 0x98, 0x85, 0x50, 0x79, 0xe1, - 0x8d, 0x8c, 0x69, 0x86, 0x27, 0xe0, 0x20, 0x24, 0xb1, 0x39, 0x55, 0xf1, 0x57, 0x45, 0x8c, 0x7e, - 0x26, 0x3c, 0x75, 0x78, 0x2b, 0x31, 0x86, 0xc3, 0x6b, 0x60, 0x33, 0x0b, 0xbb, 0xf0, 0xbb, 0x3b, - 0x3c, 0x52, 0x7c, 0x2b, 0xe3, 0xee, 0x02, 0xad, 0xc6, 0x34, 0xb6, 0xa8, 0x7a, 0xcd, 0x3c, 0x35, - 0x22, 0x5d, 0x5b, 0x44, 0x7b, 0x5d, 0x33, 0x15, 0xe8, 0x57, 0xd8, 0x79, 0xf0, 0x24, 0x0c, 0xae, - 0xeb, 0x0c, 0xee, 0x1c, 0xa1, 0x69, 0x39, 0xac, 0xe0, 0xd7, 0xda, 0xa3, 0xc1, 0xee, 0xe8, 0x16, - 0xf2, 0x8c, 0xa6, 0xf7, 0x59, 0xb8, 0x35, 0xda, 0xcb, 0xbe, 0xa7, 0x2a, 0x3e, 0x6a, 0x44, 0x47, - 0x54, 0x47, 0xb5, 0x9d, 0x82, 0x6e, 0x62, 0x7b, 0x0d, 0xd8, 0xdc, 0xe0, 0xac, 0xc5, 0x6f, 0x01, - 0xa2, 0x77, 0x57, 0xc7, 0xdb, 0xfc, 0x25, 0x87, 0xae, 0xf1, 0x4b, 0x41, 0x3f, 0x6e, 0x3a, 0x5d, - 0x5a, 0xe3, 0xe2, 0x0f, 0x88, 0xeb, 0x34, 0xf5, 0x51, 0x94, 0x0a, 0xfa, 0x1c, 0x4c, 0xc2, 0xb7, - 0xe2, 0x33, 0x1e, 0xd1, 0xd3, 0x5d, 0x84, 0x13, 0x5f, 0xf7, 0x1d, 0x0f, 0x33, 0x76, 0x07, 0xe8, - 0x6f, 0x66, 0xc2, 0x89, 0xd5, 0x64, 0x9a, 0x79, 0xf9, 0x84, 0x1a, 0x45, 0xdd, 0x4b, 0xc7, 0x92, - 0xd0, 0xce, 0x93, 0x8d, 0x7b, 0xd8, 0x5c, 0x08, 0xaf, 0x23, 0xba, 0xeb, 0x64, 0xb3, 0x79, 0x8b, - 0xf8, 0x13, 0xf0, 0x5a, 0x05, 0x5a, 0xea, 0x79, 0x58, 0x25, 0xb1, 0x78, 0xaa, 0x99, 0x19, 0x53, - 0xd1, 0x5f, 0xf4, 0xe9, 0x64, 0xb9, 0x0c, 0xd1, 0x87, 0x62, 0xfc, 0x02, 0x5d, 0x88, 0xd6, 0x2a, - 0x5a, 0x09, 0x89, 0x6e, 0x72, 0x02, 0x01, 0x63, 0x1a, 0xd2, 0x88, 0x8f, 0xba, 0xed, 0xdc, 0x44, - 0xbe, 0xd9, 0x88, 0xde, 0x19, 0x93, 0x37, 0xd0, 0x85, 0x68, 0x7d, 0x13, 0x5c, 0x04, 0x73, 0xc1, - 0xe9, 0xd2, 0x1a, 0x08, 0x66, 0xd9, 0x90, 0x46, 0x7c, 0xd8, 0xd7, 0xd6, 0x6f, 0xc9, 0x7b, 0x07, - 0xc2, 0x8f, 0x5b, 0xe6, 0xd7, 0x97, 0x0f, 0x9d, 0x77, 0x66, 0xc0, 0x32, 0x70, 0xbe, 0xc9, 0x61, - 0x4c, 0x62, 0x4b, 0x23, 0x3e, 0xec, 0xb7, 0xb8, 0x36, 0x47, 0xe1, 0xd7, 0x51, 0xf9, 0x73, 0x30, - 0x2e, 0xb1, 0x82, 0xe4, 0x03, 0x53, 0x1d, 0xf3, 0x61, 0x69, 0x75, 0xac, 0x1b, 0x8d, 0xd9, 0x1e, - 0x82, 0x93, 0x4e, 0x66, 0xf7, 0x1b, 0x9d, 0x73, 0x74, 0x48, 0x33, 0xf3, 0x89, 0xca, 0x42, 0xf8, - 0x28, 0x06, 0x7e, 0x08, 0x23, 0x13, 0x05, 0xc8, 0x70, 0x50, 0xaa, 0xeb, 0xbc, 0x6b, 0x1d, 0x08, - 0xd7, 0xcd, 0xca, 0x46, 0x28, 0x5c, 0xb8, 0x6a, 0xf7, 0x2a, 0x9e, 0x7c, 0xf3, 0xe1, 0x12, 0x25, - 0x2e, 0x81, 0x55, 0x7c, 0x8b, 0xbf, 0xaf, 0x04, 0xa2, 0x7b, 0x4a, 0xf0, 0x26, 0x9e, 0x25, 0x7f, - 0x16, 0x59, 0x2f, 0xe8, 0xc9, 0x5c, 0x82, 0x0d, 0x6f, 0xe2, 0xd1, 0x5a, 0xba, 0x27, 0xb1, 0x3e, - 0xc5, 0x87, 0xdd, 0x14, 0x15, 0x39, 0xff, 0xde, 0x8f, 0xf9, 0x22, 0xc5, 0x06, 0x72, 0xfb, 0x9c, - 0xf9, 0x40, 0xf2, 0xa2, 0x1b, 0xfa, 0xc5, 0x17, 0x3d, 0x03, 0x05, 0xe5, 0xef, 0x3f, 0xe6, 0x0b, - 0xfa, 0xe0, 0x8b, 0x4f, 0xdb, 0x7f, 0xcc, 0x17, 0x3f, 0x07, 0x85, 0x54, 0xd0, 0x7f, 0xcc, 0x17, - 0xf2, 0xb1, 0x97, 0x21, 0x69, 0x5f, 0x3e, 0xe6, 0x3b, 0xfb, 0xb2, 0xf8, 0xdf, 0xfa, 0xb2, 0xf8, - 0xbd, 0x55, 0xf1, 0x07, 0xca, 0x70, 0x0c, 0x7a, 0xac, 0xe1, 0x18, 0xb9, 0xbe, 0xa8, 0x8a, 0x77, - 0x7a, 0xc0, 0xe0, 0xb1, 0xc8, 0xbc, 0x52, 0xad, 0xe3, 0x27, 0xf6, 0x13, 0xcb, 0x9e, 0x8d, 0xc3, - 0x64, 0xd9, 0x9c, 0x57, 0xa6, 0x92, 0xc5, 0x6d, 0xa7, 0x1e, 0x3d, 0xed, 0xad, 0xfb, 0x01, 0x73, - 0x31, 0xfb, 0x56, 0xbf, 0xbb, 0x6b, 0xe0, 0xff, 0xd4, 0xf4, 0x28, 0xed, 0x66, 0x26, 0xfb, 0x0f, - 0xd5, 0x5f, 0x5d, 0xf6, 0x4d, 0x34, 0xb4, 0xb1, 0x3f, 0x01, 0xd6, 0x83, 0xde, 0x56, 0xd2, 0x33, - 0xf7, 0xed, 0xd0, 0x1b, 0xac, 0x03, 0x11, 0xb3, 0xd0, 0x78, 0x3b, 0xe8, 0xc9, 0x71, 0xb7, 0xd5, - 0x3d, 0xb4, 0xf8, 0xef, 0x03, 0xd0, 0x87, 0xd0, 0x5b, 0x4c, 0x27, 0xb6, 0xd5, 0xb0, 0x14, 0x6d, - 0xdd, 0xb3, 0x5d, 0x2b, 0xac, 0x4e, 0x7c, 0x6d, 0x47, 0x2f, 0xd8, 0xfe, 0x08, 0x0d, 0xf3, 0x10, - 0xad, 0x63, 0x3c, 0xd4, 0x7a, 0x96, 0x7d, 0x68, 0x6f, 0x7c, 0xe3, 0xc1, 0xf8, 0xee, 0xc2, 0x7a, - 0x25, 0x56, 0x4f, 0x8a, 0x45, 0xa4, 0x70, 0x55, 0x97, 0x46, 0x7c, 0xd9, 0x2e, 0x8f, 0x5a, 0xd6, - 0x8f, 0xc2, 0xe5, 0x88, 0xd6, 0xac, 0x1b, 0x2d, 0x8d, 0xf8, 0x8f, 0x8d, 0xd1, 0xfd, 0x38, 0x74, - 0x92, 0xe6, 0x25, 0x68, 0x41, 0xf4, 0x2a, 0xd0, 0x71, 0x6e, 0x65, 0x69, 0xc4, 0xeb, 0x11, 0xf3, - 0x3e, 0xab, 0x2c, 0xf9, 0x39, 0x7d, 0x46, 0xe8, 0x56, 0x04, 0x3f, 0x08, 0x3a, 0xa3, 0xfb, 0x33, - 0x1e, 0x41, 0x8d, 0x84, 0x0d, 0xa0, 0x57, 0x4c, 0xdf, 0x83, 0x6b, 0xa3, 0xb2, 0xd3, 0xd7, 0x0a, - 0x59, 0xd9, 0xcf, 0x04, 0x9a, 0x12, 0x95, 0xab, 0x74, 0xed, 0x14, 0x9b, 0x85, 0x78, 0xbd, 0x6a, - 0xaa, 0x57, 0x4e, 0xbd, 0xbc, 0xb3, 0x93, 0xd9, 0x87, 0x48, 0xc1, 0x57, 0x40, 0x52, 0xd3, 0x8b, - 0xc9, 0x7a, 0xb9, 0xd8, 0xeb, 0x3b, 0x3b, 0x59, 0x8a, 0xd7, 0x7b, 0xb9, 0x49, 0x2c, 0xd1, 0x8b, - 0xc9, 0x99, 0x15, 0x9e, 0x45, 0x20, 0x54, 0x0f, 0x04, 0xcd, 0xa0, 0xad, 0xe9, 0xc5, 0xe4, 0x69, - 0x59, 0xe4, 0x2e, 0x45, 0x0c, 0xc4, 0xd8, 0xbc, 0x86, 0x7e, 0x08, 0xbf, 0xc5, 0x10, 0xf6, 0xb6, - 0x57, 0x29, 0x74, 0x24, 0x2a, 0x02, 0x41, 0x33, 0x20, 0xca, 0xf4, 0x9a, 0xfa, 0x1b, 0x30, 0x22, - 0x51, 0xf0, 0xb2, 0x0f, 0x42, 0x98, 0xfe, 0xfb, 0x42, 0xff, 0x22, 0x5a, 0x6b, 0xfa, 0x9f, 0x9d, - 0xb7, 0xa0, 0xd5, 0x77, 0xfd, 0x15, 0xdf, 0x09, 0x95, 0x0f, 0xa1, 0x7a, 0x99, 0xf8, 0x6a, 0xd8, - 0x0b, 0xdb, 0xb8, 0x41, 0x29, 0xfa, 0x66, 0x89, 0x32, 0xfa, 0x98, 0xfd, 0x0b, 0x55, 0xca, 0x1e, - 0xf8, 0x6a, 0x59, 0xc9, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, - 0x82 -}; - -static const u_int8_t FLEXRangeSliderLeftHandle2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x50, 0x08, 0x06, 0x00, 0x00, 0x00, 0x56, 0x1d, 0x56, - 0xa7, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, - 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0xa0, 0x03, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x7d, 0xa9, - 0x20, 0x00, 0x00, 0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, - 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, - 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, - 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, - 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, - 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, - 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, - 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, - 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x05, 0xdc, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, - 0xed, 0x9b, 0xbf, 0x4b, 0x64, 0x57, 0x14, 0xc7, 0x57, 0x67, 0xc6, 0xf9, 0xa1, 0x93, 0x15, 0xc6, - 0x8c, 0x1b, 0x62, 0x58, 0x90, 0x14, 0x59, 0x48, 0x0a, 0x2d, 0x22, 0x08, 0x01, 0x21, 0x76, 0x0a, - 0x81, 0x84, 0x80, 0xff, 0x40, 0xfe, 0x01, 0x6d, 0xad, 0x6c, 0x83, 0x18, 0xb0, 0x4c, 0xb0, 0xd9, - 0x40, 0x8a, 0x14, 0x82, 0xa9, 0x84, 0x04, 0x41, 0x48, 0x2c, 0xc4, 0xc2, 0x22, 0x5b, 0x98, 0x42, - 0x2c, 0x8c, 0x18, 0x2d, 0x74, 0x57, 0x9c, 0xd1, 0x71, 0xc6, 0xdc, 0xef, 0xb8, 0x5f, 0x39, 0x39, - 0xb9, 0xef, 0xd7, 0x38, 0xf3, 0xbc, 0xee, 0xce, 0x85, 0xeb, 0x39, 0xf7, 0xdc, 0x73, 0xcf, 0x39, - 0x9f, 0x77, 0x9e, 0x6f, 0x5c, 0xde, 0xec, 0xa3, 0x47, 0x6f, 0xd8, 0xe8, 0x68, 0x01, 0x4f, 0x2b, - 0x62, 0x86, 0x2e, 0xb3, 0x19, 0xc9, 0x1b, 0x8d, 0xd1, 0xe8, 0x39, 0xc2, 0x5d, 0x53, 0x91, 0xb2, - 0xd1, 0xa0, 0x61, 0xce, 0x85, 0xf1, 0x91, 0xb5, 0x34, 0x45, 0x8f, 0x9a, 0x34, 0xc8, 0xdf, 0xb6, - 0x6f, 0xb3, 0xe9, 0xe2, 0xc3, 0xf8, 0xf0, 0x8c, 0xb5, 0x33, 0xaf, 0x37, 0xaf, 0xa3, 0x04, 0xf2, - 0xf2, 0xd5, 0x76, 0xb9, 0x4e, 0x9a, 0x44, 0x98, 0xb0, 0x61, 0x26, 0xcc, 0x6c, 0xf6, 0x90, 0x80, - 0x52, 0xf7, 0xcd, 0xc3, 0x82, 0xb4, 0xec, 0x34, 0xa7, 0x38, 0x51, 0x2c, 0x66, 0xca, 0xcc, 0xee, - 0xd1, 0xd1, 0xd1, 0xe2, 0xf6, 0xf6, 0xf6, 0x57, 0x27, 0x27, 0x27, 0xdf, 0x97, 0x4a, 0xa5, 0xf5, - 0xcb, 0xcb, 0xcb, 0xbf, 0x6a, 0xb5, 0xda, 0xab, 0xeb, 0x16, 0x0f, 0x93, 0x3b, 0x70, 0x68, 0x08, - 0xac, 0x09, 0x01, 0x29, 0x41, 0xf2, 0x8b, 0x8b, 0x8b, 0x1f, 0x19, 0x88, 0x1f, 0xaa, 0xd5, 0xea, - 0xcb, 0x16, 0xd7, 0x6e, 0x0d, 0x1f, 0x44, 0xe3, 0x07, 0x43, 0x10, 0xdc, 0x52, 0x99, 0xb1, 0xb1, - 0xb1, 0x27, 0x87, 0x87, 0x87, 0xdf, 0x9a, 0x2e, 0x9c, 0x59, 0x33, 0xc5, 0x64, 0xf4, 0x03, 0x0a, - 0x82, 0xe1, 0xef, 0x47, 0xf7, 0xc2, 0xc2, 0xc2, 0xb3, 0xf3, 0xf3, 0xf3, 0xcd, 0x98, 0x6a, 0xf6, - 0x4d, 0xe3, 0x05, 0x14, 0x06, 0x06, 0xbf, 0x2b, 0xf9, 0xe5, 0xe5, 0xe5, 0xb1, 0x4a, 0xa5, 0xb2, - 0xef, 0x9b, 0x25, 0xc6, 0x4d, 0x1b, 0x50, 0x58, 0x98, 0xdc, 0xdc, 0xdc, 0xdc, 0x27, 0x17, 0x17, - 0x17, 0x7f, 0xc7, 0x58, 0x6f, 0x60, 0xaa, 0x30, 0x40, 0x7c, 0x00, 0xe0, 0x77, 0x06, 0xb7, 0x19, - 0x3a, 0x93, 0x1d, 0x1a, 0x1a, 0x7a, 0x7a, 0x76, 0x76, 0xb6, 0x15, 0x98, 0x21, 0x66, 0x07, 0x0d, - 0xa4, 0xbb, 0x63, 0x83, 0x49, 0x9b, 0x43, 0x7d, 0x7b, 0x7b, 0x7b, 0xdf, 0xc5, 0x5c, 0x6b, 0xa8, - 0x74, 0x28, 0x38, 0x68, 0x68, 0xc8, 0xae, 0x99, 0x99, 0x99, 0xa7, 0x03, 0x03, 0x03, 0xdf, 0x04, - 0x1d, 0x74, 0x61, 0x5f, 0x16, 0xaf, 0xbb, 0xd3, 0x65, 0x0a, 0xcc, 0x9a, 0xf9, 0x64, 0x7f, 0x7f, - 0xff, 0xc7, 0x50, 0x97, 0xeb, 0x1e, 0x9c, 0x64, 0x87, 0x00, 0xa3, 0x87, 0x04, 0x84, 0x9e, 0x1c, - 0x1c, 0x1c, 0x7c, 0xa7, 0xbf, 0xbf, 0xff, 0x0b, 0xed, 0xe8, 0xca, 0x5a, 0x02, 0xc9, 0x9a, 0x24, - 0x1c, 0xa1, 0xe0, 0x9b, 0x99, 0x9f, 0x9f, 0xff, 0x2c, 0x91, 0x48, 0xf4, 0x48, 0x67, 0x97, 0x74, - 0x2f, 0x20, 0xd4, 0x48, 0x10, 0xea, 0x78, 0xca, 0xe1, 0xe9, 0xf6, 0x39, 0x0c, 0xae, 0x0e, 0x1b, - 0x90, 0xad, 0x3b, 0xb0, 0x01, 0x28, 0x9d, 0xcf, 0xe7, 0x3f, 0x74, 0x15, 0x06, 0x75, 0x11, 0x48, - 0x42, 0xc0, 0xae, 0xbb, 0x03, 0xbf, 0xfa, 0xe7, 0x50, 0x26, 0x93, 0x29, 0xc2, 0xc1, 0xd5, 0x41, - 0x20, 0xaf, 0xfa, 0x08, 0xc6, 0x0e, 0xa5, 0xd2, 0xe9, 0xf4, 0xbb, 0x5e, 0xce, 0x2e, 0xd8, 0x35, - 0x90, 0xec, 0x94, 0xd6, 0xeb, 0x5d, 0x32, 0x0f, 0x84, 0x9c, 0x0b, 0x85, 0x7b, 0xd5, 0xa0, 0x81, - 0xe8, 0x47, 0x18, 0x48, 0x4c, 0xf8, 0x71, 0xd2, 0xc7, 0x49, 0x69, 0x03, 0x22, 0x0c, 0x0b, 0xe6, - 0x1a, 0xbe, 0xd4, 0xb9, 0xe7, 0x9c, 0xb4, 0x01, 0xb1, 0x48, 0x14, 0x4f, 0x00, 0xea, 0x5c, 0xd3, - 0xc7, 0x39, 0xe9, 0x07, 0xc4, 0x62, 0x9d, 0x87, 0x60, 0xa1, 0x90, 0x5e, 0x40, 0x1a, 0xe2, 0x8d, - 0xe8, 0x10, 0x21, 0xe4, 0x05, 0x70, 0x5e, 0xf7, 0xea, 0x90, 0x2c, 0x5c, 0x77, 0x4b, 0xee, 0x39, - 0xa7, 0x87, 0x01, 0x42, 0xd1, 0x84, 0xa2, 0x74, 0x0e, 0x84, 0x05, 0x49, 0xa0, 0xa0, 0x62, 0x83, - 0xf6, 0x19, 0xf3, 0x5e, 0xa5, 0x04, 0x62, 0x21, 0x0f, 0xa2, 0x70, 0x16, 0xab, 0xa5, 0x0d, 0x48, - 0xfb, 0x3c, 0xa8, 0x75, 0x1b, 0xc8, 0xf5, 0x76, 0xb5, 0x3b, 0xd4, 0xee, 0x50, 0xcc, 0x57, 0xa0, - 0x7d, 0xcb, 0xc5, 0x7c, 0xc1, 0x23, 0xa7, 0x6b, 0x77, 0x28, 0xf2, 0x25, 0x8b, 0xf9, 0x40, 0xbb, - 0x43, 0x31, 0x5f, 0xf0, 0xc8, 0xe9, 0xda, 0x1d, 0x32, 0xaf, 0xeb, 0xcf, 0x23, 0x5f, 0xb6, 0x18, - 0x0f, 0x44, 0xed, 0xd0, 0x75, 0xb9, 0x5c, 0x3e, 0x8e, 0xb1, 0xbe, 0xc8, 0xa9, 0x6c, 0x40, 0x5e, - 0x5f, 0x2f, 0x81, 0xbd, 0x66, 0x5e, 0xdf, 0x3f, 0x18, 0x20, 0x2f, 0x10, 0x5c, 0xa5, 0x3a, 0x0c, - 0x80, 0x8e, 0x8f, 0x8f, 0xf7, 0x60, 0x70, 0x75, 0xd8, 0x3a, 0x64, 0xab, 0x15, 0x40, 0x98, 0x57, - 0x6b, 0x6b, 0x6b, 0x7f, 0xd8, 0x1c, 0x5c, 0xb1, 0xf1, 0x9f, 0xdb, 0x52, 0x42, 0x07, 0xa8, 0x9c, - 0x78, 0x9d, 0x8f, 0xf7, 0xab, 0xbd, 0x7d, 0x7d, 0x7d, 0xef, 0x1d, 0x1c, 0x1c, 0xfc, 0x92, 0x4c, - 0x26, 0xbb, 0xcd, 0xda, 0xb9, 0xe1, 0xd7, 0x21, 0x76, 0x05, 0x45, 0xf3, 0x96, 0xbb, 0x32, 0xb7, - 0x5c, 0x79, 0x67, 0x67, 0xe7, 0x57, 0xe7, 0x48, 0x5e, 0x17, 0xe4, 0x05, 0x04, 0x00, 0x39, 0xb0, - 0xae, 0x9a, 0x59, 0x31, 0xb3, 0x34, 0x3d, 0x3d, 0xfd, 0xdc, 0x3c, 0xbe, 0x4b, 0xd2, 0xc1, 0x15, - 0xdd, 0x0b, 0x48, 0xd6, 0x47, 0xb8, 0x9a, 0x31, 0x5e, 0x99, 0x59, 0x59, 0x5d, 0x5d, 0xfd, 0x67, - 0x6b, 0x6b, 0xeb, 0x67, 0xe9, 0xe4, 0x8a, 0xee, 0x07, 0x04, 0x10, 0xc2, 0x40, 0x02, 0x08, 0x1d, - 0x2a, 0x9b, 0x59, 0x9a, 0x9c, 0x9c, 0xfc, 0xc9, 0xdc, 0x7e, 0x2f, 0x8c, 0xee, 0xd4, 0xb0, 0x01, - 0x11, 0x82, 0x85, 0x72, 0x0d, 0x89, 0xdb, 0xee, 0xd2, 0xcc, 0xd2, 0xd1, 0xd1, 0xd1, 0xcb, 0xa9, - 0xa9, 0xa9, 0x39, 0xf3, 0xb9, 0x74, 0x44, 0x47, 0x17, 0x24, 0x5e, 0x04, 0x63, 0xc8, 0xa7, 0xdc, - 0x8d, 0xe5, 0xbf, 0x36, 0xec, 0x4b, 0x1f, 0xe8, 0x89, 0xdd, 0xdd, 0xdd, 0xca, 0xe9, 0xe9, 0xe9, - 0x9f, 0xe6, 0xcb, 0x7f, 0x9f, 0xa6, 0x52, 0x29, 0x27, 0x9e, 0x7a, 0x1a, 0x08, 0x30, 0xb6, 0xe2, - 0x69, 0xd3, 0x50, 0x1d, 0x9b, 0x9b, 0x9b, 0xaf, 0x36, 0x36, 0x36, 0x7e, 0x9f, 0x98, 0x98, 0x78, - 0x96, 0xcb, 0xe5, 0xee, 0xfd, 0x85, 0xb2, 0x2c, 0x10, 0x30, 0x18, 0xb2, 0x78, 0xe8, 0xb8, 0x2d, - 0x39, 0x71, 0x01, 0xea, 0xaf, 0xf7, 0x8d, 0xc4, 0xe7, 0x52, 0xde, 0x4c, 0x74, 0x26, 0x57, 0x28, - 0x14, 0x1e, 0xaf, 0xac, 0xac, 0x7c, 0x3d, 0x32, 0x32, 0xf2, 0xa5, 0x79, 0xb1, 0x8c, 0xbd, 0x7b, - 0x19, 0xec, 0x10, 0x92, 0x7b, 0xc1, 0x71, 0x8f, 0xa0, 0x2c, 0x14, 0x0f, 0x09, 0x8e, 0x0e, 0xf3, - 0xcd, 0xdf, 0xea, 0xd2, 0xd2, 0xd2, 0x8b, 0xf5, 0xf5, 0xf5, 0xdf, 0x86, 0x87, 0x87, 0xbb, 0x0c, - 0xe0, 0xfb, 0x9d, 0x9d, 0x9d, 0xf8, 0xc2, 0x53, 0xac, 0x83, 0x10, 0x48, 0xaa, 0x75, 0x02, 0x40, - 0xb2, 0x43, 0x90, 0xb8, 0x08, 0x94, 0xf8, 0x32, 0x60, 0xc6, 0x4c, 0xbc, 0xea, 0xc7, 0x84, 0x0e, - 0x5b, 0xba, 0xb7, 0xb7, 0x37, 0x33, 0x3b, 0x3b, 0xfb, 0xf1, 0xf8, 0xf8, 0xf8, 0x48, 0xb1, 0x58, - 0xfc, 0xa0, 0xa7, 0xa7, 0xa7, 0x90, 0xcd, 0x66, 0x0b, 0xe6, 0x2f, 0x8c, 0x96, 0x76, 0x4f, 0x43, - 0x98, 0x5a, 0xea, 0x83, 0x76, 0xc2, 0x50, 0xda, 0xc0, 0x00, 0x80, 0x4e, 0x10, 0x0c, 0x5f, 0x10, - 0xc4, 0x9a, 0x5f, 0xb2, 0x85, 0xc4, 0x79, 0xc6, 0x30, 0xea, 0x9d, 0x86, 0x7c, 0xea, 0x42, 0xc7, - 0x9d, 0xc2, 0x79, 0x85, 0x64, 0xb6, 0x01, 0x47, 0x14, 0x80, 0x61, 0x0b, 0x80, 0x3d, 0xde, 0x72, - 0xf8, 0x6c, 0x62, 0x60, 0x7c, 0xf0, 0x02, 0x88, 0x9d, 0x02, 0x2c, 0xbb, 0x09, 0x29, 0x07, 0xe3, - 0x4b, 0x5b, 0x90, 0xce, 0x5a, 0xe0, 0x07, 0x9d, 0x79, 0x29, 0x2b, 0x12, 0x08, 0x46, 0x9d, 0x04, - 0x36, 0x0e, 0x1e, 0x42, 0x61, 0x84, 0xe1, 0x1e, 0x40, 0x60, 0xe3, 0x9f, 0x47, 0x17, 0x46, 0x07, - 0x0c, 0x26, 0x3b, 0x85, 0x73, 0x88, 0xcf, 0x1c, 0x94, 0xc6, 0x14, 0x69, 0xa0, 0x0e, 0xdb, 0x44, - 0xee, 0xaa, 0x04, 0xd2, 0x51, 0x71, 0x48, 0x26, 0xc5, 0x1a, 0x03, 0x52, 0x03, 0xd5, 0x37, 0xcc, - 0x0f, 0x74, 0x8b, 0x50, 0x88, 0xcd, 0xa7, 0x22, 0xe2, 0x00, 0x88, 0x50, 0x46, 0xbd, 0x1d, 0x32, - 0xc7, 0xad, 0xd1, 0x43, 0x91, 0x35, 0x40, 0xe7, 0x44, 0x3d, 0xf5, 0xe9, 0x07, 0xc4, 0x98, 0x0c, - 0xc2, 0x35, 0x0e, 0xea, 0x2e, 0x31, 0x30, 0xec, 0xd4, 0xe1, 0x47, 0x10, 0x16, 0x8d, 0x7d, 0x0e, - 0xda, 0xb8, 0x0e, 0x2b, 0x59, 0x8f, 0xcc, 0x03, 0xbd, 0x0e, 0x64, 0x0b, 0xaa, 0x6d, 0x5c, 0x43, - 0xca, 0xc9, 0xab, 0x0d, 0x1b, 0x74, 0xae, 0x29, 0xa5, 0x2f, 0x74, 0x0c, 0x2d, 0x6f, 0xac, 0xd1, - 0x7e, 0x6a, 0x20, 0x09, 0x56, 0x63, 0x02, 0x19, 0xd2, 0xcf, 0x86, 0x3d, 0x3d, 0x25, 0x80, 0xd4, - 0xb5, 0x1f, 0x72, 0xc8, 0xd8, 0x52, 0x97, 0xf9, 0x83, 0x74, 0x09, 0x04, 0x5f, 0x74, 0xe6, 0x16, - 0xca, 0x2b, 0xa8, 0xcd, 0x4e, 0x1b, 0x64, 0x23, 0x13, 0xc9, 0x19, 0x03, 0x3a, 0x86, 0x5e, 0xdf, - 0x58, 0xfd, 0x7f, 0x6a, 0x20, 0xc2, 0x40, 0x5a, 0x3b, 0xc4, 0x70, 0xb6, 0x64, 0xb4, 0x41, 0x6a, - 0x9d, 0x36, 0x2d, 0x11, 0x4f, 0xfa, 0xfa, 0xc5, 0xe7, 0x5e, 0x90, 0x94, 0x50, 0xd4, 0xeb, 0x9d, - 0x62, 0x22, 0xaf, 0x00, 0xb6, 0x7d, 0xda, 0xa4, 0xd4, 0xba, 0x5e, 0x23, 0x3e, 0x6d, 0xcc, 0xa5, - 0xd7, 0xb4, 0x87, 0x91, 0x84, 0xf8, 0x9f, 0x0c, 0x13, 0xd4, 0xe6, 0x23, 0x6d, 0xd4, 0x21, 0xa5, - 0x8e, 0xc2, 0xf4, 0x5a, 0xda, 0xa0, 0xdf, 0x75, 0x34, 0x04, 0x84, 0xa4, 0x2c, 0x4c, 0x17, 0x20, - 0xed, 0xd4, 0xb5, 0xb4, 0x9d, 0xa7, 0x8f, 0x8e, 0x17, 0x65, 0x4d, 0x18, 0x9e, 0xa9, 0xaf, 0xa3, - 0x04, 0xf6, 0xf2, 0xd5, 0x76, 0xb9, 0x96, 0xba, 0x0d, 0x8c, 0xc5, 0xdc, 0x45, 0x4a, 0xb0, 0x48, - 0xff, 0x4b, 0x32, 0x4c, 0x41, 0x1a, 0x20, 0xcc, 0x99, 0xb0, 0x3e, 0x84, 0x96, 0x00, 0xb4, 0x51, - 0x46, 0x06, 0xe2, 0x41, 0x5b, 0xe1, 0xdc, 0xa3, 0x0c, 0xe3, 0x43, 0xdf, 0xa6, 0xc9, 0x66, 0x24, - 0x6d, 0x34, 0x46, 0xa3, 0xe7, 0x08, 0x6f, 0xed, 0xd4, 0x5d, 0x83, 0x32, 0xb8, 0x94, 0xad, 0x88, - 0x29, 0xe3, 0xbf, 0x5d, 0xfa, 0xbf, 0x74, 0x7e, 0xdc, 0x6e, 0x66, 0x84, 0x09, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderLeftHandle3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x78, 0x08, 0x06, 0x00, 0x00, 0x00, 0x5c, 0x89, 0xc4, - 0xad, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, - 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0xa0, 0x03, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x54, 0xdc, - 0xcf, 0x00, 0x00, 0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, - 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, - 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, - 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, - 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, - 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, - 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, - 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, - 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x0a, 0x58, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, - 0xed, 0x9d, 0xcb, 0x8b, 0x14, 0xdb, 0x1d, 0xc7, 0x9d, 0x9e, 0xd6, 0x79, 0x39, 0xd7, 0xc7, 0x98, - 0x51, 0xc9, 0x20, 0x64, 0x20, 0x3e, 0x19, 0x2e, 0x04, 0x24, 0x8a, 0x49, 0x5c, 0x24, 0x17, 0x5c, - 0x19, 0xd0, 0x24, 0x0b, 0x73, 0x71, 0x97, 0x2c, 0xee, 0xee, 0x6e, 0x44, 0x70, 0x95, 0x85, 0x22, - 0x98, 0x6c, 0x62, 0xfe, 0x00, 0x11, 0x17, 0x6e, 0xcc, 0xc2, 0x08, 0xd9, 0xb8, 0x30, 0x0a, 0x77, - 0x61, 0xc4, 0xbb, 0x31, 0x66, 0x21, 0xa8, 0x38, 0x68, 0xcc, 0x42, 0x88, 0x13, 0x93, 0x8c, 0xce, - 0x2b, 0xe7, 0x53, 0xe3, 0x77, 0xee, 0xcf, 0xe3, 0x39, 0xd5, 0x55, 0xd5, 0xd3, 0xa3, 0x55, 0x5d, - 0x07, 0xce, 0xfc, 0x9e, 0xe7, 0xf5, 0xe9, 0x5f, 0x55, 0xf7, 0xb4, 0x4c, 0xb9, 0x6a, 0x55, 0xdd, - 0x6a, 0x02, 0x2b, 0x49, 0xa0, 0x67, 0x25, 0x17, 0x33, 0x6b, 0x7d, 0xa8, 0x75, 0xcd, 0x16, 0xda, - 0x53, 0x57, 0xea, 0x00, 0x2b, 0xb5, 0x4e, 0x7b, 0x34, 0x72, 0x8c, 0xee, 0xe4, 0x81, 0xda, 0x9d, - 0xbb, 0xdd, 0xf1, 0x39, 0x30, 0xe4, 0x4a, 0x5d, 0x20, 0xbb, 0x13, 0x9b, 0x2b, 0x32, 0x67, 0x91, - 0x31, 0x3a, 0x6d, 0x3b, 0x63, 0x35, 0x07, 0x32, 0x01, 0x62, 0x1d, 0x69, 0xfa, 0x72, 0x2d, 0xca, - 0x1a, 0x79, 0xe6, 0x6a, 0x95, 0xdb, 0x2a, 0x9e, 0x76, 0xa6, 0x4e, 0xc7, 0x96, 0xad, 0xe2, 0xf2, - 0x1c, 0x32, 0x96, 0x1b, 0xf2, 0x37, 0x1c, 0x01, 0xba, 0x62, 0x92, 0x9d, 0x06, 0x13, 0x9a, 0xff, - 0xbd, 0x6a, 0x6c, 0x77, 0x33, 0x59, 0xc6, 0xc7, 0x72, 0x7c, 0x7f, 0xd3, 0xed, 0xb8, 0xf7, 0x6d, - 0x27, 0x66, 0x7b, 0xe8, 0x30, 0x2b, 0xe9, 0xf3, 0xc1, 0x2d, 0xf8, 0x9b, 0xcf, 0xb3, 0x99, 0x2c, - 0x63, 0xfd, 0x1c, 0xdf, 0xa6, 0xa2, 0xd6, 0xb8, 0x0e, 0xb4, 0xc6, 0xe1, 0xc3, 0x87, 0x07, 0xce, - 0x9d, 0x3b, 0xf7, 0xa3, 0xcd, 0x9b, 0x37, 0xff, 0xb0, 0xaf, 0xaf, 0xef, 0xbb, 0xab, 0x57, 0xaf, - 0x1e, 0xef, 0xe9, 0xe9, 0xd9, 0xe0, 0xfa, 0x5a, 0xd7, 0xc9, 0x2b, 0x7d, 0x03, 0x40, 0x5a, 0xd7, - 0x65, 0x26, 0xa9, 0x4a, 0x42, 0x02, 0x69, 0xb5, 0xeb, 0x43, 0xae, 0xaf, 0x3f, 0x79, 0xf2, 0xe4, - 0xf8, 0xe3, 0xc7, 0x8f, 0xbf, 0x78, 0xf5, 0xea, 0xd5, 0xb5, 0xf9, 0xf9, 0xf9, 0xff, 0x2c, 0x94, - 0xa4, 0xb9, 0xbd, 0xe7, 0x6a, 0x69, 0xb0, 0x88, 0x09, 0x94, 0xa4, 0x0f, 0x0c, 0x68, 0x00, 0xdb, - 0x70, 0xe4, 0xc8, 0x91, 0xb1, 0xe7, 0xcf, 0x9f, 0x9f, 0x76, 0xb0, 0xa6, 0x4a, 0xc2, 0xea, 0x9d, - 0x6d, 0xe6, 0xa1, 0x56, 0x14, 0x1a, 0xb0, 0xe8, 0x7d, 0xae, 0xaf, 0xdb, 0xb2, 0x65, 0xcb, 0xb7, - 0x1e, 0x3d, 0x7a, 0xf4, 0xe5, 0xdc, 0xdc, 0xdc, 0x3f, 0xde, 0xd9, 0x49, 0xc9, 0x8c, 0xe5, 0x02, - 0xa7, 0x0a, 0x43, 0x86, 0xaa, 0x6c, 0xc0, 0xf9, 0x37, 0x9c, 0x3f, 0x7f, 0x7e, 0x62, 0x7a, 0x7a, - 0xfa, 0x6e, 0xc9, 0x18, 0x05, 0xb7, 0x9b, 0x15, 0x5c, 0x5a, 0xb5, 0x85, 0xa0, 0xa9, 0xca, 0x74, - 0x2f, 0x1b, 0xb9, 0x7e, 0xfd, 0xfa, 0xa1, 0xd9, 0xd9, 0xd9, 0xe7, 0xc1, 0x5d, 0x94, 0xd0, 0x09, - 0x90, 0x56, 0x2d, 0x2d, 0xc7, 0xc6, 0xa4, 0x5b, 0xc9, 0xe5, 0xd9, 0x7f, 0xff, 0xfe, 0xfd, 0x5f, - 0xec, 0xdc, 0xb9, 0xf3, 0x77, 0xee, 0x9d, 0xb1, 0xbf, 0xd5, 0x62, 0x65, 0x89, 0x53, 0x19, 0x69, - 0x4d, 0x10, 0x42, 0x39, 0x36, 0x26, 0x1d, 0x29, 0x9d, 0x8f, 0x0f, 0x83, 0xf7, 0xee, 0xdd, 0xfb, - 0xf9, 0xae, 0x5d, 0xbb, 0xfe, 0x10, 0x9a, 0xa0, 0xcc, 0x3e, 0x2e, 0xb3, 0x22, 0x4d, 0x70, 0x18, - 0x2b, 0xdd, 0x42, 0xe3, 0x05, 0x19, 0xba, 0x76, 0xed, 0xda, 0xde, 0xdd, 0xbb, 0x77, 0xff, 0xb6, - 0xc8, 0x02, 0x65, 0x1e, 0x23, 0x10, 0xbe, 0x8c, 0xdd, 0xd3, 0xb8, 0x9f, 0xd1, 0xb9, 0x1c, 0x37, - 0x9d, 0x3e, 0x7d, 0xfa, 0x7b, 0x55, 0xba, 0xa7, 0xf9, 0xb7, 0x61, 0x55, 0x4b, 0xe8, 0x05, 0x0e, - 0xc5, 0xac, 0x4f, 0x3a, 0x52, 0x3a, 0x50, 0x07, 0x36, 0x6e, 0xdc, 0x38, 0x3c, 0x39, 0x39, 0xf9, - 0xa7, 0xc1, 0xc1, 0xc1, 0x4f, 0x43, 0x13, 0x57, 0xc1, 0x17, 0xbb, 0x54, 0x05, 0x22, 0x76, 0x46, - 0xc5, 0x7d, 0x68, 0x5c, 0xa2, 0x83, 0x37, 0x6e, 0xdc, 0xf8, 0x65, 0x95, 0xa1, 0x01, 0x25, 0x06, - 0x2e, 0x04, 0x4c, 0xb0, 0x14, 0xb3, 0x36, 0x3a, 0x73, 0x0d, 0xee, 0xdf, 0xbf, 0xff, 0x13, 0xf7, - 0x66, 0xf0, 0xa5, 0x92, 0xaa, 0x2a, 0x43, 0xe0, 0x2c, 0x90, 0xd0, 0xb9, 0x6d, 0x1c, 0x5d, 0xd0, - 0xa8, 0xb6, 0xfe, 0x8b, 0x17, 0x2f, 0xfe, 0xaa, 0xd9, 0x6c, 0x8e, 0x86, 0x06, 0x56, 0xc9, 0x17, - 0x02, 0x17, 0x3a, 0x9f, 0x60, 0x59, 0x29, 0x68, 0x48, 0x7e, 0x5b, 0x18, 0x3c, 0x7a, 0xf4, 0xe8, - 0xa6, 0xf1, 0xf1, 0xf1, 0x5f, 0x87, 0x26, 0xa8, 0x9a, 0x2f, 0x0b, 0x38, 0xc1, 0xd2, 0xd9, 0x43, - 0x36, 0xe0, 0xfa, 0x4f, 0x9c, 0x38, 0xf1, 0x59, 0xa3, 0xd1, 0x58, 0xab, 0xc4, 0x2a, 0x4b, 0x1f, - 0x9c, 0x0f, 0xc5, 0x9e, 0xdd, 0xc6, 0xd0, 0xd5, 0x99, 0x83, 0xdf, 0x10, 0x9a, 0xae, 0xda, 0x3e, - 0xb3, 0x03, 0xaa, 0xac, 0xfb, 0xe0, 0x5a, 0x9d, 0x55, 0xb0, 0xc8, 0x43, 0x67, 0x3c, 0xd5, 0xb6, - 0x66, 0xcf, 0x9e, 0x3d, 0x6b, 0xdd, 0xc7, 0x90, 0x03, 0x4e, 0xef, 0x8a, 0xd6, 0x0a, 0x1c, 0x70, - 0x68, 0x92, 0x8b, 0xd6, 0x37, 0xb6, 0xc0, 0xf5, 0x9d, 0x3d, 0x7b, 0xf6, 0x07, 0xee, 0x32, 0xe5, - 0x5b, 0x90, 0xae, 0x68, 0xad, 0xc0, 0x59, 0x08, 0xaa, 0x36, 0x5f, 0xf2, 0x6e, 0xda, 0x74, 0x1f, - 0x41, 0xbe, 0x6f, 0x93, 0xab, 0xae, 0x5b, 0x70, 0xb1, 0xaa, 0xf2, 0xfd, 0x62, 0x82, 0x9f, 0xf1, - 0xfc, 0x9a, 0xd5, 0xbb, 0x6e, 0xdd, 0xba, 0xef, 0x28, 0xd0, 0x0d, 0xd2, 0x82, 0xcb, 0x73, 0x5e, - 0xa0, 0x09, 0x1c, 0xf7, 0xb8, 0xe6, 0xd0, 0xd0, 0xd0, 0xb6, 0x3c, 0x13, 0x94, 0x3d, 0x37, 0x2b, - 0x38, 0x81, 0x92, 0xe4, 0xdc, 0x02, 0xc7, 0xa5, 0xda, 0xeb, 0xfe, 0x45, 0xea, 0x93, 0xb2, 0xc3, - 0xc8, 0xb3, 0xff, 0xac, 0xe0, 0xec, 0x9c, 0x82, 0x27, 0x49, 0xc5, 0xb9, 0xf7, 0x85, 0x06, 0xff, - 0x08, 0xd3, 0x35, 0x2d, 0x06, 0x0e, 0x28, 0x34, 0xc9, 0x45, 0xeb, 0x5d, 0x9b, 0x18, 0xe3, 0xe9, - 0x3d, 0x0e, 0x1c, 0xf7, 0xba, 0xae, 0x69, 0x31, 0x70, 0x16, 0x80, 0x2a, 0xcb, 0x42, 0x14, 0x34, - 0xc5, 0xb2, 0xcc, 0x63, 0xe7, 0x2c, 0xbd, 0x5e, 0xe4, 0xc0, 0x16, 0x60, 0x52, 0x6d, 0x8e, 0x82, - 0xf5, 0x95, 0x1e, 0x4a, 0x96, 0x03, 0xe4, 0x05, 0x27, 0x40, 0xaa, 0x34, 0xc9, 0x2c, 0x6b, 0x55, - 0x2a, 0x27, 0x0d, 0x9c, 0x20, 0xe9, 0xc0, 0xb2, 0x25, 0xad, 0xdf, 0xf7, 0x29, 0x56, 0x59, 0x99, - 0x06, 0xce, 0x1e, 0xda, 0x07, 0xe3, 0xdb, 0x36, 0xb7, 0x2b, 0xf4, 0x10, 0x38, 0x0b, 0x05, 0xdd, - 0xb7, 0x05, 0x46, 0x31, 0x49, 0xf9, 0xbb, 0x42, 0x86, 0xc0, 0x75, 0xc5, 0xc1, 0xdb, 0x3d, 0x64, - 0x11, 0x70, 0xb6, 0x02, 0xdb, 0x5d, 0xbf, 0xb4, 0xe3, 0xf3, 0x80, 0xb3, 0xc0, 0xec, 0xe5, 0x69, - 0xf5, 0xd2, 0x82, 0xc8, 0xbb, 0xf1, 0x3c, 0xe0, 0x42, 0x73, 0x5b, 0x98, 0xa1, 0x78, 0x65, 0x7d, - 0xed, 0x82, 0xab, 0x2c, 0x98, 0x56, 0x07, 0xab, 0xc1, 0xb5, 0x22, 0x14, 0x89, 0xe7, 0x05, 0xd7, - 0xb5, 0x97, 0xa6, 0xcf, 0x2f, 0x06, 0xae, 0x06, 0xe4, 0x93, 0xf2, 0xec, 0x18, 0x38, 0x2f, 0xad, - 0x36, 0x7d, 0x02, 0x59, 0xc1, 0xd5, 0x15, 0xe8, 0x91, 0xcb, 0x0a, 0xce, 0x0e, 0x0b, 0x41, 0x0c, - 0xf9, 0xec, 0x98, 0xca, 0xe9, 0x45, 0xc0, 0x55, 0x0e, 0x42, 0x91, 0x03, 0xd5, 0xe0, 0x8a, 0x50, - 0x73, 0x63, 0x6a, 0x70, 0x35, 0xb8, 0x82, 0x04, 0x0a, 0x0e, 0xab, 0x2b, 0xae, 0x06, 0x57, 0x90, - 0x40, 0xc1, 0x61, 0x75, 0xc5, 0xd5, 0xe0, 0x0a, 0x12, 0x28, 0x38, 0xac, 0xae, 0xb8, 0x1a, 0x5c, - 0x41, 0x02, 0x05, 0x87, 0xd5, 0x15, 0x57, 0x83, 0x2b, 0x48, 0xa0, 0xe0, 0xb0, 0xba, 0xe2, 0x6a, - 0x70, 0x05, 0x09, 0x14, 0x1c, 0x56, 0x57, 0x5c, 0x0d, 0xae, 0x20, 0x81, 0x82, 0xc3, 0xea, 0x8a, - 0xab, 0xc1, 0x15, 0x24, 0x50, 0x70, 0xd8, 0x72, 0x54, 0x5c, 0xf2, 0xc0, 0x26, 0xf7, 0xc4, 0x9a, - 0x99, 0x82, 0x7b, 0x28, 0xe5, 0xb0, 0x22, 0xe0, 0xfc, 0x27, 0x5b, 0x71, 0xf0, 0x05, 0xf7, 0xe4, - 0x9a, 0xff, 0x96, 0x92, 0x40, 0xc1, 0x4d, 0x67, 0x05, 0x17, 0x82, 0xa5, 0x25, 0x93, 0xd8, 0x9b, - 0x37, 0x6f, 0xfe, 0x2d, 0x47, 0x37, 0xc8, 0xac, 0xe0, 0xd2, 0x58, 0xcc, 0x13, 0x74, 0x4f, 0xe3, - 0x9a, 0x4c, 0x4b, 0xaa, 0x5a, 0x2c, 0x06, 0x2e, 0xad, 0xc2, 0x2c, 0x03, 0xf2, 0x00, 0xb7, 0xf0, - 0xe2, 0xc5, 0x8b, 0x27, 0x36, 0x50, 0x75, 0x3d, 0x06, 0x2e, 0x76, 0x6e, 0x0b, 0x14, 0x5d, 0x7d, - 0xfe, 0xce, 0x9d, 0x3b, 0x5f, 0xc7, 0x06, 0x55, 0xd1, 0x6f, 0xff, 0x21, 0x59, 0xba, 0x95, 0xe8, - 0xea, 0x40, 0x46, 0x47, 0xd2, 0xf9, 0x1b, 0x2e, 0xfe, 0x32, 0x3a, 0x79, 0x80, 0xde, 0xb6, 0x6d, - 0xdb, 0x36, 0x3e, 0x7c, 0xf8, 0xf0, 0x6a, 0x6f, 0x6f, 0x6f, 0x65, 0x9e, 0x9f, 0xe4, 0xce, 0x16, - 0x6d, 0x79, 0x2b, 0xce, 0x4e, 0xb4, 0x54, 0x6d, 0xce, 0x39, 0xf7, 0xe4, 0xc9, 0x93, 0xe9, 0x67, - 0xcf, 0x9e, 0xfd, 0xd5, 0x26, 0x54, 0x59, 0x6f, 0x07, 0x1c, 0x5c, 0xb8, 0xbf, 0xd1, 0xf9, 0x0c, - 0xb7, 0xe0, 0x2e, 0xd7, 0xaf, 0x9c, 0xec, 0x8a, 0x96, 0x07, 0x9c, 0x7f, 0x7f, 0x4b, 0xde, 0x14, - 0x1c, 0x25, 0xe4, 0x1c, 0xfd, 0xcc, 0x99, 0x33, 0x5f, 0xb9, 0xe7, 0x29, 0x75, 0xc5, 0xe7, 0xb9, - 0x3c, 0xe0, 0x54, 0x49, 0x21, 0x80, 0x80, 0x9b, 0x76, 0x15, 0x37, 0x75, 0xfb, 0xf6, 0xed, 0xcb, - 0x4a, 0xac, 0xb2, 0x2c, 0x02, 0xce, 0xf2, 0x00, 0x62, 0x52, 0x6d, 0x4e, 0xce, 0xba, 0x3e, 0x73, - 0xec, 0xd8, 0xb1, 0x3f, 0xba, 0xc7, 0x39, 0xbe, 0xb0, 0x49, 0x55, 0xd4, 0xf9, 0x23, 0x5d, 0x35, - 0xbd, 0x9b, 0x62, 0xeb, 0x9d, 0xd4, 0xc6, 0x14, 0xb7, 0x31, 0xe9, 0xcc, 0xc3, 0xdf, 0xab, 0x36, - 0x5e, 0xbe, 0x7c, 0xd9, 0xd8, 0xb7, 0x6f, 0xdf, 0xff, 0xb6, 0x6f, 0xdf, 0xbe, 0x5f, 0x83, 0xab, - 0x28, 0x05, 0x83, 0xb3, 0xf9, 0xba, 0x6c, 0xc1, 0xa1, 0x3a, 0xd1, 0xad, 0x44, 0x4f, 0x9e, 0xa9, - 0xe4, 0x24, 0x8f, 0xce, 0xe0, 0xa3, 0xc9, 0xb0, 0x7b, 0xf8, 0xf1, 0xe0, 0xd3, 0xa7, 0x4f, 0x7f, - 0x3f, 0x32, 0x32, 0xb2, 0xc3, 0xd9, 0x95, 0x6c, 0x69, 0x97, 0xaa, 0xbd, 0x97, 0x71, 0x78, 0xd9, - 0x92, 0x02, 0xc2, 0x9b, 0x43, 0x72, 0x99, 0x3a, 0xc9, 0xbb, 0xeb, 0xf4, 0xeb, 0xd7, 0xaf, 0x67, - 0x8e, 0x1f, 0x3f, 0xfe, 0x9b, 0x2a, 0x5f, 0xb2, 0x69, 0x97, 0x2a, 0x60, 0x54, 0x6d, 0x92, 0xf2, - 0x49, 0xca, 0xcf, 0x0b, 0xa0, 0x4e, 0x05, 0xf6, 0x3c, 0x78, 0xf0, 0x60, 0xc6, 0x3d, 0x4c, 0xf4, - 0x6f, 0x07, 0x0f, 0x1e, 0xfc, 0xb1, 0xfb, 0xb3, 0x73, 0xbb, 0x0e, 0x63, 0x4b, 0xdf, 0xec, 0x81, - 0x80, 0xa0, 0x26, 0x5d, 0x60, 0xac, 0x24, 0x47, 0xb6, 0x74, 0x8d, 0x13, 0x3c, 0xe6, 0x6d, 0xdc, - 0xbc, 0x79, 0x73, 0xca, 0x3d, 0x8d, 0xf5, 0x9f, 0x13, 0x13, 0x13, 0x95, 0x7b, 0x74, 0x50, 0x16, - 0x70, 0x82, 0x22, 0x48, 0x21, 0xa8, 0xc4, 0x80, 0x26, 0xa0, 0x4b, 0xfa, 0x95, 0x2b, 0x57, 0x26, - 0x77, 0xec, 0xd8, 0xf1, 0xcc, 0x3d, 0x64, 0x74, 0x6f, 0x95, 0x2a, 0x2f, 0x06, 0x4e, 0x90, 0x24, - 0x05, 0xc4, 0xda, 0x56, 0xb7, 0x71, 0x41, 0x5b, 0x92, 0xc0, 0x73, 0x1f, 0x8c, 0xbf, 0x3e, 0x70, - 0xe0, 0xc0, 0x5e, 0xf7, 0x50, 0xbe, 0x41, 0x06, 0x96, 0xbd, 0xe5, 0x05, 0xa7, 0x6a, 0xe3, 0xdc, - 0x16, 0x96, 0xf5, 0x8b, 0x09, 0x3e, 0xc1, 0x5b, 0x75, 0xeb, 0xd6, 0xad, 0x7f, 0xdd, 0xbd, 0x7b, - 0xf7, 0x2f, 0x87, 0x0e, 0x1d, 0xda, 0xe3, 0x9e, 0x9f, 0xb9, 0x49, 0x49, 0x65, 0x95, 0xf6, 0xc0, - 0x56, 0xe7, 0x3c, 0xb2, 0xad, 0x44, 0xa7, 0x0b, 0x88, 0x95, 0xe8, 0x74, 0xde, 0x1c, 0xf4, 0xcd, - 0x09, 0xd5, 0xc5, 0xc7, 0x14, 0x1e, 0xa6, 0xcc, 0xe7, 0xbc, 0x01, 0xf7, 0x51, 0xa5, 0x79, 0xf9, - 0xf2, 0xe5, 0x9f, 0x38, 0x80, 0x9f, 0xf7, 0xf7, 0xf7, 0x8f, 0x38, 0x5f, 0x29, 0x9b, 0xa0, 0xb0, - 0x79, 0xab, 0x5b, 0x5b, 0x7e, 0xa4, 0xed, 0x16, 0x1a, 0x7e, 0x81, 0x43, 0x52, 0xc9, 0xc0, 0x4a, - 0x1e, 0xd9, 0xed, 0x24, 0x5f, 0x35, 0x09, 0x1e, 0x7a, 0x73, 0x6c, 0x6c, 0xac, 0xff, 0xd2, 0xa5, - 0x4b, 0x3f, 0x75, 0x97, 0xef, 0xcf, 0xca, 0x78, 0xf9, 0xda, 0x4b, 0xd5, 0x9d, 0x27, 0x15, 0x9e, - 0x85, 0x86, 0xae, 0x26, 0x5d, 0x71, 0xf9, 0x25, 0xf9, 0x9c, 0x67, 0x73, 0x92, 0x2f, 0x07, 0xa6, - 0xa6, 0xa6, 0xe6, 0x2e, 0x5c, 0xb8, 0xf0, 0xf7, 0xab, 0x57, 0xaf, 0xfe, 0x79, 0xfd, 0xfa, 0xf5, - 0x93, 0xc3, 0xc3, 0xc3, 0xf3, 0xae, 0x8f, 0xba, 0x37, 0x10, 0xaa, 0xf5, 0xa3, 0x6f, 0x3a, 0x90, - 0x36, 0x1a, 0xb3, 0xe5, 0x47, 0xda, 0xae, 0xaa, 0xc3, 0xa7, 0x8a, 0xb3, 0x3a, 0x2f, 0x0c, 0x97, - 0x28, 0x9d, 0x4a, 0xa3, 0x02, 0xe9, 0xd8, 0xc4, 0x80, 0x44, 0x25, 0x26, 0xf3, 0x6c, 0xdd, 0xba, - 0x75, 0xcd, 0xa9, 0x53, 0xa7, 0x3e, 0x75, 0x8f, 0xc4, 0x9d, 0x18, 0x1d, 0x1d, 0x1d, 0x73, 0x8f, - 0x56, 0xfb, 0xb6, 0xbb, 0xb4, 0xd7, 0xba, 0x8a, 0x1c, 0xf8, 0xd8, 0x1e, 0x41, 0xc4, 0x21, 0x6d, - 0xf3, 0x6d, 0x62, 0xf2, 0x21, 0xd5, 0xf1, 0x5b, 0x68, 0xf8, 0x65, 0xfb, 0x00, 0x81, 0xa3, 0x4b, - 0x17, 0x48, 0xba, 0x84, 0xf1, 0x2b, 0x46, 0x5c, 0x20, 0x35, 0x8f, 0x73, 0x2d, 0xad, 0x8d, 0xee, - 0x37, 0xed, 0xcb, 0xf7, 0x17, 0xb1, 0xf5, 0xdb, 0x90, 0x95, 0xbe, 0xce, 0x95, 0x42, 0xa7, 0xcd, - 0xb0, 0xf1, 0x3c, 0x4d, 0x93, 0xb1, 0x69, 0xe9, 0x8c, 0xb7, 0x36, 0x7e, 0x16, 0x00, 0x00, 0x3a, - 0xbf, 0x8e, 0x21, 0xe5, 0xd7, 0xb7, 0x29, 0xaa, 0x44, 0x55, 0x1f, 0xe0, 0xc8, 0x65, 0x2e, 0xba, - 0x7d, 0x01, 0x9c, 0x19, 0x84, 0x48, 0x5e, 0xbb, 0x8d, 0x7d, 0xa9, 0x49, 0xb7, 0x12, 0x9d, 0x9e, - 0xdc, 0x62, 0xde, 0xca, 0xf7, 0xc0, 0x91, 0x10, 0xdb, 0x8c, 0x8d, 0xa1, 0xdb, 0x66, 0x6d, 0xe9, - 0x48, 0x01, 0x04, 0x16, 0x0d, 0x9f, 0xc0, 0x01, 0x49, 0x5d, 0x95, 0x87, 0x14, 0x34, 0xa4, 0xba, - 0x53, 0xa3, 0xfb, 0x22, 0xb6, 0x5c, 0xcd, 0xee, 0x1d, 0xdd, 0x76, 0xd6, 0xe0, 0x3c, 0xc9, 0xfe, - 0xb3, 0x54, 0x1c, 0x83, 0x2d, 0x4c, 0xdf, 0x66, 0x42, 0x7c, 0x6a, 0xd2, 0x05, 0x4d, 0x92, 0x05, - 0xd1, 0x89, 0xd3, 0xb1, 0x01, 0xf7, 0xc6, 0x75, 0x5b, 0x75, 0x31, 0x78, 0x76, 0x0f, 0x6e, 0xc8, - 0xb2, 0x37, 0xed, 0x9b, 0x89, 0xb5, 0xc7, 0x90, 0xe4, 0x0c, 0xb3, 0xa1, 0xcd, 0x84, 0x7c, 0x4c, - 0x26, 0xbf, 0x95, 0xe8, 0xa1, 0xae, 0xfb, 0x14, 0xb1, 0x34, 0x9d, 0x98, 0xee, 0x6f, 0x48, 0x6b, - 0x6b, 0x5e, 0x7c, 0x34, 0x6c, 0x35, 0xab, 0xcb, 0xd7, 0x8e, 0xf4, 0xa1, 0x31, 0x57, 0x08, 0x9a, - 0x7c, 0xb3, 0xa1, 0x8a, 0x23, 0x98, 0xb6, 0x31, 0x1b, 0x47, 0x0f, 0x35, 0x55, 0x19, 0x31, 0x5f, - 0x17, 0x10, 0xc6, 0x12, 0xa3, 0x53, 0x7d, 0x00, 0xa2, 0x13, 0xb7, 0xd2, 0x99, 0x4b, 0x2f, 0x0e, - 0x7a, 0x27, 0x9b, 0xce, 0x83, 0x94, 0xce, 0xfe, 0x68, 0xf2, 0x21, 0xe7, 0x42, 0xe0, 0x92, 0xac, - 0xc0, 0x0f, 0x06, 0x58, 0xa0, 0xd6, 0x46, 0xf7, 0x5b, 0x0c, 0x98, 0xc0, 0x28, 0x5f, 0xf0, 0x04, - 0x34, 0x24, 0xc9, 0xb5, 0x6b, 0x6b, 0xec, 0x72, 0x4b, 0x7b, 0x0e, 0xf4, 0x50, 0x67, 0xbf, 0x0b, - 0x31, 0x70, 0x0c, 0x48, 0xdb, 0xa8, 0xe2, 0x48, 0x1a, 0xb9, 0xd2, 0x13, 0xc7, 0xdb, 0x1f, 0x2c, - 0x62, 0x41, 0xe8, 0xb2, 0xf3, 0xfd, 0xa4, 0x2b, 0x4f, 0xba, 0x95, 0xbe, 0x8e, 0xad, 0x96, 0xb6, - 0x4f, 0xe5, 0xb4, 0x92, 0x76, 0xef, 0xd2, 0x91, 0xbe, 0x9e, 0x40, 0xc3, 0x1f, 0x03, 0x17, 0x5b, - 0x88, 0x89, 0xb4, 0x51, 0xe9, 0x9a, 0x1c, 0xbf, 0xf4, 0xd8, 0x78, 0x1f, 0x98, 0x60, 0x69, 0xac, - 0xe6, 0x96, 0x5f, 0xf3, 0x29, 0x1e, 0x9b, 0x57, 0xe3, 0x62, 0xf1, 0x56, 0x7e, 0xad, 0x43, 0x9e, - 0x74, 0x2b, 0xd1, 0xdf, 0xe9, 0xad, 0x16, 0x8c, 0xc5, 0xad, 0x5f, 0x3a, 0xd2, 0xd7, 0xe5, 0x4b, - 0xf3, 0x2b, 0x87, 0x4d, 0xdb, 0x3c, 0x6b, 0xfb, 0x3a, 0xb6, 0x9a, 0xc6, 0xc8, 0x2e, 0x22, 0x05, - 0x89, 0xb1, 0xd2, 0xad, 0xb4, 0xd0, 0xc8, 0x99, 0xcf, 0x5b, 0x71, 0x0c, 0xa2, 0x31, 0x91, 0x36, - 0x2c, 0x5d, 0x0b, 0xe1, 0x97, 0x6e, 0x73, 0x95, 0x8f, 0x8f, 0xa6, 0x71, 0xf8, 0x15, 0x8b, 0x49, - 0xf2, 0x15, 0x43, 0xef, 0x64, 0xd3, 0xde, 0x43, 0x12, 0x5f, 0xd2, 0xb3, 0x6c, 0x26, 0x2d, 0xc7, - 0xc6, 0xa4, 0x5b, 0xe9, 0xeb, 0x69, 0x36, 0x30, 0x88, 0x2b, 0x47, 0x36, 0x92, 0x66, 0xfd, 0x8b, - 0x9e, 0xce, 0xfc, 0x14, 0x30, 0x66, 0x97, 0xbe, 0x04, 0xec, 0xed, 0x92, 0x99, 0xff, 0x7f, 0xd5, - 0xb4, 0x4d, 0xdb, 0x98, 0xf4, 0x90, 0xb4, 0x3e, 0xab, 0xb3, 0x17, 0x6c, 0xdf, 0x27, 0x3f, 0x92, - 0xa6, 0xf8, 0xa2, 0xd5, 0xd9, 0x9f, 0x16, 0x18, 0x2b, 0x59, 0x3b, 0xd1, 0xf3, 0x6c, 0x26, 0x2d, - 0xd7, 0xc6, 0x42, 0xba, 0x7c, 0x48, 0xab, 0xb3, 0xa9, 0x56, 0x36, 0x39, 0x34, 0xe5, 0x2d, 0x5a, - 0x9d, 0xfd, 0x29, 0x50, 0xac, 0x22, 0xdd, 0xca, 0xcc, 0x15, 0xc7, 0x04, 0xad, 0x36, 0xee, 0xc7, - 0x65, 0xc7, 0xa4, 0xe6, 0x54, 0x5c, 0xb6, 0x95, 0xe8, 0x34, 0x9b, 0xb3, 0xe8, 0x89, 0xff, 0xcc, - 0x93, 0xcb, 0x2c, 0x02, 0xe2, 0xcf, 0x68, 0xfd, 0xd2, 0x97, 0x64, 0xde, 0x45, 0x5a, 0xe5, 0xfb, - 0x71, 0x6b, 0x4b, 0x97, 0x64, 0xa3, 0xd2, 0x25, 0xad, 0xcf, 0xd7, 0xb1, 0xfd, 0x66, 0xc7, 0xf9, - 0xb1, 0xbc, 0xb6, 0xa0, 0xf8, 0xe3, 0xac, 0x5f, 0x7a, 0xae, 0x8a, 0xb3, 0x13, 0xb6, 0xda, 0xb0, - 0x1f, 0xb7, 0x76, 0x5e, 0x5d, 0xeb, 0xda, 0x71, 0xf2, 0x75, 0x52, 0x0a, 0x92, 0xd6, 0xb0, 0x76, - 0x61, 0x70, 0x4c, 0x96, 0xe5, 0x20, 0x7e, 0x4e, 0x9a, 0x9d, 0x16, 0xd3, 0xe6, 0x7d, 0xe9, 0x8f, - 0xf1, 0xe3, 0x79, 0x6c, 0x0b, 0xc6, 0x1f, 0xe7, 0xc7, 0xda, 0x02, 0xc7, 0xe4, 0x59, 0x36, 0x1e, - 0xcb, 0xf1, 0xfd, 0xbe, 0x9d, 0x75, 0x7e, 0xff, 0x90, 0x9d, 0xb0, 0xdf, 0x03, 0xc7, 0x57, 0x39, - 0xed, 0xb6, 0xd0, 0x81, 0x63, 0x73, 0xc6, 0x72, 0x63, 0xfe, 0xd8, 0x3c, 0x2b, 0xed, 0xf7, 0xc1, - 0x65, 0xaa, 0x98, 0xac, 0x9b, 0xcc, 0x73, 0xf8, 0x56, 0xb9, 0xad, 0xe2, 0x59, 0xf7, 0xd4, 0x89, - 0xbc, 0x04, 0x62, 0x27, 0x36, 0x58, 0x64, 0xce, 0x22, 0x63, 0x04, 0xa5, 0x9d, 0xb1, 0x9a, 0x03, - 0xf9, 0x5e, 0x55, 0xd9, 0xa0, 0xaf, 0x2f, 0xd7, 0xa2, 0xfe, 0xbc, 0xd8, 0xed, 0xce, 0xdd, 0xee, - 0xf8, 0xd0, 0x9e, 0x96, 0xc3, 0xd7, 0xb1, 0x8a, 0x0b, 0x6d, 0xee, 0x63, 0x85, 0x10, 0xda, 0x6b, - 0x26, 0xdf, 0x87, 0x3a, 0xd0, 0x87, 0x5a, 0x37, 0x13, 0x94, 0x3a, 0xa9, 0x26, 0xf0, 0xf1, 0x11, - 0xf8, 0x3f, 0x7a, 0xc4, 0x58, 0xcc, 0x89, 0xbc, 0xc8, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderRightHandle2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x50, 0x08, 0x06, 0x00, 0x00, 0x00, 0x56, 0x1d, 0x56, - 0xa7, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, - 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0xa0, 0x03, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x7d, 0xa9, - 0x20, 0x00, 0x00, 0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, - 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, - 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, - 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, - 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, - 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, - 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, - 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, - 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x06, 0x18, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, - 0xed, 0x9a, 0xcf, 0x4b, 0x5c, 0x57, 0x14, 0xc7, 0x33, 0x31, 0x89, 0xb6, 0x89, 0x59, 0xb5, 0xb1, - 0x82, 0x50, 0x90, 0x2c, 0x92, 0x45, 0x16, 0x6e, 0x85, 0x10, 0x4b, 0xb6, 0xc6, 0x2e, 0x0a, 0xe2, - 0x3f, 0xd0, 0xb5, 0xa0, 0xae, 0xbb, 0x10, 0xb3, 0x2a, 0x62, 0xc0, 0x65, 0xb2, 0x4b, 0x20, 0x81, - 0x80, 0x7b, 0x41, 0x51, 0xba, 0x08, 0x48, 0x71, 0x21, 0x14, 0x17, 0x76, 0x25, 0xc5, 0xb6, 0xfe, - 0x18, 0xb0, 0xa9, 0x71, 0xe2, 0xef, 0x9e, 0xef, 0xf3, 0x7d, 0xaf, 0x67, 0xee, 0xbb, 0xef, 0xcd, - 0x7b, 0x33, 0x3a, 0x73, 0x5f, 0x99, 0x0b, 0xc7, 0x73, 0x7f, 0x9c, 0x77, 0xef, 0xf7, 0xf3, 0xce, - 0x7d, 0x77, 0x1e, 0xce, 0x5c, 0xbb, 0xf6, 0x3f, 0x2b, 0x05, 0xe1, 0x81, 0x35, 0xb2, 0x9c, 0x5d, - 0xe6, 0xe2, 0x49, 0x40, 0xb5, 0x82, 0x56, 0x2b, 0xb4, 0xda, 0xeb, 0x82, 0xfb, 0x02, 0xd1, 0xd7, - 0x2f, 0xf3, 0x0e, 0x65, 0x98, 0x2b, 0x8d, 0xf0, 0x34, 0x31, 0x65, 0x4b, 0x12, 0x28, 0x29, 0x1b, - 0x49, 0x63, 0x65, 0x93, 0x49, 0x23, 0x8d, 0x00, 0x57, 0x8c, 0xab, 0x4f, 0xcf, 0x5d, 0x69, 0xdc, - 0xc4, 0x42, 0xec, 0x5d, 0x31, 0x2d, 0x5a, 0xd7, 0x4d, 0x60, 0x8d, 0x95, 0x13, 0xb9, 0x1e, 0xa2, - 0x60, 0xc7, 0xa1, 0x89, 0x0b, 0x8a, 0x2d, 0xd6, 0x6e, 0xc7, 0xc5, 0xb1, 0xbf, 0xdc, 0x9f, 0x5d, - 0x71, 0x39, 0x3d, 0x3d, 0xfd, 0xf7, 0xf0, 0xf0, 0xf0, 0xf7, 0x52, 0xa9, 0xf4, 0xcb, 0xee, 0xee, - 0xee, 0xcb, 0x95, 0x95, 0x95, 0x1f, 0x7a, 0x7b, 0x7b, 0xef, 0x89, 0x8a, 0xdb, 0x62, 0x37, 0xc5, - 0x5a, 0x42, 0xc3, 0xd6, 0xa7, 0xe1, 0xa6, 0xba, 0x4c, 0xba, 0x2b, 0x94, 0x2b, 0xe6, 0x71, 0x4e, - 0x7f, 0x72, 0x72, 0xf2, 0x51, 0xe0, 0x5e, 0x4d, 0x4f, 0x4f, 0x3f, 0x10, 0x79, 0xed, 0x62, 0x59, - 0xc0, 0x92, 0x89, 0x9c, 0x2b, 0xd6, 0xa9, 0x53, 0xb2, 0xb7, 0xb7, 0xb9, 0xb9, 0xf9, 0x73, 0x5f, - 0x5f, 0xdf, 0x37, 0xa2, 0xb2, 0x4d, 0xec, 0x86, 0x98, 0x9d, 0xb1, 0x6c, 0x99, 0xaa, 0x93, 0xf6, - 0xc4, 0x65, 0xf6, 0xf7, 0xf7, 0x7f, 0x9d, 0x9a, 0x9a, 0x7a, 0x28, 0x30, 0xd8, 0x86, 0x80, 0x22, - 0x58, 0xd2, 0x16, 0x94, 0x30, 0x47, 0x49, 0x5c, 0xa9, 0x8e, 0x83, 0x47, 0x47, 0x47, 0x1b, 0x33, - 0x33, 0x33, 0x4f, 0x44, 0x22, 0xb7, 0x60, 0x75, 0x50, 0x75, 0xd4, 0x5c, 0x71, 0xa9, 0x83, 0x83, - 0x83, 0x3f, 0xc7, 0xc7, 0xc7, 0x1f, 0x09, 0xd4, 0x97, 0x62, 0x78, 0xae, 0xb2, 0x43, 0x55, 0x5c, - 0xa5, 0xce, 0x01, 0x7b, 0x7b, 0x7b, 0xcb, 0x3d, 0x3d, 0x3d, 0xdf, 0x0a, 0xcc, 0x17, 0x29, 0xa1, - 0x24, 0x4c, 0x95, 0x3a, 0xeb, 0x4d, 0xb5, 0xdc, 0xfa, 0xfa, 0xfa, 0x0b, 0x91, 0xf8, 0x95, 0x58, - 0xab, 0x58, 0x9a, 0x4c, 0x19, 0xa2, 0x46, 0xbd, 0xf6, 0x18, 0x01, 0xae, 0x4a, 0x57, 0x57, 0xd7, - 0x8f, 0xa3, 0xa3, 0xa3, 0xc8, 0xd2, 0x2d, 0x31, 0xfb, 0x94, 0x73, 0x5d, 0x72, 0xd1, 0x97, 0xea, - 0x96, 0x35, 0x20, 0x68, 0x63, 0x63, 0xe3, 0x8d, 0xa8, 0xc4, 0x71, 0x8e, 0xad, 0x07, 0xb0, 0xa4, - 0xe7, 0x49, 0x86, 0xcf, 0x8b, 0x97, 0x19, 0x82, 0xb4, 0x8e, 0x8e, 0x8e, 0xef, 0xbb, 0xbb, 0xbb, - 0xf1, 0x5a, 0x06, 0x90, 0x4a, 0x59, 0xc2, 0x78, 0x50, 0xbc, 0x05, 0x6a, 0x69, 0x69, 0xb9, 0x33, - 0x39, 0x39, 0xf9, 0x58, 0x54, 0xe2, 0x03, 0x17, 0x3a, 0x09, 0x15, 0x08, 0x0f, 0xdb, 0xac, 0x1b, - 0xef, 0x2d, 0x10, 0x14, 0xca, 0x69, 0xf7, 0x54, 0x1c, 0xb6, 0x1c, 0xde, 0x1e, 0x98, 0x05, 0x1b, - 0x4c, 0x86, 0x2e, 0x8a, 0xd7, 0x40, 0xed, 0xed, 0xed, 0xf7, 0x45, 0x2a, 0x4e, 0x3a, 0x02, 0xd9, - 0x30, 0x84, 0x34, 0x44, 0x5e, 0x03, 0xb5, 0xb5, 0xb5, 0xe1, 0xad, 0x5c, 0x1f, 0x06, 0x04, 0xb0, - 0xc1, 0x00, 0x14, 0x8c, 0x79, 0x0d, 0xd4, 0xda, 0xda, 0xfa, 0xb5, 0x08, 0xe5, 0x9b, 0x38, 0x21, - 0x08, 0x05, 0x88, 0x48, 0xf1, 0x1a, 0x48, 0x0e, 0x06, 0xbc, 0x02, 0x61, 0xbb, 0x41, 0xa7, 0x06, - 0x89, 0xab, 0x37, 0xec, 0xff, 0x09, 0x91, 0x3b, 0x9b, 0xd0, 0x01, 0x18, 0x1a, 0xb3, 0x84, 0x70, - 0x0d, 0x65, 0x2e, 0xf7, 0x3a, 0x43, 0xa1, 0x4a, 0x08, 0xa7, 0x4e, 0x1b, 0xc2, 0x6e, 0x9b, 0x40, - 0x43, 0xe8, 0x61, 0x05, 0xa2, 0x69, 0x90, 0xa7, 0xeb, 0x11, 0xb9, 0x24, 0x8f, 0x0c, 0x78, 0xda, - 0x11, 0xc9, 0x88, 0xad, 0x33, 0x0f, 0x40, 0xcc, 0x88, 0x0d, 0x63, 0xb7, 0x03, 0xb6, 0x3c, 0x00, - 0xd9, 0x49, 0x20, 0xa0, 0xdd, 0x9f, 0x4b, 0x20, 0x67, 0x56, 0x34, 0x59, 0x1e, 0x32, 0x44, 0x08, - 0x7a, 0xad, 0x3f, 0x52, 0xcf, 0x03, 0x10, 0x44, 0x57, 0x82, 0x31, 0xe3, 0x79, 0x01, 0x8a, 0x64, - 0x22, 0xec, 0x30, 0x20, 0x0c, 0xc8, 0x3b, 0x10, 0x39, 0x8c, 0x6f, 0x02, 0x99, 0x5b, 0xe1, 0x69, - 0xa5, 0x99, 0x21, 0x4f, 0x13, 0x63, 0x64, 0x35, 0x33, 0x64, 0x6e, 0x85, 0xa7, 0x95, 0x66, 0x86, - 0x3c, 0x4d, 0x8c, 0x91, 0xd5, 0xcc, 0x90, 0xb9, 0x15, 0x9e, 0x56, 0x9a, 0x19, 0xf2, 0x34, 0x31, - 0x46, 0x96, 0xd7, 0x19, 0x3a, 0x3e, 0x3e, 0xde, 0x37, 0x4a, 0x53, 0x56, 0xbc, 0x06, 0x92, 0xef, - 0x5c, 0x77, 0x84, 0x23, 0xee, 0x97, 0x25, 0x4e, 0x44, 0xaf, 0x81, 0xe4, 0xeb, 0x7e, 0x00, 0x9d, - 0x26, 0x40, 0x45, 0x60, 0xbd, 0x06, 0xda, 0xd9, 0xd9, 0x59, 0x0f, 0x81, 0x92, 0xa0, 0x90, 0x29, - 0x03, 0xe6, 0x35, 0xd0, 0xc2, 0xc2, 0xc2, 0x07, 0x11, 0x8b, 0x1f, 0x3b, 0x41, 0xb0, 0x11, 0x2d, - 0xf5, 0xd8, 0x52, 0xc0, 0xd7, 0xa7, 0xb1, 0xa3, 0x0d, 0x1c, 0x90, 0x03, 0xe1, 0x53, 0x67, 0x67, - 0xe7, 0x33, 0xc9, 0xd2, 0x5f, 0x22, 0x63, 0x57, 0xac, 0x24, 0x06, 0x38, 0x64, 0x4b, 0x9b, 0x86, - 0x3d, 0xf3, 0x36, 0x43, 0x6b, 0x6b, 0x6b, 0x73, 0x02, 0xf3, 0x59, 0x41, 0xf0, 0xc6, 0x6b, 0x00, - 0x19, 0x2e, 0x2f, 0x5e, 0x02, 0xc9, 0xaf, 0xb5, 0x4a, 0x23, 0x23, 0x23, 0xaf, 0x45, 0x2a, 0xb2, - 0x72, 0x24, 0xc6, 0xdf, 0xdb, 0x69, 0xf5, 0x04, 0xd4, 0x7d, 0x7e, 0xfe, 0xb3, 0x7e, 0x79, 0x79, - 0xf9, 0xfd, 0xec, 0xec, 0xec, 0x56, 0x08, 0xc3, 0x6d, 0x06, 0xe1, 0x4e, 0x08, 0x4d, 0xe4, 0x5d, - 0x86, 0x64, 0x9b, 0xad, 0xf6, 0xf7, 0xf7, 0xbf, 0x15, 0x91, 0xc8, 0x0e, 0xb6, 0x1c, 0x32, 0xa4, - 0x4f, 0xb9, 0xfc, 0x6c, 0x39, 0xf9, 0xdc, 0xd9, 0x1e, 0x1a, 0x1a, 0x1a, 0xdf, 0xde, 0xde, 0xfe, - 0x18, 0x02, 0x1d, 0x8a, 0xd7, 0xdb, 0xcd, 0xce, 0x90, 0xdd, 0xf6, 0x67, 0xcb, 0x01, 0x66, 0x6c, - 0x6c, 0xec, 0xa7, 0xf9, 0xf9, 0xf9, 0xbf, 0x43, 0x18, 0x64, 0x48, 0x03, 0x31, 0x33, 0x84, 0xa0, - 0x97, 0xb0, 0x8b, 0x82, 0x6f, 0x98, 0x1b, 0x5e, 0xb0, 0xcd, 0x06, 0x07, 0x07, 0x9f, 0xcb, 0xe7, - 0x0e, 0x8e, 0xe8, 0x4f, 0x62, 0x78, 0x87, 0x3b, 0x10, 0xd3, 0x9f, 0x41, 0x1a, 0x20, 0xae, 0x1e, - 0x7c, 0x65, 0x2e, 0xd7, 0x35, 0xa6, 0xe0, 0x34, 0x5b, 0x5a, 0x5a, 0x9a, 0x19, 0x18, 0x18, 0x78, - 0x5f, 0x2c, 0x16, 0xff, 0x11, 0x15, 0x00, 0x41, 0x66, 0x98, 0x1d, 0x3e, 0x3b, 0x00, 0xd0, 0x26, - 0x4d, 0x77, 0x69, 0x48, 0x86, 0xf0, 0xa1, 0xb9, 0xba, 0xba, 0xba, 0x30, 0x3c, 0x3c, 0xfc, 0x6e, - 0x71, 0x71, 0x11, 0xef, 0x6b, 0x78, 0xf8, 0x01, 0x81, 0xec, 0xc0, 0xd0, 0xc6, 0xb3, 0xe3, 0x02, - 0x92, 0x6e, 0x03, 0x87, 0x3a, 0x4b, 0x90, 0xb5, 0x2b, 0x07, 0x12, 0xf1, 0xf2, 0x0b, 0xe7, 0x52, - 0x51, 0x7e, 0xd8, 0x57, 0xdc, 0xda, 0xda, 0xfa, 0x63, 0x6e, 0x6e, 0x6e, 0x69, 0x62, 0x62, 0xe2, - 0x37, 0xf9, 0x55, 0x30, 0x44, 0x63, 0x5b, 0xe1, 0x14, 0x43, 0x1d, 0xd9, 0x81, 0xd9, 0x30, 0x71, - 0x50, 0x12, 0x1a, 0x3d, 0xc6, 0x6f, 0x14, 0x0a, 0x85, 0xef, 0x64, 0x00, 0x60, 0x38, 0xc2, 0x69, - 0xf8, 0xaf, 0x3e, 0xff, 0xb3, 0x4f, 0x2f, 0x5d, 0x55, 0x17, 0x2d, 0x0a, 0xcf, 0x05, 0x0d, 0x0f, - 0x3d, 0xa0, 0x08, 0x82, 0x36, 0x8f, 0x69, 0x5c, 0xa3, 0xaf, 0xe3, 0x73, 0xc3, 0xad, 0x27, 0xc3, - 0xd1, 0x02, 0x10, 0x4c, 0x86, 0x5f, 0x6b, 0x00, 0x06, 0xe2, 0xe9, 0x35, 0x88, 0xae, 0x4b, 0x48, - 0xaa, 0x42, 0x01, 0x0c, 0x86, 0x38, 0x6e, 0x23, 0x88, 0x66, 0x66, 0x00, 0x44, 0x10, 0x7e, 0x88, - 0x12, 0x84, 0x9e, 0x10, 0x7a, 0x4e, 0x5d, 0xe7, 0x1a, 0x41, 0x66, 0xf8, 0x00, 0xda, 0x3f, 0x10, - 0x02, 0x04, 0xcd, 0x5c, 0x90, 0xa1, 0xc2, 0x05, 0x29, 0x06, 0xe2, 0x98, 0x19, 0x02, 0xc1, 0xb3, - 0x0f, 0xe3, 0xb6, 0xe1, 0xda, 0x24, 0x28, 0x19, 0x0e, 0x0a, 0xd7, 0x0a, 0x80, 0x70, 0xba, 0x70, - 0xab, 0xe9, 0xec, 0x68, 0x98, 0x2c, 0x19, 0x32, 0x93, 0xab, 0xc5, 0x28, 0x14, 0x63, 0xc8, 0x12, - 0xcc, 0x95, 0x0d, 0xc6, 0xd1, 0x23, 0x9e, 0x26, 0x55, 0x53, 0xec, 0x35, 0xcc, 0x00, 0xb6, 0x1c, - 0x4e, 0x15, 0x02, 0x41, 0xb8, 0x86, 0x42, 0x60, 0x16, 0x18, 0xc4, 0xb3, 0xe8, 0x45, 0x21, 0x10, - 0x05, 0x7d, 0xa8, 0x53, 0x24, 0xeb, 0x1a, 0xc0, 0xae, 0x33, 0x96, 0x1e, 0xf3, 0xc4, 0x16, 0x00, - 0xe1, 0x4e, 0x69, 0x20, 0x66, 0x86, 0x20, 0xf4, 0xb1, 0x93, 0x24, 0x0c, 0x40, 0x04, 0x8a, 0xf6, - 0x14, 0x46, 0xef, 0x82, 0xc2, 0x18, 0xfb, 0x19, 0x07, 0x8f, 0x42, 0x7f, 0xde, 0xb2, 0xda, 0x00, - 0xc2, 0x85, 0x28, 0x08, 0x84, 0x78, 0xc0, 0xa1, 0x10, 0x84, 0xfe, 0xbc, 0x37, 0xfd, 0x5f, 0xbd, - 0x30, 0xeb, 0xf0, 0x2e, 0xd3, 0xe2, 0x75, 0x5d, 0xc7, 0x62, 0x65, 0xce, 0x13, 0xab, 0x42, 0x03, - 0x41, 0x38, 0x8c, 0x17, 0x11, 0x84, 0x3e, 0x76, 0x12, 0xc7, 0x00, 0xe7, 0xe0, 0x10, 0xdb, 0xf0, - 0xd5, 0x18, 0xe6, 0xe1, 0x1c, 0x9c, 0xd3, 0xd9, 0x47, 0x20, 0x04, 0xeb, 0xcc, 0x10, 0x82, 0x5e, - 0x4f, 0x92, 0xb6, 0xae, 0x05, 0xb0, 0xae, 0x3d, 0xea, 0x71, 0x86, 0x35, 0x38, 0xc6, 0x3a, 0xbc, - 0x2e, 0x9c, 0x4b, 0xf7, 0x05, 0xa7, 0x1c, 0x07, 0x70, 0xf2, 0x10, 0xc0, 0xf6, 0x65, 0x17, 0xa5, - 0x6c, 0x70, 0x5e, 0x86, 0xb3, 0x0d, 0x6f, 0xd7, 0xed, 0x36, 0xae, 0xd1, 0x7d, 0x9c, 0x83, 0x9e, - 0x63, 0x6c, 0x1b, 0xcf, 0x0c, 0xd9, 0x00, 0x6c, 0x9b, 0xc0, 0x1a, 0x2a, 0x7a, 0x71, 0xd6, 0x5d, - 0xde, 0xee, 0xc3, 0x92, 0xec, 0xd3, 0xcb, 0xbb, 0xfa, 0xcc, 0x38, 0x80, 0x10, 0x00, 0x03, 0x84, - 0x0e, 0xbe, 0x0c, 0x28, 0x3d, 0x9f, 0x4c, 0x5f, 0x36, 0x3f, 0xc7, 0x6c, 0x6f, 0xc7, 0xa1, 0xcd, - 0xc2, 0x58, 0xb6, 0x23, 0x1e, 0xa2, 0xf9, 0x86, 0xc0, 0xc1, 0xcb, 0x00, 0xe1, 0x5c, 0xf4, 0xb6, - 0x10, 0xdd, 0xd6, 0x75, 0xc4, 0xdb, 0xed, 0xb8, 0x39, 0xd8, 0x5f, 0xe6, 0x99, 0x21, 0xdd, 0x69, - 0x4f, 0x98, 0x05, 0xd0, 0xbe, 0x56, 0xcf, 0xcb, 0xba, 0x2b, 0xc6, 0xd5, 0xc7, 0x78, 0xf8, 0x4a, - 0xe3, 0x26, 0x16, 0x62, 0x79, 0xba, 0x99, 0xce, 0x3a, 0x55, 0xd2, 0x88, 0x4c, 0x13, 0x53, 0x26, - 0x17, 0xdb, 0x2d, 0xae, 0x64, 0xc9, 0x8c, 0x6b, 0x8e, 0xcc, 0x62, 0xc2, 0x49, 0xaa, 0xbd, 0x2e, - 0xb8, 0x1c, 0xa2, 0x6b, 0x15, 0xee, 0x82, 0xc9, 0xd2, 0x57, 0x13, 0x40, 0x96, 0x85, 0x72, 0x19, - 0xfb, 0x1f, 0xc1, 0xeb, 0xcc, 0x70, 0xd6, 0x0c, 0xd1, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderRightHandle3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x78, 0x08, 0x06, 0x00, 0x00, 0x00, 0x5c, 0x89, 0xc4, - 0xad, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x44, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x02, 0x01, 0x12, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x87, - 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x26, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x4e, 0xa0, 0x03, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x54, 0xdc, - 0xcf, 0x00, 0x00, 0x01, 0x59, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, 0x6f, 0x6d, - 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, - 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, - 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, 0x74, 0x61, - 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, 0x50, 0x20, - 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x72, - 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x77, - 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, 0x32, 0x32, - 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, 0x23, 0x22, - 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, 0x62, 0x6f, - 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, - 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, - 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, - 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, - 0x52, 0x44, 0x46, 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, - 0x3e, 0x0a, 0x4c, 0xc2, 0x27, 0x59, 0x00, 0x00, 0x0a, 0x85, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, - 0xed, 0x9c, 0xdf, 0xab, 0x55, 0x5b, 0x15, 0xc7, 0x3d, 0x76, 0xac, 0xae, 0x5e, 0xf2, 0x66, 0x3f, - 0x10, 0xcc, 0x20, 0xdf, 0xfc, 0x11, 0x41, 0x10, 0x17, 0xa9, 0x87, 0x5e, 0x82, 0x5e, 0xea, 0x41, - 0x5f, 0xc4, 0xd4, 0xb7, 0x7a, 0x88, 0x08, 0x2e, 0xa1, 0xf8, 0x24, 0x5c, 0x2e, 0x8a, 0x44, 0x0f, - 0x81, 0x7f, 0x41, 0x12, 0x78, 0xb1, 0x08, 0x12, 0x51, 0x1f, 0xa4, 0xa4, 0x30, 0xc9, 0xac, 0x38, - 0x84, 0x60, 0x04, 0xf9, 0x23, 0xf3, 0x57, 0x1c, 0x6f, 0xde, 0xce, 0x3d, 0xf7, 0x78, 0xfc, 0x71, - 0x1b, 0x9f, 0xb5, 0xf7, 0x77, 0x39, 0xf6, 0xdc, 0x73, 0xae, 0xbd, 0xf6, 0xda, 0xfb, 0x9c, 0xeb, - 0x5e, 0x6b, 0x4d, 0x98, 0x7b, 0xfc, 0x98, 0x63, 0xcc, 0x35, 0xe7, 0xe7, 0x8c, 0xb9, 0xd7, 0xde, - 0x47, 0xcf, 0x5a, 0xb1, 0xa2, 0x6d, 0x2d, 0x81, 0xe5, 0x24, 0x30, 0x65, 0x17, 0xa3, 0x4f, 0x7a, - 0xfb, 0x60, 0xb9, 0x37, 0x50, 0x17, 0x70, 0x21, 0xb7, 0x25, 0x07, 0xe9, 0xc1, 0xbd, 0xac, 0x95, - 0x37, 0x2a, 0x84, 0x51, 0xf3, 0xc3, 0x1f, 0x4a, 0x66, 0x03, 0x6b, 0x65, 0x74, 0x24, 0xed, 0x1c, - 0x17, 0xe0, 0x51, 0x36, 0x54, 0x25, 0xb7, 0x4a, 0x4e, 0x92, 0x82, 0x07, 0x37, 0x2e, 0x20, 0xc9, - 0x8b, 0x8d, 0x30, 0x30, 0x68, 0xd3, 0x83, 0xc6, 0xfd, 0xa5, 0x87, 0x89, 0xf5, 0x79, 0x3d, 0x3a, - 0xb0, 0x3e, 0xde, 0xe3, 0xe9, 0x18, 0x1f, 0x26, 0x44, 0x6d, 0x0c, 0xf9, 0xbc, 0xdb, 0xc3, 0x25, - 0x2a, 0xa6, 0xac, 0x3f, 0x8c, 0xc3, 0x4e, 0xcd, 0x11, 0x8b, 0xed, 0xf3, 0x4d, 0x9b, 0xe7, 0x63, - 0xd6, 0x43, 0x50, 0xa1, 0xdd, 0x97, 0xb8, 0x0c, 0x0e, 0x36, 0xe6, 0xfb, 0x33, 0xb3, 0xe9, 0x4f, - 0xad, 0xfb, 0xf5, 0x79, 0x00, 0x29, 0xbf, 0xa5, 0xf4, 0x35, 0x62, 0x7d, 0x6e, 0x5f, 0x40, 0x91, - 0x63, 0xea, 0x03, 0x6b, 0x45, 0x01, 0xcb, 0x3d, 0x66, 0xcb, 0x59, 0xb4, 0x3e, 0x67, 0xfd, 0x9d, - 0x27, 0x4f, 0x9e, 0xfc, 0xf3, 0xf1, 0xe3, 0xc7, 0xff, 0xb8, 0x7f, 0xff, 0xfe, 0xef, 0xf7, 0xef, - 0xdf, 0xff, 0xbb, 0x53, 0xa7, 0x4e, 0xbd, 0x6f, 0xeb, 0xa1, 0x0a, 0x81, 0xb7, 0xd8, 0xd5, 0x4d, - 0xe4, 0x2d, 0xdc, 0x4b, 0x68, 0xe7, 0x81, 0x4e, 0x29, 0x13, 0xe3, 0xc2, 0xbb, 0xaa, 0x2d, 0x70, - 0x22, 0xda, 0xf3, 0xe7, 0xcf, 0xdf, 0x9b, 0x9b, 0x9b, 0x3b, 0x7d, 0xe3, 0xc6, 0x8d, 0xef, 0x1f, - 0x3c, 0x78, 0x70, 0x93, 0x2d, 0xff, 0x35, 0xeb, 0x6b, 0xac, 0xaf, 0xb2, 0xce, 0xc9, 0xf9, 0x88, - 0xeb, 0xdc, 0xf0, 0x7c, 0xa7, 0xba, 0x8a, 0xba, 0x0d, 0x0f, 0xd9, 0x26, 0x82, 0x5a, 0xb0, 0x48, - 0x83, 0xf8, 0xee, 0xbd, 0x7b, 0xf7, 0x0e, 0xef, 0xd8, 0xb1, 0xe3, 0x73, 0xb6, 0xdd, 0x4f, 0x5a, - 0x07, 0x20, 0xf0, 0x96, 0x0f, 0x60, 0xb0, 0xa6, 0x89, 0x32, 0x9f, 0x3d, 0x7b, 0x76, 0xf7, 0xfa, - 0xf5, 0xeb, 0x6f, 0xac, 0x5f, 0xbf, 0xfe, 0x33, 0x06, 0x6d, 0xad, 0x75, 0xde, 0xaf, 0x43, 0x80, - 0xbe, 0xf2, 0xd0, 0x8b, 0x2a, 0x8f, 0xb1, 0x72, 0x6d, 0xa2, 0x48, 0x25, 0x16, 0xbb, 0xb0, 0xb0, - 0xf0, 0x97, 0x63, 0xc7, 0x8e, 0x7d, 0xd1, 0x76, 0x4c, 0xf5, 0xbd, 0x62, 0x3d, 0x84, 0xc7, 0x31, - 0xf6, 0x00, 0x8b, 0xe0, 0x59, 0x68, 0x89, 0x96, 0x58, 0xcb, 0xc4, 0xb9, 0x9f, 0x3e, 0x7d, 0x7a, - 0xef, 0xfc, 0xf9, 0xf3, 0xdf, 0xb4, 0x2d, 0x7f, 0xca, 0xba, 0x7f, 0xef, 0xf3, 0xc7, 0x77, 0x6c, - 0xf0, 0x5e, 0xba, 0xbb, 0x6a, 0x89, 0x9f, 0x75, 0x32, 0xc4, 0x7e, 0xda, 0x0b, 0xd7, 0xae, 0x5d, - 0xfb, 0xd1, 0x96, 0x2d, 0x5b, 0x4e, 0x5a, 0xd0, 0x82, 0xf5, 0xc7, 0xd6, 0x75, 0xd7, 0x0c, 0x25, - 0xf3, 0xc8, 0x87, 0x1e, 0xb6, 0xa2, 0xb1, 0x15, 0xb5, 0x02, 0xa7, 0x9d, 0x5f, 0xbd, 0x7a, 0xf5, - 0x07, 0xdb, 0xb6, 0x6d, 0xfb, 0x85, 0xd9, 0xef, 0x59, 0xe7, 0x63, 0x0b, 0x0d, 0x10, 0x82, 0x21, - 0x29, 0x3f, 0x32, 0xd6, 0x7c, 0x5c, 0xcf, 0x38, 0xa5, 0x5b, 0xbb, 0x66, 0x15, 0xf7, 0x93, 0xd3, - 0xa7, 0x4f, 0x7f, 0xc5, 0x36, 0xa6, 0xbb, 0x2d, 0x7b, 0xd4, 0xfb, 0x9a, 0x74, 0x24, 0xad, 0xfc, - 0x0d, 0xa1, 0x13, 0xdf, 0x79, 0x9d, 0xb8, 0x37, 0xb3, 0x92, 0x0b, 0xe6, 0x3d, 0xef, 0xf0, 0xe1, - 0xc3, 0x5f, 0xb6, 0x5d, 0x7e, 0xda, 0x3a, 0x5f, 0x2b, 0xf9, 0xbc, 0x17, 0x7e, 0xe6, 0x2b, 0xf3, - 0x9e, 0x67, 0x69, 0xfd, 0xad, 0x96, 0x47, 0x55, 0xdb, 0x9c, 0x9f, 0x9f, 0x9f, 0xd9, 0xb8, 0x71, - 0xe3, 0xb7, 0x1e, 0x3e, 0x7c, 0xf8, 0x3f, 0xf3, 0xe9, 0x5b, 0x07, 0xc3, 0xc3, 0x1c, 0xdb, 0xe8, - 0x71, 0xad, 0xe5, 0x51, 0x15, 0xb8, 0xd5, 0xab, 0x57, 0x7f, 0xe9, 0xc2, 0x85, 0x0b, 0xdf, 0x31, - 0x7b, 0xb5, 0x75, 0xee, 0xae, 0xda, 0x6f, 0xea, 0xd8, 0x2a, 0xd5, 0xcb, 0xe8, 0x51, 0xd6, 0x44, - 0x3e, 0xb0, 0x56, 0xfa, 0xe6, 0xcd, 0x9b, 0xdf, 0xd8, 0xbe, 0x7d, 0xfb, 0x27, 0x6c, 0x53, 0xc0, - 0x63, 0xbf, 0x1e, 0x84, 0xd7, 0xd9, 0x77, 0x68, 0xe3, 0x8b, 0xb6, 0xda, 0x83, 0x9b, 0x9e, 0x9e, - 0xfe, 0xec, 0xf1, 0xe3, 0xc7, 0xbf, 0x6b, 0xbb, 0xe7, 0x7d, 0x4e, 0x55, 0x07, 0x20, 0x0f, 0xc9, - 0xeb, 0x31, 0x50, 0x7d, 0xe3, 0xb5, 0x07, 0x07, 0x85, 0x4d, 0x9b, 0x36, 0x7d, 0x6f, 0xe7, 0xce, - 0x9d, 0xdc, 0x24, 0xa8, 0x3a, 0xbe, 0x45, 0x08, 0x9c, 0xa4, 0xb9, 0x72, 0x90, 0x7d, 0x90, 0x18, - 0x0c, 0x5b, 0x23, 0xc0, 0xad, 0x5c, 0xb9, 0xf2, 0xd5, 0x03, 0x07, 0x0e, 0x7c, 0xc3, 0x36, 0x4f, - 0xd5, 0x09, 0x9c, 0x67, 0x11, 0xc2, 0x0a, 0x6d, 0x1f, 0x9b, 0xe9, 0x8d, 0x00, 0xc7, 0x4e, 0xad, - 0xea, 0x00, 0xc7, 0x51, 0xe5, 0x17, 0x01, 0xec, 0x5b, 0xd5, 0xe6, 0x21, 0x79, 0xdd, 0x42, 0x7a, - 0x5a, 0xcf, 0x58, 0x63, 0xc0, 0xad, 0x5b, 0xb7, 0xee, 0xab, 0x5b, 0xb7, 0x6e, 0x7d, 0xd5, 0x50, - 0x7c, 0xd4, 0xba, 0xbe, 0xf4, 0x0b, 0x06, 0x52, 0x7a, 0x0f, 0xad, 0x94, 0xd1, 0x18, 0x70, 0x76, - 0x5c, 0x5f, 0x39, 0x7a, 0xf4, 0xe8, 0xd7, 0x0c, 0x04, 0x15, 0x27, 0x70, 0x70, 0x09, 0x81, 0xc9, - 0x96, 0x24, 0xa6, 0xaf, 0x35, 0x06, 0x1c, 0x3b, 0xb7, 0x8f, 0x26, 0xaf, 0x9b, 0xe0, 0xb8, 0xd2, - 0x01, 0x13, 0xeb, 0xe6, 0x1e, 0xdc, 0x1a, 0x05, 0x6e, 0xed, 0xda, 0xb5, 0x5f, 0x30, 0x24, 0x54, - 0x1b, 0x5f, 0xbd, 0xd8, 0x7b, 0xaa, 0xaa, 0xe4, 0x97, 0xb4, 0xd0, 0xac, 0xe5, 0x76, 0xa3, 0xc0, - 0xad, 0x59, 0xb3, 0xe6, 0xf3, 0xb6, 0x7d, 0xaa, 0x4d, 0x47, 0x15, 0x10, 0x39, 0x8c, 0x0c, 0x4d, - 0xc9, 0x17, 0x26, 0x69, 0x4c, 0x5b, 0xb5, 0x6a, 0x15, 0xdf, 0x20, 0x80, 0xc6, 0xbe, 0x7d, 0xc5, - 0x85, 0xf0, 0xa2, 0xdf, 0x4f, 0x3d, 0xa8, 0x46, 0x55, 0x9c, 0xdd, 0x20, 0xf8, 0x35, 0x13, 0x7b, - 0x06, 0x9e, 0xaa, 0x4d, 0xd2, 0x73, 0x19, 0xa8, 0x37, 0x0d, 0x1c, 0xef, 0x6d, 0x80, 0x62, 0xdf, - 0x74, 0x5f, 0x69, 0x5e, 0xb7, 0xa1, 0x7c, 0x2c, 0xf4, 0x33, 0x96, 0x25, 0x67, 0x4a, 0x83, 0x5e, - 0x04, 0x4c, 0x00, 0x3d, 0x18, 0x74, 0xf5, 0x42, 0x24, 0x8d, 0xaa, 0xb8, 0x2e, 0x09, 0x81, 0xf1, - 0x7b, 0xf7, 0xf0, 0x0a, 0x81, 0x69, 0xd0, 0x27, 0xcb, 0xd7, 0x04, 0x29, 0x78, 0x92, 0xec, 0x79, - 0x28, 0x78, 0x4d, 0x04, 0xe7, 0x61, 0xa9, 0x48, 0x04, 0x4d, 0x32, 0xf4, 0xcb, 0xce, 0x65, 0x13, - 0xc1, 0xe5, 0x9b, 0xef, 0x2a, 0xa5, 0x61, 0xf9, 0xc4, 0x26, 0x82, 0x53, 0xc5, 0x49, 0x8a, 0x87, - 0x07, 0x58, 0x34, 0x96, 0xc5, 0x37, 0x11, 0x9c, 0x40, 0x8d, 0x24, 0x5b, 0x70, 0x1d, 0x7c, 0xbe, - 0xda, 0x4a, 0x01, 0x6d, 0x22, 0x38, 0x7f, 0x0c, 0xbd, 0x0e, 0xb0, 0xd2, 0x00, 0x9b, 0x08, 0x4e, - 0x15, 0x55, 0x1a, 0x92, 0x12, 0xbc, 0x6c, 0x32, 0x38, 0xcf, 0x61, 0x68, 0xbd, 0x05, 0x37, 0x34, - 0xb2, 0x4e, 0x42, 0x0b, 0xee, 0x05, 0xb8, 0xa1, 0x8e, 0x6e, 0x0b, 0xee, 0x05, 0xb8, 0x94, 0x16, - 0x05, 0xda, 0x82, 0x4b, 0xe1, 0x1a, 0xe0, 0x6f, 0xc1, 0xf5, 0x03, 0x8a, 0x56, 0x58, 0x18, 0xd6, - 0x44, 0x70, 0x31, 0x30, 0x31, 0x5f, 0xc8, 0xaa, 0xc7, 0x6e, 0x22, 0xb8, 0x1e, 0x00, 0x55, 0x8d, - 0x16, 0x5c, 0x45, 0x72, 0x2d, 0xb8, 0x16, 0x5c, 0x45, 0x02, 0x15, 0xd3, 0xda, 0x8a, 0x6b, 0xc1, - 0x55, 0x24, 0x50, 0x31, 0xad, 0xad, 0xb8, 0x16, 0x5c, 0x45, 0x02, 0x15, 0xd3, 0xda, 0x8a, 0x6b, - 0xc1, 0x55, 0x24, 0x50, 0x31, 0xad, 0xad, 0xb8, 0x16, 0x5c, 0x45, 0x02, 0x15, 0xd3, 0xda, 0x8a, - 0x6b, 0xc1, 0x55, 0x24, 0x50, 0x31, 0xad, 0xad, 0xb8, 0x16, 0x5c, 0x45, 0x02, 0x15, 0xd3, 0xda, - 0x8a, 0x6b, 0xc1, 0x55, 0x24, 0x50, 0x31, 0xad, 0x51, 0x15, 0x67, 0x4f, 0xc8, 0x79, 0xd2, 0xe5, - 0x34, 0xf0, 0x7f, 0x95, 0x0f, 0xe2, 0xd9, 0x28, 0x70, 0xf6, 0x64, 0x9c, 0x79, 0x03, 0x12, 0x83, - 0x16, 0xf3, 0x15, 0xb2, 0x6b, 0x14, 0xb8, 0xc5, 0xc5, 0x45, 0xfe, 0x36, 0x9f, 0x56, 0x04, 0xaa, - 0x68, 0xac, 0x93, 0x6d, 0xaf, 0x8d, 0x02, 0x67, 0x4f, 0x03, 0xfb, 0x57, 0x77, 0xe7, 0x3c, 0x4a, - 0x6d, 0xa4, 0xd6, 0x28, 0x70, 0xb3, 0xb3, 0xb3, 0xb7, 0x8c, 0x16, 0x15, 0x05, 0xb8, 0x52, 0x95, - 0x95, 0x8a, 0x6b, 0x14, 0xb8, 0x2b, 0x57, 0xae, 0xfc, 0xd5, 0x41, 0x03, 0x9c, 0x87, 0xe7, 0x75, - 0x1b, 0x2a, 0x6e, 0xb5, 0x7e, 0xee, 0x88, 0xdf, 0xba, 0xdd, 0x18, 0x16, 0xec, 0xaf, 0xa4, 0xbf, - 0x7d, 0xeb, 0xd6, 0xad, 0x87, 0xe6, 0xff, 0xaf, 0x75, 0x1e, 0x1f, 0xc4, 0xb3, 0x97, 0x78, 0xfa, - 0x21, 0x15, 0xa8, 0x2a, 0x94, 0x14, 0x58, 0x01, 0xed, 0x91, 0x8d, 0xa9, 0xb8, 0x3b, 0x77, 0xee, - 0xfc, 0xc9, 0xa0, 0xf1, 0xa0, 0x2a, 0x9e, 0xb3, 0xe9, 0xe1, 0x98, 0x39, 0x7c, 0x6b, 0x0c, 0x38, - 0x3b, 0xa6, 0x7f, 0x30, 0x3c, 0x54, 0x0d, 0x9f, 0xe5, 0x54, 0x61, 0xc3, 0x13, 0xeb, 0x66, 0x34, - 0x02, 0x9c, 0x3d, 0x67, 0x69, 0xfe, 0xc8, 0x91, 0x23, 0x80, 0xd3, 0x93, 0x5d, 0x55, 0x71, 0x92, - 0x02, 0xa8, 0xe3, 0x28, 0x3b, 0x29, 0x1b, 0x01, 0xee, 0xf2, 0xe5, 0xcb, 0x6f, 0x5b, 0xc5, 0xbd, - 0x6b, 0x14, 0xc2, 0xa3, 0x2a, 0x30, 0xa5, 0x81, 0x29, 0xa1, 0xf6, 0xe0, 0xec, 0x31, 0x90, 0xb3, - 0xbb, 0x77, 0xef, 0xfe, 0x95, 0x6d, 0x98, 0x23, 0xca, 0x8d, 0x40, 0x55, 0x37, 0x34, 0x2c, 0x41, - 0x43, 0xd6, 0x1e, 0x9c, 0x3d, 0xfe, 0xf1, 0x67, 0x37, 0x6f, 0xde, 0xe4, 0xab, 0x16, 0x77, 0x50, - 0x3d, 0x80, 0xd9, 0xdf, 0x20, 0xe0, 0x40, 0xf3, 0x20, 0xd1, 0x43, 0x3b, 0x0b, 0xd2, 0x4b, 0xad, - 0x3f, 0x8e, 0xd8, 0x07, 0xde, 0xbf, 0x6f, 0xd8, 0xb0, 0xe1, 0x87, 0xf6, 0x10, 0x66, 0xc0, 0xf1, - 0x75, 0x8b, 0x8f, 0x20, 0x3c, 0x0e, 0x8d, 0x23, 0x9b, 0xfa, 0x18, 0xa2, 0xf7, 0x3d, 0x81, 0x8b, - 0x42, 0xac, 0x6d, 0xc5, 0x71, 0x44, 0xf7, 0xed, 0xdb, 0xf7, 0xa6, 0x41, 0xe3, 0x88, 0x0a, 0x94, - 0x8e, 0x2b, 0x70, 0x7c, 0xf3, 0x90, 0x62, 0x7e, 0xef, 0xcb, 0xf4, 0x5a, 0x82, 0xb3, 0x0f, 0xbb, - 0x8b, 0xf6, 0xb4, 0xc2, 0x37, 0xcf, 0x9c, 0x39, 0xf3, 0x1f, 0xdb, 0xa5, 0xa0, 0xf1, 0xac, 0x4c, - 0x7f, 0x44, 0x55, 0x49, 0x29, 0x68, 0x7d, 0xb0, 0xbc, 0xa3, 0x96, 0x47, 0xf5, 0xc4, 0x89, 0x13, - 0x3f, 0xb6, 0x1b, 0xc2, 0x6f, 0x6c, 0xa3, 0x1c, 0x4b, 0x8e, 0xa9, 0x3a, 0x36, 0x55, 0xe7, 0x01, - 0x52, 0x7d, 0xfe, 0x78, 0x7a, 0xa0, 0x31, 0xa8, 0x99, 0xaf, 0x56, 0x8f, 0xcf, 0xa0, 0xd2, 0x4e, - 0x9e, 0x3c, 0xf9, 0xd3, 0x2e, 0x34, 0x2a, 0x8d, 0xce, 0x4d, 0x81, 0x0e, 0x30, 0x41, 0x32, 0x35, - 0x6b, 0x82, 0x14, 0xda, 0x02, 0x26, 0x7f, 0x9f, 0xac, 0xcd, 0x51, 0xe5, 0x3d, 0xed, 0xd0, 0xa1, - 0x43, 0x07, 0x0c, 0xda, 0x6f, 0x6d, 0x97, 0x1c, 0x4b, 0x60, 0x21, 0xe9, 0xdc, 0x08, 0x74, 0x33, - 0x30, 0x35, 0xbb, 0x63, 0xc6, 0xa0, 0x31, 0xa6, 0x26, 0x78, 0x92, 0xf2, 0x67, 0xb2, 0x16, 0x15, - 0xc7, 0xdd, 0x73, 0xef, 0xde, 0xbd, 0x6f, 0x9d, 0x3d, 0x7b, 0x76, 0xd6, 0x76, 0xa5, 0x0a, 0x13, - 0x3c, 0x01, 0xf4, 0xc7, 0xd3, 0xc3, 0x08, 0x01, 0xf6, 0x00, 0x4a, 0x19, 0x13, 0x0d, 0x8e, 0x2a, - 0x3b, 0x77, 0xee, 0xdc, 0xcf, 0x77, 0xed, 0xda, 0x75, 0xde, 0xee, 0x9e, 0x54, 0x94, 0xde, 0xc3, - 0x04, 0x8d, 0xa3, 0x8a, 0x1e, 0x42, 0x13, 0x2c, 0x01, 0xf4, 0xb6, 0x7c, 0x29, 0x66, 0x99, 0x7f, - 0x22, 0xc1, 0xf1, 0xdd, 0xf3, 0xe2, 0xc5, 0x8b, 0xbf, 0xdc, 0xb3, 0x67, 0xcf, 0xaf, 0x6f, 0xdf, - 0xbe, 0xad, 0xbb, 0x26, 0x92, 0xf7, 0x31, 0x40, 0xa1, 0xcb, 0x06, 0x28, 0xe0, 0x3c, 0x1c, 0x33, - 0xf3, 0x0f, 0xb8, 0xa5, 0x40, 0x91, 0xe0, 0xdb, 0xc4, 0x80, 0xe3, 0xf7, 0x69, 0x06, 0xe9, 0xcf, - 0x97, 0x2e, 0x5d, 0xba, 0x6c, 0xcf, 0x81, 0xfb, 0xe3, 0xcc, 0xcc, 0xcc, 0x9c, 0x6d, 0x04, 0x28, - 0xc0, 0xa2, 0xa3, 0xeb, 0x98, 0xaa, 0xf2, 0xf0, 0x17, 0x55, 0x5b, 0x0a, 0x9a, 0xfc, 0x92, 0x36, - 0x4d, 0xd6, 0x72, 0xfb, 0xa5, 0x03, 0xc7, 0x3f, 0xe1, 0x59, 0x45, 0xbd, 0x6f, 0x47, 0x6f, 0xee, - 0xd1, 0xa3, 0x47, 0xff, 0x7e, 0xf0, 0xe0, 0xc1, 0x6d, 0x83, 0xf5, 0x37, 0xfb, 0x5c, 0x36, 0x73, - 0xf7, 0xee, 0x5d, 0xaa, 0x89, 0xc5, 0x73, 0x77, 0x44, 0x57, 0x35, 0x01, 0x48, 0xd0, 0x54, 0x69, - 0x82, 0x46, 0x7c, 0xac, 0x9b, 0x3b, 0xe9, 0x67, 0xac, 0xb0, 0x4d, 0x4f, 0x4d, 0x4d, 0x7d, 0xdd, - 0x22, 0x78, 0xe6, 0x10, 0x8d, 0xbb, 0x2c, 0x9d, 0x3f, 0xd1, 0xd1, 0x9f, 0xe9, 0x84, 0xba, 0x0d, - 0xe5, 0x63, 0xe8, 0xa3, 0xb6, 0xfc, 0xa7, 0x18, 0x99, 0x48, 0x63, 0x48, 0x60, 0x09, 0x14, 0x55, - 0x44, 0xc7, 0x56, 0xa5, 0x01, 0x52, 0x5d, 0xe3, 0xfe, 0xf3, 0x99, 0xd7, 0x05, 0xd2, 0x52, 0xf2, - 0x23, 0x8b, 0x4e, 0xf3, 0xd7, 0xec, 0x78, 0x22, 0xaf, 0x54, 0x1c, 0x3f, 0x19, 0x1a, 0xc0, 0x98, - 0xdc, 0x83, 0xf3, 0xf0, 0x88, 0x91, 0x1d, 0xea, 0xd8, 0x55, 0x9a, 0x16, 0xe9, 0x73, 0xe5, 0x43, - 0xb2, 0x1e, 0xbf, 0x61, 0x74, 0x41, 0x61, 0xdd, 0xea, 0x00, 0x93, 0xae, 0x71, 0xf2, 0x35, 0x87, - 0x74, 0x24, 0x2d, 0x65, 0x77, 0x46, 0x4b, 0xbc, 0x02, 0x8e, 0x8b, 0x72, 0x31, 0x1e, 0x0d, 0x06, - 0x34, 0x9a, 0xaa, 0xcc, 0x4b, 0xf9, 0xb3, 0x80, 0x25, 0x7c, 0x89, 0x6d, 0x4e, 0xf0, 0x54, 0x71, - 0x48, 0x81, 0x92, 0x64, 0x0f, 0x02, 0xcb, 0x1c, 0xca, 0xf1, 0x90, 0x52, 0xba, 0xb6, 0xa3, 0x6b, - 0xcb, 0xf6, 0xb2, 0x67, 0x0c, 0x70, 0xbc, 0x37, 0x20, 0xc3, 0x4a, 0xf3, 0xd0, 0xc6, 0x5d, 0x69, - 0x7e, 0x41, 0xa1, 0x1e, 0x6e, 0x4e, 0x00, 0x04, 0x0d, 0x40, 0xc0, 0x42, 0x7a, 0x1f, 0xb6, 0x72, - 0x95, 0x23, 0x29, 0xbf, 0xa4, 0x85, 0xf6, 0x34, 0xfc, 0xbe, 0x85, 0xb6, 0x1f, 0xcb, 0x74, 0x80, - 0x71, 0x07, 0x42, 0x86, 0xa0, 0xbc, 0x4d, 0xf0, 0x52, 0xc2, 0xf3, 0x0b, 0x95, 0xee, 0x37, 0x0d, - 0x14, 0x3a, 0x3e, 0xe9, 0xb2, 0x7d, 0x5c, 0x19, 0x9d, 0xf9, 0xc3, 0x6e, 0xae, 0xcc, 0xe7, 0x25, - 0x7a, 0xb2, 0x09, 0x5c, 0xf8, 0x04, 0x3f, 0x12, 0xc2, 0x63, 0x8b, 0xcf, 0xc3, 0xc3, 0x5e, 0x8a, - 0xa6, 0x4d, 0x31, 0xb7, 0x40, 0x78, 0x89, 0xae, 0xae, 0xd8, 0x50, 0x2a, 0x1e, 0xbf, 0xd7, 0xc3, - 0x38, 0xae, 0x41, 0xc3, 0x5f, 0xd4, 0xfa, 0xc6, 0x01, 0xc7, 0x51, 0x05, 0x48, 0xd1, 0x51, 0xd5, - 0xa4, 0xcb, 0x05, 0x8e, 0xeb, 0x85, 0x9b, 0xf4, 0x76, 0x38, 0x9e, 0x82, 0x93, 0xf2, 0x6b, 0x3f, - 0x21, 0x90, 0xd0, 0x56, 0x5c, 0x9f, 0x04, 0x1c, 0xef, 0x13, 0x00, 0x09, 0xe1, 0x11, 0x2c, 0xbf, - 0x74, 0x24, 0x6d, 0x1c, 0x00, 0x53, 0x8b, 0xf4, 0x7e, 0xe9, 0x5e, 0x86, 0x3a, 0xb6, 0x7a, 0x0a, - 0x94, 0xc6, 0xc3, 0x5c, 0xf6, 0x22, 0x1f, 0x7a, 0xac, 0x45, 0xc7, 0x01, 0xe7, 0x07, 0xb8, 0xb0, - 0x60, 0x21, 0x19, 0x13, 0x24, 0x49, 0x73, 0xe5, 0x3e, 0xf4, 0x2a, 0xcd, 0x5f, 0x33, 0x96, 0xef, - 0xc7, 0xd1, 0x65, 0x7b, 0x29, 0xff, 0x30, 0x92, 0x6b, 0x29, 0x5e, 0x3a, 0x92, 0xa6, 0xb9, 0x3b, - 0xd6, 0x80, 0x57, 0xc0, 0x01, 0x8b, 0x63, 0x4a, 0xa2, 0x87, 0x26, 0x50, 0xa1, 0xb4, 0xb0, 0x91, - 0xc1, 0x31, 0x47, 0x6a, 0xa1, 0xde, 0x2f, 0x3d, 0x26, 0xf1, 0xc5, 0xba, 0xe6, 0x0e, 0xc7, 0xbc, - 0x5f, 0x3a, 0x92, 0xa6, 0xf9, 0x3b, 0xd6, 0x8b, 0xd7, 0x94, 0x3f, 0xbb, 0x9b, 0x32, 0xa8, 0x4a, - 0x53, 0x0a, 0xbe, 0x10, 0x98, 0x6c, 0xc5, 0x2c, 0x95, 0xf4, 0x8b, 0x95, 0x1e, 0x93, 0xf8, 0xbc, - 0x5f, 0xb6, 0x24, 0xeb, 0x2b, 0xd2, 0xb5, 0x7e, 0xcd, 0x21, 0xbb, 0x94, 0xf4, 0x47, 0x95, 0x09, - 0x80, 0xa3, 0x2e, 0x5b, 0x13, 0x7f, 0x98, 0xe0, 0xd8, 0x0c, 0xeb, 0xd0, 0x5a, 0xbc, 0x0c, 0xfd, - 0x31, 0x5b, 0xf9, 0x5e, 0x86, 0x3a, 0xb6, 0x6f, 0xba, 0x86, 0xf7, 0xe5, 0xba, 0xc0, 0x11, 0x24, - 0x30, 0x5e, 0x97, 0x0f, 0x59, 0x38, 0x51, 0x3e, 0xe3, 0xe8, 0x8a, 0xbf, 0x4e, 0x4c, 0xc7, 0x27, - 0xbf, 0x97, 0x29, 0x9d, 0x15, 0xf9, 0x31, 0xad, 0x50, 0x3e, 0xd9, 0x5e, 0x16, 0x8d, 0x65, 0x71, - 0x7a, 0x8f, 0x13, 0x20, 0x12, 0x04, 0x49, 0x92, 0x40, 0x8d, 0x67, 0x49, 0x4b, 0xfc, 0x12, 0x2e, - 0x5a, 0x76, 0x19, 0x99, 0x8a, 0x61, 0xc9, 0x1a, 0x0b, 0xf5, 0x70, 0x3b, 0x3e, 0x2e, 0x1c, 0xcb, - 0x6d, 0x55, 0x9c, 0x26, 0x13, 0x2c, 0x49, 0xfc, 0x5e, 0xcf, 0x13, 0xbb, 0x7e, 0x6f, 0x0f, 0xd2, - 0x4b, 0x2d, 0xa8, 0x3b, 0x49, 0x18, 0x2b, 0x5b, 0x92, 0x30, 0xf4, 0xd0, 0x96, 0x3f, 0x26, 0xf1, - 0xd1, 0x7c, 0x4e, 0xc7, 0x53, 0xe1, 0xd5, 0x83, 0xf3, 0xe9, 0x4c, 0xae, 0x2a, 0x0b, 0x2f, 0x94, - 0xf2, 0xfb, 0xfc, 0xb2, 0x7a, 0x38, 0x77, 0x98, 0xe7, 0xc7, 0x63, 0x7a, 0x59, 0x9f, 0xe6, 0xf5, - 0xf1, 0xf2, 0x79, 0x39, 0x68, 0x3c, 0x8f, 0x0d, 0xc1, 0x91, 0x18, 0x82, 0x91, 0xad, 0xa4, 0xd2, - 0x93, 0x2b, 0x61, 0x48, 0x19, 0x9b, 0xdf, 0xfb, 0x86, 0xd5, 0xb9, 0xbc, 0xcf, 0x89, 0x2d, 0x67, - 0xd0, 0x78, 0x5f, 0x4e, 0x08, 0x4e, 0x17, 0xf1, 0xb0, 0xc2, 0x49, 0xfd, 0x58, 0xdf, 0x84, 0x43, - 0x3a, 0xc2, 0xb9, 0x63, 0xe9, 0x61, 0x8c, 0xb7, 0xbd, 0xae, 0xb5, 0xfb, 0x39, 0xc2, 0x71, 0x3f, - 0x26, 0xbd, 0x4c, 0x8c, 0x62, 0x73, 0x19, 0x03, 0x97, 0x0f, 0x26, 0x94, 0x4a, 0x17, 0x4a, 0xcc, - 0x35, 0xc8, 0x1d, 0xbb, 0x56, 0xe8, 0x0b, 0x6d, 0xcd, 0x99, 0xf2, 0x6b, 0x1c, 0x59, 0x26, 0xc6, - 0xc7, 0xe7, 0x3a, 0xe0, 0x68, 0x95, 0x27, 0xe8, 0xa4, 0x2f, 0xd9, 0x6b, 0x6a, 0x5d, 0xc3, 0xfa, - 0x63, 0x0b, 0x4c, 0xcd, 0x11, 0x8b, 0xed, 0xf3, 0xe9, 0xd7, 0x49, 0x0c, 0x8c, 0xf3, 0x08, 0xf6, - 0x5d, 0x68, 0x44, 0xc7, 0xa0, 0x4d, 0x0e, 0x1a, 0xf7, 0x97, 0x1f, 0x26, 0xd6, 0xe7, 0xf5, 0xe8, - 0x1e, 0x5c, 0xcf, 0x40, 0x81, 0x31, 0x2e, 0xc0, 0xa3, 0x6c, 0xa0, 0x4a, 0x6e, 0x95, 0x9c, 0x24, - 0x06, 0xc0, 0xa9, 0x8d, 0x0b, 0x88, 0xe6, 0x1b, 0x97, 0x1c, 0x75, 0xc3, 0xa3, 0xe6, 0x47, 0xf7, - 0x01, 0xac, 0x97, 0x15, 0x58, 0x74, 0xc1, 0x25, 0x9d, 0x4b, 0x02, 0xcb, 0x5f, 0x5b, 0x37, 0x07, - 0xef, 0x9b, 0x44, 0x7d, 0xc9, 0x41, 0x4d, 0x22, 0x94, 0x76, 0xcd, 0x75, 0x22, 0xf0, 0x7f, 0x3a, - 0xd5, 0x8c, 0xbe, 0x72, 0x32, 0xcf, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderTrack2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, 0x00, 0x00, 0x00, 0x8e, 0x5f, 0x1f, - 0x96, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x63, 0x3c, 0x75, 0xea, 0xac, - 0xc7, 0xbf, 0x7f, 0xff, 0x67, 0xff, 0xff, 0xcf, 0x20, 0xc3, 0x40, 0x01, 0x60, 0x64, 0x64, 0x78, - 0xc2, 0xc0, 0xc0, 0x9c, 0xce, 0x78, 0xe2, 0xc4, 0x99, 0x47, 0x40, 0xc3, 0x64, 0x29, 0x30, 0x0b, - 0xae, 0x15, 0x64, 0x28, 0x13, 0x90, 0xc7, 0x08, 0x17, 0xa1, 0x9c, 0xf1, 0x1f, 0x68, 0x20, 0xd0, - 0x99, 0x60, 0xe7, 0x52, 0x66, 0x1a, 0xd8, 0x75, 0x4c, 0x8c, 0x69, 0x00, 0xf4, 0x9d, 0x13, 0x90, - 0xe0, 0x80, 0xf3, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderTrack3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x08, 0x06, 0x00, 0x00, 0x00, 0xd4, 0xb5, 0x2e, - 0x54, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x77, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0x63, 0x3c, 0x73, 0xe6, 0x0c, - 0xeb, 0x9f, 0x3f, 0x0c, 0x4d, 0x0c, 0x0c, 0x0c, 0xf1, 0xff, 0xff, 0x33, 0x48, 0x02, 0x69, 0x9a, - 0x01, 0x46, 0x46, 0x86, 0xe7, 0x0c, 0x0c, 0x8c, 0x4b, 0x78, 0x79, 0x39, 0x6a, 0x58, 0x40, 0x96, - 0x02, 0x2d, 0xac, 0xa0, 0x99, 0x6d, 0x48, 0x06, 0x43, 0x3c, 0xf6, 0xbf, 0xf4, 0xd3, 0xa7, 0x1f, - 0xff, 0x99, 0xfe, 0xff, 0x67, 0x8c, 0x43, 0x92, 0xa3, 0x0b, 0x93, 0x91, 0xf1, 0x7f, 0x2c, 0x13, - 0x90, 0x60, 0xa4, 0x8b, 0x6d, 0x48, 0x96, 0x00, 0x3d, 0x0b, 0xf6, 0xf1, 0x62, 0x24, 0x31, 0xba, - 0x30, 0x81, 0x9e, 0x5d, 0xc4, 0xc2, 0xc7, 0xc7, 0x51, 0xfb, 0xf9, 0xf3, 0x0f, 0xa0, 0xaf, 0xff, - 0xc7, 0xd0, 0x27, 0x71, 0x31, 0x2c, 0x64, 0x61, 0x61, 0xa8, 0x03, 0x00, 0xad, 0xe3, 0x2a, 0xed, - 0xfc, 0x71, 0x9f, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderFill2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x04, 0x08, 0x06, 0x00, 0x00, 0x00, 0x8e, 0x5f, 0x1f, - 0x96, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x47, 0x49, 0x44, 0x41, 0x54, 0x18, 0x19, 0x63, 0x64, 0xa8, 0xf9, 0xef, - 0xc1, 0xf0, 0x8f, 0x61, 0x36, 0x03, 0x03, 0x83, 0x0c, 0x10, 0x53, 0x02, 0x9e, 0x30, 0x30, 0x31, - 0xa4, 0x33, 0x32, 0x54, 0xff, 0x7f, 0xc4, 0xf0, 0x9f, 0x41, 0x96, 0x12, 0x93, 0x90, 0xf4, 0x3e, - 0x61, 0x02, 0x1a, 0xc6, 0x88, 0x24, 0x40, 0x19, 0x93, 0x91, 0xe1, 0x3f, 0x13, 0xc8, 0x99, 0x40, - 0x53, 0x9e, 0x50, 0x66, 0x12, 0x58, 0xf7, 0x13, 0xa0, 0xd3, 0xd2, 0x00, 0xbe, 0xcf, 0x0d, 0xc0, - 0x10, 0xc9, 0x8a, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXRangeSliderFill3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x06, 0x08, 0x06, 0x00, 0x00, 0x00, 0xd4, 0xb5, 0x2e, - 0x54, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x28, 0x15, 0xbd, 0x92, 0xbb, 0x0d, 0x80, - 0x30, 0x0c, 0x05, 0xcf, 0x51, 0x32, 0x04, 0x0d, 0x93, 0xf1, 0x99, 0x02, 0x89, 0x02, 0x28, 0xd8, - 0x82, 0x92, 0xcf, 0x64, 0x34, 0x0c, 0x01, 0x92, 0x49, 0x28, 0xa2, 0x2c, 0x40, 0xdc, 0xf8, 0xc9, - 0x96, 0x7c, 0x3a, 0xc9, 0xc2, 0xa2, 0x8e, 0x93, 0x19, 0x68, 0x51, 0x0a, 0xdf, 0xff, 0x2b, 0xe1, - 0x42, 0x38, 0xb0, 0x0c, 0xf6, 0x83, 0x2a, 0xfd, 0x7f, 0xb4, 0xe4, 0x72, 0x10, 0x53, 0x3a, 0x6e, - 0xd4, 0xf8, 0xd0, 0x24, 0xab, 0x5c, 0xb1, 0x36, 0x5e, 0x5d, 0x72, 0xd1, 0x22, 0x47, 0x83, 0x31, - 0xec, 0x71, 0x90, 0x2b, 0x08, 0x9b, 0xc5, 0x31, 0xf2, 0x78, 0x6b, 0xa5, 0xca, 0xf2, 0x5c, 0xb0, - 0x52, 0x32, 0xbd, 0x8a, 0x37, 0x19, 0x0d, 0x36, 0x20, 0x19, 0x81, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - - -#pragma mark - Misc Icons - -static const u_int8_t FLEXCheckerPattern[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x03, 0x00, 0x00, 0x00, 0x6c, 0xbb, 0xce, - 0xa4, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0x1a, 0x18, 0x18, 0xff, 0xff, 0xfd, 0x2c, 0xa7, 0x7c, 0x3f, - 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, 0x53, 0x80, 0x80, 0xa0, 0xa8, 0xd6, 0x53, 0x00, 0x00, - 0x00, 0x11, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xfe, 0xc0, 0x80, 0x86, 0xfe, 0x30, - 0xa0, 0x21, 0x00, 0xcf, 0x3f, 0x0b, 0x9b, 0xd8, 0xd3, 0xac, 0x83, 0x00, 0x00, 0x00, 0x00, 0x49, - 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCheckerPattern2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x01, 0x03, 0x00, 0x00, 0x00, 0xda, 0xb9, 0xaf, - 0xbb, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00, - 0x00, 0x06, 0x50, 0x4c, 0x54, 0x45, 0x1a, 0x18, 0x18, 0xff, 0xff, 0xfd, 0x2c, 0xa7, 0x7c, 0x3f, - 0x00, 0x00, 0x00, 0x02, 0x74, 0x52, 0x4e, 0x53, 0x80, 0x80, 0xa0, 0xa8, 0xd6, 0x53, 0x00, 0x00, - 0x00, 0x14, 0x49, 0x44, 0x41, 0x54, 0x08, 0xd7, 0x63, 0x60, 0xe0, 0xff, 0xcf, 0x40, 0x0a, 0xfe, - 0xff, 0x81, 0x81, 0x14, 0x0c, 0x00, 0xbc, 0xcb, 0x23, 0xdd, 0xc8, 0xaf, 0xa2, 0x74, 0x00, 0x00, - 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXCheckerPattern3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x30, 0x08, 0x06, 0x00, 0x00, 0x01, 0x20, 0x05, 0xc9, - 0x11, 0x00, 0x00, 0x00, 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61, - 0x05, 0x00, 0x00, 0x00, 0x38, 0x65, 0x58, 0x49, 0x66, 0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x01, 0x87, 0x69, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0xa0, 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x30, 0xa0, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0xf8, 0xff, 0x4e, 0x36, 0x00, 0x00, 0x01, 0x16, 0x49, 0x44, 0x41, 0x54, 0x68, 0x05, 0xed, - 0x98, 0x51, 0x0e, 0xc2, 0x30, 0x0c, 0x43, 0x57, 0xae, 0x0c, 0x5c, 0x82, 0x8d, 0x33, 0x8f, 0x7d, - 0x6c, 0x51, 0x40, 0xb2, 0x88, 0x51, 0x2d, 0x56, 0xc9, 0xfb, 0xb2, 0x42, 0x9a, 0x34, 0xcf, 0x65, - 0x63, 0xb4, 0xe5, 0x31, 0xaf, 0xd3, 0x7e, 0x5d, 0xef, 0xb7, 0x43, 0x4e, 0x97, 0x50, 0x1f, 0x02, - 0x7e, 0xd0, 0xd6, 0xed, 0x3a, 0x92, 0x9f, 0xf3, 0x72, 0xc8, 0x5f, 0x4a, 0x9d, 0x7f, 0x57, 0x31, - 0xdd, 0x26, 0x32, 0xb7, 0x1c, 0x87, 0xa8, 0x72, 0x52, 0xd6, 0xf4, 0x82, 0x37, 0xe6, 0xb9, 0x52, - 0xe6, 0x9f, 0xe3, 0x74, 0x07, 0x7a, 0x41, 0xcb, 0xde, 0xe5, 0xd6, 0xff, 0xa3, 0x44, 0xcf, 0xa0, - 0x5f, 0x70, 0x42, 0xe3, 0xf4, 0x43, 0xd3, 0x1d, 0xe0, 0x59, 0xca, 0xe7, 0x2a, 0x6b, 0x74, 0xc6, - 0x72, 0x4e, 0xd6, 0xf4, 0x8e, 0xf2, 0xe2, 0x8a, 0x76, 0x83, 0xaf, 0x94, 0xe4, 0x88, 0xe0, 0x77, - 0x0d, 0x6d, 0x0d, 0xdd, 0x3c, 0x51, 0xbe, 0x7c, 0x02, 0x37, 0x40, 0xe8, 0x23, 0x2e, 0x47, 0xe4, - 0x7b, 0x51, 0xb0, 0x46, 0x42, 0xee, 0x81, 0x1b, 0x20, 0xf4, 0x11, 0x37, 0xa2, 0x40, 0x81, 0xc4, - 0xf8, 0x88, 0xfc, 0x44, 0x43, 0xde, 0x46, 0x7c, 0x7c, 0x93, 0x3d, 0x41, 0x98, 0x89, 0x84, 0x11, - 0x21, 0x32, 0x11, 0x97, 0x23, 0xa2, 0x7f, 0x17, 0xc5, 0xd6, 0x8a, 0x82, 0x7d, 0xa7, 0x2b, 0x96, - 0x8d, 0x34, 0x39, 0xa1, 0xe8, 0x24, 0x12, 0x1e, 0x40, 0x04, 0xb6, 0x5c, 0xd6, 0x0e, 0x94, 0x51, - 0x89, 0x12, 0xed, 0x80, 0x08, 0x6c, 0xb9, 0xac, 0x1d, 0x28, 0xa3, 0x12, 0x25, 0xda, 0x01, 0x11, - 0xd8, 0x72, 0x59, 0xfa, 0xbd, 0xac, 0x5c, 0x79, 0x4f, 0x64, 0xff, 0x99, 0x64, 0xeb, 0xfb, 0x08, - 0xb1, 0xc4, 0x7a, 0xe7, 0xdb, 0x81, 0xde, 0x44, 0xd9, 0x7a, 0x76, 0x80, 0x25, 0xd6, 0x3b, 0xdf, - 0x0e, 0xf4, 0x26, 0xca, 0xd6, 0xb3, 0x03, 0x2c, 0xb1, 0xde, 0xf9, 0xc3, 0x3b, 0xf0, 0x02, 0x0c, - 0xd8, 0x43, 0xeb, 0xbc, 0x94, 0xc3, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, - 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIndentPattern[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xf9, 0x3c, 0x0f, - 0xcd, 0x00, 0x00, 0x0a, 0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54, 0x53, 0xd9, 0x16, 0x87, - 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20, 0x25, 0xf4, 0x1a, 0x7a, 0x09, 0x20, 0xd2, 0x3b, - 0x48, 0x15, 0x04, 0x51, 0x89, 0x49, 0x80, 0x50, 0x02, 0x86, 0x84, 0x26, 0x76, 0x44, 0x05, 0x46, - 0x14, 0x11, 0x29, 0x56, 0x64, 0x54, 0xc0, 0x01, 0x47, 0x87, 0x22, 0x63, 0x45, 0x14, 0x0b, 0x83, - 0x82, 0x62, 0xd7, 0x09, 0xf2, 0x10, 0x50, 0xc6, 0xc1, 0x51, 0x44, 0x45, 0xe5, 0xdd, 0x8c, 0x6b, - 0x09, 0xef, 0xad, 0x35, 0xf3, 0xde, 0x9a, 0xfd, 0xc7, 0x59, 0xdf, 0xd9, 0xe7, 0xb7, 0xd7, 0xd9, - 0x67, 0xef, 0x7d, 0xd7, 0xba, 0x00, 0x50, 0xfc, 0x82, 0x04, 0xc2, 0x74, 0x58, 0x01, 0x80, 0x34, - 0xa1, 0x58, 0x14, 0xee, 0xeb, 0xc1, 0x5c, 0x12, 0x13, 0xcb, 0xc4, 0xf7, 0x02, 0x18, 0x10, 0x01, - 0x0e, 0x58, 0x01, 0xc0, 0xe1, 0x66, 0x66, 0x04, 0x47, 0xf8, 0x44, 0x02, 0xd4, 0xfc, 0xbd, 0x3d, - 0x99, 0x99, 0xa8, 0x48, 0xc6, 0xb3, 0xf6, 0xee, 0x2e, 0x80, 0x64, 0xbb, 0xdb, 0x2c, 0xbf, 0x50, - 0x26, 0x73, 0xd6, 0xff, 0x7f, 0x91, 0x22, 0x37, 0x43, 0x24, 0x06, 0x00, 0x0a, 0x45, 0xd5, 0x36, - 0x3c, 0x7e, 0x26, 0x17, 0xe5, 0x02, 0x94, 0x53, 0xb3, 0xc5, 0x19, 0x32, 0xff, 0x04, 0xca, 0xf4, - 0x95, 0x29, 0x32, 0x86, 0x31, 0x32, 0x16, 0xa1, 0x09, 0xa2, 0xac, 0x22, 0xe3, 0xc4, 0xaf, 0x6c, - 0xf6, 0xa7, 0xe6, 0x2b, 0xbb, 0xc9, 0x98, 0x97, 0x26, 0xe4, 0xa1, 0x1a, 0x59, 0xce, 0x19, 0xbc, - 0x34, 0x9e, 0x8c, 0xbb, 0x50, 0xde, 0x9a, 0x25, 0xe1, 0xa3, 0x8c, 0x04, 0xa1, 0x5c, 0x98, 0x25, - 0xe0, 0x67, 0xa3, 0x7c, 0x07, 0x65, 0xbd, 0x54, 0x49, 0x9a, 0x00, 0xe5, 0xf7, 0x28, 0xd3, 0xd3, - 0xf8, 0x9c, 0x4c, 0x00, 0x30, 0x14, 0x99, 0x5f, 0xcc, 0xe7, 0x26, 0xa1, 0x6c, 0x89, 0x32, 0x45, - 0x14, 0x19, 0xee, 0x89, 0xf2, 0x02, 0x00, 0x08, 0x94, 0xc4, 0x39, 0xbc, 0x72, 0x0e, 0x8b, 0xf9, - 0x39, 0x68, 0x9e, 0x00, 0x78, 0xa6, 0x67, 0xe4, 0x8a, 0x04, 0x89, 0x49, 0x62, 0xa6, 0x11, 0xd7, - 0x98, 0x69, 0xe5, 0xe8, 0xc8, 0x66, 0xfa, 0xf1, 0xb3, 0x53, 0xf9, 0x62, 0x31, 0x2b, 0x94, 0xc3, - 0x4d, 0xe1, 0x88, 0x78, 0x4c, 0xcf, 0xf4, 0xb4, 0x0c, 0x8e, 0x30, 0x17, 0x80, 0xaf, 0x6f, 0x96, - 0x45, 0x01, 0x25, 0x59, 0x6d, 0x99, 0x68, 0x91, 0xed, 0xad, 0x1c, 0xed, 0xed, 0x59, 0xd6, 0xe6, - 0x68, 0xf9, 0xbf, 0xd9, 0xdf, 0x1e, 0x7e, 0x53, 0xfd, 0x3d, 0xc8, 0x7a, 0xfb, 0x55, 0xf1, 0x26, - 0xec, 0xcf, 0x9e, 0x41, 0x8c, 0x9e, 0x59, 0xdf, 0x6c, 0xec, 0xac, 0x2f, 0xbd, 0x16, 0x00, 0xf6, - 0x24, 0x5a, 0x9b, 0x1d, 0xb3, 0xbe, 0x95, 0x55, 0x00, 0xb4, 0x6d, 0x06, 0x40, 0xe5, 0xe1, 0xac, - 0x4f, 0xef, 0x20, 0x00, 0xf2, 0x05, 0x00, 0xb4, 0xde, 0x9c, 0xf3, 0x1e, 0x86, 0x6c, 0x5e, 0x92, - 0xc4, 0xe2, 0x0c, 0x27, 0x0b, 0x8b, 0xec, 0xec, 0x6c, 0x73, 0x01, 0x9f, 0x6b, 0x2e, 0x2b, 0xe8, - 0x37, 0xfb, 0x9f, 0x82, 0x6f, 0xca, 0xbf, 0x86, 0x39, 0xf7, 0x99, 0xcb, 0xee, 0xfb, 0x56, 0x3b, - 0xa6, 0x17, 0x3f, 0x81, 0x23, 0x49, 0x15, 0x33, 0x65, 0x45, 0xe5, 0xa6, 0xa7, 0xa6, 0x4b, 0x44, - 0xcc, 0xcc, 0x0c, 0x0e, 0x97, 0xcf, 0x64, 0xfd, 0xf7, 0x10, 0xff, 0xe3, 0xc0, 0x39, 0x69, 0xcd, - 0xc9, 0xc3, 0x2c, 0x9c, 0x9f, 0xc0, 0x17, 0xf1, 0x85, 0xe8, 0x55, 0x51, 0xe8, 0x94, 0x09, 0x84, - 0x89, 0x68, 0xbb, 0x85, 0x3c, 0x81, 0x58, 0x90, 0x2e, 0x64, 0x0a, 0x84, 0x7f, 0xd5, 0xe1, 0x7f, - 0x18, 0x36, 0x27, 0x07, 0x19, 0x7e, 0x9d, 0x6b, 0x14, 0x68, 0x75, 0x5f, 0x00, 0x7d, 0x85, 0x39, - 0x50, 0xb8, 0x49, 0x07, 0xc8, 0x6f, 0x3d, 0x00, 0x43, 0x23, 0x03, 0x24, 0x6e, 0x3f, 0x7a, 0x02, - 0x7d, 0xeb, 0x5b, 0x10, 0x31, 0x0a, 0xc8, 0xbe, 0xbc, 0x68, 0xad, 0x91, 0xaf, 0x73, 0x8f, 0x32, - 0x7a, 0xfe, 0xe7, 0xfa, 0x1f, 0x0b, 0x5c, 0x8a, 0x6e, 0xe1, 0x4c, 0x41, 0x22, 0x53, 0xe6, 0xf6, - 0x0c, 0x8f, 0x64, 0x72, 0x25, 0xa2, 0x2c, 0x19, 0xa3, 0xdf, 0x84, 0x6c, 0xc1, 0x02, 0x12, 0x90, - 0x07, 0x74, 0xa0, 0x0a, 0x34, 0x81, 0x2e, 0x30, 0x02, 0x2c, 0x60, 0x0d, 0x1c, 0x80, 0x33, 0x70, - 0x03, 0xde, 0x20, 0x00, 0x84, 0x80, 0x48, 0x10, 0x03, 0x96, 0x03, 0x2e, 0x48, 0x02, 0x69, 0x40, - 0x04, 0xb2, 0x41, 0x3e, 0xd8, 0x00, 0x0a, 0x41, 0x31, 0xd8, 0x01, 0x76, 0x83, 0x6a, 0x70, 0x00, - 0xd4, 0x81, 0x7a, 0xd0, 0x04, 0x4e, 0x82, 0x36, 0x70, 0x06, 0x5c, 0x04, 0x57, 0xc0, 0x0d, 0x70, - 0x0b, 0x0c, 0x80, 0x47, 0x40, 0x0a, 0x86, 0xc1, 0x4b, 0x30, 0x01, 0xde, 0x81, 0x69, 0x08, 0x82, - 0xf0, 0x10, 0x15, 0xa2, 0x41, 0xaa, 0x90, 0x16, 0xa4, 0x0f, 0x99, 0x42, 0xd6, 0x10, 0x1b, 0x5a, - 0x08, 0x79, 0x43, 0x41, 0x50, 0x38, 0x14, 0x03, 0xc5, 0x43, 0x89, 0x90, 0x10, 0x92, 0x40, 0xf9, - 0xd0, 0x26, 0xa8, 0x18, 0x2a, 0x83, 0xaa, 0xa1, 0x43, 0x50, 0x3d, 0xf4, 0x23, 0x74, 0x1a, 0xba, - 0x08, 0x5d, 0x83, 0xfa, 0xa0, 0x07, 0xd0, 0x20, 0x34, 0x06, 0xfd, 0x01, 0x7d, 0x84, 0x11, 0x98, - 0x02, 0xd3, 0x61, 0x0d, 0xd8, 0x00, 0xb6, 0x80, 0xd9, 0xb0, 0x3b, 0x1c, 0x08, 0x47, 0xc2, 0xcb, - 0xe0, 0x44, 0x78, 0x15, 0x9c, 0x07, 0x17, 0xc0, 0xdb, 0xe1, 0x4a, 0xb8, 0x16, 0x3e, 0x0e, 0xb7, - 0xc2, 0x17, 0xe1, 0x1b, 0xf0, 0x00, 0x2c, 0x85, 0x5f, 0xc2, 0x93, 0x08, 0x40, 0xc8, 0x08, 0x03, - 0xd1, 0x46, 0x58, 0x08, 0x1b, 0xf1, 0x44, 0x42, 0x90, 0x58, 0x24, 0x01, 0x11, 0x21, 0x6b, 0x91, - 0x22, 0xa4, 0x02, 0xa9, 0x45, 0x9a, 0x90, 0x0e, 0xa4, 0x1b, 0xb9, 0x8d, 0x48, 0x91, 0x71, 0xe4, - 0x03, 0x06, 0x87, 0xa1, 0x61, 0x98, 0x18, 0x16, 0xc6, 0x19, 0xe3, 0x87, 0x59, 0x8c, 0xe1, 0x62, - 0x56, 0x61, 0xd6, 0x62, 0x4a, 0x30, 0xd5, 0x98, 0x63, 0x98, 0x56, 0x4c, 0x17, 0xe6, 0x36, 0x66, - 0x10, 0x33, 0x81, 0xf9, 0x82, 0xa5, 0x62, 0xd5, 0xb1, 0xa6, 0x58, 0x27, 0xac, 0x3f, 0x76, 0x09, - 0x36, 0x11, 0x9b, 0x8d, 0x2d, 0xc4, 0x56, 0x60, 0x8f, 0x60, 0x5b, 0xb0, 0x97, 0xb1, 0x03, 0xd8, - 0x61, 0xec, 0x3b, 0x1c, 0x0e, 0xc7, 0xc0, 0x19, 0xe2, 0x1c, 0x70, 0x7e, 0xb8, 0x18, 0x5c, 0x32, - 0x6e, 0x35, 0xae, 0x04, 0xb7, 0x0f, 0xd7, 0x8c, 0xbb, 0x80, 0xeb, 0xc3, 0x0d, 0xe1, 0x26, 0xf1, - 0x78, 0xbc, 0x2a, 0xde, 0x14, 0xef, 0x82, 0x0f, 0xc1, 0x73, 0xf0, 0x62, 0x7c, 0x21, 0xbe, 0x0a, - 0x7f, 0x1c, 0x7f, 0x1e, 0xdf, 0x8f, 0x1f, 0xc6, 0xbf, 0x27, 0x90, 0x09, 0x5a, 0x04, 0x6b, 0x82, - 0x0f, 0x21, 0x96, 0x20, 0x24, 0x6c, 0x24, 0x54, 0x10, 0x1a, 0x08, 0xe7, 0x08, 0xfd, 0x84, 0x11, - 0xc2, 0x34, 0x51, 0x81, 0xa8, 0x4f, 0x74, 0x22, 0x86, 0x10, 0x79, 0xc4, 0x5c, 0x62, 0x29, 0xb1, - 0x8e, 0xd8, 0x41, 0xbc, 0x49, 0x1c, 0x26, 0x4e, 0x93, 0x14, 0x49, 0x86, 0x24, 0x17, 0x52, 0x24, - 0x29, 0x99, 0xb4, 0x81, 0x54, 0x49, 0x6a, 0x22, 0x5d, 0x26, 0x3d, 0x26, 0xbd, 0x21, 0x93, 0xc9, - 0x3a, 0x64, 0x47, 0x72, 0x18, 0x59, 0x40, 0x5e, 0x4f, 0xae, 0x24, 0x9f, 0x20, 0x5f, 0x25, 0x0f, - 0x92, 0x3f, 0x50, 0x94, 0x28, 0x26, 0x14, 0x4f, 0x4a, 0x1c, 0x45, 0x42, 0xd9, 0x4e, 0x39, 0x4a, - 0xb9, 0x40, 0x79, 0x40, 0x79, 0x43, 0xa5, 0x52, 0x0d, 0xa8, 0x6e, 0xd4, 0x58, 0xaa, 0x98, 0xba, - 0x9d, 0x5a, 0x4f, 0xbd, 0x44, 0x7d, 0x4a, 0x7d, 0x2f, 0x47, 0x93, 0x33, 0x97, 0xf3, 0x97, 0xe3, - 0xc9, 0xad, 0x93, 0xab, 0x91, 0x6b, 0x95, 0xeb, 0x97, 0x7b, 0x25, 0x4f, 0x94, 0xd7, 0x97, 0x77, - 0x97, 0x5f, 0x2e, 0x9f, 0x27, 0x5f, 0x21, 0x7f, 0x4a, 0xfe, 0xa6, 0xfc, 0xb8, 0x02, 0x51, 0xc1, - 0x40, 0xc1, 0x53, 0x81, 0xa3, 0xb0, 0x56, 0xa1, 0x46, 0xe1, 0xb4, 0xc2, 0x3d, 0x85, 0x49, 0x45, - 0x9a, 0xa2, 0x95, 0x62, 0x88, 0x62, 0x9a, 0x62, 0x89, 0x62, 0x83, 0xe2, 0x35, 0xc5, 0x51, 0x25, - 0xbc, 0x92, 0x81, 0x92, 0xb7, 0x12, 0x4f, 0xa9, 0x40, 0xe9, 0xb0, 0xd2, 0x25, 0xa5, 0x21, 0x1a, - 0x42, 0xd3, 0xa5, 0x79, 0xd2, 0xb8, 0xb4, 0x4d, 0xb4, 0x3a, 0xda, 0x65, 0xda, 0x30, 0x1d, 0x47, - 0x37, 0xa4, 0xfb, 0xd3, 0x93, 0xe9, 0xc5, 0xf4, 0x1f, 0xe8, 0xbd, 0xf4, 0x09, 0x65, 0x25, 0x65, - 0x5b, 0xe5, 0x28, 0xe5, 0x1c, 0xe5, 0x1a, 0xe5, 0xb3, 0xca, 0x52, 0x06, 0xc2, 0x30, 0x60, 0xf8, - 0x33, 0x52, 0x19, 0xa5, 0x8c, 0x93, 0x8c, 0xbb, 0x8c, 0x8f, 0xf3, 0x34, 0xe6, 0xb9, 0xcf, 0xe3, - 0xcf, 0xdb, 0x36, 0xaf, 0x69, 0x5e, 0xff, 0xbc, 0x29, 0x95, 0xf9, 0x2a, 0x6e, 0x2a, 0x7c, 0x95, - 0x22, 0x95, 0x66, 0x95, 0x01, 0x95, 0x8f, 0xaa, 0x4c, 0x55, 0x6f, 0xd5, 0x14, 0xd5, 0x9d, 0xaa, - 0x6d, 0xaa, 0x4f, 0xd4, 0x30, 0x6a, 0x26, 0x6a, 0x61, 0x6a, 0xd9, 0x6a, 0xfb, 0xd5, 0x2e, 0xab, - 0x8d, 0xcf, 0xa7, 0xcf, 0x77, 0x9e, 0xcf, 0x9d, 0x5f, 0x34, 0xff, 0xe4, 0xfc, 0x87, 0xea, 0xb0, - 0xba, 0x89, 0x7a, 0xb8, 0xfa, 0x6a, 0xf5, 0xc3, 0xea, 0x3d, 0xea, 0x93, 0x1a, 0x9a, 0x1a, 0xbe, - 0x1a, 0x19, 0x1a, 0x55, 0x1a, 0x97, 0x34, 0xc6, 0x35, 0x19, 0x9a, 0x6e, 0x9a, 0xc9, 0x9a, 0xe5, - 0x9a, 0xe7, 0x34, 0xc7, 0xb4, 0x68, 0x5a, 0x0b, 0xb5, 0x04, 0x5a, 0xe5, 0x5a, 0xe7, 0xb5, 0x5e, - 0x30, 0x95, 0x99, 0xee, 0xcc, 0x54, 0x66, 0x25, 0xb3, 0x8b, 0x39, 0xa1, 0xad, 0xae, 0xed, 0xa7, - 0x2d, 0xd1, 0x3e, 0xa4, 0xdd, 0xab, 0x3d, 0xad, 0x63, 0xa8, 0xb3, 0x58, 0x67, 0xa3, 0x4e, 0xb3, - 0xce, 0x13, 0x5d, 0x92, 0x2e, 0x5b, 0x37, 0x41, 0xb7, 0x5c, 0xb7, 0x53, 0x77, 0x42, 0x4f, 0x4b, - 0x2f, 0x58, 0x2f, 0x5f, 0xaf, 0x51, 0xef, 0xa1, 0x3e, 0x51, 0x9f, 0xad, 0x9f, 0xa4, 0xbf, 0x47, - 0xbf, 0x5b, 0x7f, 0xca, 0xc0, 0xd0, 0x20, 0xda, 0x60, 0x8b, 0x41, 0x9b, 0xc1, 0xa8, 0xa1, 0x8a, - 0xa1, 0xbf, 0x61, 0x9e, 0x61, 0xa3, 0xe1, 0x63, 0x23, 0xaa, 0x91, 0xab, 0xd1, 0x2a, 0xa3, 0x5a, - 0xa3, 0x3b, 0xc6, 0x38, 0x63, 0xb6, 0x71, 0x8a, 0xf1, 0x3e, 0xe3, 0x5b, 0x26, 0xb0, 0x89, 0x9d, - 0x49, 0x92, 0x49, 0x8d, 0xc9, 0x4d, 0x53, 0xd8, 0xd4, 0xde, 0x54, 0x60, 0xba, 0xcf, 0xb4, 0xcf, - 0x0c, 0x6b, 0xe6, 0x68, 0x26, 0x34, 0xab, 0x35, 0xbb, 0xc7, 0xa2, 0xb0, 0xdc, 0x59, 0x59, 0xac, - 0x46, 0xd6, 0xa0, 0x39, 0xc3, 0x3c, 0xc8, 0x7c, 0xa3, 0x79, 0x9b, 0xf9, 0x2b, 0x0b, 0x3d, 0x8b, - 0x58, 0x8b, 0x9d, 0x16, 0xdd, 0x16, 0x5f, 0x2c, 0xed, 0x2c, 0x53, 0x2d, 0xeb, 0x2c, 0x1f, 0x59, - 0x29, 0x59, 0x05, 0x58, 0x6d, 0xb4, 0xea, 0xb0, 0xfa, 0xc3, 0xda, 0xc4, 0x9a, 0x6b, 0x5d, 0x63, - 0x7d, 0xc7, 0x86, 0x6a, 0xe3, 0x63, 0xb3, 0xce, 0xa6, 0xdd, 0xe6, 0xb5, 0xad, 0xa9, 0x2d, 0xdf, - 0x76, 0xbf, 0xed, 0x7d, 0x3b, 0x9a, 0x5d, 0xb0, 0xdd, 0x16, 0xbb, 0x4e, 0xbb, 0xcf, 0xf6, 0x0e, - 0xf6, 0x22, 0xfb, 0x26, 0xfb, 0x31, 0x07, 0x3d, 0x87, 0x78, 0x87, 0xbd, 0x0e, 0xf7, 0xd8, 0x74, - 0x76, 0x28, 0xbb, 0x84, 0x7d, 0xd5, 0x11, 0xeb, 0xe8, 0xe1, 0xb8, 0xce, 0xf1, 0x8c, 0xe3, 0x07, - 0x27, 0x7b, 0x27, 0xb1, 0xd3, 0x49, 0xa7, 0xdf, 0x9d, 0x59, 0xce, 0x29, 0xce, 0x0d, 0xce, 0xa3, - 0x0b, 0x0c, 0x17, 0xf0, 0x17, 0xd4, 0x2d, 0x18, 0x72, 0xd1, 0x71, 0xe1, 0xb8, 0x1c, 0x72, 0x91, - 0x2e, 0x64, 0x2e, 0x8c, 0x5f, 0x78, 0x70, 0xa1, 0xd4, 0x55, 0xdb, 0x95, 0xe3, 0x5a, 0xeb, 0xfa, - 0xcc, 0x4d, 0xd7, 0x8d, 0xe7, 0x76, 0xc4, 0x6d, 0xc4, 0xdd, 0xd8, 0x3d, 0xd9, 0xfd, 0xb8, 0xfb, - 0x2b, 0x0f, 0x4b, 0x0f, 0x91, 0x47, 0x8b, 0xc7, 0x94, 0xa7, 0x93, 0xe7, 0x1a, 0xcf, 0x0b, 0x5e, - 0x88, 0x97, 0xaf, 0x57, 0x91, 0x57, 0xaf, 0xb7, 0x92, 0xf7, 0x62, 0xef, 0x6a, 0xef, 0xa7, 0x3e, - 0x3a, 0x3e, 0x89, 0x3e, 0x8d, 0x3e, 0x13, 0xbe, 0x76, 0xbe, 0xab, 0x7d, 0x2f, 0xf8, 0x61, 0xfd, - 0x02, 0xfd, 0x76, 0xfa, 0xdd, 0xf3, 0xd7, 0xf0, 0xe7, 0xfa, 0xd7, 0xfb, 0x4f, 0x04, 0x38, 0x04, - 0xac, 0x09, 0xe8, 0x0a, 0xa4, 0x04, 0x46, 0x04, 0x56, 0x07, 0x3e, 0x0b, 0x32, 0x09, 0x12, 0x05, - 0x75, 0x04, 0xc3, 0xc1, 0x01, 0xc1, 0xbb, 0x82, 0x1f, 0x2f, 0xd2, 0x5f, 0x24, 0x5c, 0xd4, 0x16, - 0x02, 0x42, 0xfc, 0x43, 0x76, 0x85, 0x3c, 0x09, 0x35, 0x0c, 0x5d, 0x15, 0xfa, 0x73, 0x18, 0x2e, - 0x2c, 0x34, 0xac, 0x26, 0xec, 0x79, 0xb8, 0x55, 0x78, 0x7e, 0x78, 0x77, 0x04, 0x2d, 0x62, 0x45, - 0x44, 0x43, 0xc4, 0xbb, 0x48, 0x8f, 0xc8, 0xd2, 0xc8, 0x47, 0x8b, 0x8d, 0x16, 0x4b, 0x16, 0x77, - 0x46, 0xc9, 0x47, 0xc5, 0x45, 0xd5, 0x47, 0x4d, 0x45, 0x7b, 0x45, 0x97, 0x45, 0x4b, 0x97, 0x58, - 0x2c, 0x59, 0xb3, 0xe4, 0x46, 0x8c, 0x5a, 0x8c, 0x20, 0xa6, 0x3d, 0x16, 0x1f, 0x1b, 0x15, 0x7b, - 0x24, 0x76, 0x72, 0xa9, 0xf7, 0xd2, 0xdd, 0x4b, 0x87, 0xe3, 0xec, 0xe2, 0x0a, 0xe3, 0xee, 0x2e, - 0x33, 0x5c, 0x96, 0xb3, 0xec, 0xda, 0x72, 0xb5, 0xe5, 0xa9, 0xcb, 0xcf, 0xae, 0x90, 0x5f, 0xc1, - 0x59, 0x71, 0x2a, 0x1e, 0x1b, 0x1f, 0x1d, 0xdf, 0x10, 0xff, 0x89, 0x13, 0xc2, 0xa9, 0xe5, 0x4c, - 0xae, 0xf4, 0x5f, 0xb9, 0x77, 0xe5, 0x04, 0xd7, 0x93, 0xbb, 0x87, 0xfb, 0x92, 0xe7, 0xc6, 0x2b, - 0xe7, 0x8d, 0xf1, 0x5d, 0xf8, 0x65, 0xfc, 0x91, 0x04, 0x97, 0x84, 0xb2, 0x84, 0xd1, 0x44, 0x97, - 0xc4, 0x5d, 0x89, 0x63, 0x49, 0xae, 0x49, 0x15, 0x49, 0xe3, 0x02, 0x4f, 0x41, 0xb5, 0xe0, 0x75, - 0xb2, 0x5f, 0xf2, 0x81, 0xe4, 0xa9, 0x94, 0x90, 0x94, 0xa3, 0x29, 0x33, 0xa9, 0xd1, 0xa9, 0xcd, - 0x69, 0x84, 0xb4, 0xf8, 0xb4, 0xd3, 0x42, 0x25, 0x61, 0x8a, 0xb0, 0x2b, 0x5d, 0x33, 0x3d, 0x27, - 0xbd, 0x2f, 0xc3, 0x34, 0xa3, 0x30, 0x43, 0xba, 0xca, 0x69, 0xd5, 0xee, 0x55, 0x13, 0xa2, 0x40, - 0xd1, 0x91, 0x4c, 0x28, 0x73, 0x59, 0x66, 0xbb, 0x98, 0x8e, 0xfe, 0x4c, 0xf5, 0x48, 0x8c, 0x24, - 0x9b, 0x25, 0x83, 0x59, 0x0b, 0xb3, 0x6a, 0xb2, 0xde, 0x67, 0x47, 0x65, 0x9f, 0xca, 0x51, 0xcc, - 0x11, 0xe6, 0xf4, 0xe4, 0x9a, 0xe4, 0x6e, 0xcb, 0x1d, 0xc9, 0xf3, 0xc9, 0xfb, 0x7e, 0x35, 0x66, - 0x35, 0x77, 0x75, 0x67, 0xbe, 0x76, 0xfe, 0x86, 0xfc, 0xc1, 0x35, 0xee, 0x6b, 0x0e, 0xad, 0x85, - 0xd6, 0xae, 0x5c, 0xdb, 0xb9, 0x4e, 0x77, 0x5d, 0xc1, 0xba, 0xe1, 0xf5, 0xbe, 0xeb, 0x8f, 0x6d, - 0x20, 0x6d, 0x48, 0xd9, 0xf0, 0xcb, 0x46, 0xcb, 0x8d, 0x65, 0x1b, 0xdf, 0x6e, 0x8a, 0xde, 0xd4, - 0x51, 0xa0, 0x51, 0xb0, 0xbe, 0x60, 0x68, 0xb3, 0xef, 0xe6, 0xc6, 0x42, 0xb9, 0x42, 0x51, 0xe1, - 0xbd, 0x2d, 0xce, 0x5b, 0x0e, 0x6c, 0xc5, 0x6c, 0x15, 0x6c, 0xed, 0xdd, 0x66, 0xb3, 0xad, 0x6a, - 0xdb, 0x97, 0x22, 0x5e, 0xd1, 0xf5, 0x62, 0xcb, 0xe2, 0x8a, 0xe2, 0x4f, 0x25, 0xdc, 0x92, 0xeb, - 0xdf, 0x59, 0x7d, 0x57, 0xf9, 0xdd, 0xcc, 0xf6, 0x84, 0xed, 0xbd, 0xa5, 0xf6, 0xa5, 0xfb, 0x77, - 0xe0, 0x76, 0x08, 0x77, 0xdc, 0xdd, 0xe9, 0xba, 0xf3, 0x58, 0x99, 0x62, 0x59, 0x5e, 0xd9, 0xd0, - 0xae, 0xe0, 0x5d, 0xad, 0xe5, 0xcc, 0xf2, 0xa2, 0xf2, 0xb7, 0xbb, 0x57, 0xec, 0xbe, 0x56, 0x61, - 0x5b, 0x71, 0x60, 0x0f, 0x69, 0x8f, 0x64, 0x8f, 0xb4, 0x32, 0xa8, 0xb2, 0xbd, 0x4a, 0xaf, 0x6a, - 0x47, 0xd5, 0xa7, 0xea, 0xa4, 0xea, 0x81, 0x1a, 0x8f, 0x9a, 0xe6, 0xbd, 0xea, 0x7b, 0xb7, 0xed, - 0x9d, 0xda, 0xc7, 0xdb, 0xd7, 0xbf, 0xdf, 0x6d, 0x7f, 0xd3, 0x01, 0x8d, 0x03, 0xc5, 0x07, 0x3e, - 0x1e, 0x14, 0x1c, 0xbc, 0x7f, 0xc8, 0xf7, 0x50, 0x6b, 0xad, 0x41, 0x6d, 0xc5, 0x61, 0xdc, 0xe1, - 0xac, 0xc3, 0xcf, 0xeb, 0xa2, 0xea, 0xba, 0xbf, 0x67, 0x7f, 0x5f, 0x7f, 0x44, 0xed, 0x48, 0xf1, - 0x91, 0xcf, 0x47, 0x85, 0x47, 0xa5, 0xc7, 0xc2, 0x8f, 0x75, 0xd5, 0x3b, 0xd4, 0xd7, 0x37, 0xa8, - 0x37, 0x94, 0x36, 0xc2, 0x8d, 0x92, 0xc6, 0xb1, 0xe3, 0x71, 0xc7, 0x6f, 0xfd, 0xe0, 0xf5, 0x43, - 0x7b, 0x13, 0xab, 0xe9, 0x50, 0x33, 0xa3, 0xb9, 0xf8, 0x04, 0x38, 0x21, 0x39, 0xf1, 0xe2, 0xc7, - 0xf8, 0x1f, 0xef, 0x9e, 0x0c, 0x3c, 0xd9, 0x79, 0x8a, 0x7d, 0xaa, 0xe9, 0x27, 0xfd, 0x9f, 0xf6, - 0xb6, 0xd0, 0x5a, 0x8a, 0x5a, 0xa1, 0xd6, 0xdc, 0xd6, 0x89, 0xb6, 0xa4, 0x36, 0x69, 0x7b, 0x4c, - 0x7b, 0xdf, 0xe9, 0x80, 0xd3, 0x9d, 0x1d, 0xce, 0x1d, 0x2d, 0x3f, 0x9b, 0xff, 0x7c, 0xf4, 0x8c, - 0xf6, 0x99, 0x9a, 0xb3, 0xca, 0x67, 0x4b, 0xcf, 0x91, 0xce, 0x15, 0x9c, 0x9b, 0x39, 0x9f, 0x77, - 0x7e, 0xf2, 0x42, 0xc6, 0x85, 0xf1, 0x8b, 0x89, 0x17, 0x87, 0x3a, 0x57, 0x74, 0x3e, 0xba, 0xb4, - 0xe4, 0xd2, 0x9d, 0xae, 0xb0, 0xae, 0xde, 0xcb, 0x81, 0x97, 0xaf, 0x5e, 0xf1, 0xb9, 0x72, 0xa9, - 0xdb, 0xbd, 0xfb, 0xfc, 0x55, 0x97, 0xab, 0x67, 0xae, 0x39, 0x5d, 0x3b, 0x7d, 0x9d, 0x7d, 0xbd, - 0xed, 0x86, 0xfd, 0x8d, 0xd6, 0x1e, 0xbb, 0x9e, 0x96, 0x5f, 0xec, 0x7e, 0x69, 0xe9, 0xb5, 0xef, - 0x6d, 0xbd, 0xe9, 0x70, 0xb3, 0xfd, 0x96, 0xe3, 0xad, 0x8e, 0xbe, 0x05, 0x7d, 0xe7, 0xfa, 0x5d, - 0xfb, 0x2f, 0xde, 0xf6, 0xba, 0x7d, 0xe5, 0x8e, 0xff, 0x9d, 0x1b, 0x03, 0x8b, 0x06, 0xfa, 0xee, - 0x2e, 0xbe, 0x7b, 0xff, 0x5e, 0xdc, 0x3d, 0xe9, 0x7d, 0xde, 0xfd, 0xd1, 0x07, 0xa9, 0x0f, 0x5e, - 0x3f, 0xcc, 0x7a, 0x38, 0xfd, 0x68, 0xfd, 0x63, 0xec, 0xe3, 0xa2, 0x27, 0x0a, 0x4f, 0x2a, 0x9e, - 0xaa, 0x3f, 0xad, 0xfd, 0xd5, 0xf8, 0xd7, 0x66, 0xa9, 0xbd, 0xf4, 0xec, 0xa0, 0xd7, 0x60, 0xcf, - 0xb3, 0x88, 0x67, 0x8f, 0x86, 0xb8, 0x43, 0x2f, 0xff, 0x95, 0xf9, 0xaf, 0x4f, 0xc3, 0x05, 0xcf, - 0xa9, 0xcf, 0x2b, 0x46, 0xb4, 0x46, 0xea, 0x47, 0xad, 0x47, 0xcf, 0x8c, 0xf9, 0x8c, 0xdd, 0x7a, - 0xb1, 0xf4, 0xc5, 0xf0, 0xcb, 0x8c, 0x97, 0xd3, 0xe3, 0x85, 0xbf, 0x29, 0xfe, 0xb6, 0xf7, 0x95, - 0xd1, 0xab, 0x9f, 0x7e, 0x77, 0xfb, 0xbd, 0x67, 0x62, 0xc9, 0xc4, 0xf0, 0x6b, 0xd1, 0xeb, 0x99, - 0x3f, 0x4a, 0xde, 0xa8, 0xbe, 0x39, 0xfa, 0xd6, 0xf6, 0x6d, 0xe7, 0x64, 0xe8, 0xe4, 0xd3, 0x77, - 0x69, 0xef, 0xa6, 0xa7, 0x8a, 0xde, 0xab, 0xbe, 0x3f, 0xf6, 0x81, 0xfd, 0xa1, 0xfb, 0x63, 0xf4, - 0xc7, 0x91, 0xe9, 0xec, 0x4f, 0xf8, 0x4f, 0x95, 0x9f, 0x8d, 0x3f, 0x77, 0x7c, 0x09, 0xfc, 0xf2, - 0x78, 0x26, 0x6d, 0x66, 0xe6, 0xdf, 0xf7, 0x84, 0xf3, 0xfb, 0x32, 0x3a, 0x59, 0x7e, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa4, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x35, 0x2d, 0x30, 0x32, 0x54, - 0x31, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x35, 0x35, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, - 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, - 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, - 0x69, 0x74, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, - 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, - 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, - 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x34, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, - 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0xc0, - 0x10, 0xf8, 0x70, 0x00, 0x00, 0x00, 0x10, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1d, 0x63, 0x60, 0x60, - 0x60, 0xf8, 0x0f, 0xc4, 0x70, 0x00, 0x00, 0x0d, 0x04, 0x01, 0x00, 0x65, 0x59, 0x09, 0xe8, 0x00, - 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIndentPattern2x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xe3, 0x00, 0xef, - 0x43, 0x00, 0x00, 0x0a, 0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54, 0x53, 0xd9, 0x16, 0x87, - 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20, 0x25, 0xf4, 0x1a, 0x7a, 0x09, 0x20, 0xd2, 0x3b, - 0x48, 0x15, 0x04, 0x51, 0x89, 0x49, 0x80, 0x50, 0x02, 0x86, 0x84, 0x26, 0x76, 0x44, 0x05, 0x46, - 0x14, 0x11, 0x29, 0x56, 0x64, 0x54, 0xc0, 0x01, 0x47, 0x87, 0x22, 0x63, 0x45, 0x14, 0x0b, 0x83, - 0x82, 0x62, 0xd7, 0x09, 0xf2, 0x10, 0x50, 0xc6, 0xc1, 0x51, 0x44, 0x45, 0xe5, 0xdd, 0x8c, 0x6b, - 0x09, 0xef, 0xad, 0x35, 0xf3, 0xde, 0x9a, 0xfd, 0xc7, 0x59, 0xdf, 0xd9, 0xe7, 0xb7, 0xd7, 0xd9, - 0x67, 0xef, 0x7d, 0xd7, 0xba, 0x00, 0x50, 0xfc, 0x82, 0x04, 0xc2, 0x74, 0x58, 0x01, 0x80, 0x34, - 0xa1, 0x58, 0x14, 0xee, 0xeb, 0xc1, 0x5c, 0x12, 0x13, 0xcb, 0xc4, 0xf7, 0x02, 0x18, 0x10, 0x01, - 0x0e, 0x58, 0x01, 0xc0, 0xe1, 0x66, 0x66, 0x04, 0x47, 0xf8, 0x44, 0x02, 0xd4, 0xfc, 0xbd, 0x3d, - 0x99, 0x99, 0xa8, 0x48, 0xc6, 0xb3, 0xf6, 0xee, 0x2e, 0x80, 0x64, 0xbb, 0xdb, 0x2c, 0xbf, 0x50, - 0x26, 0x73, 0xd6, 0xff, 0x7f, 0x91, 0x22, 0x37, 0x43, 0x24, 0x06, 0x00, 0x0a, 0x45, 0xd5, 0x36, - 0x3c, 0x7e, 0x26, 0x17, 0xe5, 0x02, 0x94, 0x53, 0xb3, 0xc5, 0x19, 0x32, 0xff, 0x04, 0xca, 0xf4, - 0x95, 0x29, 0x32, 0x86, 0x31, 0x32, 0x16, 0xa1, 0x09, 0xa2, 0xac, 0x22, 0xe3, 0xc4, 0xaf, 0x6c, - 0xf6, 0xa7, 0xe6, 0x2b, 0xbb, 0xc9, 0x98, 0x97, 0x26, 0xe4, 0xa1, 0x1a, 0x59, 0xce, 0x19, 0xbc, - 0x34, 0x9e, 0x8c, 0xbb, 0x50, 0xde, 0x9a, 0x25, 0xe1, 0xa3, 0x8c, 0x04, 0xa1, 0x5c, 0x98, 0x25, - 0xe0, 0x67, 0xa3, 0x7c, 0x07, 0x65, 0xbd, 0x54, 0x49, 0x9a, 0x00, 0xe5, 0xf7, 0x28, 0xd3, 0xd3, - 0xf8, 0x9c, 0x4c, 0x00, 0x30, 0x14, 0x99, 0x5f, 0xcc, 0xe7, 0x26, 0xa1, 0x6c, 0x89, 0x32, 0x45, - 0x14, 0x19, 0xee, 0x89, 0xf2, 0x02, 0x00, 0x08, 0x94, 0xc4, 0x39, 0xbc, 0x72, 0x0e, 0x8b, 0xf9, - 0x39, 0x68, 0x9e, 0x00, 0x78, 0xa6, 0x67, 0xe4, 0x8a, 0x04, 0x89, 0x49, 0x62, 0xa6, 0x11, 0xd7, - 0x98, 0x69, 0xe5, 0xe8, 0xc8, 0x66, 0xfa, 0xf1, 0xb3, 0x53, 0xf9, 0x62, 0x31, 0x2b, 0x94, 0xc3, - 0x4d, 0xe1, 0x88, 0x78, 0x4c, 0xcf, 0xf4, 0xb4, 0x0c, 0x8e, 0x30, 0x17, 0x80, 0xaf, 0x6f, 0x96, - 0x45, 0x01, 0x25, 0x59, 0x6d, 0x99, 0x68, 0x91, 0xed, 0xad, 0x1c, 0xed, 0xed, 0x59, 0xd6, 0xe6, - 0x68, 0xf9, 0xbf, 0xd9, 0xdf, 0x1e, 0x7e, 0x53, 0xfd, 0x3d, 0xc8, 0x7a, 0xfb, 0x55, 0xf1, 0x26, - 0xec, 0xcf, 0x9e, 0x41, 0x8c, 0x9e, 0x59, 0xdf, 0x6c, 0xec, 0xac, 0x2f, 0xbd, 0x16, 0x00, 0xf6, - 0x24, 0x5a, 0x9b, 0x1d, 0xb3, 0xbe, 0x95, 0x55, 0x00, 0xb4, 0x6d, 0x06, 0x40, 0xe5, 0xe1, 0xac, - 0x4f, 0xef, 0x20, 0x00, 0xf2, 0x05, 0x00, 0xb4, 0xde, 0x9c, 0xf3, 0x1e, 0x86, 0x6c, 0x5e, 0x92, - 0xc4, 0xe2, 0x0c, 0x27, 0x0b, 0x8b, 0xec, 0xec, 0x6c, 0x73, 0x01, 0x9f, 0x6b, 0x2e, 0x2b, 0xe8, - 0x37, 0xfb, 0x9f, 0x82, 0x6f, 0xca, 0xbf, 0x86, 0x39, 0xf7, 0x99, 0xcb, 0xee, 0xfb, 0x56, 0x3b, - 0xa6, 0x17, 0x3f, 0x81, 0x23, 0x49, 0x15, 0x33, 0x65, 0x45, 0xe5, 0xa6, 0xa7, 0xa6, 0x4b, 0x44, - 0xcc, 0xcc, 0x0c, 0x0e, 0x97, 0xcf, 0x64, 0xfd, 0xf7, 0x10, 0xff, 0xe3, 0xc0, 0x39, 0x69, 0xcd, - 0xc9, 0xc3, 0x2c, 0x9c, 0x9f, 0xc0, 0x17, 0xf1, 0x85, 0xe8, 0x55, 0x51, 0xe8, 0x94, 0x09, 0x84, - 0x89, 0x68, 0xbb, 0x85, 0x3c, 0x81, 0x58, 0x90, 0x2e, 0x64, 0x0a, 0x84, 0x7f, 0xd5, 0xe1, 0x7f, - 0x18, 0x36, 0x27, 0x07, 0x19, 0x7e, 0x9d, 0x6b, 0x14, 0x68, 0x75, 0x5f, 0x00, 0x7d, 0x85, 0x39, - 0x50, 0xb8, 0x49, 0x07, 0xc8, 0x6f, 0x3d, 0x00, 0x43, 0x23, 0x03, 0x24, 0x6e, 0x3f, 0x7a, 0x02, - 0x7d, 0xeb, 0x5b, 0x10, 0x31, 0x0a, 0xc8, 0xbe, 0xbc, 0x68, 0xad, 0x91, 0xaf, 0x73, 0x8f, 0x32, - 0x7a, 0xfe, 0xe7, 0xfa, 0x1f, 0x0b, 0x5c, 0x8a, 0x6e, 0xe1, 0x4c, 0x41, 0x22, 0x53, 0xe6, 0xf6, - 0x0c, 0x8f, 0x64, 0x72, 0x25, 0xa2, 0x2c, 0x19, 0xa3, 0xdf, 0x84, 0x6c, 0xc1, 0x02, 0x12, 0x90, - 0x07, 0x74, 0xa0, 0x0a, 0x34, 0x81, 0x2e, 0x30, 0x02, 0x2c, 0x60, 0x0d, 0x1c, 0x80, 0x33, 0x70, - 0x03, 0xde, 0x20, 0x00, 0x84, 0x80, 0x48, 0x10, 0x03, 0x96, 0x03, 0x2e, 0x48, 0x02, 0x69, 0x40, - 0x04, 0xb2, 0x41, 0x3e, 0xd8, 0x00, 0x0a, 0x41, 0x31, 0xd8, 0x01, 0x76, 0x83, 0x6a, 0x70, 0x00, - 0xd4, 0x81, 0x7a, 0xd0, 0x04, 0x4e, 0x82, 0x36, 0x70, 0x06, 0x5c, 0x04, 0x57, 0xc0, 0x0d, 0x70, - 0x0b, 0x0c, 0x80, 0x47, 0x40, 0x0a, 0x86, 0xc1, 0x4b, 0x30, 0x01, 0xde, 0x81, 0x69, 0x08, 0x82, - 0xf0, 0x10, 0x15, 0xa2, 0x41, 0xaa, 0x90, 0x16, 0xa4, 0x0f, 0x99, 0x42, 0xd6, 0x10, 0x1b, 0x5a, - 0x08, 0x79, 0x43, 0x41, 0x50, 0x38, 0x14, 0x03, 0xc5, 0x43, 0x89, 0x90, 0x10, 0x92, 0x40, 0xf9, - 0xd0, 0x26, 0xa8, 0x18, 0x2a, 0x83, 0xaa, 0xa1, 0x43, 0x50, 0x3d, 0xf4, 0x23, 0x74, 0x1a, 0xba, - 0x08, 0x5d, 0x83, 0xfa, 0xa0, 0x07, 0xd0, 0x20, 0x34, 0x06, 0xfd, 0x01, 0x7d, 0x84, 0x11, 0x98, - 0x02, 0xd3, 0x61, 0x0d, 0xd8, 0x00, 0xb6, 0x80, 0xd9, 0xb0, 0x3b, 0x1c, 0x08, 0x47, 0xc2, 0xcb, - 0xe0, 0x44, 0x78, 0x15, 0x9c, 0x07, 0x17, 0xc0, 0xdb, 0xe1, 0x4a, 0xb8, 0x16, 0x3e, 0x0e, 0xb7, - 0xc2, 0x17, 0xe1, 0x1b, 0xf0, 0x00, 0x2c, 0x85, 0x5f, 0xc2, 0x93, 0x08, 0x40, 0xc8, 0x08, 0x03, - 0xd1, 0x46, 0x58, 0x08, 0x1b, 0xf1, 0x44, 0x42, 0x90, 0x58, 0x24, 0x01, 0x11, 0x21, 0x6b, 0x91, - 0x22, 0xa4, 0x02, 0xa9, 0x45, 0x9a, 0x90, 0x0e, 0xa4, 0x1b, 0xb9, 0x8d, 0x48, 0x91, 0x71, 0xe4, - 0x03, 0x06, 0x87, 0xa1, 0x61, 0x98, 0x18, 0x16, 0xc6, 0x19, 0xe3, 0x87, 0x59, 0x8c, 0xe1, 0x62, - 0x56, 0x61, 0xd6, 0x62, 0x4a, 0x30, 0xd5, 0x98, 0x63, 0x98, 0x56, 0x4c, 0x17, 0xe6, 0x36, 0x66, - 0x10, 0x33, 0x81, 0xf9, 0x82, 0xa5, 0x62, 0xd5, 0xb1, 0xa6, 0x58, 0x27, 0xac, 0x3f, 0x76, 0x09, - 0x36, 0x11, 0x9b, 0x8d, 0x2d, 0xc4, 0x56, 0x60, 0x8f, 0x60, 0x5b, 0xb0, 0x97, 0xb1, 0x03, 0xd8, - 0x61, 0xec, 0x3b, 0x1c, 0x0e, 0xc7, 0xc0, 0x19, 0xe2, 0x1c, 0x70, 0x7e, 0xb8, 0x18, 0x5c, 0x32, - 0x6e, 0x35, 0xae, 0x04, 0xb7, 0x0f, 0xd7, 0x8c, 0xbb, 0x80, 0xeb, 0xc3, 0x0d, 0xe1, 0x26, 0xf1, - 0x78, 0xbc, 0x2a, 0xde, 0x14, 0xef, 0x82, 0x0f, 0xc1, 0x73, 0xf0, 0x62, 0x7c, 0x21, 0xbe, 0x0a, - 0x7f, 0x1c, 0x7f, 0x1e, 0xdf, 0x8f, 0x1f, 0xc6, 0xbf, 0x27, 0x90, 0x09, 0x5a, 0x04, 0x6b, 0x82, - 0x0f, 0x21, 0x96, 0x20, 0x24, 0x6c, 0x24, 0x54, 0x10, 0x1a, 0x08, 0xe7, 0x08, 0xfd, 0x84, 0x11, - 0xc2, 0x34, 0x51, 0x81, 0xa8, 0x4f, 0x74, 0x22, 0x86, 0x10, 0x79, 0xc4, 0x5c, 0x62, 0x29, 0xb1, - 0x8e, 0xd8, 0x41, 0xbc, 0x49, 0x1c, 0x26, 0x4e, 0x93, 0x14, 0x49, 0x86, 0x24, 0x17, 0x52, 0x24, - 0x29, 0x99, 0xb4, 0x81, 0x54, 0x49, 0x6a, 0x22, 0x5d, 0x26, 0x3d, 0x26, 0xbd, 0x21, 0x93, 0xc9, - 0x3a, 0x64, 0x47, 0x72, 0x18, 0x59, 0x40, 0x5e, 0x4f, 0xae, 0x24, 0x9f, 0x20, 0x5f, 0x25, 0x0f, - 0x92, 0x3f, 0x50, 0x94, 0x28, 0x26, 0x14, 0x4f, 0x4a, 0x1c, 0x45, 0x42, 0xd9, 0x4e, 0x39, 0x4a, - 0xb9, 0x40, 0x79, 0x40, 0x79, 0x43, 0xa5, 0x52, 0x0d, 0xa8, 0x6e, 0xd4, 0x58, 0xaa, 0x98, 0xba, - 0x9d, 0x5a, 0x4f, 0xbd, 0x44, 0x7d, 0x4a, 0x7d, 0x2f, 0x47, 0x93, 0x33, 0x97, 0xf3, 0x97, 0xe3, - 0xc9, 0xad, 0x93, 0xab, 0x91, 0x6b, 0x95, 0xeb, 0x97, 0x7b, 0x25, 0x4f, 0x94, 0xd7, 0x97, 0x77, - 0x97, 0x5f, 0x2e, 0x9f, 0x27, 0x5f, 0x21, 0x7f, 0x4a, 0xfe, 0xa6, 0xfc, 0xb8, 0x02, 0x51, 0xc1, - 0x40, 0xc1, 0x53, 0x81, 0xa3, 0xb0, 0x56, 0xa1, 0x46, 0xe1, 0xb4, 0xc2, 0x3d, 0x85, 0x49, 0x45, - 0x9a, 0xa2, 0x95, 0x62, 0x88, 0x62, 0x9a, 0x62, 0x89, 0x62, 0x83, 0xe2, 0x35, 0xc5, 0x51, 0x25, - 0xbc, 0x92, 0x81, 0x92, 0xb7, 0x12, 0x4f, 0xa9, 0x40, 0xe9, 0xb0, 0xd2, 0x25, 0xa5, 0x21, 0x1a, - 0x42, 0xd3, 0xa5, 0x79, 0xd2, 0xb8, 0xb4, 0x4d, 0xb4, 0x3a, 0xda, 0x65, 0xda, 0x30, 0x1d, 0x47, - 0x37, 0xa4, 0xfb, 0xd3, 0x93, 0xe9, 0xc5, 0xf4, 0x1f, 0xe8, 0xbd, 0xf4, 0x09, 0x65, 0x25, 0x65, - 0x5b, 0xe5, 0x28, 0xe5, 0x1c, 0xe5, 0x1a, 0xe5, 0xb3, 0xca, 0x52, 0x06, 0xc2, 0x30, 0x60, 0xf8, - 0x33, 0x52, 0x19, 0xa5, 0x8c, 0x93, 0x8c, 0xbb, 0x8c, 0x8f, 0xf3, 0x34, 0xe6, 0xb9, 0xcf, 0xe3, - 0xcf, 0xdb, 0x36, 0xaf, 0x69, 0x5e, 0xff, 0xbc, 0x29, 0x95, 0xf9, 0x2a, 0x6e, 0x2a, 0x7c, 0x95, - 0x22, 0x95, 0x66, 0x95, 0x01, 0x95, 0x8f, 0xaa, 0x4c, 0x55, 0x6f, 0xd5, 0x14, 0xd5, 0x9d, 0xaa, - 0x6d, 0xaa, 0x4f, 0xd4, 0x30, 0x6a, 0x26, 0x6a, 0x61, 0x6a, 0xd9, 0x6a, 0xfb, 0xd5, 0x2e, 0xab, - 0x8d, 0xcf, 0xa7, 0xcf, 0x77, 0x9e, 0xcf, 0x9d, 0x5f, 0x34, 0xff, 0xe4, 0xfc, 0x87, 0xea, 0xb0, - 0xba, 0x89, 0x7a, 0xb8, 0xfa, 0x6a, 0xf5, 0xc3, 0xea, 0x3d, 0xea, 0x93, 0x1a, 0x9a, 0x1a, 0xbe, - 0x1a, 0x19, 0x1a, 0x55, 0x1a, 0x97, 0x34, 0xc6, 0x35, 0x19, 0x9a, 0x6e, 0x9a, 0xc9, 0x9a, 0xe5, - 0x9a, 0xe7, 0x34, 0xc7, 0xb4, 0x68, 0x5a, 0x0b, 0xb5, 0x04, 0x5a, 0xe5, 0x5a, 0xe7, 0xb5, 0x5e, - 0x30, 0x95, 0x99, 0xee, 0xcc, 0x54, 0x66, 0x25, 0xb3, 0x8b, 0x39, 0xa1, 0xad, 0xae, 0xed, 0xa7, - 0x2d, 0xd1, 0x3e, 0xa4, 0xdd, 0xab, 0x3d, 0xad, 0x63, 0xa8, 0xb3, 0x58, 0x67, 0xa3, 0x4e, 0xb3, - 0xce, 0x13, 0x5d, 0x92, 0x2e, 0x5b, 0x37, 0x41, 0xb7, 0x5c, 0xb7, 0x53, 0x77, 0x42, 0x4f, 0x4b, - 0x2f, 0x58, 0x2f, 0x5f, 0xaf, 0x51, 0xef, 0xa1, 0x3e, 0x51, 0x9f, 0xad, 0x9f, 0xa4, 0xbf, 0x47, - 0xbf, 0x5b, 0x7f, 0xca, 0xc0, 0xd0, 0x20, 0xda, 0x60, 0x8b, 0x41, 0x9b, 0xc1, 0xa8, 0xa1, 0x8a, - 0xa1, 0xbf, 0x61, 0x9e, 0x61, 0xa3, 0xe1, 0x63, 0x23, 0xaa, 0x91, 0xab, 0xd1, 0x2a, 0xa3, 0x5a, - 0xa3, 0x3b, 0xc6, 0x38, 0x63, 0xb6, 0x71, 0x8a, 0xf1, 0x3e, 0xe3, 0x5b, 0x26, 0xb0, 0x89, 0x9d, - 0x49, 0x92, 0x49, 0x8d, 0xc9, 0x4d, 0x53, 0xd8, 0xd4, 0xde, 0x54, 0x60, 0xba, 0xcf, 0xb4, 0xcf, - 0x0c, 0x6b, 0xe6, 0x68, 0x26, 0x34, 0xab, 0x35, 0xbb, 0xc7, 0xa2, 0xb0, 0xdc, 0x59, 0x59, 0xac, - 0x46, 0xd6, 0xa0, 0x39, 0xc3, 0x3c, 0xc8, 0x7c, 0xa3, 0x79, 0x9b, 0xf9, 0x2b, 0x0b, 0x3d, 0x8b, - 0x58, 0x8b, 0x9d, 0x16, 0xdd, 0x16, 0x5f, 0x2c, 0xed, 0x2c, 0x53, 0x2d, 0xeb, 0x2c, 0x1f, 0x59, - 0x29, 0x59, 0x05, 0x58, 0x6d, 0xb4, 0xea, 0xb0, 0xfa, 0xc3, 0xda, 0xc4, 0x9a, 0x6b, 0x5d, 0x63, - 0x7d, 0xc7, 0x86, 0x6a, 0xe3, 0x63, 0xb3, 0xce, 0xa6, 0xdd, 0xe6, 0xb5, 0xad, 0xa9, 0x2d, 0xdf, - 0x76, 0xbf, 0xed, 0x7d, 0x3b, 0x9a, 0x5d, 0xb0, 0xdd, 0x16, 0xbb, 0x4e, 0xbb, 0xcf, 0xf6, 0x0e, - 0xf6, 0x22, 0xfb, 0x26, 0xfb, 0x31, 0x07, 0x3d, 0x87, 0x78, 0x87, 0xbd, 0x0e, 0xf7, 0xd8, 0x74, - 0x76, 0x28, 0xbb, 0x84, 0x7d, 0xd5, 0x11, 0xeb, 0xe8, 0xe1, 0xb8, 0xce, 0xf1, 0x8c, 0xe3, 0x07, - 0x27, 0x7b, 0x27, 0xb1, 0xd3, 0x49, 0xa7, 0xdf, 0x9d, 0x59, 0xce, 0x29, 0xce, 0x0d, 0xce, 0xa3, - 0x0b, 0x0c, 0x17, 0xf0, 0x17, 0xd4, 0x2d, 0x18, 0x72, 0xd1, 0x71, 0xe1, 0xb8, 0x1c, 0x72, 0x91, - 0x2e, 0x64, 0x2e, 0x8c, 0x5f, 0x78, 0x70, 0xa1, 0xd4, 0x55, 0xdb, 0x95, 0xe3, 0x5a, 0xeb, 0xfa, - 0xcc, 0x4d, 0xd7, 0x8d, 0xe7, 0x76, 0xc4, 0x6d, 0xc4, 0xdd, 0xd8, 0x3d, 0xd9, 0xfd, 0xb8, 0xfb, - 0x2b, 0x0f, 0x4b, 0x0f, 0x91, 0x47, 0x8b, 0xc7, 0x94, 0xa7, 0x93, 0xe7, 0x1a, 0xcf, 0x0b, 0x5e, - 0x88, 0x97, 0xaf, 0x57, 0x91, 0x57, 0xaf, 0xb7, 0x92, 0xf7, 0x62, 0xef, 0x6a, 0xef, 0xa7, 0x3e, - 0x3a, 0x3e, 0x89, 0x3e, 0x8d, 0x3e, 0x13, 0xbe, 0x76, 0xbe, 0xab, 0x7d, 0x2f, 0xf8, 0x61, 0xfd, - 0x02, 0xfd, 0x76, 0xfa, 0xdd, 0xf3, 0xd7, 0xf0, 0xe7, 0xfa, 0xd7, 0xfb, 0x4f, 0x04, 0x38, 0x04, - 0xac, 0x09, 0xe8, 0x0a, 0xa4, 0x04, 0x46, 0x04, 0x56, 0x07, 0x3e, 0x0b, 0x32, 0x09, 0x12, 0x05, - 0x75, 0x04, 0xc3, 0xc1, 0x01, 0xc1, 0xbb, 0x82, 0x1f, 0x2f, 0xd2, 0x5f, 0x24, 0x5c, 0xd4, 0x16, - 0x02, 0x42, 0xfc, 0x43, 0x76, 0x85, 0x3c, 0x09, 0x35, 0x0c, 0x5d, 0x15, 0xfa, 0x73, 0x18, 0x2e, - 0x2c, 0x34, 0xac, 0x26, 0xec, 0x79, 0xb8, 0x55, 0x78, 0x7e, 0x78, 0x77, 0x04, 0x2d, 0x62, 0x45, - 0x44, 0x43, 0xc4, 0xbb, 0x48, 0x8f, 0xc8, 0xd2, 0xc8, 0x47, 0x8b, 0x8d, 0x16, 0x4b, 0x16, 0x77, - 0x46, 0xc9, 0x47, 0xc5, 0x45, 0xd5, 0x47, 0x4d, 0x45, 0x7b, 0x45, 0x97, 0x45, 0x4b, 0x97, 0x58, - 0x2c, 0x59, 0xb3, 0xe4, 0x46, 0x8c, 0x5a, 0x8c, 0x20, 0xa6, 0x3d, 0x16, 0x1f, 0x1b, 0x15, 0x7b, - 0x24, 0x76, 0x72, 0xa9, 0xf7, 0xd2, 0xdd, 0x4b, 0x87, 0xe3, 0xec, 0xe2, 0x0a, 0xe3, 0xee, 0x2e, - 0x33, 0x5c, 0x96, 0xb3, 0xec, 0xda, 0x72, 0xb5, 0xe5, 0xa9, 0xcb, 0xcf, 0xae, 0x90, 0x5f, 0xc1, - 0x59, 0x71, 0x2a, 0x1e, 0x1b, 0x1f, 0x1d, 0xdf, 0x10, 0xff, 0x89, 0x13, 0xc2, 0xa9, 0xe5, 0x4c, - 0xae, 0xf4, 0x5f, 0xb9, 0x77, 0xe5, 0x04, 0xd7, 0x93, 0xbb, 0x87, 0xfb, 0x92, 0xe7, 0xc6, 0x2b, - 0xe7, 0x8d, 0xf1, 0x5d, 0xf8, 0x65, 0xfc, 0x91, 0x04, 0x97, 0x84, 0xb2, 0x84, 0xd1, 0x44, 0x97, - 0xc4, 0x5d, 0x89, 0x63, 0x49, 0xae, 0x49, 0x15, 0x49, 0xe3, 0x02, 0x4f, 0x41, 0xb5, 0xe0, 0x75, - 0xb2, 0x5f, 0xf2, 0x81, 0xe4, 0xa9, 0x94, 0x90, 0x94, 0xa3, 0x29, 0x33, 0xa9, 0xd1, 0xa9, 0xcd, - 0x69, 0x84, 0xb4, 0xf8, 0xb4, 0xd3, 0x42, 0x25, 0x61, 0x8a, 0xb0, 0x2b, 0x5d, 0x33, 0x3d, 0x27, - 0xbd, 0x2f, 0xc3, 0x34, 0xa3, 0x30, 0x43, 0xba, 0xca, 0x69, 0xd5, 0xee, 0x55, 0x13, 0xa2, 0x40, - 0xd1, 0x91, 0x4c, 0x28, 0x73, 0x59, 0x66, 0xbb, 0x98, 0x8e, 0xfe, 0x4c, 0xf5, 0x48, 0x8c, 0x24, - 0x9b, 0x25, 0x83, 0x59, 0x0b, 0xb3, 0x6a, 0xb2, 0xde, 0x67, 0x47, 0x65, 0x9f, 0xca, 0x51, 0xcc, - 0x11, 0xe6, 0xf4, 0xe4, 0x9a, 0xe4, 0x6e, 0xcb, 0x1d, 0xc9, 0xf3, 0xc9, 0xfb, 0x7e, 0x35, 0x66, - 0x35, 0x77, 0x75, 0x67, 0xbe, 0x76, 0xfe, 0x86, 0xfc, 0xc1, 0x35, 0xee, 0x6b, 0x0e, 0xad, 0x85, - 0xd6, 0xae, 0x5c, 0xdb, 0xb9, 0x4e, 0x77, 0x5d, 0xc1, 0xba, 0xe1, 0xf5, 0xbe, 0xeb, 0x8f, 0x6d, - 0x20, 0x6d, 0x48, 0xd9, 0xf0, 0xcb, 0x46, 0xcb, 0x8d, 0x65, 0x1b, 0xdf, 0x6e, 0x8a, 0xde, 0xd4, - 0x51, 0xa0, 0x51, 0xb0, 0xbe, 0x60, 0x68, 0xb3, 0xef, 0xe6, 0xc6, 0x42, 0xb9, 0x42, 0x51, 0xe1, - 0xbd, 0x2d, 0xce, 0x5b, 0x0e, 0x6c, 0xc5, 0x6c, 0x15, 0x6c, 0xed, 0xdd, 0x66, 0xb3, 0xad, 0x6a, - 0xdb, 0x97, 0x22, 0x5e, 0xd1, 0xf5, 0x62, 0xcb, 0xe2, 0x8a, 0xe2, 0x4f, 0x25, 0xdc, 0x92, 0xeb, - 0xdf, 0x59, 0x7d, 0x57, 0xf9, 0xdd, 0xcc, 0xf6, 0x84, 0xed, 0xbd, 0xa5, 0xf6, 0xa5, 0xfb, 0x77, - 0xe0, 0x76, 0x08, 0x77, 0xdc, 0xdd, 0xe9, 0xba, 0xf3, 0x58, 0x99, 0x62, 0x59, 0x5e, 0xd9, 0xd0, - 0xae, 0xe0, 0x5d, 0xad, 0xe5, 0xcc, 0xf2, 0xa2, 0xf2, 0xb7, 0xbb, 0x57, 0xec, 0xbe, 0x56, 0x61, - 0x5b, 0x71, 0x60, 0x0f, 0x69, 0x8f, 0x64, 0x8f, 0xb4, 0x32, 0xa8, 0xb2, 0xbd, 0x4a, 0xaf, 0x6a, - 0x47, 0xd5, 0xa7, 0xea, 0xa4, 0xea, 0x81, 0x1a, 0x8f, 0x9a, 0xe6, 0xbd, 0xea, 0x7b, 0xb7, 0xed, - 0x9d, 0xda, 0xc7, 0xdb, 0xd7, 0xbf, 0xdf, 0x6d, 0x7f, 0xd3, 0x01, 0x8d, 0x03, 0xc5, 0x07, 0x3e, - 0x1e, 0x14, 0x1c, 0xbc, 0x7f, 0xc8, 0xf7, 0x50, 0x6b, 0xad, 0x41, 0x6d, 0xc5, 0x61, 0xdc, 0xe1, - 0xac, 0xc3, 0xcf, 0xeb, 0xa2, 0xea, 0xba, 0xbf, 0x67, 0x7f, 0x5f, 0x7f, 0x44, 0xed, 0x48, 0xf1, - 0x91, 0xcf, 0x47, 0x85, 0x47, 0xa5, 0xc7, 0xc2, 0x8f, 0x75, 0xd5, 0x3b, 0xd4, 0xd7, 0x37, 0xa8, - 0x37, 0x94, 0x36, 0xc2, 0x8d, 0x92, 0xc6, 0xb1, 0xe3, 0x71, 0xc7, 0x6f, 0xfd, 0xe0, 0xf5, 0x43, - 0x7b, 0x13, 0xab, 0xe9, 0x50, 0x33, 0xa3, 0xb9, 0xf8, 0x04, 0x38, 0x21, 0x39, 0xf1, 0xe2, 0xc7, - 0xf8, 0x1f, 0xef, 0x9e, 0x0c, 0x3c, 0xd9, 0x79, 0x8a, 0x7d, 0xaa, 0xe9, 0x27, 0xfd, 0x9f, 0xf6, - 0xb6, 0xd0, 0x5a, 0x8a, 0x5a, 0xa1, 0xd6, 0xdc, 0xd6, 0x89, 0xb6, 0xa4, 0x36, 0x69, 0x7b, 0x4c, - 0x7b, 0xdf, 0xe9, 0x80, 0xd3, 0x9d, 0x1d, 0xce, 0x1d, 0x2d, 0x3f, 0x9b, 0xff, 0x7c, 0xf4, 0x8c, - 0xf6, 0x99, 0x9a, 0xb3, 0xca, 0x67, 0x4b, 0xcf, 0x91, 0xce, 0x15, 0x9c, 0x9b, 0x39, 0x9f, 0x77, - 0x7e, 0xf2, 0x42, 0xc6, 0x85, 0xf1, 0x8b, 0x89, 0x17, 0x87, 0x3a, 0x57, 0x74, 0x3e, 0xba, 0xb4, - 0xe4, 0xd2, 0x9d, 0xae, 0xb0, 0xae, 0xde, 0xcb, 0x81, 0x97, 0xaf, 0x5e, 0xf1, 0xb9, 0x72, 0xa9, - 0xdb, 0xbd, 0xfb, 0xfc, 0x55, 0x97, 0xab, 0x67, 0xae, 0x39, 0x5d, 0x3b, 0x7d, 0x9d, 0x7d, 0xbd, - 0xed, 0x86, 0xfd, 0x8d, 0xd6, 0x1e, 0xbb, 0x9e, 0x96, 0x5f, 0xec, 0x7e, 0x69, 0xe9, 0xb5, 0xef, - 0x6d, 0xbd, 0xe9, 0x70, 0xb3, 0xfd, 0x96, 0xe3, 0xad, 0x8e, 0xbe, 0x05, 0x7d, 0xe7, 0xfa, 0x5d, - 0xfb, 0x2f, 0xde, 0xf6, 0xba, 0x7d, 0xe5, 0x8e, 0xff, 0x9d, 0x1b, 0x03, 0x8b, 0x06, 0xfa, 0xee, - 0x2e, 0xbe, 0x7b, 0xff, 0x5e, 0xdc, 0x3d, 0xe9, 0x7d, 0xde, 0xfd, 0xd1, 0x07, 0xa9, 0x0f, 0x5e, - 0x3f, 0xcc, 0x7a, 0x38, 0xfd, 0x68, 0xfd, 0x63, 0xec, 0xe3, 0xa2, 0x27, 0x0a, 0x4f, 0x2a, 0x9e, - 0xaa, 0x3f, 0xad, 0xfd, 0xd5, 0xf8, 0xd7, 0x66, 0xa9, 0xbd, 0xf4, 0xec, 0xa0, 0xd7, 0x60, 0xcf, - 0xb3, 0x88, 0x67, 0x8f, 0x86, 0xb8, 0x43, 0x2f, 0xff, 0x95, 0xf9, 0xaf, 0x4f, 0xc3, 0x05, 0xcf, - 0xa9, 0xcf, 0x2b, 0x46, 0xb4, 0x46, 0xea, 0x47, 0xad, 0x47, 0xcf, 0x8c, 0xf9, 0x8c, 0xdd, 0x7a, - 0xb1, 0xf4, 0xc5, 0xf0, 0xcb, 0x8c, 0x97, 0xd3, 0xe3, 0x85, 0xbf, 0x29, 0xfe, 0xb6, 0xf7, 0x95, - 0xd1, 0xab, 0x9f, 0x7e, 0x77, 0xfb, 0xbd, 0x67, 0x62, 0xc9, 0xc4, 0xf0, 0x6b, 0xd1, 0xeb, 0x99, - 0x3f, 0x4a, 0xde, 0xa8, 0xbe, 0x39, 0xfa, 0xd6, 0xf6, 0x6d, 0xe7, 0x64, 0xe8, 0xe4, 0xd3, 0x77, - 0x69, 0xef, 0xa6, 0xa7, 0x8a, 0xde, 0xab, 0xbe, 0x3f, 0xf6, 0x81, 0xfd, 0xa1, 0xfb, 0x63, 0xf4, - 0xc7, 0x91, 0xe9, 0xec, 0x4f, 0xf8, 0x4f, 0x95, 0x9f, 0x8d, 0x3f, 0x77, 0x7c, 0x09, 0xfc, 0xf2, - 0x78, 0x26, 0x6d, 0x66, 0xe6, 0xdf, 0xf7, 0x84, 0xf3, 0xfb, 0x32, 0x3a, 0x59, 0x7e, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa4, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x35, 0x2d, 0x30, 0x32, 0x54, - 0x31, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x30, 0x36, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, - 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, - 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, - 0x69, 0x74, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, - 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, - 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, - 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x38, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, - 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x90, - 0x7a, 0xe1, 0x8d, 0x00, 0x00, 0x00, 0x12, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1d, 0x63, 0x60, 0x60, - 0x60, 0xf8, 0x0f, 0xc5, 0x40, 0x0a, 0x13, 0x00, 0x00, 0x35, 0xeb, 0x01, 0xff, 0x0f, 0x5e, 0xbc, - 0xf4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - -static const u_int8_t FLEXHierarchyIndentPattern3x[] = { - 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06, 0x00, 0x00, 0x00, 0xe3, 0x00, 0xef, - 0x43, 0x00, 0x00, 0x0a, 0x41, 0x69, 0x43, 0x43, 0x50, 0x49, 0x43, 0x43, 0x20, 0x50, 0x72, 0x6f, - 0x66, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x48, 0x0d, 0x9d, 0x96, 0x77, 0x54, 0x53, 0xd9, 0x16, 0x87, - 0xcf, 0xbd, 0x37, 0xbd, 0xd0, 0x12, 0x22, 0x20, 0x25, 0xf4, 0x1a, 0x7a, 0x09, 0x20, 0xd2, 0x3b, - 0x48, 0x15, 0x04, 0x51, 0x89, 0x49, 0x80, 0x50, 0x02, 0x86, 0x84, 0x26, 0x76, 0x44, 0x05, 0x46, - 0x14, 0x11, 0x29, 0x56, 0x64, 0x54, 0xc0, 0x01, 0x47, 0x87, 0x22, 0x63, 0x45, 0x14, 0x0b, 0x83, - 0x82, 0x62, 0xd7, 0x09, 0xf2, 0x10, 0x50, 0xc6, 0xc1, 0x51, 0x44, 0x45, 0xe5, 0xdd, 0x8c, 0x6b, - 0x09, 0xef, 0xad, 0x35, 0xf3, 0xde, 0x9a, 0xfd, 0xc7, 0x59, 0xdf, 0xd9, 0xe7, 0xb7, 0xd7, 0xd9, - 0x67, 0xef, 0x7d, 0xd7, 0xba, 0x00, 0x50, 0xfc, 0x82, 0x04, 0xc2, 0x74, 0x58, 0x01, 0x80, 0x34, - 0xa1, 0x58, 0x14, 0xee, 0xeb, 0xc1, 0x5c, 0x12, 0x13, 0xcb, 0xc4, 0xf7, 0x02, 0x18, 0x10, 0x01, - 0x0e, 0x58, 0x01, 0xc0, 0xe1, 0x66, 0x66, 0x04, 0x47, 0xf8, 0x44, 0x02, 0xd4, 0xfc, 0xbd, 0x3d, - 0x99, 0x99, 0xa8, 0x48, 0xc6, 0xb3, 0xf6, 0xee, 0x2e, 0x80, 0x64, 0xbb, 0xdb, 0x2c, 0xbf, 0x50, - 0x26, 0x73, 0xd6, 0xff, 0x7f, 0x91, 0x22, 0x37, 0x43, 0x24, 0x06, 0x00, 0x0a, 0x45, 0xd5, 0x36, - 0x3c, 0x7e, 0x26, 0x17, 0xe5, 0x02, 0x94, 0x53, 0xb3, 0xc5, 0x19, 0x32, 0xff, 0x04, 0xca, 0xf4, - 0x95, 0x29, 0x32, 0x86, 0x31, 0x32, 0x16, 0xa1, 0x09, 0xa2, 0xac, 0x22, 0xe3, 0xc4, 0xaf, 0x6c, - 0xf6, 0xa7, 0xe6, 0x2b, 0xbb, 0xc9, 0x98, 0x97, 0x26, 0xe4, 0xa1, 0x1a, 0x59, 0xce, 0x19, 0xbc, - 0x34, 0x9e, 0x8c, 0xbb, 0x50, 0xde, 0x9a, 0x25, 0xe1, 0xa3, 0x8c, 0x04, 0xa1, 0x5c, 0x98, 0x25, - 0xe0, 0x67, 0xa3, 0x7c, 0x07, 0x65, 0xbd, 0x54, 0x49, 0x9a, 0x00, 0xe5, 0xf7, 0x28, 0xd3, 0xd3, - 0xf8, 0x9c, 0x4c, 0x00, 0x30, 0x14, 0x99, 0x5f, 0xcc, 0xe7, 0x26, 0xa1, 0x6c, 0x89, 0x32, 0x45, - 0x14, 0x19, 0xee, 0x89, 0xf2, 0x02, 0x00, 0x08, 0x94, 0xc4, 0x39, 0xbc, 0x72, 0x0e, 0x8b, 0xf9, - 0x39, 0x68, 0x9e, 0x00, 0x78, 0xa6, 0x67, 0xe4, 0x8a, 0x04, 0x89, 0x49, 0x62, 0xa6, 0x11, 0xd7, - 0x98, 0x69, 0xe5, 0xe8, 0xc8, 0x66, 0xfa, 0xf1, 0xb3, 0x53, 0xf9, 0x62, 0x31, 0x2b, 0x94, 0xc3, - 0x4d, 0xe1, 0x88, 0x78, 0x4c, 0xcf, 0xf4, 0xb4, 0x0c, 0x8e, 0x30, 0x17, 0x80, 0xaf, 0x6f, 0x96, - 0x45, 0x01, 0x25, 0x59, 0x6d, 0x99, 0x68, 0x91, 0xed, 0xad, 0x1c, 0xed, 0xed, 0x59, 0xd6, 0xe6, - 0x68, 0xf9, 0xbf, 0xd9, 0xdf, 0x1e, 0x7e, 0x53, 0xfd, 0x3d, 0xc8, 0x7a, 0xfb, 0x55, 0xf1, 0x26, - 0xec, 0xcf, 0x9e, 0x41, 0x8c, 0x9e, 0x59, 0xdf, 0x6c, 0xec, 0xac, 0x2f, 0xbd, 0x16, 0x00, 0xf6, - 0x24, 0x5a, 0x9b, 0x1d, 0xb3, 0xbe, 0x95, 0x55, 0x00, 0xb4, 0x6d, 0x06, 0x40, 0xe5, 0xe1, 0xac, - 0x4f, 0xef, 0x20, 0x00, 0xf2, 0x05, 0x00, 0xb4, 0xde, 0x9c, 0xf3, 0x1e, 0x86, 0x6c, 0x5e, 0x92, - 0xc4, 0xe2, 0x0c, 0x27, 0x0b, 0x8b, 0xec, 0xec, 0x6c, 0x73, 0x01, 0x9f, 0x6b, 0x2e, 0x2b, 0xe8, - 0x37, 0xfb, 0x9f, 0x82, 0x6f, 0xca, 0xbf, 0x86, 0x39, 0xf7, 0x99, 0xcb, 0xee, 0xfb, 0x56, 0x3b, - 0xa6, 0x17, 0x3f, 0x81, 0x23, 0x49, 0x15, 0x33, 0x65, 0x45, 0xe5, 0xa6, 0xa7, 0xa6, 0x4b, 0x44, - 0xcc, 0xcc, 0x0c, 0x0e, 0x97, 0xcf, 0x64, 0xfd, 0xf7, 0x10, 0xff, 0xe3, 0xc0, 0x39, 0x69, 0xcd, - 0xc9, 0xc3, 0x2c, 0x9c, 0x9f, 0xc0, 0x17, 0xf1, 0x85, 0xe8, 0x55, 0x51, 0xe8, 0x94, 0x09, 0x84, - 0x89, 0x68, 0xbb, 0x85, 0x3c, 0x81, 0x58, 0x90, 0x2e, 0x64, 0x0a, 0x84, 0x7f, 0xd5, 0xe1, 0x7f, - 0x18, 0x36, 0x27, 0x07, 0x19, 0x7e, 0x9d, 0x6b, 0x14, 0x68, 0x75, 0x5f, 0x00, 0x7d, 0x85, 0x39, - 0x50, 0xb8, 0x49, 0x07, 0xc8, 0x6f, 0x3d, 0x00, 0x43, 0x23, 0x03, 0x24, 0x6e, 0x3f, 0x7a, 0x02, - 0x7d, 0xeb, 0x5b, 0x10, 0x31, 0x0a, 0xc8, 0xbe, 0xbc, 0x68, 0xad, 0x91, 0xaf, 0x73, 0x8f, 0x32, - 0x7a, 0xfe, 0xe7, 0xfa, 0x1f, 0x0b, 0x5c, 0x8a, 0x6e, 0xe1, 0x4c, 0x41, 0x22, 0x53, 0xe6, 0xf6, - 0x0c, 0x8f, 0x64, 0x72, 0x25, 0xa2, 0x2c, 0x19, 0xa3, 0xdf, 0x84, 0x6c, 0xc1, 0x02, 0x12, 0x90, - 0x07, 0x74, 0xa0, 0x0a, 0x34, 0x81, 0x2e, 0x30, 0x02, 0x2c, 0x60, 0x0d, 0x1c, 0x80, 0x33, 0x70, - 0x03, 0xde, 0x20, 0x00, 0x84, 0x80, 0x48, 0x10, 0x03, 0x96, 0x03, 0x2e, 0x48, 0x02, 0x69, 0x40, - 0x04, 0xb2, 0x41, 0x3e, 0xd8, 0x00, 0x0a, 0x41, 0x31, 0xd8, 0x01, 0x76, 0x83, 0x6a, 0x70, 0x00, - 0xd4, 0x81, 0x7a, 0xd0, 0x04, 0x4e, 0x82, 0x36, 0x70, 0x06, 0x5c, 0x04, 0x57, 0xc0, 0x0d, 0x70, - 0x0b, 0x0c, 0x80, 0x47, 0x40, 0x0a, 0x86, 0xc1, 0x4b, 0x30, 0x01, 0xde, 0x81, 0x69, 0x08, 0x82, - 0xf0, 0x10, 0x15, 0xa2, 0x41, 0xaa, 0x90, 0x16, 0xa4, 0x0f, 0x99, 0x42, 0xd6, 0x10, 0x1b, 0x5a, - 0x08, 0x79, 0x43, 0x41, 0x50, 0x38, 0x14, 0x03, 0xc5, 0x43, 0x89, 0x90, 0x10, 0x92, 0x40, 0xf9, - 0xd0, 0x26, 0xa8, 0x18, 0x2a, 0x83, 0xaa, 0xa1, 0x43, 0x50, 0x3d, 0xf4, 0x23, 0x74, 0x1a, 0xba, - 0x08, 0x5d, 0x83, 0xfa, 0xa0, 0x07, 0xd0, 0x20, 0x34, 0x06, 0xfd, 0x01, 0x7d, 0x84, 0x11, 0x98, - 0x02, 0xd3, 0x61, 0x0d, 0xd8, 0x00, 0xb6, 0x80, 0xd9, 0xb0, 0x3b, 0x1c, 0x08, 0x47, 0xc2, 0xcb, - 0xe0, 0x44, 0x78, 0x15, 0x9c, 0x07, 0x17, 0xc0, 0xdb, 0xe1, 0x4a, 0xb8, 0x16, 0x3e, 0x0e, 0xb7, - 0xc2, 0x17, 0xe1, 0x1b, 0xf0, 0x00, 0x2c, 0x85, 0x5f, 0xc2, 0x93, 0x08, 0x40, 0xc8, 0x08, 0x03, - 0xd1, 0x46, 0x58, 0x08, 0x1b, 0xf1, 0x44, 0x42, 0x90, 0x58, 0x24, 0x01, 0x11, 0x21, 0x6b, 0x91, - 0x22, 0xa4, 0x02, 0xa9, 0x45, 0x9a, 0x90, 0x0e, 0xa4, 0x1b, 0xb9, 0x8d, 0x48, 0x91, 0x71, 0xe4, - 0x03, 0x06, 0x87, 0xa1, 0x61, 0x98, 0x18, 0x16, 0xc6, 0x19, 0xe3, 0x87, 0x59, 0x8c, 0xe1, 0x62, - 0x56, 0x61, 0xd6, 0x62, 0x4a, 0x30, 0xd5, 0x98, 0x63, 0x98, 0x56, 0x4c, 0x17, 0xe6, 0x36, 0x66, - 0x10, 0x33, 0x81, 0xf9, 0x82, 0xa5, 0x62, 0xd5, 0xb1, 0xa6, 0x58, 0x27, 0xac, 0x3f, 0x76, 0x09, - 0x36, 0x11, 0x9b, 0x8d, 0x2d, 0xc4, 0x56, 0x60, 0x8f, 0x60, 0x5b, 0xb0, 0x97, 0xb1, 0x03, 0xd8, - 0x61, 0xec, 0x3b, 0x1c, 0x0e, 0xc7, 0xc0, 0x19, 0xe2, 0x1c, 0x70, 0x7e, 0xb8, 0x18, 0x5c, 0x32, - 0x6e, 0x35, 0xae, 0x04, 0xb7, 0x0f, 0xd7, 0x8c, 0xbb, 0x80, 0xeb, 0xc3, 0x0d, 0xe1, 0x26, 0xf1, - 0x78, 0xbc, 0x2a, 0xde, 0x14, 0xef, 0x82, 0x0f, 0xc1, 0x73, 0xf0, 0x62, 0x7c, 0x21, 0xbe, 0x0a, - 0x7f, 0x1c, 0x7f, 0x1e, 0xdf, 0x8f, 0x1f, 0xc6, 0xbf, 0x27, 0x90, 0x09, 0x5a, 0x04, 0x6b, 0x82, - 0x0f, 0x21, 0x96, 0x20, 0x24, 0x6c, 0x24, 0x54, 0x10, 0x1a, 0x08, 0xe7, 0x08, 0xfd, 0x84, 0x11, - 0xc2, 0x34, 0x51, 0x81, 0xa8, 0x4f, 0x74, 0x22, 0x86, 0x10, 0x79, 0xc4, 0x5c, 0x62, 0x29, 0xb1, - 0x8e, 0xd8, 0x41, 0xbc, 0x49, 0x1c, 0x26, 0x4e, 0x93, 0x14, 0x49, 0x86, 0x24, 0x17, 0x52, 0x24, - 0x29, 0x99, 0xb4, 0x81, 0x54, 0x49, 0x6a, 0x22, 0x5d, 0x26, 0x3d, 0x26, 0xbd, 0x21, 0x93, 0xc9, - 0x3a, 0x64, 0x47, 0x72, 0x18, 0x59, 0x40, 0x5e, 0x4f, 0xae, 0x24, 0x9f, 0x20, 0x5f, 0x25, 0x0f, - 0x92, 0x3f, 0x50, 0x94, 0x28, 0x26, 0x14, 0x4f, 0x4a, 0x1c, 0x45, 0x42, 0xd9, 0x4e, 0x39, 0x4a, - 0xb9, 0x40, 0x79, 0x40, 0x79, 0x43, 0xa5, 0x52, 0x0d, 0xa8, 0x6e, 0xd4, 0x58, 0xaa, 0x98, 0xba, - 0x9d, 0x5a, 0x4f, 0xbd, 0x44, 0x7d, 0x4a, 0x7d, 0x2f, 0x47, 0x93, 0x33, 0x97, 0xf3, 0x97, 0xe3, - 0xc9, 0xad, 0x93, 0xab, 0x91, 0x6b, 0x95, 0xeb, 0x97, 0x7b, 0x25, 0x4f, 0x94, 0xd7, 0x97, 0x77, - 0x97, 0x5f, 0x2e, 0x9f, 0x27, 0x5f, 0x21, 0x7f, 0x4a, 0xfe, 0xa6, 0xfc, 0xb8, 0x02, 0x51, 0xc1, - 0x40, 0xc1, 0x53, 0x81, 0xa3, 0xb0, 0x56, 0xa1, 0x46, 0xe1, 0xb4, 0xc2, 0x3d, 0x85, 0x49, 0x45, - 0x9a, 0xa2, 0x95, 0x62, 0x88, 0x62, 0x9a, 0x62, 0x89, 0x62, 0x83, 0xe2, 0x35, 0xc5, 0x51, 0x25, - 0xbc, 0x92, 0x81, 0x92, 0xb7, 0x12, 0x4f, 0xa9, 0x40, 0xe9, 0xb0, 0xd2, 0x25, 0xa5, 0x21, 0x1a, - 0x42, 0xd3, 0xa5, 0x79, 0xd2, 0xb8, 0xb4, 0x4d, 0xb4, 0x3a, 0xda, 0x65, 0xda, 0x30, 0x1d, 0x47, - 0x37, 0xa4, 0xfb, 0xd3, 0x93, 0xe9, 0xc5, 0xf4, 0x1f, 0xe8, 0xbd, 0xf4, 0x09, 0x65, 0x25, 0x65, - 0x5b, 0xe5, 0x28, 0xe5, 0x1c, 0xe5, 0x1a, 0xe5, 0xb3, 0xca, 0x52, 0x06, 0xc2, 0x30, 0x60, 0xf8, - 0x33, 0x52, 0x19, 0xa5, 0x8c, 0x93, 0x8c, 0xbb, 0x8c, 0x8f, 0xf3, 0x34, 0xe6, 0xb9, 0xcf, 0xe3, - 0xcf, 0xdb, 0x36, 0xaf, 0x69, 0x5e, 0xff, 0xbc, 0x29, 0x95, 0xf9, 0x2a, 0x6e, 0x2a, 0x7c, 0x95, - 0x22, 0x95, 0x66, 0x95, 0x01, 0x95, 0x8f, 0xaa, 0x4c, 0x55, 0x6f, 0xd5, 0x14, 0xd5, 0x9d, 0xaa, - 0x6d, 0xaa, 0x4f, 0xd4, 0x30, 0x6a, 0x26, 0x6a, 0x61, 0x6a, 0xd9, 0x6a, 0xfb, 0xd5, 0x2e, 0xab, - 0x8d, 0xcf, 0xa7, 0xcf, 0x77, 0x9e, 0xcf, 0x9d, 0x5f, 0x34, 0xff, 0xe4, 0xfc, 0x87, 0xea, 0xb0, - 0xba, 0x89, 0x7a, 0xb8, 0xfa, 0x6a, 0xf5, 0xc3, 0xea, 0x3d, 0xea, 0x93, 0x1a, 0x9a, 0x1a, 0xbe, - 0x1a, 0x19, 0x1a, 0x55, 0x1a, 0x97, 0x34, 0xc6, 0x35, 0x19, 0x9a, 0x6e, 0x9a, 0xc9, 0x9a, 0xe5, - 0x9a, 0xe7, 0x34, 0xc7, 0xb4, 0x68, 0x5a, 0x0b, 0xb5, 0x04, 0x5a, 0xe5, 0x5a, 0xe7, 0xb5, 0x5e, - 0x30, 0x95, 0x99, 0xee, 0xcc, 0x54, 0x66, 0x25, 0xb3, 0x8b, 0x39, 0xa1, 0xad, 0xae, 0xed, 0xa7, - 0x2d, 0xd1, 0x3e, 0xa4, 0xdd, 0xab, 0x3d, 0xad, 0x63, 0xa8, 0xb3, 0x58, 0x67, 0xa3, 0x4e, 0xb3, - 0xce, 0x13, 0x5d, 0x92, 0x2e, 0x5b, 0x37, 0x41, 0xb7, 0x5c, 0xb7, 0x53, 0x77, 0x42, 0x4f, 0x4b, - 0x2f, 0x58, 0x2f, 0x5f, 0xaf, 0x51, 0xef, 0xa1, 0x3e, 0x51, 0x9f, 0xad, 0x9f, 0xa4, 0xbf, 0x47, - 0xbf, 0x5b, 0x7f, 0xca, 0xc0, 0xd0, 0x20, 0xda, 0x60, 0x8b, 0x41, 0x9b, 0xc1, 0xa8, 0xa1, 0x8a, - 0xa1, 0xbf, 0x61, 0x9e, 0x61, 0xa3, 0xe1, 0x63, 0x23, 0xaa, 0x91, 0xab, 0xd1, 0x2a, 0xa3, 0x5a, - 0xa3, 0x3b, 0xc6, 0x38, 0x63, 0xb6, 0x71, 0x8a, 0xf1, 0x3e, 0xe3, 0x5b, 0x26, 0xb0, 0x89, 0x9d, - 0x49, 0x92, 0x49, 0x8d, 0xc9, 0x4d, 0x53, 0xd8, 0xd4, 0xde, 0x54, 0x60, 0xba, 0xcf, 0xb4, 0xcf, - 0x0c, 0x6b, 0xe6, 0x68, 0x26, 0x34, 0xab, 0x35, 0xbb, 0xc7, 0xa2, 0xb0, 0xdc, 0x59, 0x59, 0xac, - 0x46, 0xd6, 0xa0, 0x39, 0xc3, 0x3c, 0xc8, 0x7c, 0xa3, 0x79, 0x9b, 0xf9, 0x2b, 0x0b, 0x3d, 0x8b, - 0x58, 0x8b, 0x9d, 0x16, 0xdd, 0x16, 0x5f, 0x2c, 0xed, 0x2c, 0x53, 0x2d, 0xeb, 0x2c, 0x1f, 0x59, - 0x29, 0x59, 0x05, 0x58, 0x6d, 0xb4, 0xea, 0xb0, 0xfa, 0xc3, 0xda, 0xc4, 0x9a, 0x6b, 0x5d, 0x63, - 0x7d, 0xc7, 0x86, 0x6a, 0xe3, 0x63, 0xb3, 0xce, 0xa6, 0xdd, 0xe6, 0xb5, 0xad, 0xa9, 0x2d, 0xdf, - 0x76, 0xbf, 0xed, 0x7d, 0x3b, 0x9a, 0x5d, 0xb0, 0xdd, 0x16, 0xbb, 0x4e, 0xbb, 0xcf, 0xf6, 0x0e, - 0xf6, 0x22, 0xfb, 0x26, 0xfb, 0x31, 0x07, 0x3d, 0x87, 0x78, 0x87, 0xbd, 0x0e, 0xf7, 0xd8, 0x74, - 0x76, 0x28, 0xbb, 0x84, 0x7d, 0xd5, 0x11, 0xeb, 0xe8, 0xe1, 0xb8, 0xce, 0xf1, 0x8c, 0xe3, 0x07, - 0x27, 0x7b, 0x27, 0xb1, 0xd3, 0x49, 0xa7, 0xdf, 0x9d, 0x59, 0xce, 0x29, 0xce, 0x0d, 0xce, 0xa3, - 0x0b, 0x0c, 0x17, 0xf0, 0x17, 0xd4, 0x2d, 0x18, 0x72, 0xd1, 0x71, 0xe1, 0xb8, 0x1c, 0x72, 0x91, - 0x2e, 0x64, 0x2e, 0x8c, 0x5f, 0x78, 0x70, 0xa1, 0xd4, 0x55, 0xdb, 0x95, 0xe3, 0x5a, 0xeb, 0xfa, - 0xcc, 0x4d, 0xd7, 0x8d, 0xe7, 0x76, 0xc4, 0x6d, 0xc4, 0xdd, 0xd8, 0x3d, 0xd9, 0xfd, 0xb8, 0xfb, - 0x2b, 0x0f, 0x4b, 0x0f, 0x91, 0x47, 0x8b, 0xc7, 0x94, 0xa7, 0x93, 0xe7, 0x1a, 0xcf, 0x0b, 0x5e, - 0x88, 0x97, 0xaf, 0x57, 0x91, 0x57, 0xaf, 0xb7, 0x92, 0xf7, 0x62, 0xef, 0x6a, 0xef, 0xa7, 0x3e, - 0x3a, 0x3e, 0x89, 0x3e, 0x8d, 0x3e, 0x13, 0xbe, 0x76, 0xbe, 0xab, 0x7d, 0x2f, 0xf8, 0x61, 0xfd, - 0x02, 0xfd, 0x76, 0xfa, 0xdd, 0xf3, 0xd7, 0xf0, 0xe7, 0xfa, 0xd7, 0xfb, 0x4f, 0x04, 0x38, 0x04, - 0xac, 0x09, 0xe8, 0x0a, 0xa4, 0x04, 0x46, 0x04, 0x56, 0x07, 0x3e, 0x0b, 0x32, 0x09, 0x12, 0x05, - 0x75, 0x04, 0xc3, 0xc1, 0x01, 0xc1, 0xbb, 0x82, 0x1f, 0x2f, 0xd2, 0x5f, 0x24, 0x5c, 0xd4, 0x16, - 0x02, 0x42, 0xfc, 0x43, 0x76, 0x85, 0x3c, 0x09, 0x35, 0x0c, 0x5d, 0x15, 0xfa, 0x73, 0x18, 0x2e, - 0x2c, 0x34, 0xac, 0x26, 0xec, 0x79, 0xb8, 0x55, 0x78, 0x7e, 0x78, 0x77, 0x04, 0x2d, 0x62, 0x45, - 0x44, 0x43, 0xc4, 0xbb, 0x48, 0x8f, 0xc8, 0xd2, 0xc8, 0x47, 0x8b, 0x8d, 0x16, 0x4b, 0x16, 0x77, - 0x46, 0xc9, 0x47, 0xc5, 0x45, 0xd5, 0x47, 0x4d, 0x45, 0x7b, 0x45, 0x97, 0x45, 0x4b, 0x97, 0x58, - 0x2c, 0x59, 0xb3, 0xe4, 0x46, 0x8c, 0x5a, 0x8c, 0x20, 0xa6, 0x3d, 0x16, 0x1f, 0x1b, 0x15, 0x7b, - 0x24, 0x76, 0x72, 0xa9, 0xf7, 0xd2, 0xdd, 0x4b, 0x87, 0xe3, 0xec, 0xe2, 0x0a, 0xe3, 0xee, 0x2e, - 0x33, 0x5c, 0x96, 0xb3, 0xec, 0xda, 0x72, 0xb5, 0xe5, 0xa9, 0xcb, 0xcf, 0xae, 0x90, 0x5f, 0xc1, - 0x59, 0x71, 0x2a, 0x1e, 0x1b, 0x1f, 0x1d, 0xdf, 0x10, 0xff, 0x89, 0x13, 0xc2, 0xa9, 0xe5, 0x4c, - 0xae, 0xf4, 0x5f, 0xb9, 0x77, 0xe5, 0x04, 0xd7, 0x93, 0xbb, 0x87, 0xfb, 0x92, 0xe7, 0xc6, 0x2b, - 0xe7, 0x8d, 0xf1, 0x5d, 0xf8, 0x65, 0xfc, 0x91, 0x04, 0x97, 0x84, 0xb2, 0x84, 0xd1, 0x44, 0x97, - 0xc4, 0x5d, 0x89, 0x63, 0x49, 0xae, 0x49, 0x15, 0x49, 0xe3, 0x02, 0x4f, 0x41, 0xb5, 0xe0, 0x75, - 0xb2, 0x5f, 0xf2, 0x81, 0xe4, 0xa9, 0x94, 0x90, 0x94, 0xa3, 0x29, 0x33, 0xa9, 0xd1, 0xa9, 0xcd, - 0x69, 0x84, 0xb4, 0xf8, 0xb4, 0xd3, 0x42, 0x25, 0x61, 0x8a, 0xb0, 0x2b, 0x5d, 0x33, 0x3d, 0x27, - 0xbd, 0x2f, 0xc3, 0x34, 0xa3, 0x30, 0x43, 0xba, 0xca, 0x69, 0xd5, 0xee, 0x55, 0x13, 0xa2, 0x40, - 0xd1, 0x91, 0x4c, 0x28, 0x73, 0x59, 0x66, 0xbb, 0x98, 0x8e, 0xfe, 0x4c, 0xf5, 0x48, 0x8c, 0x24, - 0x9b, 0x25, 0x83, 0x59, 0x0b, 0xb3, 0x6a, 0xb2, 0xde, 0x67, 0x47, 0x65, 0x9f, 0xca, 0x51, 0xcc, - 0x11, 0xe6, 0xf4, 0xe4, 0x9a, 0xe4, 0x6e, 0xcb, 0x1d, 0xc9, 0xf3, 0xc9, 0xfb, 0x7e, 0x35, 0x66, - 0x35, 0x77, 0x75, 0x67, 0xbe, 0x76, 0xfe, 0x86, 0xfc, 0xc1, 0x35, 0xee, 0x6b, 0x0e, 0xad, 0x85, - 0xd6, 0xae, 0x5c, 0xdb, 0xb9, 0x4e, 0x77, 0x5d, 0xc1, 0xba, 0xe1, 0xf5, 0xbe, 0xeb, 0x8f, 0x6d, - 0x20, 0x6d, 0x48, 0xd9, 0xf0, 0xcb, 0x46, 0xcb, 0x8d, 0x65, 0x1b, 0xdf, 0x6e, 0x8a, 0xde, 0xd4, - 0x51, 0xa0, 0x51, 0xb0, 0xbe, 0x60, 0x68, 0xb3, 0xef, 0xe6, 0xc6, 0x42, 0xb9, 0x42, 0x51, 0xe1, - 0xbd, 0x2d, 0xce, 0x5b, 0x0e, 0x6c, 0xc5, 0x6c, 0x15, 0x6c, 0xed, 0xdd, 0x66, 0xb3, 0xad, 0x6a, - 0xdb, 0x97, 0x22, 0x5e, 0xd1, 0xf5, 0x62, 0xcb, 0xe2, 0x8a, 0xe2, 0x4f, 0x25, 0xdc, 0x92, 0xeb, - 0xdf, 0x59, 0x7d, 0x57, 0xf9, 0xdd, 0xcc, 0xf6, 0x84, 0xed, 0xbd, 0xa5, 0xf6, 0xa5, 0xfb, 0x77, - 0xe0, 0x76, 0x08, 0x77, 0xdc, 0xdd, 0xe9, 0xba, 0xf3, 0x58, 0x99, 0x62, 0x59, 0x5e, 0xd9, 0xd0, - 0xae, 0xe0, 0x5d, 0xad, 0xe5, 0xcc, 0xf2, 0xa2, 0xf2, 0xb7, 0xbb, 0x57, 0xec, 0xbe, 0x56, 0x61, - 0x5b, 0x71, 0x60, 0x0f, 0x69, 0x8f, 0x64, 0x8f, 0xb4, 0x32, 0xa8, 0xb2, 0xbd, 0x4a, 0xaf, 0x6a, - 0x47, 0xd5, 0xa7, 0xea, 0xa4, 0xea, 0x81, 0x1a, 0x8f, 0x9a, 0xe6, 0xbd, 0xea, 0x7b, 0xb7, 0xed, - 0x9d, 0xda, 0xc7, 0xdb, 0xd7, 0xbf, 0xdf, 0x6d, 0x7f, 0xd3, 0x01, 0x8d, 0x03, 0xc5, 0x07, 0x3e, - 0x1e, 0x14, 0x1c, 0xbc, 0x7f, 0xc8, 0xf7, 0x50, 0x6b, 0xad, 0x41, 0x6d, 0xc5, 0x61, 0xdc, 0xe1, - 0xac, 0xc3, 0xcf, 0xeb, 0xa2, 0xea, 0xba, 0xbf, 0x67, 0x7f, 0x5f, 0x7f, 0x44, 0xed, 0x48, 0xf1, - 0x91, 0xcf, 0x47, 0x85, 0x47, 0xa5, 0xc7, 0xc2, 0x8f, 0x75, 0xd5, 0x3b, 0xd4, 0xd7, 0x37, 0xa8, - 0x37, 0x94, 0x36, 0xc2, 0x8d, 0x92, 0xc6, 0xb1, 0xe3, 0x71, 0xc7, 0x6f, 0xfd, 0xe0, 0xf5, 0x43, - 0x7b, 0x13, 0xab, 0xe9, 0x50, 0x33, 0xa3, 0xb9, 0xf8, 0x04, 0x38, 0x21, 0x39, 0xf1, 0xe2, 0xc7, - 0xf8, 0x1f, 0xef, 0x9e, 0x0c, 0x3c, 0xd9, 0x79, 0x8a, 0x7d, 0xaa, 0xe9, 0x27, 0xfd, 0x9f, 0xf6, - 0xb6, 0xd0, 0x5a, 0x8a, 0x5a, 0xa1, 0xd6, 0xdc, 0xd6, 0x89, 0xb6, 0xa4, 0x36, 0x69, 0x7b, 0x4c, - 0x7b, 0xdf, 0xe9, 0x80, 0xd3, 0x9d, 0x1d, 0xce, 0x1d, 0x2d, 0x3f, 0x9b, 0xff, 0x7c, 0xf4, 0x8c, - 0xf6, 0x99, 0x9a, 0xb3, 0xca, 0x67, 0x4b, 0xcf, 0x91, 0xce, 0x15, 0x9c, 0x9b, 0x39, 0x9f, 0x77, - 0x7e, 0xf2, 0x42, 0xc6, 0x85, 0xf1, 0x8b, 0x89, 0x17, 0x87, 0x3a, 0x57, 0x74, 0x3e, 0xba, 0xb4, - 0xe4, 0xd2, 0x9d, 0xae, 0xb0, 0xae, 0xde, 0xcb, 0x81, 0x97, 0xaf, 0x5e, 0xf1, 0xb9, 0x72, 0xa9, - 0xdb, 0xbd, 0xfb, 0xfc, 0x55, 0x97, 0xab, 0x67, 0xae, 0x39, 0x5d, 0x3b, 0x7d, 0x9d, 0x7d, 0xbd, - 0xed, 0x86, 0xfd, 0x8d, 0xd6, 0x1e, 0xbb, 0x9e, 0x96, 0x5f, 0xec, 0x7e, 0x69, 0xe9, 0xb5, 0xef, - 0x6d, 0xbd, 0xe9, 0x70, 0xb3, 0xfd, 0x96, 0xe3, 0xad, 0x8e, 0xbe, 0x05, 0x7d, 0xe7, 0xfa, 0x5d, - 0xfb, 0x2f, 0xde, 0xf6, 0xba, 0x7d, 0xe5, 0x8e, 0xff, 0x9d, 0x1b, 0x03, 0x8b, 0x06, 0xfa, 0xee, - 0x2e, 0xbe, 0x7b, 0xff, 0x5e, 0xdc, 0x3d, 0xe9, 0x7d, 0xde, 0xfd, 0xd1, 0x07, 0xa9, 0x0f, 0x5e, - 0x3f, 0xcc, 0x7a, 0x38, 0xfd, 0x68, 0xfd, 0x63, 0xec, 0xe3, 0xa2, 0x27, 0x0a, 0x4f, 0x2a, 0x9e, - 0xaa, 0x3f, 0xad, 0xfd, 0xd5, 0xf8, 0xd7, 0x66, 0xa9, 0xbd, 0xf4, 0xec, 0xa0, 0xd7, 0x60, 0xcf, - 0xb3, 0x88, 0x67, 0x8f, 0x86, 0xb8, 0x43, 0x2f, 0xff, 0x95, 0xf9, 0xaf, 0x4f, 0xc3, 0x05, 0xcf, - 0xa9, 0xcf, 0x2b, 0x46, 0xb4, 0x46, 0xea, 0x47, 0xad, 0x47, 0xcf, 0x8c, 0xf9, 0x8c, 0xdd, 0x7a, - 0xb1, 0xf4, 0xc5, 0xf0, 0xcb, 0x8c, 0x97, 0xd3, 0xe3, 0x85, 0xbf, 0x29, 0xfe, 0xb6, 0xf7, 0x95, - 0xd1, 0xab, 0x9f, 0x7e, 0x77, 0xfb, 0xbd, 0x67, 0x62, 0xc9, 0xc4, 0xf0, 0x6b, 0xd1, 0xeb, 0x99, - 0x3f, 0x4a, 0xde, 0xa8, 0xbe, 0x39, 0xfa, 0xd6, 0xf6, 0x6d, 0xe7, 0x64, 0xe8, 0xe4, 0xd3, 0x77, - 0x69, 0xef, 0xa6, 0xa7, 0x8a, 0xde, 0xab, 0xbe, 0x3f, 0xf6, 0x81, 0xfd, 0xa1, 0xfb, 0x63, 0xf4, - 0xc7, 0x91, 0xe9, 0xec, 0x4f, 0xf8, 0x4f, 0x95, 0x9f, 0x8d, 0x3f, 0x77, 0x7c, 0x09, 0xfc, 0xf2, - 0x78, 0x26, 0x6d, 0x66, 0xe6, 0xdf, 0xf7, 0x84, 0xf3, 0xfb, 0x32, 0x3a, 0x59, 0x7e, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x13, 0x01, 0x00, - 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x03, 0xa4, 0x69, 0x54, 0x58, 0x74, 0x58, 0x4d, 0x4c, 0x3a, 0x63, - 0x6f, 0x6d, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x78, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x3c, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x78, 0x6d, 0x6c, 0x6e, - 0x73, 0x3a, 0x78, 0x3d, 0x22, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x3a, 0x6e, 0x73, 0x3a, 0x6d, 0x65, - 0x74, 0x61, 0x2f, 0x22, 0x20, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x74, 0x6b, 0x3d, 0x22, 0x58, 0x4d, - 0x50, 0x20, 0x43, 0x6f, 0x72, 0x65, 0x20, 0x35, 0x2e, 0x34, 0x2e, 0x30, 0x22, 0x3e, 0x0a, 0x20, - 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, - 0x3a, 0x72, 0x64, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, - 0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x31, 0x39, 0x39, 0x39, 0x2f, 0x30, 0x32, 0x2f, - 0x32, 0x32, 0x2d, 0x72, 0x64, 0x66, 0x2d, 0x73, 0x79, 0x6e, 0x74, 0x61, 0x78, 0x2d, 0x6e, 0x73, - 0x23, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x72, 0x64, 0x66, 0x3a, 0x44, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x72, 0x64, 0x66, 0x3a, 0x61, - 0x62, 0x6f, 0x75, 0x74, 0x3d, 0x22, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x78, 0x6d, 0x70, 0x3d, 0x22, 0x68, - 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x78, 0x61, 0x70, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x74, - 0x69, 0x66, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, - 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x2f, 0x31, 0x2e, - 0x30, 0x2f, 0x22, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x78, 0x6d, 0x6c, 0x6e, 0x73, 0x3a, 0x65, 0x78, 0x69, 0x66, 0x3d, 0x22, 0x68, 0x74, 0x74, 0x70, - 0x3a, 0x2f, 0x2f, 0x6e, 0x73, 0x2e, 0x61, 0x64, 0x6f, 0x62, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x65, 0x78, 0x69, 0x66, 0x2f, 0x31, 0x2e, 0x30, 0x2f, 0x22, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x79, - 0x44, 0x61, 0x74, 0x65, 0x3e, 0x32, 0x30, 0x31, 0x34, 0x2d, 0x30, 0x35, 0x2d, 0x30, 0x32, 0x54, - 0x31, 0x31, 0x3a, 0x30, 0x35, 0x3a, 0x30, 0x36, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x4d, 0x6f, - 0x64, 0x69, 0x66, 0x79, 0x44, 0x61, 0x74, 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x3c, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x6d, 0x61, 0x74, 0x6f, 0x72, 0x20, 0x33, - 0x2e, 0x31, 0x3c, 0x2f, 0x78, 0x6d, 0x70, 0x3a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72, 0x54, - 0x6f, 0x6f, 0x6c, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3e, - 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x4f, 0x72, 0x69, 0x65, 0x6e, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x3e, - 0x35, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x43, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, - 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, - 0x69, 0x74, 0x3e, 0x31, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x55, 0x6e, 0x69, 0x74, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, 0x52, 0x65, 0x73, 0x6f, 0x6c, - 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x59, - 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x66, 0x66, 0x3a, 0x58, 0x52, 0x65, 0x73, 0x6f, - 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x37, 0x32, 0x3c, 0x2f, 0x74, 0x69, 0x66, 0x66, 0x3a, - 0x58, 0x52, 0x65, 0x73, 0x6f, 0x6c, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, - 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, - 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x38, 0x3c, 0x2f, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x58, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, - 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x3e, 0x31, - 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x70, 0x61, 0x63, - 0x65, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x65, 0x78, 0x69, - 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x3e, 0x31, 0x3c, 0x2f, 0x65, 0x78, 0x69, 0x66, 0x3a, 0x50, 0x69, 0x78, 0x65, 0x6c, 0x59, - 0x44, 0x69, 0x6d, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, - 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x3e, 0x0a, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x72, 0x64, 0x66, 0x3a, 0x52, 0x44, 0x46, - 0x3e, 0x0a, 0x3c, 0x2f, 0x78, 0x3a, 0x78, 0x6d, 0x70, 0x6d, 0x65, 0x74, 0x61, 0x3e, 0x0a, 0x90, - 0x7a, 0xe1, 0x8d, 0x00, 0x00, 0x00, 0x12, 0x49, 0x44, 0x41, 0x54, 0x08, 0x1d, 0x63, 0x60, 0x60, - 0x60, 0xf8, 0x0f, 0xc5, 0x40, 0x0a, 0x13, 0x00, 0x00, 0x35, 0xeb, 0x01, 0xff, 0x0f, 0x5e, 0xbc, - 0xf4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82 -}; - - -#pragma clang diagnostic pop - -@implementation FLEXResources - -#define FLEXImage(base) ( \ - (UIScreen.mainScreen.scale > 1.5) ? \ - ( (UIScreen.mainScreen.scale > 2.5) ? \ - [self imageWithBytesNoCopy:(void *)base##3x length:sizeof(base##3x) scale:3.0] : \ - [self imageWithBytesNoCopy:(void *)base##2x length:sizeof(base##2x) scale:2.0] \ - ) : \ - nil \ -) - -#define FLEXImageTemplate(base) ([FLEXImage(base) imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]) - -#define FLEXRetinaOnlyImage(base) ([self imageWithBytesNoCopy:(void *)(base) length:sizeof(base) scale:2.0]) - - -#pragma mark - FLEX Toolbar Icons - -+ (UIImage *)closeIcon { - return FLEXImageTemplate(FLEXCloseIcon); -} - -+ (UIImage *)dragHandle { - return FLEXImageTemplate(FLEXDragHandle); -} - -+ (UIImage *)globalsIcon { - return FLEXImageTemplate(FLEXGlobalsIcon); -} - -+ (UIImage *)hierarchyIcon { - return FLEXImageTemplate(FLEXHierarchyIcon); -} - -+ (UIImage *)recentIcon { - return FLEXImageTemplate(FLEXRecentTabIcon); -} - -+ (UIImage *)moveIcon { - return FLEXImageTemplate(FLEXMoveIcon); -} - -+ (UIImage *)selectIcon { - return FLEXImageTemplate(FLEXSelectIcon); -} - - -#pragma mark - Toolbar Icons - -+ (UIImage *)bookmarksIcon { - return FLEXImage(FLEXBookmarksIcon); -} - -+ (UIImage *)openTabsIcon { - return FLEXImage(FLEXOpenTabsIcon); -} - -+ (UIImage *)moreIcon { - return FLEXImage(FLEXMoreIcon); -} - -+ (UIImage *)gearIcon { - return FLEXImage(FLEXGearIcon); -} - -+ (UIImage *)scrollToBottomIcon { - return FLEXImage(FLEXCircleDownArrowIcon); -} - - -#pragma mark - Content Type Icons - -+ (UIImage *)jsonIcon { - return FLEXImage(FLEXJSONIcon); -} - -+ (UIImage *)textPlainIcon { - return FLEXImage(FLEXTextPlainIcon); -} - -+ (UIImage *)htmlIcon { - return FLEXImage(FLEXHTMLIcon); -} - -+ (UIImage *)audioIcon { - return FLEXImage(FLEXAudioIcon); -} - -+ (UIImage *)jsIcon { - return FLEXImage(FLEXJSIcon); -} - -+ (UIImage *)plistIcon { - return FLEXImage(FLEXPlistIcon); -} - -+ (UIImage *)textIcon { - return FLEXImage(FLEXTextIcon); -} - -+ (UIImage *)videoIcon { - return FLEXImage(FLEXVideoIcon); -} - -+ (UIImage *)xmlIcon { - return FLEXImage(FLEXXMLIcon); -} - -+ (UIImage *)binaryIcon { - return FLEXImage(FLEXBinaryIcon); -} - - -#pragma mark - 3D Explorer Icons - -+ (UIImage *)toggle2DIcon { - return FLEXImage(FLEXToggle2DIcon); -} - -+ (UIImage *)toggle3DIcon { - return FLEXImage(FLEXToggle3DIcon); -} - -+ (UIImage *)rangeSliderLeftHandle { - return FLEXImage(FLEXRangeSliderLeftHandle); -} - -+ (UIImage *)rangeSliderRightHandle { - return FLEXImage(FLEXRangeSliderRightHandle); -} - -+ (UIImage *)rangeSliderTrack { - UIEdgeInsets cap = UIEdgeInsetsMake(0, 5, 0, 4); - return [FLEXImage(FLEXRangeSliderTrack) resizableImageWithCapInsets:cap]; -} - -+ (UIImage *)rangeSliderFill { - UIEdgeInsets cap = UIEdgeInsetsMake(0, 5, 0, 4); - return [FLEXImage(FLEXRangeSliderFill) resizableImageWithCapInsets:cap]; -} - - -#pragma mark - Misc Icons - -+ (UIImage *)checkerPattern { - return FLEXImage(FLEXCheckerPattern); -} - -+ (UIColor *)checkerPatternColor { - return [UIColor colorWithPatternImage:FLEXResources.checkerPattern]; -} - -+ (UIImage *)hierarchyIndentPattern { - return FLEXImageTemplate(FLEXHierarchyIndentPattern); -} - - -#undef FLEXImage -#undef FLEXRetinaOnlyImage - - -#pragma mark - Helpers - -+ (UIImage *)imageWithBytesNoCopy:(void *)bytes length:(NSUInteger)length scale:(CGFloat)scale { - NSData *data = [NSData dataWithBytesNoCopy:bytes length:length freeWhenDone:NO]; - return [UIImage imageWithData:data scale:scale]; -} - -@end diff --git a/BHTwitter/Classes/Utility/FLEXUtility.h b/BHTwitter/Classes/Utility/FLEXUtility.h deleted file mode 100644 index 28beb055..00000000 --- a/BHTwitter/Classes/Utility/FLEXUtility.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// FLEXUtility.h -// Flipboard -// -// Created by Ryan Olson on 4/18/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import -#import -#import -#import -#import "FLEXTypeEncodingParser.h" -#import "FLEXAlert.h" -#import "NSArray+FLEX.h" -#import "UIFont+FLEX.h" -#import "FLEXMacros.h" - -@interface FLEXUtility : NSObject - -/// The key window of the app, if it is not a \c FLEXWindow. -/// If it is, then \c FLEXWindow.previousKeyWindow is returned. -@property (nonatomic, readonly, class) UIWindow *appKeyWindow; -/// @return the result of +[UIWindow allWindowsIncludingInternalWindows:onlyVisibleWindows:] -@property (nonatomic, readonly, class) NSArray *allWindows; -/// The first active \c UIWindowScene of the app. -@property (nonatomic, readonly, class) UIWindowScene *activeScene API_AVAILABLE(ios(13.0)); -/// @return top-most view controller of the given window -+ (UIViewController *)topViewControllerInWindow:(UIWindow *)window; - -+ (UIColor *)consistentRandomColorForObject:(id)object; -+ (NSString *)descriptionForView:(UIView *)view includingFrame:(BOOL)includeFrame; -+ (NSString *)stringForCGRect:(CGRect)rect; -+ (UIViewController *)viewControllerForView:(UIView *)view; -+ (UIViewController *)viewControllerForAncestralView:(UIView *)view; -+ (UIImage *)previewImageForView:(UIView *)view; -+ (UIImage *)previewImageForLayer:(CALayer *)layer; -+ (NSString *)detailDescriptionForView:(UIView *)view; -+ (UIImage *)circularImageWithColor:(UIColor *)color radius:(CGFloat)radius; -+ (UIColor *)hierarchyIndentPatternColor; -+ (NSString *)pointerToString:(void *)ptr; -+ (NSString *)addressOfObject:(id)object; -+ (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString; -+ (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask; -+ (UIImage *)thumbnailedImageWithMaxPixelDimension:(NSInteger)dimension fromImageData:(NSData *)data; -+ (NSString *)stringFromRequestDuration:(NSTimeInterval)duration; -+ (NSString *)statusCodeStringFromURLResponse:(NSURLResponse *)response; -+ (BOOL)isErrorStatusCodeFromURLResponse:(NSURLResponse *)response; -+ (NSArray *)itemsFromQueryString:(NSString *)query; -+ (NSString *)prettyJSONStringFromData:(NSData *)data; -+ (BOOL)isValidJSONData:(NSData *)data; -+ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData; - -// Swizzling utilities - -+ (SEL)swizzledSelectorForSelector:(SEL)selector; -+ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls; -+ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector onClass:(Class)_class withBlock:(id)block swizzledSelector:(SEL)swizzledSelector; -+ (void)replaceImplementationOfSelector:(SEL)selector withSelector:(SEL)swizzledSelector forClass:(Class)cls withMethodDescription:(struct objc_method_description)methodDescription implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock; - -@end diff --git a/BHTwitter/Classes/Utility/FLEXUtility.m b/BHTwitter/Classes/Utility/FLEXUtility.m deleted file mode 100644 index 631d74bb..00000000 --- a/BHTwitter/Classes/Utility/FLEXUtility.m +++ /dev/null @@ -1,527 +0,0 @@ -// -// FLEXUtility.m -// Flipboard -// -// Created by Ryan Olson on 4/18/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXUtility.h" -#import "FLEXResources.h" -#import "FLEXWindow.h" -#import -#import -#import - -BOOL FLEXConstructorsShouldRun() { - #if FLEX_DISABLE_CTORS - return NO; - #else - static BOOL _FLEXConstructorsShouldRun_storage = YES; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *key = @"FLEX_SKIP_INIT"; - if (getenv(key.UTF8String) || [NSUserDefaults.standardUserDefaults boolForKey:key]) { - _FLEXConstructorsShouldRun_storage = NO; - } - }); - - return _FLEXConstructorsShouldRun_storage; - #endif -} - -@implementation FLEXUtility - -+ (UIWindow *)appKeyWindow { - // First, check UIApplication.keyWindow - FLEXWindow *window = (id)UIApplication.sharedApplication.keyWindow; - if (window) { - if ([window isKindOfClass:[FLEXWindow class]]) { - return window.previousKeyWindow; - } - - return window; - } - - // As of iOS 13, UIApplication.keyWindow does not return nil, - // so this is more of a safeguard against it returning nil in the future. - // - // Also, these are obviously not all FLEXWindows; FLEXWindow is used - // so we can call window.previousKeyWindow without an ugly cast - for (FLEXWindow *window in UIApplication.sharedApplication.windows) { - if (window.isKeyWindow) { - if ([window isKindOfClass:[FLEXWindow class]]) { - return window.previousKeyWindow; - } - - return window; - } - } - - return nil; -} - -+ (UIWindowScene *)activeScene { - for (UIScene *scene in UIApplication.sharedApplication.connectedScenes) { - // Look for an active UIWindowScene - if (scene.activationState == UISceneActivationStateForegroundActive && - [scene isKindOfClass:[UIWindowScene class]]) { - return (UIWindowScene *)scene; - } - } - - return nil; -} - -+ (UIViewController *)topViewControllerInWindow:(UIWindow *)window { - UIViewController *topViewController = window.rootViewController; - while (topViewController.presentedViewController) { - topViewController = topViewController.presentedViewController; - } - return topViewController; -} - -+ (UIColor *)consistentRandomColorForObject:(id)object { - CGFloat hue = (((NSUInteger)object >> 4) % 256) / 255.0; - return [UIColor colorWithHue:hue saturation:1.0 brightness:1.0 alpha:1.0]; -} - -+ (NSString *)descriptionForView:(UIView *)view includingFrame:(BOOL)includeFrame { - NSString *description = [[view class] description]; - - NSString *viewControllerDescription = [[[self viewControllerForView:view] class] description]; - if (viewControllerDescription.length > 0) { - description = [description stringByAppendingFormat:@" (%@)", viewControllerDescription]; - } - - if (includeFrame) { - description = [description stringByAppendingFormat:@" %@", [self stringForCGRect:view.frame]]; - } - - if (view.accessibilityLabel.length > 0) { - description = [description stringByAppendingFormat:@" · %@", view.accessibilityLabel]; - } - - return description; -} - -+ (NSString *)stringForCGRect:(CGRect)rect { - return [NSString stringWithFormat:@"{(%g, %g), (%g, %g)}", - rect.origin.x, rect.origin.y, rect.size.width, rect.size.height - ]; -} - -+ (UIViewController *)viewControllerForView:(UIView *)view { - NSString *viewDelegate = @"_viewDelegate"; - if ([view respondsToSelector:NSSelectorFromString(viewDelegate)]) { - return [view valueForKey:viewDelegate]; - } - - return nil; -} - -+ (UIViewController *)viewControllerForAncestralView:(UIView *)view { - NSString *_viewControllerForAncestor = @"_viewControllerForAncestor"; - if ([view respondsToSelector:NSSelectorFromString(_viewControllerForAncestor)]) { - return [view valueForKey:_viewControllerForAncestor]; - } - - return nil; -} - -+ (UIImage *)previewImageForView:(UIView *)view { - if (CGRectIsEmpty(view.bounds)) { - return [UIImage new]; - } - - CGSize viewSize = view.bounds.size; - UIGraphicsBeginImageContextWithOptions(viewSize, NO, 0.0); - [view drawViewHierarchyInRect:CGRectMake(0, 0, viewSize.width, viewSize.height) afterScreenUpdates:YES]; - UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return previewImage; -} - -+ (UIImage *)previewImageForLayer:(CALayer *)layer { - if (CGRectIsEmpty(layer.bounds)) { - return nil; - } - - UIGraphicsBeginImageContextWithOptions(layer.bounds.size, NO, 0.0); - CGContextRef imageContext = UIGraphicsGetCurrentContext(); - [layer renderInContext:imageContext]; - UIImage *previewImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return previewImage; -} - -+ (NSString *)detailDescriptionForView:(UIView *)view { - return [NSString stringWithFormat:@"frame %@", [self stringForCGRect:view.frame]]; -} - -+ (UIImage *)circularImageWithColor:(UIColor *)color radius:(CGFloat)radius { - CGFloat diameter = radius * 2.0; - UIGraphicsBeginImageContextWithOptions(CGSizeMake(diameter, diameter), NO, 0.0); - CGContextRef imageContext = UIGraphicsGetCurrentContext(); - CGContextSetFillColorWithColor(imageContext, color.CGColor); - CGContextFillEllipseInRect(imageContext, CGRectMake(0, 0, diameter, diameter)); - UIImage *circularImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return circularImage; -} - -+ (UIColor *)hierarchyIndentPatternColor { - static UIColor *patternColor = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - UIImage *indentationPatternImage = FLEXResources.hierarchyIndentPattern; - patternColor = [UIColor colorWithPatternImage:indentationPatternImage]; - if (@available(iOS 13.0, *)) { - // Create a dark mode version - UIGraphicsBeginImageContextWithOptions( - indentationPatternImage.size, NO, indentationPatternImage.scale - ); - [FLEXColor.iconColor set]; - [indentationPatternImage drawInRect:CGRectMake( - 0, 0, indentationPatternImage.size.width, indentationPatternImage.size.height - )]; - UIImage *darkModePatternImage = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - - // Create dynamic color provider - patternColor = [UIColor colorWithDynamicProvider:^UIColor *(UITraitCollection *traitCollection) { - return (traitCollection.userInterfaceStyle == UIUserInterfaceStyleLight - ? [UIColor colorWithPatternImage:indentationPatternImage] - : [UIColor colorWithPatternImage:darkModePatternImage]); - }]; - } - }); - - return patternColor; -} - -+ (NSString *)applicationImageName { - return NSBundle.mainBundle.executablePath; -} - -+ (NSString *)applicationName { - return FLEXUtility.applicationImageName.lastPathComponent; -} - -+ (NSString *)pointerToString:(void *)ptr { - return [NSString stringWithFormat:@"%p", ptr]; -} - -+ (NSString *)addressOfObject:(id)object { - return [NSString stringWithFormat:@"%p", object]; -} - -+ (NSString *)stringByEscapingHTMLEntitiesInString:(NSString *)originalString { - static NSDictionary *escapingDictionary = nil; - static NSRegularExpression *regex = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - escapingDictionary = @{ @" " : @" ", - @">" : @">", - @"<" : @"<", - @"&" : @"&", - @"'" : @"'", - @"\"" : @""", - @"«" : @"«", - @"»" : @"»" - }; - regex = [NSRegularExpression regularExpressionWithPattern:@"(&|>|<|'|\"|«|»)" options:0 error:NULL]; - }); - - NSMutableString *mutableString = originalString.mutableCopy; - - NSArray *matches = [regex - matchesInString:mutableString options:0 range:NSMakeRange(0, mutableString.length) - ]; - for (NSTextCheckingResult *result in matches.reverseObjectEnumerator) { - NSString *foundString = [mutableString substringWithRange:result.range]; - NSString *replacementString = escapingDictionary[foundString]; - if (replacementString) { - [mutableString replaceCharactersInRange:result.range withString:replacementString]; - } - } - - return [mutableString copy]; -} - -+ (UIInterfaceOrientationMask)infoPlistSupportedInterfaceOrientationsMask { - NSArray *supportedOrientations = NSBundle.mainBundle.infoDictionary[@"UISupportedInterfaceOrientations"]; - UIInterfaceOrientationMask supportedOrientationsMask = 0; - if ([supportedOrientations containsObject:@"UIInterfaceOrientationPortrait"]) { - supportedOrientationsMask |= UIInterfaceOrientationMaskPortrait; - } - if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskLandscapeRight"]) { - supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeRight; - } - if ([supportedOrientations containsObject:@"UIInterfaceOrientationMaskPortraitUpsideDown"]) { - supportedOrientationsMask |= UIInterfaceOrientationMaskPortraitUpsideDown; - } - if ([supportedOrientations containsObject:@"UIInterfaceOrientationLandscapeLeft"]) { - supportedOrientationsMask |= UIInterfaceOrientationMaskLandscapeLeft; - } - return supportedOrientationsMask; -} - -+ (UIImage *)thumbnailedImageWithMaxPixelDimension:(NSInteger)dimension fromImageData:(NSData *)data { - UIImage *thumbnail = nil; - CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)data, 0); - if (imageSource) { - NSDictionary *options = @{ - (__bridge id)kCGImageSourceCreateThumbnailWithTransform : @YES, - (__bridge id)kCGImageSourceCreateThumbnailFromImageAlways : @YES, - (__bridge id)kCGImageSourceThumbnailMaxPixelSize : @(dimension) - }; - - CGImageRef scaledImageRef = CGImageSourceCreateThumbnailAtIndex( - imageSource, 0, (__bridge CFDictionaryRef)options - ); - if (scaledImageRef) { - thumbnail = [UIImage imageWithCGImage:scaledImageRef]; - CFRelease(scaledImageRef); - } - CFRelease(imageSource); - } - return thumbnail; -} - -+ (NSString *)stringFromRequestDuration:(NSTimeInterval)duration { - NSString *string = @"0s"; - if (duration > 0.0) { - if (duration < 1.0) { - string = [NSString stringWithFormat:@"%dms", (int)(duration * 1000)]; - } else if (duration < 10.0) { - string = [NSString stringWithFormat:@"%.2fs", duration]; - } else { - string = [NSString stringWithFormat:@"%.1fs", duration]; - } - } - return string; -} - -+ (NSString *)statusCodeStringFromURLResponse:(NSURLResponse *)response { - NSString *httpResponseString = nil; - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - NSString *statusCodeDescription = nil; - if (httpResponse.statusCode == 200) { - // Prefer OK to the default "no error" - statusCodeDescription = @"OK"; - } else { - statusCodeDescription = [NSHTTPURLResponse localizedStringForStatusCode:httpResponse.statusCode]; - } - httpResponseString = [NSString stringWithFormat:@"%ld %@", (long)httpResponse.statusCode, statusCodeDescription]; - } - return httpResponseString; -} - -+ (BOOL)isErrorStatusCodeFromURLResponse:(NSURLResponse *)response { - if ([response isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - return httpResponse.statusCode >= 400; - } - - return NO; -} - -+ (NSArray *)itemsFromQueryString:(NSString *)query { - NSMutableArray *items = [NSMutableArray new]; - - // [a=1, b=2, c=3] - NSArray *queryComponents = [query componentsSeparatedByString:@"&"]; - for (NSString *keyValueString in queryComponents) { - // [a, 1] - NSArray *components = [keyValueString componentsSeparatedByString:@"="]; - if (components.count == 2) { - NSString *key = components.firstObject.stringByRemovingPercentEncoding; - NSString *value = components.lastObject.stringByRemovingPercentEncoding; - - [items addObject:[NSURLQueryItem queryItemWithName:key value:value]]; - } - } - - return items.copy; -} - -+ (NSString *)prettyJSONStringFromData:(NSData *)data { - NSString *prettyString = nil; - - id jsonObject = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]; - if ([NSJSONSerialization isValidJSONObject:jsonObject]) { - // Thanks RaziPour1993 - prettyString = [[NSString alloc] - initWithData:[NSJSONSerialization - dataWithJSONObject:jsonObject options:NSJSONWritingPrettyPrinted error:NULL - ] - encoding:NSUTF8StringEncoding - ]; - // NSJSONSerialization escapes forward slashes. - // We want pretty json, so run through and unescape the slashes. - prettyString = [prettyString stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; - } else { - prettyString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; - } - - return prettyString; -} - -+ (BOOL)isValidJSONData:(NSData *)data { - return [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL] ? YES : NO; -} - -// Thanks to the following links for help with this method -// https://www.cocoanetics.com/2012/02/decompressing-files-into-memory/ -// https://github.com/nicklockwood/GZIP -+ (NSData *)inflatedDataFromCompressedData:(NSData *)compressedData { - NSData *inflatedData = nil; - NSUInteger compressedDataLength = compressedData.length; - if (compressedDataLength > 0) { - z_stream stream; - stream.zalloc = Z_NULL; - stream.zfree = Z_NULL; - stream.avail_in = (uInt)compressedDataLength; - stream.next_in = (void *)compressedData.bytes; - stream.total_out = 0; - stream.avail_out = 0; - - NSMutableData *mutableData = [NSMutableData dataWithLength:compressedDataLength * 1.5]; - if (inflateInit2(&stream, 15 + 32) == Z_OK) { - int status = Z_OK; - while (status == Z_OK) { - if (stream.total_out >= mutableData.length) { - mutableData.length += compressedDataLength / 2; - } - stream.next_out = (uint8_t *)[mutableData mutableBytes] + stream.total_out; - stream.avail_out = (uInt)(mutableData.length - stream.total_out); - status = inflate(&stream, Z_SYNC_FLUSH); - } - if (inflateEnd(&stream) == Z_OK) { - if (status == Z_STREAM_END) { - mutableData.length = stream.total_out; - inflatedData = [mutableData copy]; - } - } - } - } - return inflatedData; -} - -+ (NSArray *)allWindows { - BOOL includeInternalWindows = YES; - BOOL onlyVisibleWindows = NO; - - // Obfuscating selector allWindowsIncludingInternalWindows:onlyVisibleWindows: - NSArray *allWindowsComponents = @[ - @"al", @"lWindo", @"wsIncl", @"udingInt", @"ernalWin", @"dows:o", @"nlyVisi", @"bleWin", @"dows:" - ]; - SEL allWindowsSelector = NSSelectorFromString([allWindowsComponents componentsJoinedByString:@""]); - - NSMethodSignature *methodSignature = [[UIWindow class] methodSignatureForSelector:allWindowsSelector]; - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; - - invocation.target = [UIWindow class]; - invocation.selector = allWindowsSelector; - [invocation setArgument:&includeInternalWindows atIndex:2]; - [invocation setArgument:&onlyVisibleWindows atIndex:3]; - [invocation invoke]; - - __unsafe_unretained NSArray *windows = nil; - [invocation getReturnValue:&windows]; - return windows; -} - -+ (UIAlertController *)alert:(NSString *)title message:(NSString *)message { - return [UIAlertController - alertControllerWithTitle:title - message:message - preferredStyle:UIAlertControllerStyleAlert - ]; -} - -+ (SEL)swizzledSelectorForSelector:(SEL)selector { - return NSSelectorFromString([NSString stringWithFormat: - @"_flex_swizzle_%x_%@", arc4random(), NSStringFromSelector(selector) - ]); -} - -+ (BOOL)instanceRespondsButDoesNotImplementSelector:(SEL)selector class:(Class)cls { - if ([cls instancesRespondToSelector:selector]) { - unsigned int numMethods = 0; - Method *methods = class_copyMethodList(cls, &numMethods); - - BOOL implementsSelector = NO; - for (int index = 0; index < numMethods; index++) { - SEL methodSelector = method_getName(methods[index]); - if (selector == methodSelector) { - implementsSelector = YES; - break; - } - } - - free(methods); - - if (!implementsSelector) { - return YES; - } - } - - return NO; -} - -+ (void)replaceImplementationOfKnownSelector:(SEL)originalSelector - onClass:(Class)_class - withBlock:(id)block - swizzledSelector:(SEL)swizzledSelector { - // This method is only intended for swizzling methods that are know to exist on the class. - // Bail if that isn't the case. - Method originalMethod = class_getInstanceMethod(_class, originalSelector); - if (!originalMethod) { - return; - } - - IMP implementation = imp_implementationWithBlock(block); - class_addMethod(_class, swizzledSelector, implementation, method_getTypeEncoding(originalMethod)); - Method newMethod = class_getInstanceMethod(_class, swizzledSelector); - method_exchangeImplementations(originalMethod, newMethod); -} - -+ (void)replaceImplementationOfSelector:(SEL)selector - withSelector:(SEL)swizzledSelector - forClass:(Class)cls - withMethodDescription:(struct objc_method_description)methodDescription - implementationBlock:(id)implementationBlock undefinedBlock:(id)undefinedBlock { - if ([self instanceRespondsButDoesNotImplementSelector:selector class:cls]) { - return; - } - - IMP implementation = imp_implementationWithBlock((id)( - [cls instancesRespondToSelector:selector] ? implementationBlock : undefinedBlock) - ); - - Method oldMethod = class_getInstanceMethod(cls, selector); - const char *types = methodDescription.types; - if (oldMethod) { - if (!types) { - types = method_getTypeEncoding(oldMethod); - } - - class_addMethod(cls, swizzledSelector, implementation, types); - Method newMethod = class_getInstanceMethod(cls, swizzledSelector); - method_exchangeImplementations(oldMethod, newMethod); - } else { - if (!types) { - // Some protocol method descriptions don't have .types populated - // Set the return type to void and ignore arguments - types = "v@:"; - } - class_addMethod(cls, selector, implementation, types); - } -} - -@end diff --git a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.h b/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.h deleted file mode 100644 index 4fae64e4..00000000 --- a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// FLEXKeyboardHelpViewController.h -// FLEX -// -// Created by Ryan Olson on 9/19/15. -// Copyright © 2015 f. All rights reserved. -// - -#import - -@interface FLEXKeyboardHelpViewController : UIViewController - -@end diff --git a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m b/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m deleted file mode 100644 index 66e9d7e6..00000000 --- a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardHelpViewController.m +++ /dev/null @@ -1,42 +0,0 @@ -// -// FLEXKeyboardHelpViewController.m -// FLEX -// -// Created by Ryan Olson on 9/19/15. -// Copyright © 2015 f. All rights reserved. -// - -#import "FLEXKeyboardHelpViewController.h" -#import "FLEXKeyboardShortcutManager.h" - -@interface FLEXKeyboardHelpViewController () - -@property (nonatomic) UITextView *textView; - -@end - -@implementation FLEXKeyboardHelpViewController - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.textView = [[UITextView alloc] initWithFrame:self.view.bounds]; - self.textView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; - [self.view addSubview:self.textView]; -#if TARGET_OS_SIMULATOR - self.textView.text = FLEXKeyboardShortcutManager.sharedManager.keyboardShortcutsDescription; -#endif - self.textView.backgroundColor = UIColor.blackColor; - self.textView.textColor = UIColor.whiteColor; - self.textView.font = [UIFont boldSystemFontOfSize:14.0]; - self.navigationController.navigationBar.barStyle = UIBarStyleBlackOpaque; - - self.title = @"Simulator Shortcuts"; - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed:)]; -} - -- (void)donePressed:(id)sender { - [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h b/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h deleted file mode 100644 index 292f3d4c..00000000 --- a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FLEXKeyboardShortcutManager.h -// FLEX -// -// Created by Ryan Olson on 9/19/15. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXKeyboardShortcutManager : NSObject - -@property (nonatomic, readonly, class) FLEXKeyboardShortcutManager *sharedManager; - -/// @param key A single character string matching a key on the keyboard -/// @param modifiers Modifier keys such as shift, command, or alt/option -/// @param action The block to run on the main thread when the key & modifier combination is recognized. -/// @param description Shown the the keyboard shortcut help menu, which is accessed via the '?' key. -/// @param allowOverride Allow registering even if there's an existing action associated with that key/modifier. -- (void)registerSimulatorShortcutWithKey:(NSString *)key - modifiers:(UIKeyModifierFlags)modifiers - action:(dispatch_block_t)action - description:(NSString *)description - allowOverride:(BOOL)allowOverride; - -@property (nonatomic, getter=isEnabled) BOOL enabled; -@property (nonatomic, readonly) NSString *keyboardShortcutsDescription; - -@end diff --git a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m b/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m deleted file mode 100644 index 4263245d..00000000 --- a/BHTwitter/Classes/Utility/Keyboard/FLEXKeyboardShortcutManager.m +++ /dev/null @@ -1,326 +0,0 @@ -// -// FLEXKeyboardShortcutManager.m -// FLEX -// -// Created by Ryan Olson on 9/19/15. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXKeyboardShortcutManager.h" -#import "FLEXUtility.h" -#import -#import - -#if TARGET_OS_SIMULATOR - -@interface UIEvent (UIPhysicalKeyboardEvent) - -@property (nonatomic) NSString *_modifiedInput; -@property (nonatomic) NSString *_unmodifiedInput; -@property (nonatomic) UIKeyModifierFlags _modifierFlags; -@property (nonatomic) BOOL _isKeyDown; -@property (nonatomic) long _keyCode; - -@end - -@interface FLEXKeyInput : NSObject - -@property (nonatomic, copy, readonly) NSString *key; -@property (nonatomic, readonly) UIKeyModifierFlags flags; -@property (nonatomic, copy, readonly) NSString *helpDescription; - -@end - -@implementation FLEXKeyInput - -- (BOOL)isEqual:(id)object { - BOOL isEqual = NO; - if ([object isKindOfClass:[FLEXKeyInput class]]) { - FLEXKeyInput *keyCommand = (FLEXKeyInput *)object; - BOOL equalKeys = self.key == keyCommand.key || [self.key isEqual:keyCommand.key]; - BOOL equalFlags = self.flags == keyCommand.flags; - isEqual = equalKeys && equalFlags; - } - return isEqual; -} - -- (NSUInteger)hash { - return self.key.hash ^ self.flags; -} - -- (id)copyWithZone:(NSZone *)zone { - return [[self class] keyInputForKey:self.key flags:self.flags helpDescription:self.helpDescription]; -} - -- (NSString *)description { - NSDictionary *keyMappings = @{ - UIKeyInputUpArrow : @"↑", - UIKeyInputDownArrow : @"↓", - UIKeyInputLeftArrow : @"←", - UIKeyInputRightArrow : @"→", - UIKeyInputEscape : @"␛", - @" " : @"␠" - }; - - NSString *prettyKey = nil; - if (self.key && keyMappings[self.key]) { - prettyKey = keyMappings[self.key]; - } else { - prettyKey = [self.key uppercaseString]; - } - - NSString *prettyFlags = @""; - if (self.flags & UIKeyModifierControl) { - prettyFlags = [prettyFlags stringByAppendingString:@"⌃"]; - } - if (self.flags & UIKeyModifierAlternate) { - prettyFlags = [prettyFlags stringByAppendingString:@"⌥"]; - } - if (self.flags & UIKeyModifierShift) { - prettyFlags = [prettyFlags stringByAppendingString:@"⇧"]; - } - if (self.flags & UIKeyModifierCommand) { - prettyFlags = [prettyFlags stringByAppendingString:@"⌘"]; - } - - // Fudging to get easy columns with tabs - if (prettyFlags.length < 2) { - prettyKey = [prettyKey stringByAppendingString:@"\t"]; - } - - return [NSString stringWithFormat:@"%@%@\t%@", prettyFlags, prettyKey, self.helpDescription]; -} - -+ (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags { - return [self keyInputForKey:key flags:flags helpDescription:nil]; -} - -+ (instancetype)keyInputForKey:(NSString *)key - flags:(UIKeyModifierFlags)flags - helpDescription:(NSString *)helpDescription { - FLEXKeyInput *keyInput = [self new]; - if (keyInput) { - keyInput->_key = key; - keyInput->_flags = flags; - keyInput->_helpDescription = helpDescription; - } - return keyInput; -} - -@end - -@interface FLEXKeyboardShortcutManager () - -@property (nonatomic) NSMutableDictionary *actionsForKeyInputs; - -@property (nonatomic, getter=isPressingShift) BOOL pressingShift; -@property (nonatomic, getter=isPressingCommand) BOOL pressingCommand; -@property (nonatomic, getter=isPressingControl) BOOL pressingControl; - -@end - -@implementation FLEXKeyboardShortcutManager - -+ (instancetype)sharedManager { - static FLEXKeyboardShortcutManager *sharedManager = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - sharedManager = [self new]; - }); - return sharedManager; -} - -+ (void)load { - SEL originalKeyEventSelector = NSSelectorFromString(@"handleKeyUIEvent:"); - SEL swizzledKeyEventSelector = [FLEXUtility swizzledSelectorForSelector:originalKeyEventSelector]; - - void (^handleKeyUIEventSwizzleBlock)(UIApplication *, UIEvent *) = ^(UIApplication *slf, UIEvent *event) { - - [[[self class] sharedManager] handleKeyboardEvent:event]; - - ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledKeyEventSelector, event); - }; - - [FLEXUtility replaceImplementationOfKnownSelector:originalKeyEventSelector - onClass:[UIApplication class] - withBlock:handleKeyUIEventSwizzleBlock - swizzledSelector:swizzledKeyEventSelector - ]; - - if ([[UITouch class] instancesRespondToSelector:@selector(maximumPossibleForce)]) { - SEL originalSendEventSelector = NSSelectorFromString(@"sendEvent:"); - SEL swizzledSendEventSelector = [FLEXUtility swizzledSelectorForSelector:originalSendEventSelector]; - - void (^sendEventSwizzleBlock)(UIApplication *, UIEvent *) = ^(UIApplication *slf, UIEvent *event) { - if (event.type == UIEventTypeTouches) { - FLEXKeyboardShortcutManager *keyboardManager = FLEXKeyboardShortcutManager.sharedManager; - NSInteger pressureLevel = 0; - if (keyboardManager.isPressingShift) { - pressureLevel++; - } - if (keyboardManager.isPressingCommand) { - pressureLevel++; - } - if (keyboardManager.isPressingControl) { - pressureLevel++; - } - if (pressureLevel > 0) { - if (@available(iOS 9.0, *)) { - for (UITouch *touch in [event allTouches]) { - double adjustedPressureLevel = pressureLevel * 20 * touch.maximumPossibleForce; - [touch setValue:@(adjustedPressureLevel) forKey:@"_pressure"]; - } - } - } - } - - ((void(*)(id, SEL, id))objc_msgSend)(slf, swizzledSendEventSelector, event); - }; - - [FLEXUtility replaceImplementationOfKnownSelector:originalSendEventSelector - onClass:[UIApplication class] - withBlock:sendEventSwizzleBlock - swizzledSelector:swizzledSendEventSelector - ]; - - SEL originalSupportsTouchPressureSelector = NSSelectorFromString(@"_supportsForceTouch"); - SEL swizzledSupportsTouchPressureSelector = [FLEXUtility swizzledSelectorForSelector:originalSupportsTouchPressureSelector]; - - BOOL (^supportsTouchPressureSwizzleBlock)(UIDevice *) = ^BOOL(UIDevice *slf) { - return YES; - }; - - [FLEXUtility replaceImplementationOfKnownSelector:originalSupportsTouchPressureSelector - onClass:[UIDevice class] - withBlock:supportsTouchPressureSwizzleBlock - swizzledSelector:swizzledSupportsTouchPressureSelector - ]; - } -} - -- (instancetype)init { - self = [super init]; - - if (self) { - _actionsForKeyInputs = [NSMutableDictionary new]; - _enabled = YES; - } - - return self; -} - -- (void)registerSimulatorShortcutWithKey:(NSString *)key - modifiers:(UIKeyModifierFlags)modifiers - action:(dispatch_block_t)action - description:(NSString *)description - allowOverride:(BOOL)allowOverride { - FLEXKeyInput *keyInput = [FLEXKeyInput keyInputForKey:key flags:modifiers helpDescription:description]; - if (!allowOverride && self.actionsForKeyInputs[keyInput] != nil) { - return; - } else { - [self.actionsForKeyInputs setObject:action forKey:keyInput]; - } -} - -static const long kFLEXControlKeyCode = 0xe0; -static const long kFLEXShiftKeyCode = 0xe1; -static const long kFLEXCommandKeyCode = 0xe3; - -- (void)handleKeyboardEvent:(UIEvent *)event { - if (!self.enabled) { - return; - } - - NSString *modifiedInput = nil; - NSString *unmodifiedInput = nil; - UIKeyModifierFlags flags = 0; - BOOL isKeyDown = NO; - - if ([event respondsToSelector:@selector(_modifiedInput)]) { - modifiedInput = [event _modifiedInput]; - } - - if ([event respondsToSelector:@selector(_unmodifiedInput)]) { - unmodifiedInput = [event _unmodifiedInput]; - } - - if ([event respondsToSelector:@selector(_modifierFlags)]) { - flags = [event _modifierFlags]; - } - - if ([event respondsToSelector:@selector(_isKeyDown)]) { - isKeyDown = [event _isKeyDown]; - } - - BOOL interactionEnabled = !UIApplication.sharedApplication.isIgnoringInteractionEvents; - BOOL hasFirstResponder = NO; - if (isKeyDown && modifiedInput.length > 0 && interactionEnabled) { - UIResponder *firstResponder = nil; - for (UIWindow *window in FLEXUtility.allWindows) { - firstResponder = [window valueForKey:@"firstResponder"]; - if (firstResponder) { - hasFirstResponder = YES; - break; - } - } - - // Ignore key commands (except escape) when there's an active responder - if (firstResponder) { - if ([unmodifiedInput isEqual:UIKeyInputEscape]) { - [firstResponder resignFirstResponder]; - } - } else { - FLEXKeyInput *exactMatch = [FLEXKeyInput keyInputForKey:unmodifiedInput flags:flags]; - - dispatch_block_t actionBlock = self.actionsForKeyInputs[exactMatch]; - - if (!actionBlock) { - FLEXKeyInput *shiftMatch = [FLEXKeyInput - keyInputForKey:modifiedInput flags:flags&(~UIKeyModifierShift) - ]; - actionBlock = self.actionsForKeyInputs[shiftMatch]; - } - - if (!actionBlock) { - FLEXKeyInput *capitalMatch = [FLEXKeyInput - keyInputForKey:[unmodifiedInput uppercaseString] flags:flags - ]; - actionBlock = self.actionsForKeyInputs[capitalMatch]; - } - - if (actionBlock) { - actionBlock(); - } - } - } - - // Calling _keyCode on events from the simulator keyboard will crash. - // It is only safe to call _keyCode when there's not an active responder. - if (!hasFirstResponder && [event respondsToSelector:@selector(_keyCode)]) { - long keyCode = [event _keyCode]; - if (keyCode == kFLEXControlKeyCode) { - self.pressingControl = isKeyDown; - } else if (keyCode == kFLEXCommandKeyCode) { - self.pressingCommand = isKeyDown; - } else if (keyCode == kFLEXShiftKeyCode) { - self.pressingShift = isKeyDown; - } - } -} - -- (NSString *)keyboardShortcutsDescription { - NSMutableString *description = [NSMutableString new]; - NSArray *keyInputs = [self.actionsForKeyInputs.allKeys - sortedArrayUsingComparator:^NSComparisonResult(FLEXKeyInput *input1, FLEXKeyInput *input2) { - return [input1.key caseInsensitiveCompare:input2.key]; - } - ]; - for (FLEXKeyInput *keyInput in keyInputs) { - [description appendFormat:@"%@\n", keyInput]; - } - return [description copy]; -} - -@end - -#endif diff --git a/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.h b/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.h deleted file mode 100644 index 38d12a58..00000000 --- a/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.h +++ /dev/null @@ -1,108 +0,0 @@ -// -// FLEXRuntimeUtility.h -// Flipboard -// -// Created by Ryan Olson on 6/8/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" - -#define PropertyKey(suffix) kFLEXPropertyAttributeKey##suffix : @"" -#define PropertyKeyGetter(getter) kFLEXPropertyAttributeKeyCustomGetter : NSStringFromSelector(@selector(getter)) -#define PropertyKeySetter(setter) kFLEXPropertyAttributeKeyCustomSetter : NSStringFromSelector(@selector(setter)) - -/// Takes: min iOS version, property name, target class, property type, and a list of attributes -#define FLEXRuntimeUtilityTryAddProperty(iOS_atLeast, name, cls, type, ...) ({ \ - if (@available(iOS iOS_atLeast, *)) { \ - NSMutableDictionary *attrs = [NSMutableDictionary dictionaryWithDictionary:@{ \ - kFLEXPropertyAttributeKeyTypeEncoding : @(type), \ - __VA_ARGS__ \ - }]; \ - [FLEXRuntimeUtility \ - tryAddPropertyWithName:#name \ - attributes:attrs \ - toClass:cls \ - ]; \ - } \ -}) - -/// Takes: min iOS version, property name, target class, property type, and a list of attributes -#define FLEXRuntimeUtilityTryAddNonatomicProperty(iOS_atLeast, name, cls, type, ...) \ - FLEXRuntimeUtilityTryAddProperty(iOS_atLeast, name, cls, @encode(type), PropertyKey(NonAtomic), __VA_ARGS__); -/// Takes: min iOS version, property name, target class, property type (class name), and a list of attributes -#define FLEXRuntimeUtilityTryAddObjectProperty(iOS_atLeast, name, cls, type, ...) \ - FLEXRuntimeUtilityTryAddProperty(iOS_atLeast, name, cls, FLEXEncodeClass(type), PropertyKey(NonAtomic), __VA_ARGS__); - -extern NSString * const FLEXRuntimeUtilityErrorDomain; - -typedef NS_ENUM(NSInteger, FLEXRuntimeUtilityErrorCode) { - // Start at a random value instead of 0 to avoid confusion with an absent code - FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector = 0xbabe, - FLEXRuntimeUtilityErrorCodeInvocationFailed, - FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch -}; - -@interface FLEXRuntimeUtility : NSObject - -// General Helpers -+ (BOOL)pointerIsValidObjcObject:(const void *)pointer; -/// Unwraps raw pointers to objects stored in NSValue, and re-boxes C strings into NSStrings. -+ (id)potentiallyUnwrapBoxedPointer:(id)returnedObjectOrNil type:(const FLEXTypeEncoding *)returnType; -/// Some fields have a name in their encoded string (e.g. \"width\"d) -/// @return the offset to skip the field name, 0 if there is no name -+ (NSUInteger)fieldNameOffsetForTypeEncoding:(const FLEXTypeEncoding *)typeEncoding; -/// Given name "foo" and type "int" this would return "int foo", but -/// given name "foo" and type "T *" it would return "T *foo" -+ (NSString *)appendName:(NSString *)name toType:(NSString *)typeEncoding; - -/// @return The class hierarchy for the given object or class, -/// from the current class to the root-most class. -+ (NSArray *)classHierarchyOfObject:(id)objectOrClass; - -/// Used to describe an object in brief within an explorer row -+ (NSString *)summaryForObject:(id)value; -+ (NSString *)safeClassNameForObject:(id)object; -+ (NSString *)safeDescriptionForObject:(id)object; -+ (NSString *)safeDebugDescriptionForObject:(id)object; - -+ (BOOL)safeObject:(id)object isKindOfClass:(Class)cls; -+ (BOOL)safeObject:(id)object respondsToSelector:(SEL)sel; - -// Property Helpers -+ (BOOL)tryAddPropertyWithName:(const char *)name - attributes:(NSDictionary *)attributePairs - toClass:(__unsafe_unretained Class)theClass; -+ (NSArray *)allPropertyAttributeKeys; - -// Method Helpers -+ (NSArray *)prettyArgumentComponentsForMethod:(Method)method; - -// Method Calling/Field Editing -+ (id)performSelector:(SEL)selector onObject:(id)object; -+ (id)performSelector:(SEL)selector - onObject:(id)object - withArguments:(NSArray *)arguments - error:(NSError * __autoreleasing *)error; -+ (id)performSelector:(SEL)selector - onObject:(id)object - withArguments:(NSArray *)arguments - allowForwarding:(BOOL)mightForwardMsgSend - error:(NSError * __autoreleasing *)error; - -+ (NSString *)editableJSONStringForObject:(id)object; -+ (id)objectValueFromEditableJSONString:(NSString *)string; -+ (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString; -+ (void)enumerateTypesInStructEncoding:(const char *)structEncoding - usingBlock:(void (^)(NSString *structName, - const char *fieldTypeEncoding, - NSString *prettyTypeEncoding, - NSUInteger fieldIndex, - NSUInteger fieldOffset))typeBlock; -+ (NSValue *)valueForPrimitivePointer:(void *)pointer objCType:(const char *)type; - -#pragma mark - Metadata Helpers - -+ (NSString *)readableTypeForEncoding:(NSString *)encodingString; - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.m b/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.m deleted file mode 100644 index b9cd77c7..00000000 --- a/BHTwitter/Classes/Utility/Runtime/FLEXRuntimeUtility.m +++ /dev/null @@ -1,881 +0,0 @@ -// -// FLEXRuntimeUtility.m -// Flipboard -// -// Created by Ryan Olson on 6/8/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import "FLEXRuntimeUtility.h" -#import "FLEXObjcInternal.h" -#import "FLEXTypeEncodingParser.h" -#import "FLEXMethod.h" - -NSString * const FLEXRuntimeUtilityErrorDomain = @"FLEXRuntimeUtilityErrorDomain"; - -@implementation FLEXRuntimeUtility - -#pragma mark - General Helpers (Public) - -+ (BOOL)pointerIsValidObjcObject:(const void *)pointer { - return FLEXPointerIsValidObjcObject(pointer); -} - -+ (id)potentiallyUnwrapBoxedPointer:(id)returnedObjectOrNil type:(const FLEXTypeEncoding *)returnType { - if (!returnedObjectOrNil) { - return nil; - } - - NSInteger i = 0; - if (returnType[i] == FLEXTypeEncodingConst) { - i++; - } - - BOOL returnsObjectOrClass = returnType[i] == FLEXTypeEncodingObjcObject || - returnType[i] == FLEXTypeEncodingObjcClass; - BOOL returnsVoidPointer = returnType[i] == FLEXTypeEncodingPointer && - returnType[i+1] == FLEXTypeEncodingVoid; - BOOL returnsCString = returnType[i] == FLEXTypeEncodingCString; - - // If we got back an NSValue and the return type is not an object, - // we check to see if the pointer is of a valid object. If not, - // we just display the NSValue. - if (!returnsObjectOrClass) { - // Skip NSNumber instances - if ([returnedObjectOrNil isKindOfClass:[NSNumber class]]) { - return returnedObjectOrNil; - } - - // Can only be NSValue since return type is not an object, - // so we bail if this doesn't add up - if (![returnedObjectOrNil isKindOfClass:[NSValue class]]) { - return returnedObjectOrNil; - } - - NSValue *value = (NSValue *)returnedObjectOrNil; - - if (returnsCString) { - // Wrap char * in NSString - const char *string = (const char *)value.pointerValue; - returnedObjectOrNil = string ? [NSString stringWithCString:string encoding:NSUTF8StringEncoding] : NULL; - } else if (returnsVoidPointer) { - // Cast valid objects disguised as void * to id - if ([FLEXRuntimeUtility pointerIsValidObjcObject:value.pointerValue]) { - returnedObjectOrNil = (__bridge id)value.pointerValue; - } - } - } - - return returnedObjectOrNil; -} - -+ (NSUInteger)fieldNameOffsetForTypeEncoding:(const FLEXTypeEncoding *)typeEncoding { - NSUInteger beginIndex = 0; - while (typeEncoding[beginIndex] == FLEXTypeEncodingQuote) { - NSUInteger endIndex = beginIndex + 1; - while (typeEncoding[endIndex] != FLEXTypeEncodingQuote) { - ++endIndex; - } - beginIndex = endIndex + 1; - } - return beginIndex; -} - -+ (NSArray *)classHierarchyOfObject:(id)objectOrClass { - NSMutableArray *superClasses = [NSMutableArray new]; - id cls = [objectOrClass class]; - do { - [superClasses addObject:cls]; - } while ((cls = [cls superclass])); - - return superClasses; -} - -+ (NSString *)safeClassNameForObject:(id)object { - // Don't assume that we have an NSObject subclass - if ([self safeObject:object respondsToSelector:@selector(class)]) { - return NSStringFromClass([object class]); - } - - return NSStringFromClass(object_getClass(object)); -} - -/// Could be nil -+ (NSString *)safeDescriptionForObject:(id)object { - // Don't assume that we have an NSObject subclass; not all objects respond to -description - if ([self safeObject:object respondsToSelector:@selector(description)]) { - @try { - return [object description]; - } @catch (NSException *exception) { - return nil; - } - } - - return nil; -} - -/// Never nil -+ (NSString *)safeDebugDescriptionForObject:(id)object { - NSString *description = nil; - - if ([self safeObject:object respondsToSelector:@selector(debugDescription)]) { - @try { - description = [object debugDescription]; - } @catch (NSException *exception) { } - } else { - description = [self safeDescriptionForObject:object]; - } - - if (!description.length) { - NSString *cls = NSStringFromClass(object_getClass(object)); - if (object_isClass(object)) { - description = [cls stringByAppendingString:@" class (no description)"]; - } else { - description = [cls stringByAppendingString:@" instance (no description)"]; - } - } - - return description; -} - -+ (NSString *)summaryForObject:(id)value { - NSString *description = nil; - - // Special case BOOL for better readability. - if ([self safeObject:value isKindOfClass:[NSValue class]]) { - const char *type = [value objCType]; - if (strcmp(type, @encode(BOOL)) == 0) { - BOOL boolValue = NO; - [value getValue:&boolValue]; - return boolValue ? @"YES" : @"NO"; - } else if (strcmp(type, @encode(SEL)) == 0) { - SEL selector = NULL; - [value getValue:&selector]; - return NSStringFromSelector(selector); - } - } - - @try { - // Single line display - replace newlines and tabs with spaces. - description = [[self safeDescriptionForObject:value] stringByReplacingOccurrencesOfString:@"\n" withString:@" "]; - description = [description stringByReplacingOccurrencesOfString:@"\t" withString:@" "]; - } @catch (NSException *e) { - description = [@"Thrown: " stringByAppendingString:e.reason ?: @"(nil exception reason)"]; - } - - if (!description) { - description = @"nil"; - } - - return description; -} - -+ (BOOL)safeObject:(id)object isKindOfClass:(Class)cls { - static BOOL (*isKindOfClass)(id, SEL, Class) = nil; - static BOOL (*isKindOfClass_meta)(id, SEL, Class) = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - isKindOfClass = (BOOL(*)(id, SEL, Class))[NSObject instanceMethodForSelector:@selector(isKindOfClass:)]; - isKindOfClass_meta = (BOOL(*)(id, SEL, Class))[NSObject methodForSelector:@selector(isKindOfClass:)]; - }); - - BOOL isClass = object_isClass(object); - return (isClass ? isKindOfClass_meta : isKindOfClass)(object, @selector(isKindOfClass:), cls); -} - -+ (BOOL)safeObject:(id)object respondsToSelector:(SEL)sel { - // If we're given a class, we want to know if classes respond to this selector. - // Similarly, if we're given an instance, we want to know if instances respond. - BOOL isClass = object_isClass(object); - Class cls = isClass ? object : object_getClass(object); - // BOOL isMetaclass = class_isMetaClass(cls); - - if (isClass) { - // In theory, this should also work for metaclasses... - return class_getClassMethod(cls, sel) != nil; - } else { - return class_getInstanceMethod(cls, sel) != nil; - } -} - - -#pragma mark - Property Helpers (Public) - -+ (BOOL)tryAddPropertyWithName:(const char *)name - attributes:(NSDictionary *)attributePairs - toClass:(__unsafe_unretained Class)theClass { - objc_property_t property = class_getProperty(theClass, name); - if (!property) { - unsigned int totalAttributesCount = (unsigned int)attributePairs.count; - objc_property_attribute_t *attributes = malloc(sizeof(objc_property_attribute_t) * totalAttributesCount); - if (attributes) { - unsigned int attributeIndex = 0; - for (NSString *attributeName in attributePairs.allKeys) { - objc_property_attribute_t attribute; - attribute.name = attributeName.UTF8String; - attribute.value = attributePairs[attributeName].UTF8String; - attributes[attributeIndex++] = attribute; - } - - BOOL success = class_addProperty(theClass, name, attributes, totalAttributesCount); - free(attributes); - return success; - } else { - return NO; - } - } - - return YES; -} - -+ (NSArray *)allPropertyAttributeKeys { - static NSArray *allPropertyAttributeKeys = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - allPropertyAttributeKeys = @[ - kFLEXPropertyAttributeKeyTypeEncoding, - kFLEXPropertyAttributeKeyBackingIvarName, - kFLEXPropertyAttributeKeyReadOnly, - kFLEXPropertyAttributeKeyCopy, - kFLEXPropertyAttributeKeyRetain, - kFLEXPropertyAttributeKeyNonAtomic, - kFLEXPropertyAttributeKeyCustomGetter, - kFLEXPropertyAttributeKeyCustomSetter, - kFLEXPropertyAttributeKeyDynamic, - kFLEXPropertyAttributeKeyWeak, - kFLEXPropertyAttributeKeyGarbageCollectable, - kFLEXPropertyAttributeKeyOldStyleTypeEncoding, - ]; - }); - - return allPropertyAttributeKeys; -} - - -#pragma mark - Method Helpers (Public) - -+ (NSArray *)prettyArgumentComponentsForMethod:(Method)method { - NSMutableArray *components = [NSMutableArray new]; - - NSString *selectorName = NSStringFromSelector(method_getName(method)); - NSMutableArray *selectorComponents = [selectorName componentsSeparatedByString:@":"].mutableCopy; - - // this is a workaround cause method_getNumberOfArguments() returns wrong number for some methods - if (selectorComponents.count == 1) { - return @[]; - } - - if ([selectorComponents.lastObject isEqualToString:@""]) { - [selectorComponents removeLastObject]; - } - - for (unsigned int argIndex = 0; argIndex < selectorComponents.count; argIndex++) { - char *argType = method_copyArgumentType(method, argIndex + kFLEXNumberOfImplicitArgs); - NSString *readableArgType = (argType != NULL) ? [self readableTypeForEncoding:@(argType)] : nil; - free(argType); - NSString *prettyComponent = [NSString - stringWithFormat:@"%@:(%@) ", - selectorComponents[argIndex], - readableArgType - ]; - [components addObject:prettyComponent]; - } - - return components; -} - - -#pragma mark - Method Calling/Field Editing (Public) - -+ (id)performSelector:(SEL)selector onObject:(id)object { - return [self performSelector:selector onObject:object withArguments:@[] error:nil]; -} - -+ (id)performSelector:(SEL)selector - onObject:(id)object - withArguments:(NSArray *)arguments - error:(NSError * __autoreleasing *)error { - return [self performSelector:selector - onObject:object - withArguments:arguments - allowForwarding:NO - error:error - ]; -} - -+ (id)performSelector:(SEL)selector - onObject:(id)object - withArguments:(NSArray *)arguments - allowForwarding:(BOOL)mightForwardMsgSend - error:(NSError * __autoreleasing *)error { - static dispatch_once_t onceToken; - static SEL stdStringExclusion = nil; - dispatch_once(&onceToken, ^{ - stdStringExclusion = NSSelectorFromString(@"stdString"); - }); - - // Bail if the object won't respond to this selector - if (mightForwardMsgSend || ![self safeObject:object respondsToSelector:selector]) { - if (error) { - NSString *msg = [NSString - stringWithFormat:@"This object does not respond to the selector %@", - NSStringFromSelector(selector) - ]; - NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : msg }; - *error = [NSError - errorWithDomain:FLEXRuntimeUtilityErrorDomain - code:FLEXRuntimeUtilityErrorCodeDoesNotRecognizeSelector - userInfo:userInfo - ]; - } - - return nil; - } - - // It is important to use object_getClass and not -class here, as - // object_getClass will return a different result for class objects - Class cls = object_getClass(object); - NSMethodSignature *methodSignature = [FLEXMethod selector:selector class:cls].signature; - if (!methodSignature) { - // Unsupported type encoding - return nil; - } - - // Probably an unsupported type encoding, like bitfields. - // In the future, we could calculate the return length - // on our own. For now, we abort. - // - // For future reference, the code here will get the true type encoding. - // NSMethodSignature will convert {?=b8b4b1b1b18[8S]} to {?} - // - // returnType = method_getTypeEncoding(class_getInstanceMethod([object class], selector)); - if (!methodSignature.methodReturnLength && - methodSignature.methodReturnType[0] != FLEXTypeEncodingVoid) { - return nil; - } - - // Build the invocation - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; - [invocation setSelector:selector]; - [invocation setTarget:object]; - [invocation retainArguments]; - - // Always self and _cmd - NSUInteger numberOfArguments = methodSignature.numberOfArguments; - for (NSUInteger argumentIndex = kFLEXNumberOfImplicitArgs; argumentIndex < numberOfArguments; argumentIndex++) { - NSUInteger argumentsArrayIndex = argumentIndex - kFLEXNumberOfImplicitArgs; - id argumentObject = arguments.count > argumentsArrayIndex ? arguments[argumentsArrayIndex] : nil; - - // NSNull in the arguments array can be passed as a placeholder to indicate nil. - // We only need to set the argument if it will be non-nil. - if (argumentObject && ![argumentObject isKindOfClass:[NSNull class]]) { - const char *typeEncodingCString = [methodSignature getArgumentTypeAtIndex:argumentIndex]; - if (typeEncodingCString[0] == FLEXTypeEncodingObjcObject || - typeEncodingCString[0] == FLEXTypeEncodingObjcClass || - [self isTollFreeBridgedValue:argumentObject forCFType:typeEncodingCString]) { - // Object - [invocation setArgument:&argumentObject atIndex:argumentIndex]; - } else if (strcmp(typeEncodingCString, @encode(CGColorRef)) == 0 && - [argumentObject isKindOfClass:[UIColor class]]) { - // Bridging UIColor to CGColorRef - CGColorRef colorRef = [argumentObject CGColor]; - [invocation setArgument:&colorRef atIndex:argumentIndex]; - } else if ([argumentObject isKindOfClass:[NSValue class]]) { - // Primitive boxed in NSValue - NSValue *argumentValue = (NSValue *)argumentObject; - - // Ensure that the type encoding on the NSValue matches the type encoding of the argument in the method signature - if (strcmp([argumentValue objCType], typeEncodingCString) != 0) { - if (error) { - NSString *msg = [NSString - stringWithFormat:@"Type encoding mismatch for argument at index %lu. " - "Value type: %s; Method argument type: %s.", - (unsigned long)argumentsArrayIndex, argumentValue.objCType, typeEncodingCString - ]; - NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : msg }; - *error = [NSError - errorWithDomain:FLEXRuntimeUtilityErrorDomain - code:FLEXRuntimeUtilityErrorCodeArgumentTypeMismatch - userInfo:userInfo - ]; - } - return nil; - } - - @try { - NSUInteger bufferSize = 0; - FLEXGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL); - - if (bufferSize > 0) { - void *buffer = alloca(bufferSize); - [argumentValue getValue:buffer]; - [invocation setArgument:buffer atIndex:argumentIndex]; - } - } @catch (NSException *exception) { } - } - } - } - - // Try to invoke the invocation but guard against an exception being thrown. - id returnObject = nil; - @try { - [invocation invoke]; - - // Retrieve the return value and box if necessary. - const char *returnType = methodSignature.methodReturnType; - - if (returnType[0] == FLEXTypeEncodingObjcObject || returnType[0] == FLEXTypeEncodingObjcClass) { - // Return value is an object. - __unsafe_unretained id objectReturnedFromMethod = nil; - [invocation getReturnValue:&objectReturnedFromMethod]; - returnObject = objectReturnedFromMethod; - } else if (returnType[0] != FLEXTypeEncodingVoid) { - NSAssert(methodSignature.methodReturnLength, @"Memory corruption lies ahead"); - - if (returnType[0] == FLEXTypeEncodingStructBegin) { - if (selector == stdStringExclusion && [object isKindOfClass:[NSString class]]) { - // stdString is a C++ object and we will crash if we try to access it - if (error) { - *error = [NSError - errorWithDomain:FLEXRuntimeUtilityErrorDomain - code:FLEXRuntimeUtilityErrorCodeInvocationFailed - userInfo:@{ NSLocalizedDescriptionKey : @"Skipping -[NSString stdString]" } - ]; - } - - return nil; - } - } - - // Will use arbitrary buffer for return value and box it. - void *returnValue = malloc(methodSignature.methodReturnLength); - [invocation getReturnValue:returnValue]; - returnObject = [self valueForPrimitivePointer:returnValue objCType:returnType]; - free(returnValue); - } - } @catch (NSException *exception) { - // Bummer... - if (error) { - // "… on " / "… on instance of " - NSString *class = NSStringFromClass([object class]); - NSString *calledOn = object == [object class] ? class : [@"an instance of " stringByAppendingString:class]; - - NSString *message = [NSString - stringWithFormat:@"Exception '%@' thrown while performing selector '%@' on %@.\nReason:\n\n%@", - exception.name, NSStringFromSelector(selector), calledOn, exception.reason - ]; - - *error = [NSError - errorWithDomain:FLEXRuntimeUtilityErrorDomain - code:FLEXRuntimeUtilityErrorCodeInvocationFailed - userInfo:@{ NSLocalizedDescriptionKey : message } - ]; - } - } - - return returnObject; -} - -+ (BOOL)isTollFreeBridgedValue:(id)value forCFType:(const char *)typeEncoding { - // See https://developer.apple.com/library/archive/documentation/General/Conceptual/CocoaEncyclopedia/Toll-FreeBridgin/Toll-FreeBridgin.html -#define CASE(cftype, foundationClass) \ - if (strcmp(typeEncoding, @encode(cftype)) == 0) { \ - return [value isKindOfClass:[foundationClass class]]; \ - } - - CASE(CFArrayRef, NSArray); - CASE(CFAttributedStringRef, NSAttributedString); - CASE(CFCalendarRef, NSCalendar); - CASE(CFCharacterSetRef, NSCharacterSet); - CASE(CFDataRef, NSData); - CASE(CFDateRef, NSDate); - CASE(CFDictionaryRef, NSDictionary); - CASE(CFErrorRef, NSError); - CASE(CFLocaleRef, NSLocale); - CASE(CFMutableArrayRef, NSMutableArray); - CASE(CFMutableAttributedStringRef, NSMutableAttributedString); - CASE(CFMutableCharacterSetRef, NSMutableCharacterSet); - CASE(CFMutableDataRef, NSMutableData); - CASE(CFMutableDictionaryRef, NSMutableDictionary); - CASE(CFMutableSetRef, NSMutableSet); - CASE(CFMutableStringRef, NSMutableString); - CASE(CFNumberRef, NSNumber); - CASE(CFReadStreamRef, NSInputStream); - CASE(CFRunLoopTimerRef, NSTimer); - CASE(CFSetRef, NSSet); - CASE(CFStringRef, NSString); - CASE(CFTimeZoneRef, NSTimeZone); - CASE(CFURLRef, NSURL); - CASE(CFWriteStreamRef, NSOutputStream); - -#undef CASE - - return NO; -} - -+ (NSString *)editableJSONStringForObject:(id)object { - NSString *editableDescription = nil; - - if (object) { - // This is a hack to use JSON serialization for our editable objects. - // NSJSONSerialization doesn't allow writing fragments - the top level object must be an array or dictionary. - // We always wrap the object inside an array and then strip the outer square braces off the final string. - NSArray *wrappedObject = @[object]; - if ([NSJSONSerialization isValidJSONObject:wrappedObject]) { - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:wrappedObject options:0 error:NULL]; - NSString *wrappedDescription = [NSString stringWithUTF8String:jsonData.bytes]; - editableDescription = [wrappedDescription substringWithRange:NSMakeRange(1, wrappedDescription.length - 2)]; - } - } - - return editableDescription; -} - -+ (id)objectValueFromEditableJSONString:(NSString *)string { - id value = nil; - // nil for empty string/whitespace - if ([string stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceAndNewlineCharacterSet].length) { - value = [NSJSONSerialization - JSONObjectWithData:[string dataUsingEncoding:NSUTF8StringEncoding] - options:NSJSONReadingAllowFragments - error:NULL - ]; - } - return value; -} - -+ (NSValue *)valueForNumberWithObjCType:(const char *)typeEncoding fromInputString:(NSString *)inputString { - NSNumberFormatter *formatter = [NSNumberFormatter new]; - [formatter setNumberStyle:NSNumberFormatterDecimalStyle]; - NSNumber *number = [formatter numberFromString:inputString]; - - // Is the type encoding longer than one character? - if (strlen(typeEncoding) > 1) { - NSString *type = @(typeEncoding); - - // Is it NSDecimalNumber or NSNumber? - if ([type isEqualToString:@FLEXEncodeClass(NSDecimalNumber)]) { - return [NSDecimalNumber decimalNumberWithString:inputString]; - } else if ([type isEqualToString:@FLEXEncodeClass(NSNumber)]) { - return number; - } - - return nil; - } - - // Type encoding is one character, switch on the type - FLEXTypeEncoding type = typeEncoding[0]; - uint8_t value[32]; - void *bufferStart = &value[0]; - - // Make sure we box the number with the correct type encoding - // so it can be properly unboxed later via getValue: - switch (type) { - case FLEXTypeEncodingChar: - *(char *)bufferStart = number.charValue; break; - case FLEXTypeEncodingInt: - *(int *)bufferStart = number.intValue; break; - case FLEXTypeEncodingShort: - *(short *)bufferStart = number.shortValue; break; - case FLEXTypeEncodingLong: - *(long *)bufferStart = number.longValue; break; - case FLEXTypeEncodingLongLong: - *(long long *)bufferStart = number.longLongValue; break; - case FLEXTypeEncodingUnsignedChar: - *(unsigned char *)bufferStart = number.unsignedCharValue; break; - case FLEXTypeEncodingUnsignedInt: - *(unsigned int *)bufferStart = number.unsignedIntValue; break; - case FLEXTypeEncodingUnsignedShort: - *(unsigned short *)bufferStart = number.unsignedShortValue; break; - case FLEXTypeEncodingUnsignedLong: - *(unsigned long *)bufferStart = number.unsignedLongValue; break; - case FLEXTypeEncodingUnsignedLongLong: - *(unsigned long long *)bufferStart = number.unsignedLongLongValue; break; - case FLEXTypeEncodingFloat: - *(float *)bufferStart = number.floatValue; break; - case FLEXTypeEncodingDouble: - *(double *)bufferStart = number.doubleValue; break; - - case FLEXTypeEncodingLongDouble: - // NSNumber does not support long double - default: - return nil; - } - - return [NSValue value:value withObjCType:typeEncoding]; -} - -+ (void)enumerateTypesInStructEncoding:(const char *)structEncoding - usingBlock:(void (^)(NSString *structName, - const char *fieldTypeEncoding, - NSString *prettyTypeEncoding, - NSUInteger fieldIndex, - NSUInteger fieldOffset))typeBlock { - if (structEncoding && structEncoding[0] == FLEXTypeEncodingStructBegin) { - const char *equals = strchr(structEncoding, '='); - if (equals) { - const char *nameStart = structEncoding + 1; - NSString *structName = [@(structEncoding) - substringWithRange:NSMakeRange(nameStart - structEncoding, equals - nameStart) - ]; - - NSUInteger fieldAlignment = 0, structSize = 0; - if (FLEXGetSizeAndAlignment(structEncoding, &structSize, &fieldAlignment)) { - NSUInteger runningFieldIndex = 0; - NSUInteger runningFieldOffset = 0; - const char *typeStart = equals + 1; - - while (*typeStart != FLEXTypeEncodingStructEnd) { - NSUInteger fieldSize = 0; - // If the struct type encoding was successfully handled by - // FLEXGetSizeAndAlignment above, we *should* be ok with the field here. - const char *nextTypeStart = NSGetSizeAndAlignment(typeStart, &fieldSize, NULL); - NSString *typeEncoding = [@(structEncoding) - substringWithRange:NSMakeRange(typeStart - structEncoding, nextTypeStart - typeStart) - ]; - - // Padding to keep proper alignment. __attribute((packed)) structs - // will break here. The type encoding is no different for packed structs, - // so it's not clear there's anything we can do for those. - const NSUInteger currentSizeSum = runningFieldOffset % fieldAlignment; - if (currentSizeSum != 0 && currentSizeSum + fieldSize > fieldAlignment) { - runningFieldOffset += fieldAlignment - currentSizeSum; - } - - typeBlock( - structName, - typeEncoding.UTF8String, - [self readableTypeForEncoding:typeEncoding], - runningFieldIndex, - runningFieldOffset - ); - runningFieldOffset += fieldSize; - runningFieldIndex++; - typeStart = nextTypeStart; - } - } - } - } -} - - -#pragma mark - Metadata Helpers - -+ (NSDictionary *)attributesForProperty:(objc_property_t)property { - NSString *attributes = @(property_getAttributes(property) ?: ""); - // Thanks to MAObjcRuntime for inspiration here. - NSArray *attributePairs = [attributes componentsSeparatedByString:@","]; - NSMutableDictionary *attributesDictionary = [NSMutableDictionary new]; - for (NSString *attributePair in attributePairs) { - attributesDictionary[[attributePair substringToIndex:1]] = [attributePair substringFromIndex:1]; - } - return attributesDictionary; -} - -+ (NSString *)appendName:(NSString *)name toType:(NSString *)type { - if (!type.length) { - type = @"(?)"; - } - - NSString *combined = nil; - if ([type characterAtIndex:type.length - 1] == FLEXTypeEncodingCString) { - combined = [type stringByAppendingString:name]; - } else { - combined = [type stringByAppendingFormat:@" %@", name]; - } - return combined; -} - -+ (NSString *)readableTypeForEncoding:(NSString *)encodingString { - if (!encodingString.length) { - return @"?"; - } - - // See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html - // class-dump has a much nicer and much more complete implementation for this task, but it is distributed under GPLv2 :/ - // See https://github.com/nygard/class-dump/blob/master/Source/CDType.m - // Warning: this method uses multiple middle returns and macros to cut down on boilerplate. - // The use of macros here was inspired by https://www.mikeash.com/pyblog/friday-qa-2013-02-08-lets-build-key-value-coding.html - const char *encodingCString = encodingString.UTF8String; - - // Some fields have a name, such as {Size=\"width\"d\"height\"d}, we need to extract the name out and recursive - const NSUInteger fieldNameOffset = [FLEXRuntimeUtility fieldNameOffsetForTypeEncoding:encodingCString]; - if (fieldNameOffset > 0) { - // According to https://github.com/nygard/class-dump/commit/33fb5ed221810685f57c192e1ce8ab6054949a7c, - // there are some consecutive quoted strings, so use `_` to concatenate the names. - NSString *const fieldNamesString = [encodingString substringWithRange:NSMakeRange(0, fieldNameOffset)]; - NSArray *const fieldNames = [fieldNamesString - componentsSeparatedByString:[NSString stringWithFormat:@"%c", FLEXTypeEncodingQuote] - ]; - NSMutableString *finalFieldNamesString = [NSMutableString new]; - for (NSString *const fieldName in fieldNames) { - if (fieldName.length > 0) { - if (finalFieldNamesString.length > 0) { - [finalFieldNamesString appendString:@"_"]; - } - [finalFieldNamesString appendString:fieldName]; - } - } - NSString *const recursiveType = [self readableTypeForEncoding:[encodingString substringFromIndex:fieldNameOffset]]; - return [NSString stringWithFormat:@"%@ %@", recursiveType, finalFieldNamesString]; - } - - // Objects - if (encodingCString[0] == FLEXTypeEncodingObjcObject) { - NSString *class = [encodingString substringFromIndex:1]; - class = [class stringByReplacingOccurrencesOfString:@"\"" withString:@""]; - if (class.length == 0 || (class.length == 1 && [class characterAtIndex:0] == FLEXTypeEncodingUnknown)) { - class = @"id"; - } else { - class = [class stringByAppendingString:@" *"]; - } - return class; - } - - // Qualifier Prefixes - // Do this first since some of the direct translations (i.e. Method) contain a prefix. -#define RECURSIVE_TRANSLATE(prefix, formatString) \ - if (encodingCString[0] == prefix) { \ - NSString *recursiveType = [self readableTypeForEncoding:[encodingString substringFromIndex:1]]; \ - return [NSString stringWithFormat:formatString, recursiveType]; \ - } - - // If there's a qualifier prefix on the encoding, translate it and then - // recursively call this method with the rest of the encoding string. - RECURSIVE_TRANSLATE('^', @"%@ *"); - RECURSIVE_TRANSLATE('r', @"const %@"); - RECURSIVE_TRANSLATE('n', @"in %@"); - RECURSIVE_TRANSLATE('N', @"inout %@"); - RECURSIVE_TRANSLATE('o', @"out %@"); - RECURSIVE_TRANSLATE('O', @"bycopy %@"); - RECURSIVE_TRANSLATE('R', @"byref %@"); - RECURSIVE_TRANSLATE('V', @"oneway %@"); - RECURSIVE_TRANSLATE('b', @"bitfield(%@)"); - -#undef RECURSIVE_TRANSLATE - - // C Types -#define TRANSLATE(ctype) \ - if (strcmp(encodingCString, @encode(ctype)) == 0) { \ - return (NSString *)CFSTR(#ctype); \ - } - - // Order matters here since some of the cocoa types are typedefed to c types. - // We can't recover the exact mapping, but we choose to prefer the cocoa types. - // This is not an exhaustive list, but it covers the most common types - TRANSLATE(CGRect); - TRANSLATE(CGPoint); - TRANSLATE(CGSize); - TRANSLATE(CGVector); - TRANSLATE(UIEdgeInsets); - if (@available(iOS 11.0, *)) { - TRANSLATE(NSDirectionalEdgeInsets); - } - TRANSLATE(UIOffset); - TRANSLATE(NSRange); - TRANSLATE(CGAffineTransform); - TRANSLATE(CATransform3D); - TRANSLATE(CGColorRef); - TRANSLATE(CGPathRef); - TRANSLATE(CGContextRef); - TRANSLATE(NSInteger); - TRANSLATE(NSUInteger); - TRANSLATE(CGFloat); - TRANSLATE(BOOL); - TRANSLATE(int); - TRANSLATE(short); - TRANSLATE(long); - TRANSLATE(long long); - TRANSLATE(unsigned char); - TRANSLATE(unsigned int); - TRANSLATE(unsigned short); - TRANSLATE(unsigned long); - TRANSLATE(unsigned long long); - TRANSLATE(float); - TRANSLATE(double); - TRANSLATE(long double); - TRANSLATE(char *); - TRANSLATE(Class); - TRANSLATE(objc_property_t); - TRANSLATE(Ivar); - TRANSLATE(Method); - TRANSLATE(Category); - TRANSLATE(NSZone *); - TRANSLATE(SEL); - TRANSLATE(void); - -#undef TRANSLATE - - // For structs, we only use the name of the structs - if (encodingCString[0] == FLEXTypeEncodingStructBegin) { - // Special case: std::string - if ([encodingString hasPrefix:@"{basic_string d) - const NSUInteger fieldNameOffset = [FLEXRuntimeUtility fieldNameOffsetForTypeEncoding:type]; - if (fieldNameOffset > 0) { - return [self valueForPrimitivePointer:pointer objCType:type + fieldNameOffset]; - } - - // CASE macro inspired by https://www.mikeash.com/pyblog/friday-qa-2013-02-08-lets-build-key-value-coding.html -#define CASE(ctype, selectorpart) \ - if (strcmp(type, @encode(ctype)) == 0) { \ - return [NSNumber numberWith ## selectorpart: *(ctype *)pointer]; \ - } - - CASE(BOOL, Bool); - CASE(unsigned char, UnsignedChar); - CASE(short, Short); - CASE(unsigned short, UnsignedShort); - CASE(int, Int); - CASE(unsigned int, UnsignedInt); - CASE(long, Long); - CASE(unsigned long, UnsignedLong); - CASE(long long, LongLong); - CASE(unsigned long long, UnsignedLongLong); - CASE(float, Float); - CASE(double, Double); - CASE(long double, Double); - -#undef CASE - - NSValue *value = nil; - if (FLEXGetSizeAndAlignment(type, nil, nil)) { - @try { - value = [NSValue valueWithBytes:pointer objCType:type]; - } @catch (NSException *exception) { - // Certain type encodings are not supported by valueWithBytes:objCType:. - // Just fail silently if an exception is thrown. - } - } - - return value; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.h b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.h deleted file mode 100644 index d5e0ddc3..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// FLEXObjcInternal.h -// FLEX -// -// Created by Tanner Bennett on 11/1/18. -// - -#import - -#ifdef __cplusplus -extern "C" { -#endif - -// The macros below are copied straight from -// objc-internal.h, objc-private.h, objc-object.h, and objc-config.h with -// as few modifications as possible. Changes are noted in boxed comments. -// https://opensource.apple.com/source/objc4/objc4-723/ -// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-internal.h.auto.html -// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-object.h.auto.html - -///////////////////// -// objc-internal.h // -///////////////////// - -#if __LP64__ -#define OBJC_HAVE_TAGGED_POINTERS 1 -#endif - -#if OBJC_HAVE_TAGGED_POINTERS - -#if TARGET_OS_OSX && __x86_64__ -// 64-bit Mac - tag bit is LSB -# define OBJC_MSB_TAGGED_POINTERS 0 -#else -// Everything else - tag bit is MSB -# define OBJC_MSB_TAGGED_POINTERS 1 -#endif - -#if OBJC_MSB_TAGGED_POINTERS -# define _OBJC_TAG_MASK (1UL<<63) -# define _OBJC_TAG_EXT_MASK (0xfUL<<60) -#else -# define _OBJC_TAG_MASK 1UL -# define _OBJC_TAG_EXT_MASK 0xfUL -#endif - -#endif // OBJC_HAVE_TAGGED_POINTERS - -////////////////////////////////////// -// originally _objc_isTaggedPointer // -////////////////////////////////////// -NS_INLINE BOOL flex_isTaggedPointer(const void *ptr) { - #if OBJC_HAVE_TAGGED_POINTERS - return ((uintptr_t)ptr & _OBJC_TAG_MASK) == _OBJC_TAG_MASK; - #else - return NO; - #endif -} - -#define FLEXPointerIsTaggedPointer(obj) flex_isTaggedPointer((__bridge void *)obj) - -BOOL FLEXPointerIsReadable(const void * ptr); - -/// @brief Assumes memory is valid and readable. -/// @discussion objc-internal.h, objc-private.h, and objc-config.h -/// https://blog.timac.org/2016/1124-testing-if-an-arbitrary-pointer-is-a-valid-objective-c-object/ -/// https://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/objc_runtime.py -/// https://blog.timac.org/2016/1124-testing-if-an-arbitrary-pointer-is-a-valid-objective-c-object/ -BOOL FLEXPointerIsValidObjcObject(const void * ptr); - -#ifdef __cplusplus -} -#endif diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.mm b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.mm deleted file mode 100644 index ff17dcfd..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXObjcInternal.mm +++ /dev/null @@ -1,196 +0,0 @@ -// -// FLEXObjcInternal.mm -// FLEX -// -// Created by Tanner Bennett on 11/1/18. -// - -/* - * Copyright (c) 2005-2007 Apple Inc. All Rights Reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#import "FLEXObjcInternal.h" -#import -// For malloc_size -#import -// For vm_region_64 -#include - -#if __arm64e__ -#include -#endif - -#define ALWAYS_INLINE inline __attribute__((always_inline)) -#define NEVER_INLINE inline __attribute__((noinline)) - -// The macros below are copied straight from -// objc-internal.h, objc-private.h, objc-object.h, and objc-config.h with -// as few modifications as possible. Changes are noted in boxed comments. -// https://opensource.apple.com/source/objc4/objc4-723/ -// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-internal.h.auto.html -// https://opensource.apple.com/source/objc4/objc4-723/runtime/objc-object.h.auto.html - -///////////////////// -// objc-internal.h // -///////////////////// - -#if OBJC_HAVE_TAGGED_POINTERS - -/////////////////// -// objc-object.h // -/////////////////// - -//////////////////////////////////////////////// -// originally objc_object::isExtTaggedPointer // -//////////////////////////////////////////////// -NS_INLINE BOOL flex_isExtTaggedPointer(const void *ptr) { - return ((uintptr_t)ptr & _OBJC_TAG_EXT_MASK) == _OBJC_TAG_EXT_MASK; -} - -#endif // OBJC_HAVE_TAGGED_POINTERS - -///////////////////////////////////// -// FLEXObjectInternal // -// No Apple code beyond this point // -///////////////////////////////////// - -extern "C" { - -BOOL FLEXPointerIsReadable(const void *inPtr) { - kern_return_t error = KERN_SUCCESS; - - vm_size_t vmsize; -#if __arm64e__ - // On arm64e, we need to strip the PAC from the pointer so the adress is readable - vm_address_t address = (vm_address_t)ptrauth_strip(inPtr, ptrauth_key_function_pointer); -#else - vm_address_t address = (vm_address_t)inPtr; -#endif - vm_region_basic_info_data_t info; - mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64; - memory_object_name_t object; - - error = vm_region_64( - mach_task_self(), - &address, - &vmsize, - VM_REGION_BASIC_INFO, - (vm_region_info_t)&info, - &info_count, - &object - ); - - if (error != KERN_SUCCESS) { - // vm_region/vm_region_64 returned an error - return NO; - } else if (!(BOOL)(info.protection & VM_PROT_READ)) { - return NO; - } - -#if __arm64e__ - address = (vm_address_t)ptrauth_strip(inPtr, ptrauth_key_function_pointer); -#else - address = (vm_address_t)inPtr; -#endif - - // Read the memory - vm_size_t size = 0; - char buf[sizeof(uintptr_t)]; - error = vm_read_overwrite(mach_task_self(), address, sizeof(uintptr_t), (vm_address_t)buf, &size); - if (error != KERN_SUCCESS) { - // vm_read_overwrite returned an error - return NO; - } - - return YES; -} - -/// Accepts addresses that may or may not be readable. -/// https://blog.timac.org/2016/1124-testing-if-an-arbitrary-pointer-is-a-valid-objective-c-object/ -BOOL FLEXPointerIsValidObjcObject(const void *ptr) { - uintptr_t pointer = (uintptr_t)ptr; - - if (!ptr) { - return NO; - } - -#if OBJC_HAVE_TAGGED_POINTERS - // Tagged pointers have 0x1 set, no other valid pointers do - // objc-internal.h -> _objc_isTaggedPointer() - if (flex_isTaggedPointer(ptr) || flex_isExtTaggedPointer(ptr)) { - return YES; - } -#endif - - // Check pointer alignment - if ((pointer % sizeof(uintptr_t)) != 0) { - return NO; - } - - // From LLDB: - // Pointers in a class_t will only have bits 0 through 46 set, - // so if any pointer has bits 47 through 63 high, we know that this is not a valid isa - // https://llvm.org/svn/llvm-project/lldb/trunk/examples/summaries/cocoa/objc_runtime.py - if ((pointer & 0xFFFF800000000000) != 0) { - return NO; - } - - // Make sure dereferencing this address won't crash - if (!FLEXPointerIsReadable(ptr)) { - return NO; - } - - // http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html - // We check if the returned class is readable because object_getClass - // can return a garbage value when given a non-nil pointer to a non-object - Class cls = object_getClass((__bridge id)ptr); - if (!cls || !FLEXPointerIsReadable((__bridge void *)cls)) { - return NO; - } - - // Just because this pointer is readable doesn't mean whatever is at - // it's ISA offset is readable. We need to do the same checks on it's ISA. - // Even this isn't perfect, because once we call object_isClass, we're - // going to dereference a member of the metaclass, which may or may not - // be readable itself. For the time being there is no way to access it - // to check here, and I have yet to hard-code a solution. - Class metaclass = object_getClass(cls); - if (!metaclass || !FLEXPointerIsReadable((__bridge void *)metaclass)) { - return NO; - } - - // Does the class pointer we got appear as a class to the runtime? - if (!object_isClass(cls)) { - return NO; - } - - // Is the allocation size at least as large as the expected instance size? - ssize_t instanceSize = class_getInstanceSize(cls); - if (malloc_size(ptr) < instanceSize) { - return NO; - } - - return YES; -} - - -} // End extern "C" diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.h b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.h deleted file mode 100644 index 09b07e78..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.h +++ /dev/null @@ -1,79 +0,0 @@ -// -// FLEXRuntimeConstants.h -// FLEX -// -// Created by Tanner on 3/11/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import -#import - -#define FLEXEncodeClass(class) ("@\"" #class "\"") -#define FLEXEncodeObject(obj) (obj ? [NSString stringWithFormat:@"@\"%@\"", [obj class]].UTF8String : @encode(id)) - -// Arguments 0 and 1 are self and _cmd always -extern const unsigned int kFLEXNumberOfImplicitArgs; - -// See https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP40008048-CH101-SW6 -extern NSString *const kFLEXPropertyAttributeKeyTypeEncoding; -extern NSString *const kFLEXPropertyAttributeKeyBackingIvarName; -extern NSString *const kFLEXPropertyAttributeKeyReadOnly; -extern NSString *const kFLEXPropertyAttributeKeyCopy; -extern NSString *const kFLEXPropertyAttributeKeyRetain; -extern NSString *const kFLEXPropertyAttributeKeyNonAtomic; -extern NSString *const kFLEXPropertyAttributeKeyCustomGetter; -extern NSString *const kFLEXPropertyAttributeKeyCustomSetter; -extern NSString *const kFLEXPropertyAttributeKeyDynamic; -extern NSString *const kFLEXPropertyAttributeKeyWeak; -extern NSString *const kFLEXPropertyAttributeKeyGarbageCollectable; -extern NSString *const kFLEXPropertyAttributeKeyOldStyleTypeEncoding; - -typedef NS_ENUM(NSUInteger, FLEXPropertyAttribute) { - FLEXPropertyAttributeTypeEncoding = 'T', - FLEXPropertyAttributeBackingIvarName = 'V', - FLEXPropertyAttributeCopy = 'C', - FLEXPropertyAttributeCustomGetter = 'G', - FLEXPropertyAttributeCustomSetter = 'S', - FLEXPropertyAttributeDynamic = 'D', - FLEXPropertyAttributeGarbageCollectible = 'P', - FLEXPropertyAttributeNonAtomic = 'N', - FLEXPropertyAttributeOldTypeEncoding = 't', - FLEXPropertyAttributeReadOnly = 'R', - FLEXPropertyAttributeRetain = '&', - FLEXPropertyAttributeWeak = 'W' -}; //NS_SWIFT_NAME(FLEX.PropertyAttribute); - -typedef NS_ENUM(char, FLEXTypeEncoding) { - FLEXTypeEncodingNull = '\0', - FLEXTypeEncodingUnknown = '?', - FLEXTypeEncodingChar = 'c', - FLEXTypeEncodingInt = 'i', - FLEXTypeEncodingShort = 's', - FLEXTypeEncodingLong = 'l', - FLEXTypeEncodingLongLong = 'q', - FLEXTypeEncodingUnsignedChar = 'C', - FLEXTypeEncodingUnsignedInt = 'I', - FLEXTypeEncodingUnsignedShort = 'S', - FLEXTypeEncodingUnsignedLong = 'L', - FLEXTypeEncodingUnsignedLongLong = 'Q', - FLEXTypeEncodingFloat = 'f', - FLEXTypeEncodingDouble = 'd', - FLEXTypeEncodingLongDouble = 'D', - FLEXTypeEncodingCBool = 'B', - FLEXTypeEncodingVoid = 'v', - FLEXTypeEncodingCString = '*', - FLEXTypeEncodingObjcObject = '@', - FLEXTypeEncodingObjcClass = '#', - FLEXTypeEncodingSelector = ':', - FLEXTypeEncodingArrayBegin = '[', - FLEXTypeEncodingArrayEnd = ']', - FLEXTypeEncodingStructBegin = '{', - FLEXTypeEncodingStructEnd = '}', - FLEXTypeEncodingUnionBegin = '(', - FLEXTypeEncodingUnionEnd = ')', - FLEXTypeEncodingQuote = '\"', - FLEXTypeEncodingBitField = 'b', - FLEXTypeEncodingPointer = '^', - FLEXTypeEncodingConst = 'r' -}; //NS_SWIFT_NAME(FLEX.TypeEncoding); diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.m b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.m deleted file mode 100644 index 2b274df9..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeConstants.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// FLEXRuntimeConstants.m -// FLEX -// -// Created by Tanner on 3/11/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" - -const unsigned int kFLEXNumberOfImplicitArgs = 2; - -NSString *const kFLEXPropertyAttributeKeyTypeEncoding = @"T"; -NSString *const kFLEXPropertyAttributeKeyBackingIvarName = @"V"; -NSString *const kFLEXPropertyAttributeKeyReadOnly = @"R"; -NSString *const kFLEXPropertyAttributeKeyCopy = @"C"; -NSString *const kFLEXPropertyAttributeKeyRetain = @"&"; -NSString *const kFLEXPropertyAttributeKeyNonAtomic = @"N"; -NSString *const kFLEXPropertyAttributeKeyCustomGetter = @"G"; -NSString *const kFLEXPropertyAttributeKeyCustomSetter = @"S"; -NSString *const kFLEXPropertyAttributeKeyDynamic = @"D"; -NSString *const kFLEXPropertyAttributeKeyWeak = @"W"; -NSString *const kFLEXPropertyAttributeKeyGarbageCollectable = @"P"; -NSString *const kFLEXPropertyAttributeKeyOldStyleTypeEncoding = @"t"; diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.h b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.h deleted file mode 100644 index 147db677..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// FLEXRuntimeSafety.h -// FLEX -// -// Created by Tanner on 3/25/17. -// - -#import -#import - -#pragma mark - Classes - -extern NSUInteger const kFLEXKnownUnsafeClassCount; -extern const Class * FLEXKnownUnsafeClassList(void); -extern NSSet * FLEXKnownUnsafeClassNames(void); -extern CFSetRef FLEXKnownUnsafeClasses; - -static Class cNSObject = nil, cNSProxy = nil; - -__attribute__((constructor)) -static void FLEXInitKnownRootClasses(void) { - cNSObject = [NSObject class]; - cNSProxy = [NSProxy class]; -} - -static inline BOOL FLEXClassIsSafe(Class cls) { - // Is it nil or known to be unsafe? - if (!cls || CFSetContainsValue(FLEXKnownUnsafeClasses, (__bridge void *)cls)) { - return NO; - } - - // Is it a known root class? - if (!class_getSuperclass(cls)) { - return cls == cNSObject || cls == cNSProxy; - } - - // Probably safe - return YES; -} - -static inline BOOL FLEXClassNameIsSafe(NSString *cls) { - if (!cls) return NO; - - NSSet *ignored = FLEXKnownUnsafeClassNames(); - return ![ignored containsObject:cls]; -} - -#pragma mark - Ivars - -extern CFSetRef FLEXKnownUnsafeIvars; - -static inline BOOL FLEXIvarIsSafe(Ivar ivar) { - if (!ivar) return NO; - - return !CFSetContainsValue(FLEXKnownUnsafeIvars, ivar); -} diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.m b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.m deleted file mode 100644 index 8a80cb7b..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXRuntimeSafety.m +++ /dev/null @@ -1,107 +0,0 @@ -// -// FLEXRuntimeSafety.m -// FLEX -// -// Created by Tanner on 3/25/17. -// - -#import "FLEXRuntimeSafety.h" - -NSUInteger const kFLEXKnownUnsafeClassCount = 19; -Class * _UnsafeClasses = NULL; -CFSetRef FLEXKnownUnsafeClasses = nil; -CFSetRef FLEXKnownUnsafeIvars = nil; - -#define FLEXClassPointerOrCFNull(name) \ - (NSClassFromString(name) ?: (__bridge id)kCFNull) - -#define FLEXIvarOrCFNull(cls, name) \ - (class_getInstanceVariable([cls class], name) ?: (void *)kCFNull) - -__attribute__((constructor)) -static void FLEXRuntimeSafteyInit() { - FLEXKnownUnsafeClasses = CFSetCreate( - kCFAllocatorDefault, - (const void **)(uintptr_t)FLEXKnownUnsafeClassList(), - kFLEXKnownUnsafeClassCount, - nil - ); - - Ivar unsafeIvars[] = { - FLEXIvarOrCFNull(NSURL, "_urlString"), - FLEXIvarOrCFNull(NSURL, "_baseURL"), - }; - FLEXKnownUnsafeIvars = CFSetCreate( - kCFAllocatorDefault, - (const void **)unsafeIvars, - sizeof(unsafeIvars), - nil - ); -} - -const Class * FLEXKnownUnsafeClassList() { - if (!_UnsafeClasses) { - const Class ignored[] = { - FLEXClassPointerOrCFNull(@"__ARCLite__"), - FLEXClassPointerOrCFNull(@"__NSCFCalendar"), - FLEXClassPointerOrCFNull(@"__NSCFTimer"), - FLEXClassPointerOrCFNull(@"NSCFTimer"), - FLEXClassPointerOrCFNull(@"__NSGenericDeallocHandler"), - FLEXClassPointerOrCFNull(@"NSAutoreleasePool"), - FLEXClassPointerOrCFNull(@"NSPlaceholderNumber"), - FLEXClassPointerOrCFNull(@"NSPlaceholderString"), - FLEXClassPointerOrCFNull(@"NSPlaceholderValue"), - FLEXClassPointerOrCFNull(@"Object"), - FLEXClassPointerOrCFNull(@"VMUArchitecture"), - FLEXClassPointerOrCFNull(@"JSExport"), - FLEXClassPointerOrCFNull(@"__NSAtom"), - FLEXClassPointerOrCFNull(@"_NSZombie_"), - FLEXClassPointerOrCFNull(@"_CNZombie_"), - FLEXClassPointerOrCFNull(@"__NSMessage"), - FLEXClassPointerOrCFNull(@"__NSMessageBuilder"), - FLEXClassPointerOrCFNull(@"FigIrisAutoTrimmerMotionSampleExport"), - // Temporary until we have our own type encoding parser; - // setVectors: has an invalid type encoding and crashes NSMethodSignature - FLEXClassPointerOrCFNull(@"_UIPointVector"), - }; - - assert((sizeof(ignored) / sizeof(Class)) == kFLEXKnownUnsafeClassCount); - - _UnsafeClasses = (Class *)malloc(sizeof(ignored)); - memcpy(_UnsafeClasses, ignored, sizeof(ignored)); - } - - return _UnsafeClasses; -} - -NSSet * FLEXKnownUnsafeClassNames() { - static NSSet *set = nil; - if (!set) { - NSArray *ignored = @[ - @"__ARCLite__", - @"__NSCFCalendar", - @"__NSCFTimer", - @"NSCFTimer", - @"__NSGenericDeallocHandler", - @"NSAutoreleasePool", - @"NSPlaceholderNumber", - @"NSPlaceholderString", - @"NSPlaceholderValue", - @"Object", - @"VMUArchitecture", - @"JSExport", - @"__NSAtom", - @"_NSZombie_", - @"_CNZombie_", - @"__NSMessage", - @"__NSMessageBuilder", - @"FigIrisAutoTrimmerMotionSampleExport", - @"_UIPointVector", - ]; - - set = [NSSet setWithArray:ignored]; - assert(set.count == kFLEXKnownUnsafeClassCount); - } - - return set; -} diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h deleted file mode 100644 index 7a8b1fb6..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// FLEXTypeEncodingParser.h -// FLEX -// -// Created by Tanner Bennett on 8/22/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -/// @return \c YES if the type is supported, \c NO otherwise -BOOL FLEXGetSizeAndAlignment(const char *type, NSUInteger * _Nullable sizep, NSUInteger * _Nullable alignp); - -@interface FLEXTypeEncodingParser : NSObject - -/// \c cleanedEncoding is necessary because a type encoding may contain a pointer -/// to an unsupported type. \c NSMethodSignature will pass each type to \c NSGetSizeAndAlignment -/// which will throw an exception on unsupported struct pointers, and this exception is caught -/// by \c NSMethodSignature, but it still bothers anyone debugging with \c objc_exception_throw -/// -/// @param cleanedEncoding the "safe" type encoding you can pass to \c NSMethodSignature -/// @return whether the given type encoding can be passed to -/// \c NSMethodSignature without it throwing an exception. -+ (BOOL)methodTypeEncodingSupported:(NSString *)typeEncoding cleaned:(NSString *_Nonnull*_Nullable)cleanedEncoding; - -/// @return The type encoding of an individual argument in a method's type encoding string. -/// Pass 0 to get the type of the return value. 1 and 2 are `self` and `_cmd` respectively. -+ (NSString *)type:(NSString *)typeEncoding forMethodArgumentAtIndex:(NSUInteger)idx; - -/// @return The size in bytes of the typeof an individual argument in a method's type encoding string. -/// Pass 0 to get the size of the return value. 1 and 2 are `self` and `_cmd` respectively. -+ (ssize_t)size:(NSString *)typeEncoding forMethodArgumentAtIndex:(NSUInteger)idx; - -/// @param unaligned whether to compute the aligned or unaligned size. -/// @return The size in bytes, or \c -1 if the type encoding is unsupported. -/// Do not pass in the result of \c method_getTypeEncoding -+ (ssize_t)sizeForTypeEncoding:(NSString *)type alignment:(nullable ssize_t *)alignOut unaligned:(BOOL)unaligned; - -/// Defaults to \C unaligned:NO -+ (ssize_t)sizeForTypeEncoding:(NSString *)type alignment:(nullable ssize_t *)alignOut; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.m b/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.m deleted file mode 100644 index 5bbfb9a0..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/FLEXTypeEncodingParser.m +++ /dev/null @@ -1,900 +0,0 @@ -// -// FLEXTypeEncodingParser.m -// FLEX -// -// Created by Tanner Bennett on 8/22/19. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTypeEncodingParser.h" -#import "FLEXRuntimeUtility.h" - -#define S(__ch) ({ \ - unichar __c = __ch; \ - [[NSString alloc] initWithCharacters:&__c length:1]; \ -}) - -typedef struct FLEXTypeInfo { - /// The size is unaligned. -1 if not supported at all. - ssize_t size; - ssize_t align; - /// NO if the type cannot be supported at all - /// YES if the type is either fully or partially supported. - BOOL supported; - /// YES if the type was only partially supported, such as in - /// the case of unions in pointer types, or named structure - /// types without member info. These can be corrected manually - /// since they can be fixed or replaced with less info. - BOOL fixesApplied; - /// Whether this type is a union or one of its members - /// recursively contains a union, exlcuding pointers. - /// - /// Unions are tricky because they're supported by - /// \c NSGetSizeAndAlignment but not by \c NSMethodSignature - /// so we need to track whenever a type contains a union - /// so that we can clean it out of pointer types. - BOOL containsUnion; - /// size can only be 0 if not void - BOOL isVoid; -} FLEXTypeInfo; - -/// Type info for a completely unsupported type. -static FLEXTypeInfo FLEXTypeInfoUnsupported = (FLEXTypeInfo){ -1, 0, NO, NO, NO, NO }; -/// Type info for the void return type. -static FLEXTypeInfo FLEXTypeInfoVoid = (FLEXTypeInfo){ 0, 0, YES, NO, NO, YES }; - -/// Builds type info for a fully or partially supported type. -static inline FLEXTypeInfo FLEXTypeInfoMake(ssize_t size, ssize_t align, BOOL fixed) { - return (FLEXTypeInfo){ size, align, YES, fixed, NO, NO }; -} - -/// Builds type info for a fully or partially supported type. -static inline FLEXTypeInfo FLEXTypeInfoMakeU(ssize_t size, ssize_t align, BOOL fixed, BOOL hasUnion) { - return (FLEXTypeInfo){ size, align, YES, fixed, hasUnion, NO }; -} - -BOOL FLEXGetSizeAndAlignment(const char *type, NSUInteger *sizep, NSUInteger *alignp) { - NSInteger size = 0; - ssize_t align = 0; - size = [FLEXTypeEncodingParser sizeForTypeEncoding:@(type) alignment:&align]; - - if (size == -1) { - return NO; - } - - if (sizep) { - *sizep = (NSUInteger)size; - } - - if (alignp) { - *alignp = (NSUInteger)size; - } - - return YES; -} - -@interface FLEXTypeEncodingParser () -@property (nonatomic, readonly) NSScanner *scan; -@property (nonatomic, readonly) NSString *scanned; -@property (nonatomic, readonly) NSString *unscanned; -@property (nonatomic, readonly) char nextChar; - -/// Replacements are made to this string as we scan as needed -@property (nonatomic) NSMutableString *cleaned; -/// Offset for \e further replacements to be made within \c cleaned -@property (nonatomic, readonly) NSUInteger cleanedReplacingOffset; -@end - -@implementation FLEXTypeEncodingParser - -- (NSString *)scanned { - return [self.scan.string substringToIndex:self.scan.scanLocation]; -} - -- (NSString *)unscanned { - return [self.scan.string substringFromIndex:self.scan.scanLocation]; -} - -#pragma mark Initialization - -- (id)initWithObjCTypes:(NSString *)typeEncoding { - self = [super init]; - if (self) { - _scan = [NSScanner scannerWithString:typeEncoding]; - _scan.caseSensitive = YES; - _cleaned = typeEncoding.mutableCopy; - } - - return self; -} - - -#pragma mark Public - -+ (BOOL)methodTypeEncodingSupported:(NSString *)typeEncoding cleaned:(NSString * __autoreleasing *)cleanedEncoding { - if (!typeEncoding.length) { - return NO; - } - - FLEXTypeEncodingParser *parser = [[self alloc] initWithObjCTypes:typeEncoding]; - - while (!parser.scan.isAtEnd) { - FLEXTypeInfo info = [parser parseNextType]; - - if (!info.supported || info.containsUnion || (info.size == 0 && !info.isVoid)) { - return NO; - } - } - - if (cleanedEncoding) { - *cleanedEncoding = parser.cleaned.copy; - } - - return YES; -} - -+ (NSString *)type:(NSString *)typeEncoding forMethodArgumentAtIndex:(NSUInteger)idx { - FLEXTypeEncodingParser *parser = [[self alloc] initWithObjCTypes:typeEncoding]; - - // Scan up to the argument we want - for (NSUInteger i = 0; i < idx; i++) { - if (![parser scanPastArg]) { - [NSException raise:NSRangeException - format:@"Index %@ out of bounds for type encoding '%@'", - @(idx), typeEncoding - ]; - } - } - - return [parser scanArg]; -} - -+ (ssize_t)size:(NSString *)typeEncoding forMethodArgumentAtIndex:(NSUInteger)idx { - return [self sizeForTypeEncoding:[self type:typeEncoding forMethodArgumentAtIndex:idx] alignment:nil]; -} - -+ (ssize_t)sizeForTypeEncoding:(NSString *)type alignment:(ssize_t *)alignOut { - return [self sizeForTypeEncoding:type alignment:alignOut unaligned:NO]; -} - -+ (ssize_t)sizeForTypeEncoding:(NSString *)type alignment:(ssize_t *)alignOut unaligned:(BOOL)unaligned { - FLEXTypeInfo info = [self parseType:type]; - - ssize_t size = info.size; - ssize_t align = info.align; - - if (info.supported) { - if (alignOut) { - *alignOut = align; - } - - if (!unaligned) { - size += size % align; - } - } - - // size is -1 if not supported - return size; -} - -+ (FLEXTypeInfo)parseType:(NSString *)type cleaned:(NSString * __autoreleasing *)cleanedEncoding { - FLEXTypeEncodingParser *parser = [[self alloc] initWithObjCTypes:type]; - FLEXTypeInfo info = [parser parseNextType]; - if (cleanedEncoding) { - *cleanedEncoding = parser.cleaned; - } - - return info; -} - -+ (FLEXTypeInfo)parseType:(NSString *)type { - return [self parseType:type cleaned:nil]; -} - -#pragma mark Private - -- (NSCharacterSet *)identifierFirstCharCharacterSet { - static NSCharacterSet *identifierFirstSet = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *allowed = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$"; - identifierFirstSet = [NSCharacterSet characterSetWithCharactersInString:allowed]; - }); - - return identifierFirstSet; -} - -- (NSCharacterSet *)identifierCharacterSet { - static NSCharacterSet *identifierSet = nil; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - NSString *allowed = @"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_$1234567890"; - identifierSet = [NSCharacterSet characterSetWithCharactersInString:allowed]; - }); - - return identifierSet; -} - -- (char)nextChar { - NSScanner *scan = self.scan; - return [scan.string characterAtIndex:scan.scanLocation]; -} - -/// For scanning struct/class names -- (NSString *)scanIdentifier { - NSString *prefix = nil, *suffix = nil; - - // Identifiers cannot start with a number - if (![self.scan scanCharactersFromSet:self.identifierFirstCharCharacterSet intoString:&prefix]) { - return nil; - } - - // Optional because identifier may just be one character - [self.scan scanCharactersFromSet:self.identifierCharacterSet intoString:&suffix]; - - if (suffix) { - return [prefix stringByAppendingString:suffix]; - } - - return prefix; -} - -/// @return the size in bytes -- (ssize_t)sizeForType:(FLEXTypeEncoding)type { - switch (type) { - case FLEXTypeEncodingChar: return sizeof(char); - case FLEXTypeEncodingInt: return sizeof(int); - case FLEXTypeEncodingShort: return sizeof(short); - case FLEXTypeEncodingLong: return sizeof(long); - case FLEXTypeEncodingLongLong: return sizeof(long long); - case FLEXTypeEncodingUnsignedChar: return sizeof(unsigned char); - case FLEXTypeEncodingUnsignedInt: return sizeof(unsigned int); - case FLEXTypeEncodingUnsignedShort: return sizeof(unsigned short); - case FLEXTypeEncodingUnsignedLong: return sizeof(unsigned long); - case FLEXTypeEncodingUnsignedLongLong: return sizeof(unsigned long long); - case FLEXTypeEncodingFloat: return sizeof(float); - case FLEXTypeEncodingDouble: return sizeof(double); - case FLEXTypeEncodingLongDouble: return sizeof(long double); - case FLEXTypeEncodingCBool: return sizeof(_Bool); - case FLEXTypeEncodingVoid: return 0; - case FLEXTypeEncodingCString: return sizeof(char *); - case FLEXTypeEncodingObjcObject: return sizeof(id); - case FLEXTypeEncodingObjcClass: return sizeof(Class); - case FLEXTypeEncodingSelector: return sizeof(SEL); - // Unknown / '?' is typically a pointer. In the rare case - // it isn't, such as in '{?=...}', it is never passed here. - case FLEXTypeEncodingUnknown: - case FLEXTypeEncodingPointer: return sizeof(uintptr_t); - - default: return -1; - } -} - -- (FLEXTypeInfo)parseNextType { - NSUInteger start = self.scan.scanLocation; - - // Check for void first - if ([self scanChar:FLEXTypeEncodingVoid]) { - // Skip argument frame for method signatures - [self scanSize]; - return FLEXTypeInfoVoid; - } - - // Scan optional const - [self scanChar:FLEXTypeEncodingConst]; - - // Check for pointer, then scan next - if ([self scanChar:FLEXTypeEncodingPointer]) { - // Recurse to scan something else - NSUInteger pointerTypeStart = self.scan.scanLocation; - if ([self scanPastArg]) { - // Make sure the pointer type is supported, and clean it if not - NSUInteger pointerTypeLength = self.scan.scanLocation - pointerTypeStart; - NSString *pointerType = [self.scan.string - substringWithRange:NSMakeRange(pointerTypeStart, pointerTypeLength) - ]; - - // Deeeep nested cleaning info gets lost here - NSString *cleaned = nil; - FLEXTypeInfo info = [self.class parseType:pointerType cleaned:&cleaned]; - BOOL needsCleaning = !info.supported || info.containsUnion || info.fixesApplied; - - // Clean the type if it is unsupported, malformed, or contains a union. - // (Unions are supported by NSGetSizeAndAlignment but not - // supported by NSMethodSignature for some reason) - if (needsCleaning) { - // If unsupported, no cleaning occurred in parseType:cleaned: above. - // Otherwise, the type is partially supported and we did clean it, - // and we will replace this type with the cleaned type from above. - if (!info.supported || info.containsUnion) { - cleaned = [self cleanPointeeTypeAtLocation:pointerTypeStart]; - } - - NSInteger offset = self.cleanedReplacingOffset; - NSInteger location = pointerTypeStart - offset; - [self.cleaned replaceCharactersInRange:NSMakeRange( - location, pointerTypeLength - ) withString:cleaned]; - } - - // Skip optional frame offset - [self scanSize]; - - ssize_t size = [self sizeForType:FLEXTypeEncodingPointer]; - return FLEXTypeInfoMake(size, size, !info.supported || info.fixesApplied); - } else { - // Scan failed, abort - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - } - - // Check for struct/union/array - char next = self.nextChar; - BOOL didScanSUA = YES, structOrUnion = NO, isUnion = NO; - FLEXTypeEncoding opening = FLEXTypeEncodingNull, closing = FLEXTypeEncodingNull; - switch (next) { - case FLEXTypeEncodingStructBegin: - structOrUnion = YES; - opening = FLEXTypeEncodingStructBegin; - closing = FLEXTypeEncodingStructEnd; - break; - case FLEXTypeEncodingUnionBegin: - structOrUnion = isUnion = YES; - opening = FLEXTypeEncodingUnionBegin; - closing = FLEXTypeEncodingUnionEnd; - break; - case FLEXTypeEncodingArrayBegin: - opening = FLEXTypeEncodingArrayBegin; - closing = FLEXTypeEncodingArrayEnd; - break; - - default: - didScanSUA = NO; - break; - } - - if (didScanSUA) { - BOOL containsUnion = isUnion; - BOOL fixesApplied = NO; - - NSUInteger backup = self.scan.scanLocation; - - // Ensure we have a closing tag - if (![self scanPair:opening close:closing]) { - // Scan failed, abort - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - - // Move cursor just after opening tag (struct/union/array) - NSInteger arrayCount = -1; - self.scan.scanLocation = backup + 1; - - if (!structOrUnion) { - arrayCount = [self scanSize]; - if (!arrayCount || self.nextChar == FLEXTypeEncodingArrayEnd) { - // Malformed array type: - // 1. Arrays must have a count after the opening brace - // 2. Arrays must have an element type after the count - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - } else { - // If we encounter the ?= portion of something like {?=b8b4b1b1b18[8S]} - // then we skip over it, since it means nothing to us in this context. - // It is completely optional, and if it fails, we go right back where we were. - if (![self scanTypeName] && self.nextChar == FLEXTypeEncodingUnknown) { - // Exception: we are trying to parse {?} which is invalid - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - } - - // Sum sizes of members together: - // Scan for bitfields before checking for other members - // - // Arrays will only have one "member," but - // this logic still works for them - ssize_t sizeSoFar = 0; - ssize_t maxAlign = 0; - NSMutableString *cleanedBackup = self.cleaned.mutableCopy; - - while (![self scanChar:closing]) { - next = self.nextChar; - // Check for bitfields, which we cannot support because - // type encodings for bitfields do not include alignment info - if (next == FLEXTypeEncodingBitField) { - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - - // Structure fields could be named - if (next == FLEXTypeEncodingQuote) { - [self scanPair:FLEXTypeEncodingQuote close:FLEXTypeEncodingQuote]; - } - - FLEXTypeInfo info = [self parseNextType]; - if (!info.supported || info.containsUnion) { - // The above call is the only time in this method where - // `cleaned` might be mutated recursively, so this is the - // only place where we need to keep and restore a backup - // - // For instance, if we've been iterating over the members - // of a struct and we've encountered a few pointers so far - // that we needed to clean, and suddenly we come across an - // unsupported member, we need to be able to "rewind" and - // undo any changes to `self.cleaned` so that the parent - // call in the call stack can wipe the current structure - // clean entirely if needed. Example below: - // - // Initial: ^{foo=^{pair}{^pair}{invalid_type}} - // v-- here - // 1st clean: ^{foo=^{?=}{^pair}{invalid_type} - // v-- here - // 2nd clean: ^{foo=^{?=}{?=}{invalid_type} - // v-- here - // Can't clean: ^{foo=^{?=}{?=}{invalid_type} - // v-- to here - // Rewind: ^{foo=^{pair}{^pair}{invalid_type}} - // Final clean: ^{foo=} - self.cleaned = cleanedBackup; - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } - - // Unions are the size of their largest member, - // arrays are element.size x length, and - // structs are the sum of their members - if (structOrUnion) { - if (isUnion) { // Union - sizeSoFar = MAX(sizeSoFar, info.size); - } else { // Struct - sizeSoFar += info.size; - } - } else { // Array - sizeSoFar = info.size * arrayCount; - } - - // Propogate the max alignment and other metadata - maxAlign = MAX(maxAlign, info.align); - containsUnion = containsUnion || info.containsUnion; - fixesApplied = fixesApplied || info.fixesApplied; - } - - // Skip optional frame offset - [self scanSize]; - - return FLEXTypeInfoMakeU(sizeSoFar, maxAlign, fixesApplied, containsUnion); - } - - // Scan single thing and possible size and return - ssize_t size = -1; - char t = self.nextChar; - switch (t) { - case FLEXTypeEncodingUnknown: - case FLEXTypeEncodingChar: - case FLEXTypeEncodingInt: - case FLEXTypeEncodingShort: - case FLEXTypeEncodingLong: - case FLEXTypeEncodingLongLong: - case FLEXTypeEncodingUnsignedChar: - case FLEXTypeEncodingUnsignedInt: - case FLEXTypeEncodingUnsignedShort: - case FLEXTypeEncodingUnsignedLong: - case FLEXTypeEncodingUnsignedLongLong: - case FLEXTypeEncodingFloat: - case FLEXTypeEncodingDouble: - case FLEXTypeEncodingLongDouble: - case FLEXTypeEncodingCBool: - case FLEXTypeEncodingCString: - case FLEXTypeEncodingSelector: - case FLEXTypeEncodingBitField: { - self.scan.scanLocation++; - // Skip optional frame offset - [self scanSize]; - - if (t == FLEXTypeEncodingBitField) { - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; - } else { - // Compute size - size = [self sizeForType:t]; - } - } - break; - - case FLEXTypeEncodingObjcObject: - case FLEXTypeEncodingObjcClass: { - self.scan.scanLocation++; - // These might have numbers OR quotes after them - // Skip optional frame offset - [self scanSize]; - [self scanPair:FLEXTypeEncodingQuote close:FLEXTypeEncodingQuote]; - size = sizeof(id); - } - break; - - default: break; - } - - if (size > 0) { - // Alignment of scalar types is its size - return FLEXTypeInfoMake(size, size, NO); - } - - self.scan.scanLocation = start; - return FLEXTypeInfoUnsupported; -} - -- (BOOL)scanString:(NSString *)str { - return [self.scan scanString:str intoString:nil]; -} - -- (BOOL)canScanString:(NSString *)str { - NSScanner *scan = self.scan; - NSUInteger len = str.length; - unichar buff1[len], buff2[len]; - - [str getCharacters:buff1]; - [scan.string getCharacters:buff2 range:NSMakeRange(scan.scanLocation, len)]; - if (memcmp(buff1, buff2, len) == 0) { - return YES; - } - - return NO; -} - -- (BOOL)canScanChar:(char)c { - // By avoiding any ARC calls on these two objects which we know won't be - // free'd out from under us, we're making HUGE performance savings in this - // parser, because this method is one of the most-used methods of the parser. - // This is probably the most performance-critical method in this class. - __unsafe_unretained NSScanner *scan = self.scan; - __unsafe_unretained NSString *string = scan.string; - if (scan.scanLocation >= string.length) return NO; - - return [string characterAtIndex:scan.scanLocation] == c; -} - -- (BOOL)scanChar:(char)c { - if ([self canScanChar:c]) { - self.scan.scanLocation++; - return YES; - } - - return NO; -} - -- (BOOL)scanChar:(char)c into:(char *)ref { - if ([self scanChar:c]) { - *ref = c; - return YES; - } - - return NO; -} - -- (ssize_t)scanSize { - NSInteger size = 0; - if ([self.scan scanInteger:&size]) { - return size; - } - - return 0; -} - -- (NSString *)scanPair:(char)c1 close:(char)c2 { - // Starting position and string variables - NSUInteger start = self.scan.scanLocation; - NSString *s1 = S(c1); - - // Scan opening tag - if (![self scanChar:c1]) { - self.scan.scanLocation = start; - return nil; - } - - // Character set for scanning up to either symbol - NSCharacterSet *bothChars = ({ - unichar buff[2] = { c1, c2 }; - NSString *bothCharsStr = [[NSString alloc] initWithCharacters:buff length:2]; - [NSCharacterSet characterSetWithCharactersInString:bothCharsStr]; - }); - - // Stack for finding pairs, starting with the opening symbol - NSMutableArray *stack = [NSMutableArray arrayWithObject:s1]; - - // Algorithm for scanning to the closing end of a pair of opening/closing symbols - // scanUpToCharactersFromSet:intoString: returns NO if you're already at one of the chars, - // so we need to check if we can actually scan one if it returns NO - while ([self.scan scanUpToCharactersFromSet:bothChars intoString:nil] || - [self canScanChar:c1] || [self canScanChar:c2]) { - // Closing symbol found - if ([self scanChar:c2]) { - if (!stack.count) { - // Abort, no matching opening symbol - self.scan.scanLocation = start; - return nil; - } - - // Pair found, pop opening symbol - [stack removeLastObject]; - // Exit loop if we reached the closing brace we needed - if (!stack.count) { - break; - } - } - // Opening symbol found - if ([self scanChar:c1]) { - // Begin pair - [stack addObject:s1]; - } - } - - if (stack.count) { - // Abort, no matching closing symbol - self.scan.scanLocation = start; - return nil; - } - - // Slice out the string we just scanned - return [self.scan.string - substringWithRange:NSMakeRange(start, self.scan.scanLocation - start) - ]; -} - -- (BOOL)scanPastArg { - NSUInteger start = self.scan.scanLocation; - - // Check for void first - if ([self scanChar:FLEXTypeEncodingVoid]) { - return YES; - } - - // Scan optional const - [self scanChar:FLEXTypeEncodingConst]; - - // Check for pointer, then scan next - if ([self scanChar:FLEXTypeEncodingPointer]) { - // Recurse to scan something else - if ([self scanPastArg]) { - return YES; - } else { - // Scan failed, abort - self.scan.scanLocation = start; - return NO; - } - } - - char next = self.nextChar; - - // Check for struct/union/array, scan past it - FLEXTypeEncoding opening = FLEXTypeEncodingNull, closing = FLEXTypeEncodingNull; - BOOL checkPair = YES; - switch (next) { - case FLEXTypeEncodingStructBegin: - opening = FLEXTypeEncodingStructBegin; - closing = FLEXTypeEncodingStructEnd; - break; - case FLEXTypeEncodingUnionBegin: - opening = FLEXTypeEncodingUnionBegin; - closing = FLEXTypeEncodingUnionEnd; - break; - case FLEXTypeEncodingArrayBegin: - opening = FLEXTypeEncodingArrayBegin; - closing = FLEXTypeEncodingArrayEnd; - break; - - default: - checkPair = NO; - break; - } - - if (checkPair && [self scanPair:opening close:closing]) { - return YES; - } - - // Scan single thing and possible size and return - switch (next) { - case FLEXTypeEncodingUnknown: - case FLEXTypeEncodingChar: - case FLEXTypeEncodingInt: - case FLEXTypeEncodingShort: - case FLEXTypeEncodingLong: - case FLEXTypeEncodingLongLong: - case FLEXTypeEncodingUnsignedChar: - case FLEXTypeEncodingUnsignedInt: - case FLEXTypeEncodingUnsignedShort: - case FLEXTypeEncodingUnsignedLong: - case FLEXTypeEncodingUnsignedLongLong: - case FLEXTypeEncodingFloat: - case FLEXTypeEncodingDouble: - case FLEXTypeEncodingLongDouble: - case FLEXTypeEncodingCBool: - case FLEXTypeEncodingCString: - case FLEXTypeEncodingSelector: - case FLEXTypeEncodingBitField: { - self.scan.scanLocation++; - // Size is optional - [self scanSize]; - return YES; - } - - case FLEXTypeEncodingObjcObject: - case FLEXTypeEncodingObjcClass: { - self.scan.scanLocation++; - // These might have numbers OR quotes after them - [self scanSize] || [self scanPair:FLEXTypeEncodingQuote close:FLEXTypeEncodingQuote]; - return YES; - } - - default: break; - } - - self.scan.scanLocation = start; - return NO; -} - -- (NSString *)scanArg { - NSUInteger start = self.scan.scanLocation; - if (![self scanPastArg]) { - return nil; - } - - return [self.scan.string - substringWithRange:NSMakeRange(start, self.scan.scanLocation - start) - ]; -} - -- (BOOL)scanTypeName { - NSUInteger start = self.scan.scanLocation; - - // The ?= portion of something like {?=b8b4b1b1b18[8S]} - if ([self scanChar:FLEXTypeEncodingUnknown]) { - if (![self scanString:@"="]) { - // No size information available for strings like {?=} - self.scan.scanLocation = start; - return NO; - } - } else { - if (![self scanIdentifier] || ![self scanString:@"="]) { - // 1. Not a valid identifier - // 2. No size information available for strings like {CGPoint} - self.scan.scanLocation = start; - return NO; - } - } - - return YES; -} - -- (NSString *)extractTypeNameFromScanLocation:(BOOL)allowMissingTypeInfo closing:(FLEXTypeEncoding)closeTag { - NSUInteger start = self.scan.scanLocation; - - // The ?= portion of something like {?=b8b4b1b1b18[8S]} - if ([self scanChar:FLEXTypeEncodingUnknown]) { - return @"?"; - } else { - NSString *typeName = [self scanIdentifier]; - char next = self.nextChar; - - if (!typeName) { - // Did not scan an identifier - self.scan.scanLocation = start; - return nil; - } - - switch (next) { - case '=': - return typeName; - - default: { - // = is non-optional unless we allowMissingTypeInfo, in whcih - // case the next character needs to be a closing brace - if (allowMissingTypeInfo && next == closeTag) { - return typeName; - } else { - // Not a valid identifier; possibly a generic C++ type - // i.e. {pair} where `name` was found as `pair` - self.scan.scanLocation = start; - return nil; - } - } - } - } -} - -- (NSString *)cleanPointeeTypeAtLocation:(NSUInteger)scanLocation { - NSUInteger start = self.scan.scanLocation; - self.scan.scanLocation = scanLocation; - - // The return / cleanup code for when the scanned type is already clean - NSString * (^typeIsClean)(void) = ^NSString * { - NSString *clean = [self.scan.string - substringWithRange:NSMakeRange(scanLocation, self.scan.scanLocation - scanLocation) - ]; - // Reset scan location even on success, because this method is not supposed to change it - self.scan.scanLocation = start; - return clean; - }; - - // No void, this is not a return type - - // Scan optional const - [self scanChar:FLEXTypeEncodingConst]; - - char next = self.nextChar; - switch (next) { - case FLEXTypeEncodingPointer: - // Recurse to scan something else - [self scanChar:next]; - return [self cleanPointeeTypeAtLocation:self.scan.scanLocation]; - - case FLEXTypeEncodingArrayBegin: - // All arrays are supported, scan past them - if ([self scanPair:FLEXTypeEncodingArrayBegin close:FLEXTypeEncodingArrayEnd]) { - return typeIsClean(); - } - break; - - case FLEXTypeEncodingUnionBegin: - // Unions are not supported at all in NSMethodSignature - // We could check for the closing token to be safe, but eh - self.scan.scanLocation = start; - return @"?"; - - case FLEXTypeEncodingStructBegin: { - FLEXTypeInfo info = [self.class parseType:self.unscanned]; - if (info.supported && !info.fixesApplied) { - [self scanPastArg]; - return typeIsClean(); - } - - // The structure we just tried to scan is unsupported, so just return its name - // if it has one. If not, just return a question mark. - self.scan.scanLocation++; // Skip past { - NSString *name = [self extractTypeNameFromScanLocation:YES closing:FLEXTypeEncodingStructEnd]; - if (name) { - // Got the name, scan past the closing token - [self.scan scanUpToString:@"}" intoString:nil]; - if (![self scanChar:FLEXTypeEncodingStructEnd]) { - // Missing struct close token - self.scan.scanLocation = start; - return nil; - } - } else { - // Did not scan valid identifier, possibly a C++ type - self.scan.scanLocation = start; - return @"{?=}"; - } - - // Reset scan location even on success, because this method is not supposed to change it - self.scan.scanLocation = start; - return ({ // "{name=}" - NSMutableString *format = @"{".mutableCopy; - [format appendString:name]; - [format appendString:@"=}"]; - format; - }); - } - - default: - break; - } - - // Check for other types, which in theory are all valid but whatever - FLEXTypeInfo info = [self parseNextType]; - if (info.supported && !info.fixesApplied) { - return typeIsClean(); - } - - self.scan.scanLocation = start; - return @"?"; -} - -- (NSUInteger)cleanedReplacingOffset { - return self.scan.string.length - self.cleaned.length; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.h deleted file mode 100644 index 037abcf7..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// FLEXBlockDescription.h -// FLEX -// -// Created by Oliver Letterer on 2012-09-01 -// Forked from CTObjectiveCRuntimeAdditions (MIT License) -// https://github.com/ebf/CTObjectiveCRuntimeAdditions -// -// Copyright (c) 2020 FLEX Team-EDV Beratung Föllmer GmbH -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#import - -typedef NS_OPTIONS(NSUInteger, FLEXBlockOptions) { - FLEXBlockOptionHasCopyDispose = (1 << 25), - FLEXBlockOptionHasCtor = (1 << 26), // helpers have C++ code - FLEXBlockOptionIsGlobal = (1 << 28), - FLEXBlockOptionHasStret = (1 << 29), // IFF BLOCK_HAS_SIGNATURE - FLEXBlockOptionHasSignature = (1 << 30), -}; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark - -@interface FLEXBlockDescription : NSObject - -+ (instancetype)describing:(id)block; - -@property (nonatomic, readonly, nullable) NSMethodSignature *signature; -@property (nonatomic, readonly, nullable) NSString *signatureString; -@property (nonatomic, readonly, nullable) NSString *sourceDeclaration; -@property (nonatomic, readonly) FLEXBlockOptions flags; -@property (nonatomic, readonly) NSUInteger size; -@property (nonatomic, readonly) NSString *summary; -@property (nonatomic, readonly) id block; - -- (BOOL)isCompatibleForBlockSwizzlingWithMethodSignature:(NSMethodSignature *)methodSignature; - -@end - -#pragma mark - -@interface NSBlock : NSObject -- (void)invoke; -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.m deleted file mode 100644 index f943e314..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXBlockDescription.m +++ /dev/null @@ -1,157 +0,0 @@ -// -// FLEXBlockDescription.m -// FLEX -// -// Created by Oliver Letterer on 2012-09-01 -// Forked from CTObjectiveCRuntimeAdditions (MIT License) -// https://github.com/ebf/CTObjectiveCRuntimeAdditions -// -// Copyright (c) 2020 FLEX Team-EDV Beratung Föllmer GmbH -// Permission is hereby granted, free of charge, to any person obtaining a copy of this -// software and associated documentation files (the "Software"), to deal in the Software -// without restriction, including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons -// to whom the Software is furnished to do so, subject to the following conditions: -// The above copyright notice and this permission notice shall be included in all copies or -// substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -#import "FLEXBlockDescription.h" -#import "FLEXRuntimeUtility.h" - -struct block_object { - void *isa; - int flags; - int reserved; - void (*invoke)(void *, ...); - struct block_descriptor { - unsigned long int reserved; // NULL - unsigned long int size; // sizeof(struct Block_literal_1) - // optional helper functions - void (*copy_helper)(void *dst, void *src); // IFF (1<<25) - void (*dispose_helper)(void *src); // IFF (1<<25) - // required ABI.2010.3.16 - const char *signature; // IFF (1<<30) - } *descriptor; - // imported variables -}; - -@implementation FLEXBlockDescription - -+ (instancetype)describing:(id)block { - return [[self alloc] initWithObjcBlock:block]; -} - -- (id)initWithObjcBlock:(id)block { - self = [super init]; - if (self) { - _block = block; - - struct block_object *blockRef = (__bridge struct block_object *)block; - _flags = blockRef->flags; - _size = blockRef->descriptor->size; - - if (_flags & FLEXBlockOptionHasSignature) { - void *signatureLocation = blockRef->descriptor; - signatureLocation += sizeof(unsigned long int); - signatureLocation += sizeof(unsigned long int); - - if (_flags & FLEXBlockOptionHasCopyDispose) { - signatureLocation += sizeof(void(*)(void *dst, void *src)); - signatureLocation += sizeof(void (*)(void *src)); - } - - const char *signature = (*(const char **)signatureLocation); - _signatureString = @(signature); - - @try { - _signature = [NSMethodSignature signatureWithObjCTypes:signature]; - } @catch (NSException *exception) { } - } - - NSMutableString *summary = [NSMutableString stringWithFormat: - @"Type signature: %@\nSize: %@\nIs global: %@\nHas constructor: %@\nIs stret: %@", - self.signatureString ?: @"nil", @(self.size), - @((BOOL)(_flags & FLEXBlockOptionIsGlobal)), - @((BOOL)(_flags & FLEXBlockOptionHasCtor)), - @((BOOL)(_flags & FLEXBlockOptionHasStret)) - ]; - - if (!self.signature) { - [summary appendFormat:@"\nNumber of arguments: %@", @(self.signature.numberOfArguments)]; - } - - _summary = summary.copy; - _sourceDeclaration = [self buildLikelyDeclaration]; - } - - return self; -} - -- (BOOL)isCompatibleForBlockSwizzlingWithMethodSignature:(NSMethodSignature *)methodSignature { - if (!self.signature) { - return NO; - } - - if (self.signature.numberOfArguments != methodSignature.numberOfArguments + 1) { - return NO; - } - - if (strcmp(self.signature.methodReturnType, methodSignature.methodReturnType) != 0) { - return NO; - } - - for (int i = 0; i < methodSignature.numberOfArguments; i++) { - if (i == 1) { - // SEL in method, IMP in block - if (strcmp([methodSignature getArgumentTypeAtIndex:i], ":") != 0) { - return NO; - } - - if (strcmp([self.signature getArgumentTypeAtIndex:i + 1], "^?") != 0) { - return NO; - } - } else { - if (strcmp([self.signature getArgumentTypeAtIndex:i], [self.signature getArgumentTypeAtIndex:i + 1]) != 0) { - return NO; - } - } - } - - return YES; -} - -- (NSString *)buildLikelyDeclaration { - NSMethodSignature *signature = self.signature; - NSUInteger numberOfArguments = signature.numberOfArguments; - const char *returnType = signature.methodReturnType; - - // Return type - NSMutableString *decl = [NSMutableString stringWithString:@"^"]; - if (returnType[0] != FLEXTypeEncodingVoid) { - [decl appendString:[FLEXRuntimeUtility readableTypeForEncoding:@(returnType)]]; - [decl appendString:@" "]; - } - - // Arguments - if (numberOfArguments) { - [decl appendString:@"("]; - for (NSUInteger i = 1; i < numberOfArguments; i++) { - const char *argType = [self.signature getArgumentTypeAtIndex:i] ?: "?"; - NSString *readableArgType = [FLEXRuntimeUtility readableTypeForEncoding:@(argType)]; - [decl appendFormat:@"%@ arg%@, ", readableArgType, @(i)]; - } - - [decl deleteCharactersInRange:NSMakeRange(decl.length-2, 2)]; - [decl appendString:@")"]; - } - - return decl.copy; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.h deleted file mode 100644 index f6d84413..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.h +++ /dev/null @@ -1,80 +0,0 @@ -// -// FLEXClassBuilder.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/3/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -@class FLEXIvarBuilder, FLEXMethodBase, FLEXProperty, FLEXProtocol; - - -#pragma mark FLEXClassBuilder -@interface FLEXClassBuilder : NSObject - -@property (nonatomic, readonly) Class workingClass; - -/// Begins constructing a class with the given name. -/// -/// This new class will implicitly inherits from \c NSObject with \c 0 extra bytes. -/// Classes created this way must be registered with \c -registerClass before being used. -+ (instancetype)allocateClass:(NSString *)name; -/// Begins constructing a class with the given name and superclass. -/// @discussion Calls \c -allocateClass:superclass:extraBytes: with \c 0 extra bytes. -/// Classes created this way must be registered with \c -registerClass before being used. -+ (instancetype)allocateClass:(NSString *)name superclass:(Class)superclass; -/// Begins constructing a new class object with the given name and superclass. -/// @discussion Pass \c nil to \e superclass to create a new root class. -/// Classes created this way must be registered with \c -registerClass before being used. -+ (instancetype)allocateClass:(NSString *)name superclass:(Class)superclass extraBytes:(size_t)bytes; -/// Begins constructing a new root class object with the given name and \c 0 extra bytes. -/// @discussion Classes created this way must be registered with \c -registerClass before being used. -+ (instancetype)allocateRootClass:(NSString *)name; -/// Use this to modify existing classes. @warning You cannot add instance variables to existing classes. -+ (instancetype)builderForClass:(Class)cls; - -/// @return Any methods that failed to be added. -- (NSArray *)addMethods:(NSArray *)methods; -/// @return Any properties that failed to be added. -- (NSArray *)addProperties:(NSArray *)properties; -/// @return Any protocols that failed to be added. -- (NSArray *)addProtocols:(NSArray *)protocols; -/// @warning Adding Ivars to existing classes is not supported and will always fail. -- (NSArray *)addIvars:(NSArray *)ivars; - -/// Finalizes construction of a new class. -/// @discussion Once a class is registered, instance variables cannot be added. -/// @note Raises an exception if called on a previously registered class. -- (Class)registerClass; -/// Uses \c objc_lookupClass to determine if the working class is registered. -@property (nonatomic, readonly) BOOL isRegistered; - -@end - - -#pragma mark FLEXIvarBuilder -@interface FLEXIvarBuilder : NSObject - -/// Consider using the \c FLEXIvarBuilderWithNameAndType() macro below. -/// @param name The name of the Ivar, such as \c \@"_value". -/// @param size The size of the Ivar. Usually \c sizeof(type). For objects, this is \c sizeof(id). -/// @param alignment The alignment of the Ivar. Usually \c log2(sizeof(type)). -/// @param encoding The type encoding of the Ivar. For objects, this is \c \@(\@encode(id)), and for others it is \c \@(\@encode(type)). -+ (instancetype)name:(NSString *)name size:(size_t)size alignment:(uint8_t)alignment typeEncoding:(NSString *)encoding; - -@property (nonatomic, readonly) NSString *name; -@property (nonatomic, readonly) NSString *encoding; -@property (nonatomic, readonly) size_t size; -@property (nonatomic, readonly) uint8_t alignment; - -@end - - -#define FLEXIvarBuilderWithNameAndType(nameString, type) [FLEXIvarBuilder \ - name:nameString \ - size:sizeof(type) \ - alignment:log2(sizeof(type)) \ - typeEncoding:@(@encode(type)) \ -] diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.m deleted file mode 100644 index f7103347..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXClassBuilder.m +++ /dev/null @@ -1,168 +0,0 @@ -// -// FLEXClassBuilder.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/3/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXClassBuilder.h" -#import "FLEXProperty.h" -#import "FLEXMethodBase.h" -#import "FLEXProtocol.h" -#import - - -#pragma mark FLEXClassBuilder - -@interface FLEXClassBuilder () -@property (nonatomic) NSString *name; -@end - -@implementation FLEXClassBuilder - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -#pragma mark Initializers -+ (instancetype)allocateClass:(NSString *)name { - return [self allocateClass:name superclass:NSObject.class]; -} - -+ (instancetype)allocateClass:(NSString *)name superclass:(Class)superclass { - return [self allocateClass:name superclass:superclass extraBytes:0]; -} - -+ (instancetype)allocateClass:(NSString *)name superclass:(Class)superclass extraBytes:(size_t)bytes { - NSParameterAssert(name); - return [[self alloc] initWithClass:objc_allocateClassPair(superclass, name.UTF8String, bytes)]; -} - -+ (instancetype)allocateRootClass:(NSString *)name { - NSParameterAssert(name); - return [[self alloc] initWithClass:objc_allocateClassPair(Nil, name.UTF8String, 0)]; -} - -+ (instancetype)builderForClass:(Class)cls { - return [[self alloc] initWithClass:cls]; -} - -- (id)initWithClass:(Class)cls { - NSParameterAssert(cls); - - self = [super init]; - if (self) { - _workingClass = cls; - _name = NSStringFromClass(_workingClass); - } - - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"<%@ name=%@, registered=%d>", - NSStringFromClass(self.class), self.name, self.isRegistered]; -} - -#pragma mark Building -- (NSArray *)addMethods:(NSArray *)methods { - NSParameterAssert(methods.count); - - NSMutableArray *failed = [NSMutableArray new]; - for (FLEXMethodBase *m in methods) { - if (!class_addMethod(self.workingClass, m.selector, m.implementation, m.typeEncoding.UTF8String)) { - [failed addObject:m]; - } - } - - return failed; -} - -- (NSArray *)addProperties:(NSArray *)properties { - NSParameterAssert(properties.count); - - NSMutableArray *failed = [NSMutableArray new]; - for (FLEXProperty *p in properties) { - unsigned int pcount; - objc_property_attribute_t *attributes = [p copyAttributesList:&pcount]; - if (!class_addProperty(self.workingClass, p.name.UTF8String, attributes, pcount)) { - [failed addObject:p]; - } - free(attributes); - } - - return failed; -} - -- (NSArray *)addProtocols:(NSArray *)protocols { - NSParameterAssert(protocols.count); - - NSMutableArray *failed = [NSMutableArray new]; - for (FLEXProtocol *p in protocols) { - if (!class_addProtocol(self.workingClass, p.objc_protocol)) { - [failed addObject:p]; - } - } - - return failed; -} - -- (NSArray *)addIvars:(NSArray *)ivars { - NSParameterAssert(ivars.count); - - NSMutableArray *failed = [NSMutableArray new]; - for (FLEXIvarBuilder *ivar in ivars) { - if (!class_addIvar(self.workingClass, ivar.name.UTF8String, ivar.size, ivar.alignment, ivar.encoding.UTF8String)) { - [failed addObject:ivar]; - } - } - - return failed; -} - -- (Class)registerClass { - if (self.isRegistered) { - [NSException raise:NSInternalInconsistencyException format:@"Class is already registered"]; - } - - objc_registerClassPair(self.workingClass); - return self.workingClass; -} - -- (BOOL)isRegistered { - return objc_lookUpClass(self.name.UTF8String) != nil; -} - -@end - - -#pragma mark FLEXIvarBuilder - -@implementation FLEXIvarBuilder - -+ (instancetype)name:(NSString *)name size:(size_t)size alignment:(uint8_t)alignment typeEncoding:(NSString *)encoding { - return [[self alloc] initWithName:name size:size alignment:alignment typeEncoding:encoding]; -} - -- (id)initWithName:(NSString *)name size:(size_t)size alignment:(uint8_t)alignment typeEncoding:(NSString *)encoding { - NSParameterAssert(name); NSParameterAssert(encoding); - NSParameterAssert(size > 0); NSParameterAssert(alignment > 0); - - self = [super init]; - if (self) { - _name = name; - _encoding = encoding; - _size = size; - _alignment = alignment; - } - - return self; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h deleted file mode 100644 index db4aa97a..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// FLEXIvar.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLEXIvar : NSObject - -+ (instancetype)ivar:(Ivar)ivar; -+ (instancetype)named:(NSString *)name onClass:(Class)cls; - -/// The underlying \c Ivar data structure. -@property (nonatomic, readonly) Ivar objc_ivar; - -/// The name of the instance variable. -@property (nonatomic, readonly) NSString *name; -/// The type of the instance variable. -@property (nonatomic, readonly) FLEXTypeEncoding type; -/// The type encoding string of the instance variable. -@property (nonatomic, readonly) NSString *typeEncoding; -/// The offset of the instance variable. -@property (nonatomic, readonly) NSInteger offset; -/// The size of the instance variable. 0 if unknown. -@property (nonatomic, readonly) NSUInteger size; -/// Describes the type encoding, size, offset, and objc_ivar -@property (nonatomic, readonly) NSString *details; -/// The full path of the image that contains this ivar definition, -/// or \c nil if this ivar was probably defined at runtime. -@property (nonatomic, readonly, nullable) NSString *imagePath; - -/// For internal use -@property (nonatomic) id tag; - -- (nullable id)getValue:(id)target; -- (void)setValue:(nullable id)value onObject:(id)target; - -/// Calls into -getValue: and passes that value into -/// -[FLEXRuntimeUtility potentiallyUnwrapBoxedPointer:type:] -/// and returns the result -- (nullable id)getPotentiallyUnboxedValue:(id)target; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.m deleted file mode 100644 index a589036a..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXIvar.m +++ /dev/null @@ -1,158 +0,0 @@ -// -// FLEXIvar.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXIvar.h" -#import "FLEXRuntimeUtility.h" -#import "FLEXRuntimeSafety.h" -#import "FLEXTypeEncodingParser.h" -#import "NSString+FLEX.h" -#include "FLEXObjcInternal.h" -#include - -@interface FLEXIvar () { - NSString *_flex_description; -} -@end - -@implementation FLEXIvar - -#pragma mark Initializers - -+ (instancetype)ivar:(Ivar)ivar { - return [[self alloc] initWithIvar:ivar]; -} - -+ (instancetype)named:(NSString *)name onClass:(Class)cls { - Ivar _Nullable ivar = class_getInstanceVariable(cls, name.UTF8String); - NSAssert(ivar, @"Cannot find ivar with name %@ on class %@", name, cls); - return [self ivar:ivar]; -} - -- (id)initWithIvar:(Ivar)ivar { - NSParameterAssert(ivar); - - self = [super init]; - if (self) { - _objc_ivar = ivar; - [self examine]; - } - - return self; -} - -#pragma mark Other - -- (NSString *)description { - if (!_flex_description) { - NSString *readableType = [FLEXRuntimeUtility readableTypeForEncoding:self.typeEncoding]; - _flex_description = [FLEXRuntimeUtility appendName:self.name toType:readableType]; - } - - return _flex_description; -} - -- (NSString *)debugDescription { - return [NSString stringWithFormat:@"<%@ name=%@, encoding=%@, offset=%ld>", - NSStringFromClass(self.class), self.name, self.typeEncoding, (long)self.offset]; -} - -- (void)examine { - _name = @(ivar_getName(self.objc_ivar) ?: "(nil)"); - _offset = ivar_getOffset(self.objc_ivar); - _typeEncoding = @(ivar_getTypeEncoding(self.objc_ivar) ?: ""); - - NSString *typeForDetails = _typeEncoding; - NSString *sizeForDetails = nil; - if (_typeEncoding.length) { - _type = (FLEXTypeEncoding)[_typeEncoding characterAtIndex:0]; - FLEXGetSizeAndAlignment(_typeEncoding.UTF8String, &_size, nil); - sizeForDetails = [@(_size).stringValue stringByAppendingString:@" bytes"]; - } else { - _type = FLEXTypeEncodingNull; - typeForDetails = @"no type info"; - sizeForDetails = @"unknown size"; - } - - Dl_info exeInfo; - if (dladdr(_objc_ivar, &exeInfo)) { - _imagePath = exeInfo.dli_fname ? @(exeInfo.dli_fname) : nil; - } - - _details = [NSString stringWithFormat: - @"%@, offset %@ — %@", - sizeForDetails, @(_offset), typeForDetails - ]; -} - -- (id)getValue:(id)target { - id value = nil; - if (!FLEXIvarIsSafe(_objc_ivar) || - _type == FLEXTypeEncodingNull || - FLEXPointerIsTaggedPointer(target)) { - return nil; - } - -#ifdef __arm64__ - // See http://www.sealiesoftware.com/blog/archive/2013/09/24/objc_explain_Non-pointer_isa.html - if (self.type == FLEXTypeEncodingObjcClass && [self.name isEqualToString:@"isa"]) { - value = object_getClass(target); - } else -#endif - if (self.type == FLEXTypeEncodingObjcObject || self.type == FLEXTypeEncodingObjcClass) { - value = object_getIvar(target, self.objc_ivar); - } else { - void *pointer = (__bridge void *)target + self.offset; - value = [FLEXRuntimeUtility - valueForPrimitivePointer:pointer - objCType:self.typeEncoding.UTF8String - ]; - } - - return value; -} - -- (void)setValue:(id)value onObject:(id)target { - const char *typeEncodingCString = self.typeEncoding.UTF8String; - if (self.type == FLEXTypeEncodingObjcObject) { - object_setIvar(target, self.objc_ivar, value); - } else if ([value isKindOfClass:[NSValue class]]) { - // Primitive - unbox the NSValue. - NSValue *valueValue = (NSValue *)value; - - // Make sure that the box contained the correct type. - NSAssert( - strcmp(valueValue.objCType, typeEncodingCString) == 0, - @"Type encoding mismatch (value: %s; ivar: %s) in setting ivar named: %@ on object: %@", - valueValue.objCType, typeEncodingCString, self.name, target - ); - - NSUInteger bufferSize = 0; - if (FLEXGetSizeAndAlignment(typeEncodingCString, &bufferSize, NULL)) { - void *buffer = calloc(bufferSize, 1); - [valueValue getValue:buffer]; - void *pointer = (__bridge void *)target + self.offset; - memcpy(pointer, buffer, bufferSize); - free(buffer); - } - } -} - -- (id)getPotentiallyUnboxedValue:(id)target { - NSString *type = self.typeEncoding; - if (type.flex_typeIsNonObjcPointer && type.flex_pointeeType != FLEXTypeEncodingVoid) { - return [self getValue:target]; - } - - return [FLEXRuntimeUtility - potentiallyUnwrapBoxedPointer:[self getValue:target] - type:type.UTF8String - ]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h deleted file mode 100644 index 25650534..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.h +++ /dev/null @@ -1,96 +0,0 @@ -// -// FLEXMethod.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" -#import "FLEXMethodBase.h" - -NS_ASSUME_NONNULL_BEGIN - -/// A class representing a concrete method which already exists in a class. -/// This class contains helper methods for swizzling or invoking the method. -/// -/// Any of the initializers will return nil if the type encoding -/// of the method is unsupported by `NSMethodSignature`. In general, -/// any method whose return type or parameters involve a struct with -/// bitfields or arrays is unsupported. -/// -/// I do not remember why I didn't include \c signature in the base class -/// when I originally wrote this, but I probably had a good reason. We can -/// always go back and move it to \c FLEXMethodBase if we find we need to. -@interface FLEXMethod : FLEXMethodBase - -/// Defaults to instance method -+ (nullable instancetype)method:(Method)method; -+ (nullable instancetype)method:(Method)method isInstanceMethod:(BOOL)isInstanceMethod; - -/// Constructs an \c FLEXMethod for the given method on the given class. -/// @param cls the class, or metaclass if this is a class method -/// @return The newly constructed \c FLEXMethod object, or \c nil if the -/// specified class or its superclasses do not contain a method with the specified selector. -+ (nullable instancetype)selector:(SEL)selector class:(Class)cls; -/// Constructs an \c FLEXMethod for the given method on the given class, -/// only if the given class itself defines or overrides the desired method. -/// @param cls the class, or metaclass if this is a class method -/// @return The newly constructed \c FLEXMethod object, or \c nil \e if the -/// specified class does not define or override, or if the specified class -/// or its superclasses do not contain, a method with the specified selector. -+ (nullable instancetype)selector:(SEL)selector implementedInClass:(Class)cls; - -@property (nonatomic, readonly) Method objc_method; -/// The implementation of the method. -/// @discussion Setting \c implementation will change the implementation of this method -/// for the entire class which implements said method. It will also not modify the selector of said method. -@property (nonatomic ) IMP implementation; -/// Whether the method is an instance method or not. -@property (nonatomic, readonly) BOOL isInstanceMethod; -/// The number of arguments to the method. -@property (nonatomic, readonly) NSUInteger numberOfArguments; -/// The \c NSMethodSignature object corresponding to the method's type encoding. -@property (nonatomic, readonly) NSMethodSignature *signature; -/// Same as \e typeEncoding but with parameter sizes up front and offsets after the types. -@property (nonatomic, readonly) NSString *signatureString; -/// The return type of the method. -@property (nonatomic, readonly) FLEXTypeEncoding *returnType; -/// The return size of the method. -@property (nonatomic, readonly) NSUInteger returnSize; -/// The full path of the image that contains this method definition, -/// or \c nil if this ivar was probably defined at runtime. -@property (nonatomic, readonly) NSString *imagePath; - -/// Like @code - (void)foo:(int)bar @endcode -@property (nonatomic, readonly) NSString *description; -/// Like @code -[Class foo:] @endcode -- (NSString *)debugNameGivenClassName:(NSString *)name; - -/// Swizzles the recieving method with the given method. -- (void)swapImplementations:(FLEXMethod *)method; - -#define FLEXMagicNumber 0xdeadbeef -#define FLEXArg(expr) FLEXMagicNumber,/// @encode(__typeof__(expr)), (__typeof__(expr) []){ expr } - -/// Sends a message to \e target, and returns it's value, or \c nil if not applicable. -/// @discussion You may send any message with this method. Primitive return values will be wrapped -/// in instances of \c NSNumber and \c NSValue. \c void and bitfield returning methods return \c nil. -/// \c SEL return types are converted to strings using \c NSStringFromSelector. -/// @return The object returned by this method, or an instance of \c NSValue or \c NSNumber containing -/// the primitive return type, or a string for \c SEL return types. -- (id)sendMessage:(id)target, ...; -/// Used internally by \c sendMessage:target,. Pass \c NULL to the first parameter for void methods. -- (void)getReturnValue:(void *)retPtr forMessageSend:(id)target, ...; - -@end - - -@interface FLEXMethod (Comparison) - -- (NSComparisonResult)compare:(FLEXMethod *)method; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.m deleted file mode 100644 index f8c3b822..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethod.m +++ /dev/null @@ -1,430 +0,0 @@ -// -// FLEXMethod.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMethod.h" -#import "FLEXMirror.h" -#import "FLEXTypeEncodingParser.h" -#import "FLEXRuntimeUtility.h" -#include - -@implementation FLEXMethod -@synthesize imagePath = _imagePath; -@dynamic implementation; - -+ (instancetype)buildMethodNamed:(NSString *)name withTypes:(NSString *)typeEncoding implementation:(IMP)implementation { - [NSException raise:NSInternalInconsistencyException format:@"Class instance should not be created with +buildMethodNamed:withTypes:implementation"]; return nil; -} - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -#pragma mark Initializers - -+ (instancetype)method:(Method)method { - return [[self alloc] initWithMethod:method isInstanceMethod:YES]; -} - -+ (instancetype)method:(Method)method isInstanceMethod:(BOOL)isInstanceMethod { - return [[self alloc] initWithMethod:method isInstanceMethod:isInstanceMethod]; -} - -+ (instancetype)selector:(SEL)selector class:(Class)cls { - BOOL instance = !class_isMetaClass(cls); - // class_getInstanceMethod will return an instance method if not given - // not given a metaclass, or a class method if given a metaclass, but - // this isn't documented so we just want to be safe here. - Method m = instance ? class_getInstanceMethod(cls, selector) : class_getClassMethod(cls, selector); - if (m == NULL) return nil; - - return [self method:m isInstanceMethod:instance]; -} - -+ (instancetype)selector:(SEL)selector implementedInClass:(Class)cls { - if (![cls superclass]) { return [self selector:selector class:cls]; } - - BOOL unique = [cls methodForSelector:selector] != [[cls superclass] methodForSelector:selector]; - - if (unique) { - return [self selector:selector class:cls]; - } - - return nil; -} - -- (id)initWithMethod:(Method)method isInstanceMethod:(BOOL)isInstanceMethod { - NSParameterAssert(method); - - self = [super init]; - if (self) { - _objc_method = method; - _isInstanceMethod = isInstanceMethod; - _signatureString = @(method_getTypeEncoding(method) ?: "?@:"); - - NSString *cleanSig = nil; - if ([FLEXTypeEncodingParser methodTypeEncodingSupported:_signatureString cleaned:&cleanSig]) { - _signature = [NSMethodSignature signatureWithObjCTypes:cleanSig.UTF8String]; - } - - [self examine]; - } - - return self; -} - - -#pragma mark Other - -- (NSString *)description { - if (!_flex_description) { - _flex_description = [self prettyName]; - } - - return _flex_description; -} - -- (NSString *)debugNameGivenClassName:(NSString *)name { - NSMutableString *string = [NSMutableString stringWithString:_isInstanceMethod ? @"-[" : @"+["]; - [string appendString:name]; - [string appendString:@" "]; - [string appendString:self.selectorString]; - [string appendString:@"]"]; - return string; -} - -- (NSString *)prettyName { - NSString *methodTypeString = self.isInstanceMethod ? @"-" : @"+"; - NSString *readableReturnType = [FLEXRuntimeUtility readableTypeForEncoding:@(self.signature.methodReturnType ?: "")]; - - NSString *prettyName = [NSString stringWithFormat:@"%@ (%@)", methodTypeString, readableReturnType]; - NSArray *components = [self prettyArgumentComponents]; - - if (components.count) { - return [prettyName stringByAppendingString:[components componentsJoinedByString:@" "]]; - } else { - return [prettyName stringByAppendingString:self.selectorString]; - } -} - -- (NSArray *)prettyArgumentComponents { - // NSMethodSignature can't handle some type encodings - // like ^AI@:ir* which happen to very much exist - if (self.signature.numberOfArguments < self.numberOfArguments) { - return nil; - } - - NSMutableArray *components = [NSMutableArray new]; - - NSArray *selectorComponents = [self.selectorString componentsSeparatedByString:@":"]; - NSUInteger numberOfArguments = self.numberOfArguments; - - for (NSUInteger argIndex = 2; argIndex < numberOfArguments; argIndex++) { - assert(argIndex < self.signature.numberOfArguments); - - const char *argType = [self.signature getArgumentTypeAtIndex:argIndex] ?: "?"; - NSString *readableArgType = [FLEXRuntimeUtility readableTypeForEncoding:@(argType)]; - NSString *prettyComponent = [NSString - stringWithFormat:@"%@:(%@) ", - selectorComponents[argIndex - 2], - readableArgType - ]; - - [components addObject:prettyComponent]; - } - - return components; -} - -- (NSString *)debugDescription { - return [NSString stringWithFormat:@"<%@ selector=%@, signature=%@>", - NSStringFromClass(self.class), self.selectorString, self.signatureString]; -} - -- (void)examine { - _implementation = method_getImplementation(_objc_method); - _selector = method_getName(_objc_method); - _numberOfArguments = method_getNumberOfArguments(_objc_method); - _name = NSStringFromSelector(_selector); - _returnType = (FLEXTypeEncoding *)_signature.methodReturnType ?: ""; - _returnSize = _signature.methodReturnLength; -} - -#pragma mark Public - -- (void)setImplementation:(IMP)implementation { - NSParameterAssert(implementation); - method_setImplementation(self.objc_method, implementation); - [self examine]; -} - -- (NSString *)typeEncoding { - if (!_typeEncoding) { - _typeEncoding = [_signatureString - stringByReplacingOccurrencesOfString:@"[0-9]" - withString:@"" - options:NSRegularExpressionSearch - range:NSMakeRange(0, _signatureString.length) - ]; - } - - return _typeEncoding; -} - -- (NSString *)imagePath { - if (!_imagePath) { - Dl_info exeInfo; - if (dladdr(_implementation, &exeInfo)) { - _imagePath = exeInfo.dli_fname ? @(exeInfo.dli_fname) : @""; - } - } - - return _imagePath; -} - -#pragma mark Misc - -- (void)swapImplementations:(FLEXMethod *)method { - method_exchangeImplementations(self.objc_method, method.objc_method); - [self examine]; - [method examine]; -} - -// Some code borrowed from MAObjcRuntime, by Mike Ash. -- (id)sendMessage:(id)target, ... { - id ret = nil; - va_list args; - va_start(args, target); - - switch (self.returnType[0]) { - case FLEXTypeEncodingUnknown: { - [self getReturnValue:NULL forMessageSend:target arguments:args]; - break; - } - case FLEXTypeEncodingChar: { - char val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingInt: { - int val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingShort: { - short val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingLong: { - long val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingLongLong: { - long long val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingUnsignedChar: { - unsigned char val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingUnsignedInt: { - unsigned int val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingUnsignedShort: { - unsigned short val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingUnsignedLong: { - unsigned long val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingUnsignedLongLong: { - unsigned long long val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingFloat: { - float val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingDouble: { - double val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingLongDouble: { - long double val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = [NSValue value:&val withObjCType:self.returnType]; - break; - } - case FLEXTypeEncodingCBool: { - bool val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingVoid: { - [self getReturnValue:NULL forMessageSend:target arguments:args]; - return nil; - break; - } - case FLEXTypeEncodingCString: { - char *val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = @(val); - break; - } - case FLEXTypeEncodingObjcObject: { - id val = nil; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = val; - break; - } - case FLEXTypeEncodingObjcClass: { - Class val = Nil; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = val; - break; - } - case FLEXTypeEncodingSelector: { - SEL val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = NSStringFromSelector(val); - break; - } - case FLEXTypeEncodingArrayBegin: { - void *val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = [NSValue valueWithBytes:val objCType:self.signature.methodReturnType]; - break; - } - case FLEXTypeEncodingUnionBegin: - case FLEXTypeEncodingStructBegin: { - if (self.signature.methodReturnLength) { - void * val = malloc(self.signature.methodReturnLength); - [self getReturnValue:val forMessageSend:target arguments:args]; - ret = [NSValue valueWithBytes:val objCType:self.signature.methodReturnType]; - } else { - [self getReturnValue:NULL forMessageSend:target arguments:args]; - } - break; - } - case FLEXTypeEncodingBitField: { - [self getReturnValue:NULL forMessageSend:target arguments:args]; - break; - } - case FLEXTypeEncodingPointer: { - void * val = 0; - [self getReturnValue:&val forMessageSend:target arguments:args]; - ret = [NSValue valueWithPointer:val]; - break; - } - - default: { - [NSException raise:NSInvalidArgumentException - format:@"Unsupported type encoding: %s", (char *)self.returnType]; - } - } - - va_end(args); - return ret; -} - -// Code borrowed from MAObjcRuntime, by Mike Ash. -- (void)getReturnValue:(void *)retPtr forMessageSend:(id)target, ... { - va_list args; - va_start(args, target); - [self getReturnValue:retPtr forMessageSend:target arguments:args]; - va_end(args); -} - -// Code borrowed from MAObjcRuntime, by Mike Ash. -- (void)getReturnValue:(void *)retPtr forMessageSend:(id)target arguments:(va_list)args { - if (!_signature) { - return; - } - - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:_signature]; - NSUInteger argumentCount = _signature.numberOfArguments; - - invocation.target = target; - - for (NSUInteger i = 2; i < argumentCount; i++) { - int cookie = va_arg(args, int); - if (cookie != FLEXMagicNumber) { - [NSException - raise:NSInternalInconsistencyException - format:@"%s: incorrect magic cookie %08x; make sure you didn't forget " - "any arguments and that all arguments are wrapped in FLEXArg().", __func__, cookie - ]; - } - const char *typeString = va_arg(args, char *); - void *argPointer = va_arg(args, void *); - - NSUInteger inSize, sigSize; - NSGetSizeAndAlignment(typeString, &inSize, NULL); - NSGetSizeAndAlignment([_signature getArgumentTypeAtIndex:i], &sigSize, NULL); - - if (inSize != sigSize) { - [NSException - raise:NSInternalInconsistencyException - format:@"%s:size mismatch between passed-in argument and " - "required argument; in type:%s (%lu) requested:%s (%lu)", - __func__, typeString, (long)inSize, [_signature getArgumentTypeAtIndex:i], (long)sigSize - ]; - } - - [invocation setArgument:argPointer atIndex:i]; - } - - // Hack to make NSInvocation invoke the desired implementation - IMP imp = [invocation methodForSelector:NSSelectorFromString(@"invokeUsingIMP:")]; - void (*invokeWithIMP)(id, SEL, IMP) = (void *)imp; - invokeWithIMP(invocation, 0, _implementation); - - if (_signature.methodReturnLength && retPtr) { - [invocation getReturnValue:retPtr]; - } -} - -@end - - -@implementation FLEXMethod (Comparison) - -- (NSComparisonResult)compare:(FLEXMethod *)method { - return [self.selectorString compare:method.selectorString]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.h deleted file mode 100644 index 177ec1d4..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// FLEXMethodBase.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - - -/// A base class for methods which encompasses those that may not -/// have been added to a class yet. Useful on it's own for adding -/// methods to a class, or building a new class from the ground up. -@interface FLEXMethodBase : NSObject { -@protected - SEL _selector; - NSString *_name; - NSString *_typeEncoding; - IMP _implementation; - - NSString *_flex_description; -} - -/// Constructs and returns an \c FLEXSimpleMethod instance with the given name, type encoding, and implementation. -+ (instancetype)buildMethodNamed:(NSString *)name withTypes:(NSString *)typeEncoding implementation:(IMP)implementation; - -/// The selector of the method. -@property (nonatomic, readonly) SEL selector; -/// The selector string of the method. -@property (nonatomic, readonly) NSString *selectorString; -/// Same as selectorString. -@property (nonatomic, readonly) NSString *name; -/// The type encoding of the method. -@property (nonatomic, readonly) NSString *typeEncoding; -/// The implementation of the method. -@property (nonatomic, readonly) IMP implementation; - -/// For internal use -@property (nonatomic) id tag; - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.m deleted file mode 100644 index a8aeb3fe..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMethodBase.m +++ /dev/null @@ -1,49 +0,0 @@ -// -// FLEXMethodBase.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMethodBase.h" - - -@implementation FLEXMethodBase - -#pragma mark Initializers - -+ (instancetype)buildMethodNamed:(NSString *)name withTypes:(NSString *)typeEncoding implementation:(IMP)implementation { - return [[self alloc] initWithSelector:sel_registerName(name.UTF8String) types:typeEncoding imp:implementation]; -} - -- (id)initWithSelector:(SEL)selector types:(NSString *)types imp:(IMP)imp { - NSParameterAssert(selector); NSParameterAssert(types); NSParameterAssert(imp); - - self = [super init]; - if (self) { - _selector = selector; - _typeEncoding = types; - _implementation = imp; - _name = NSStringFromSelector(self.selector); - } - - return self; -} - -- (NSString *)selectorString { - return _name; -} - -#pragma mark Overrides - -- (NSString *)description { - if (!_flex_description) { - _flex_description = [NSString stringWithFormat:@"%@ '%@'", _name, _typeEncoding]; - } - - return _flex_description; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.h deleted file mode 100644 index 0423b237..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.h +++ /dev/null @@ -1,83 +0,0 @@ -// -// FLEXMirror.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/29/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import -@class FLEXMethod, FLEXProperty, FLEXIvar, FLEXProtocol; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark FLEXMirror Protocol -NS_SWIFT_NAME(FLEXMirrorProtocol) -@protocol FLEXMirror - -/// Swift initializer -- (instancetype)initWithSubject:(id)objectOrClass NS_SWIFT_NAME(init(reflecting:)); - -/// The underlying object or \c Class used to create this \c FLEXMirror instance. -@property (nonatomic, readonly) id value; -/// Whether the reflected thing was a class or a class instance. -@property (nonatomic, readonly) BOOL isClass; -/// The name of the \c Class of the \c value property. -@property (nonatomic, readonly) NSString *className; - -@property (nonatomic, readonly) NSArray *properties; -@property (nonatomic, readonly) NSArray *ivars; -@property (nonatomic, readonly) NSArray *methods; -@property (nonatomic, readonly) NSArray *protocols; - -/// @return A reflection of \c value.superClass. -@property (nonatomic, readonly, nullable) id superMirror NS_SWIFT_NAME(superMirror); - -@end - -#pragma mark FLEXMirror Class -@interface FLEXMirror : NSObject - -/// Reflects an instance of an object or \c Class. -/// @discussion \c FLEXMirror will immediately gather all useful information. Consider using the -/// \c NSObject categories provided if your code will only use a few pieces of information, -/// or if your code needs to run faster. -/// -/// If you reflect an instance of a class then \c methods and \c properties will be populated -/// with instance methods and properties. If you reflect a class itself, then \c methods -/// and \c properties will be populated with class methods and properties as you'd expect. -/// -/// @param objectOrClass An instance of an objct or a \c Class object. -/// @return An instance of \c FLEXMirror. -+ (instancetype)reflect:(id)objectOrClass; - -@property (nonatomic, readonly) id value; -@property (nonatomic, readonly) BOOL isClass; -@property (nonatomic, readonly) NSString *className; - -@property (nonatomic, readonly) NSArray *properties; -@property (nonatomic, readonly) NSArray *ivars; -@property (nonatomic, readonly) NSArray *methods; -@property (nonatomic, readonly) NSArray *protocols; - -@property (nonatomic, readonly, nullable) FLEXMirror *superMirror NS_SWIFT_NAME(superMirror); - -@end - - -@interface FLEXMirror (ExtendedMirror) - -/// @return The method with the given name, or \c nil if one does not exist. -- (nullable FLEXMethod *)methodNamed:(nullable NSString *)name; -/// @return The property with the given name, or \c nil if one does not exist. -- (nullable FLEXProperty *)propertyNamed:(nullable NSString *)name; -/// @return The instance variable with the given name, or \c nil if one does not exist. -- (nullable FLEXIvar *)ivarNamed:(nullable NSString *)name; -/// @return The protocol with the given name, or \c nil if one does not exist. -- (nullable FLEXProtocol *)protocolNamed:(nullable NSString *)name; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.m deleted file mode 100644 index 55c52ca6..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXMirror.m +++ /dev/null @@ -1,136 +0,0 @@ -// -// FLEXMirror.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/29/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXMirror.h" -#import "FLEXProperty.h" -#import "FLEXMethod.h" -#import "FLEXIvar.h" -#import "FLEXProtocol.h" -#import "FLEXUtility.h" - - -#pragma mark FLEXMirror - -@implementation FLEXMirror - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -#pragma mark Initialization -+ (instancetype)reflect:(id)objectOrClass { - return [[self alloc] initWithSubject:objectOrClass]; -} - -- (id)initWithSubject:(id)objectOrClass { - NSParameterAssert(objectOrClass); - - self = [super init]; - if (self) { - _value = objectOrClass; - [self examine]; - } - - return self; -} - -- (NSString *)description { - NSString *type = self.isClass ? @"metaclass" : @"class"; - return [NSString - stringWithFormat:@"<%@ %@=%@, %lu properties, %lu ivars, %lu methods, %lu protocols>", - NSStringFromClass(self.class), - type, - self.className, - (unsigned long)self.properties.count, - (unsigned long)self.ivars.count, - (unsigned long)self.methods.count, - (unsigned long)self.protocols.count - ]; -} - -- (void)examine { - // cls is a metaclass if self.value is a class - Class cls = object_getClass(self.value); - - unsigned int pcount, mcount, ivcount, pccount; - objc_property_t *objcproperties = class_copyPropertyList(cls, &pcount); - Protocol*__unsafe_unretained *procs = class_copyProtocolList(cls, &pccount); - Method *objcmethods = class_copyMethodList(cls, &mcount); - Ivar *objcivars = class_copyIvarList(cls, &ivcount); - - _className = NSStringFromClass(cls); - _isClass = class_isMetaClass(cls); // or object_isClass(self.value) - - NSMutableArray *properties = [NSMutableArray new]; - for (int i = 0; i < pcount; i++) - [properties addObject:[FLEXProperty property:objcproperties[i]]]; - _properties = properties; - - NSMutableArray *methods = [NSMutableArray new]; - for (int i = 0; i < mcount; i++) - [methods addObject:[FLEXMethod method:objcmethods[i]]]; - _methods = methods; - - NSMutableArray *ivars = [NSMutableArray new]; - for (int i = 0; i < ivcount; i++) - [ivars addObject:[FLEXIvar ivar:objcivars[i]]]; - _ivars = ivars; - - NSMutableArray *protocols = [NSMutableArray new]; - for (int i = 0; i < pccount; i++) - [protocols addObject:[FLEXProtocol protocol:procs[i]]]; - _protocols = protocols; - - // Cleanup - free(objcproperties); - free(objcmethods); - free(objcivars); - free(procs); - procs = NULL; -} - -#pragma mark Misc - -- (FLEXMirror *)superMirror { - return [FLEXMirror reflect:[self.value superclass]]; -} - -@end - - -#pragma mark ExtendedMirror - -@implementation FLEXMirror (ExtendedMirror) - -- (id)filter:(NSArray *)array forName:(NSString *)name { - NSPredicate *filter = [NSPredicate predicateWithFormat:@"%K = %@", @"name", name]; - return [array filteredArrayUsingPredicate:filter].firstObject; -} - -- (FLEXMethod *)methodNamed:(NSString *)name { - return [self filter:self.methods forName:name]; -} - -- (FLEXProperty *)propertyNamed:(NSString *)name { - return [self filter:self.properties forName:name]; -} - -- (FLEXIvar *)ivarNamed:(NSString *)name { - return [self filter:self.ivars forName:name]; -} - -- (FLEXProtocol *)protocolNamed:(NSString *)name { - return [self filter:self.protocols forName:name]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h deleted file mode 100644 index accc539d..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.h +++ /dev/null @@ -1,138 +0,0 @@ -// -// FLEXProperty.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" -@class FLEXPropertyAttributes, FLEXMethodBase; - - -#pragma mark FLEXProperty -@interface FLEXProperty : NSObject - -/// You may use this initializer instead of \c property:onClass: if you don't need -/// to know anything about the uniqueness of this property or where it comes from. -+ (instancetype)property:(objc_property_t)property; -/// This initializer can be used to access additional information -/// in an efficient manner. That information being whether this property -/// is certainly not unique and the name of the binary image which declares it. -/// @param cls the class, or metaclass if this is a class property. -+ (instancetype)property:(objc_property_t)property onClass:(Class)cls; -/// @param cls the class, or metaclass if this is a class property -+ (instancetype)named:(NSString *)name onClass:(Class)cls; -/// Constructs a new property with the given name and attributes. -+ (instancetype)propertyWithName:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes; - -/// \c 0 if the instance was created via \c +propertyWithName:attributes, -/// otherwise this is the first property in \c objc_properties -@property (nonatomic, readonly) objc_property_t objc_property; -@property (nonatomic, readonly) objc_property_t *objc_properties; -@property (nonatomic, readonly) NSInteger objc_propertyCount; -@property (nonatomic, readonly) BOOL isClassProperty; - -/// The name of the property. -@property (nonatomic, readonly) NSString *name; -/// The type of the property. Get the full type from the attributes. -@property (nonatomic, readonly) FLEXTypeEncoding type; -/// The property's attributes. -@property (nonatomic ) FLEXPropertyAttributes *attributes; -/// The (likely) setter, regardless of whether the property is readonly. -/// For example, this might be the custom setter. -@property (nonatomic, readonly) SEL likelySetter; -@property (nonatomic, readonly) NSString *likelySetterString; -/// Not valid unless initialized with the owning class. -@property (nonatomic, readonly) BOOL likelySetterExists; -/// The (likely) getter. For example, this might be the custom getter. -@property (nonatomic, readonly) SEL likelyGetter; -@property (nonatomic, readonly) NSString *likelyGetterString; -/// Not valid unless initialized with the owning class. -@property (nonatomic, readonly) BOOL likelyGetterExists; -/// Always \c nil for class properties. -@property (nonatomic, readonly) NSString *likelyIvarName; -/// Not valid unless initialized with the owning class. -@property (nonatomic, readonly) BOOL likelyIvarExists; - -/// Whether there are certainly multiple definitions of this property, -/// such as in categories in other binary images or something. -/// @return Whether \c objc_property matches the return value of \c class_getProperty, -/// or \c NO if this property was not created with \c property:onClass -@property (nonatomic, readonly) BOOL multiple; -/// @return The bundle of the image that contains this property definition, -/// or \c nil if this property was not created with \c property:onClass or -/// if this property was probably defined at runtime. -@property (nonatomic, readonly) NSString *imageName; -/// The full path of the image that contains this property definition, -/// or \c nil if this property was not created with \c property:onClass or -/// if this property was probably defined at runtime. -@property (nonatomic, readonly) NSString *imagePath; - -/// For internal use -@property (nonatomic) id tag; - -/// @return The value of this property on \c target as given by \c -valueForKey: -/// A source-like description of the property, with all of its attributes. -@property (nonatomic, readonly) NSString *fullDescription; - -/// If this is a class property, you must class the class object. -- (id)getValue:(id)target; -/// Calls into -getValue: and passes that value into -/// -[FLEXRuntimeUtility potentiallyUnwrapBoxedPointer:type:] -/// and returns the result. -/// -/// If this is a class property, you must class the class object. -- (id)getPotentiallyUnboxedValue:(id)target; - -/// Safe to use regardless of how the \c FLEXProperty instance was initialized. -/// -/// This uses \c self.objc_property if it exists, otherwise it uses \c self.attributes -- (objc_property_attribute_t *)copyAttributesList:(unsigned int *)attributesCount; - -/// Replace the attributes of the current property in the given class, -/// using the attributes in \c self.attributes -/// -/// What happens when the property does not exist is undocumented. -- (void)replacePropertyOnClass:(Class)cls; - -#pragma mark Convenience getters and setters -/// @return A getter for the property with the given implementation. -/// @discussion Consider using the \c FLEXPropertyGetter macros. -- (FLEXMethodBase *)getterWithImplementation:(IMP)implementation; -/// @return A setter for the property with the given implementation. -/// @discussion Consider using the \c FLEXPropertySetter macros. -- (FLEXMethodBase *)setterWithImplementation:(IMP)implementation; - -#pragma mark FLEXMethod property getter / setter macros -// Easier than using the above methods yourself in most cases - -/// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and -/// uses the \c FLEXProperty's \c attribute's \c backingIvarName to get the Ivar. -#define FLEXPropertyGetter(FLEXProperty, type) [FLEXProperty \ - getterWithImplementation:imp_implementationWithBlock(^(id self) { \ - return *(type *)[self getIvarAddressByName:FLEXProperty.attributes.backingIvar]; \ - }) \ -]; -/// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and -/// uses the \c FLEXProperty's \c attribute's \c backingIvarName to set the Ivar. -#define FLEXPropertySetter(FLEXProperty, type) [FLEXProperty \ - setterWithImplementation:imp_implementationWithBlock(^(id self, type value) { \ - [self setIvarByName:FLEXProperty.attributes.backingIvar value:&value size:sizeof(type)]; \ - }) \ -]; -/// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and an Ivar name string to get the Ivar. -#define FLEXPropertyGetterWithIvar(FLEXProperty, ivarName, type) [FLEXProperty \ - getterWithImplementation:imp_implementationWithBlock(^(id self) { \ - return *(type *)[self getIvarAddressByName:ivarName]; \ - }) \ -]; -/// Takes a \c FLEXProperty and a type (ie \c NSUInteger or \c id) and an Ivar name string to set the Ivar. -#define FLEXPropertySetterWithIvar(FLEXProperty, ivarName, type) [FLEXProperty \ - setterWithImplementation:imp_implementationWithBlock(^(id self, type value) { \ - [self setIvarByName:ivarName value:&value size:sizeof(type)]; \ - }) \ -]; - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.m deleted file mode 100644 index d5d217fb..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProperty.m +++ /dev/null @@ -1,295 +0,0 @@ -// -// FLEXProperty.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXProperty.h" -#import "FLEXPropertyAttributes.h" -#import "FLEXMethodBase.h" -#import "FLEXRuntimeUtility.h" -#include - - -@interface FLEXProperty () { - NSString *_flex_description; -} -@property (nonatomic ) BOOL uniqueCheckFlag; -@property (nonatomic, readonly) Class cls; -@end - -@implementation FLEXProperty -@synthesize multiple = _multiple; -@synthesize imageName = _imageName; -@synthesize imagePath = _imagePath; - -#pragma mark Initializers - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -+ (instancetype)property:(objc_property_t)property { - return [[self alloc] initWithProperty:property onClass:nil]; -} - -+ (instancetype)property:(objc_property_t)property onClass:(Class)cls { - return [[self alloc] initWithProperty:property onClass:cls]; -} - -+ (instancetype)named:(NSString *)name onClass:(Class)cls { - objc_property_t _Nullable property = class_getProperty(cls, name.UTF8String); - NSAssert(property, @"Cannot find property with name %@ on class %@", name, cls); - return [self property:property onClass:cls]; -} - -+ (instancetype)propertyWithName:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes { - return [[self alloc] initWithName:name attributes:attributes]; -} - -- (id)initWithProperty:(objc_property_t)property onClass:(Class)cls { - NSParameterAssert(property); - - self = [super init]; - if (self) { - _objc_property = property; - _attributes = [FLEXPropertyAttributes attributesForProperty:property]; - _name = @(property_getName(property) ?: "(nil)"); - _cls = cls; - - if (!_attributes) [NSException raise:NSInternalInconsistencyException format:@"Error retrieving property attributes"]; - if (!_name) [NSException raise:NSInternalInconsistencyException format:@"Error retrieving property name"]; - - [self examine]; - } - - return self; -} - -- (id)initWithName:(NSString *)name attributes:(FLEXPropertyAttributes *)attributes { - NSParameterAssert(name); NSParameterAssert(attributes); - - self = [super init]; - if (self) { - _attributes = attributes; - _name = name; - - [self examine]; - } - - return self; -} - -#pragma mark Private - -- (void)examine { - if (self.attributes.typeEncoding.length) { - _type = (FLEXTypeEncoding)[self.attributes.typeEncoding characterAtIndex:0]; - } - - // Return the given selector if the class responds to it - Class cls = _cls; - SEL (^selectorIfValid)(SEL) = ^SEL(SEL sel) { - if (!sel || !cls) return nil; - return [cls instancesRespondToSelector:sel] ? sel : nil; - }; - - SEL customGetter = self.attributes.customGetter; - SEL customSetter = self.attributes.customSetter; - SEL defaultGetter = NSSelectorFromString(self.name); - SEL defaultSetter = NSSelectorFromString([NSString - stringWithFormat:@"set%c%@:", - (char)toupper([self.name characterAtIndex:0]), - [self.name substringFromIndex:1] - ]); - - // Check if the likely getters/setters exist - SEL validGetter = selectorIfValid(customGetter) ?: selectorIfValid(defaultGetter); - SEL validSetter = selectorIfValid(customSetter) ?: selectorIfValid(defaultSetter); - _likelyGetterExists = validGetter != nil; - _likelySetterExists = validSetter != nil; - - // Assign likely getters and setters to the valid one, - // or the default, regardless of whether the default exists - _likelyGetter = validGetter ?: defaultGetter; - _likelySetter = validSetter ?: defaultSetter; - _likelyGetterString = NSStringFromSelector(_likelyGetter); - _likelySetterString = NSStringFromSelector(_likelySetter); - - _isClassProperty = _cls ? class_isMetaClass(_cls) : NO; - - _likelyIvarName = _isClassProperty ? nil : ( - self.attributes.backingIvar ?: [@"_" stringByAppendingString:_name] - ); -} - -#pragma mark Overrides - -- (NSString *)description { - if (!_flex_description) { - NSString *readableType = [FLEXRuntimeUtility readableTypeForEncoding:self.attributes.typeEncoding]; - _flex_description = [FLEXRuntimeUtility appendName:self.name toType:readableType]; - } - - return _flex_description; -} - -- (NSString *)debugDescription { - return [NSString stringWithFormat:@"<%@ name=%@, property=%p, attributes:\n\t%@\n>", - NSStringFromClass(self.class), self.name, self.objc_property, self.attributes]; -} - -#pragma mark Public - -- (objc_property_attribute_t *)copyAttributesList:(unsigned int *)attributesCount { - if (self.objc_property) { - return property_copyAttributeList(self.objc_property, attributesCount); - } else { - return [self.attributes copyAttributesList:attributesCount]; - } -} - -- (void)replacePropertyOnClass:(Class)cls { - class_replaceProperty(cls, self.name.UTF8String, self.attributes.list, (unsigned int)self.attributes.count); -} - -- (void)computeSymbolInfo:(BOOL)forceBundle { - Dl_info exeInfo; - if (dladdr(_objc_property, &exeInfo)) { - _imagePath = exeInfo.dli_fname ? @(exeInfo.dli_fname) : nil; - } - - if ((!_multiple || !_uniqueCheckFlag) && _cls) { - _multiple = _objc_property != class_getProperty(_cls, self.name.UTF8String); - - if (_multiple || forceBundle) { - NSString *path = _imagePath.stringByDeletingLastPathComponent; - _imageName = [NSBundle bundleWithPath:path].executablePath.lastPathComponent; - } - } -} - -- (BOOL)multiple { - [self computeSymbolInfo:NO]; - return _multiple; -} - -- (NSString *)imagePath { - [self computeSymbolInfo:YES]; - return _imagePath; -} - -- (NSString *)imageName { - [self computeSymbolInfo:YES]; - return _imageName; -} - -- (BOOL)likelyIvarExists { - if (_likelyIvarName && _cls) { - return class_getInstanceVariable(_cls, _likelyIvarName.UTF8String) != nil; - } - - return NO; -} - -- (NSString *)fullDescription { - NSMutableArray *attributesStrings = [NSMutableArray new]; - FLEXPropertyAttributes *attributes = self.attributes; - - // Atomicity - if (attributes.isNonatomic) { - [attributesStrings addObject:@"nonatomic"]; - } else { - [attributesStrings addObject:@"atomic"]; - } - - // Storage - if (attributes.isRetained) { - [attributesStrings addObject:@"strong"]; - } else if (attributes.isCopy) { - [attributesStrings addObject:@"copy"]; - } else if (attributes.isWeak) { - [attributesStrings addObject:@"weak"]; - } else { - [attributesStrings addObject:@"assign"]; - } - - // Mutability - if (attributes.isReadOnly) { - [attributesStrings addObject:@"readonly"]; - } else { - [attributesStrings addObject:@"readwrite"]; - } - - // Class or not - if (self.isClassProperty) { - [attributesStrings addObject:@"class"]; - } - - // Custom getter/setter - SEL customGetter = attributes.customGetter; - SEL customSetter = attributes.customSetter; - if (customGetter) { - [attributesStrings addObject:[NSString stringWithFormat:@"getter=%s", sel_getName(customGetter)]]; - } - if (customSetter) { - [attributesStrings addObject:[NSString stringWithFormat:@"setter=%s", sel_getName(customSetter)]]; - } - - NSString *attributesString = [attributesStrings componentsJoinedByString:@", "]; - return [NSString stringWithFormat:@"@property (%@) %@", attributesString, self.description]; -} - -- (id)getValue:(id)target { - if (!target) return nil; - - // We don't care about checking dynamically whether the getter - // _now_ exists on this object. If the getter doesn't exist - // when this property is initialized, it will never call it. - // Just re-create the property object if you need to call it. - if (self.likelyGetterExists) { - BOOL objectIsClass = object_isClass(target); - BOOL instanceAndInstanceProperty = !objectIsClass && !self.isClassProperty; - BOOL classAndClassProperty = objectIsClass && self.isClassProperty; - - if (instanceAndInstanceProperty || classAndClassProperty) { - return [FLEXRuntimeUtility performSelector:self.likelyGetter onObject:target]; - } - } - - return nil; -} - -- (id)getPotentiallyUnboxedValue:(id)target { - if (!target) return nil; - - return [FLEXRuntimeUtility - potentiallyUnwrapBoxedPointer:[self getValue:target] - type:self.attributes.typeEncoding.UTF8String - ]; -} - -#pragma mark Suggested getters and setters - -- (FLEXMethodBase *)getterWithImplementation:(IMP)implementation { - NSString *types = [NSString stringWithFormat:@"%@%s%s", self.attributes.typeEncoding, @encode(id), @encode(SEL)]; - NSString *name = [NSString stringWithFormat:@"%@", self.name]; - FLEXMethodBase *getter = [FLEXMethodBase buildMethodNamed:name withTypes:types implementation:implementation]; - return getter; -} - -- (FLEXMethodBase *)setterWithImplementation:(IMP)implementation { - NSString *types = [NSString stringWithFormat:@"%s%s%s%@", @encode(void), @encode(id), @encode(SEL), self.attributes.typeEncoding]; - NSString *name = [NSString stringWithFormat:@"set%@:", self.name.capitalizedString]; - FLEXMethodBase *setter = [FLEXMethodBase buildMethodNamed:name withTypes:types implementation:implementation]; - return setter; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h deleted file mode 100644 index e5771018..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.h +++ /dev/null @@ -1,110 +0,0 @@ -// -// FLEXPropertyAttributes.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark FLEXPropertyAttributes - -/// See \e FLEXRuntimeUtilitiy.h for valid string tokens. -/// See this link on how to construct a proper attributes string: -/// https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html -@interface FLEXPropertyAttributes : NSObject { -// These are necessary for the mutable subclass to function -@protected - NSUInteger _count; - NSString *_string, *_backingIvar, *_typeEncoding, *_oldTypeEncoding, *_fullDeclaration; - NSDictionary *_dictionary; - objc_property_attribute_t *_list; - SEL _customGetter, _customSetter; - BOOL _isReadOnly, _isCopy, _isRetained, _isNonatomic, _isDynamic, _isWeak, _isGarbageCollectable; -} - -+ (instancetype)attributesForProperty:(objc_property_t)property; -/// @warning Raises an exception if \e attributes is invalid, \c nil, or contains unsupported keys. -+ (instancetype)attributesFromDictionary:(NSDictionary *)attributes; - -/// Copies the attributes list to a buffer you must \c free() yourself. -/// Use \c list instead if you do not need more control over the lifetime of the list. -/// @param attributesCountOut the number of attributes is returned in this parameter. -- (objc_property_attribute_t *)copyAttributesList:(nullable unsigned int *)attributesCountOut; - -/// The number of property attributes. -@property (nonatomic, readonly) NSUInteger count; -/// For use with \c class_replaceProperty and the like. -@property (nonatomic, readonly) objc_property_attribute_t *list; -/// The string value of the property attributes. -@property (nonatomic, readonly) NSString *string; -/// A human-readable version of the property attributes. -@property (nonatomic, readonly) NSString *fullDeclaration; -/// A dictionary of the property attributes. -/// Values are either a string or \c YES. Boolean attributes -/// which are false will not be present in the dictionary. -@property (nonatomic, readonly) NSDictionary *dictionary; - -/// The name of the instance variable backing the property. -@property (nonatomic, readonly, nullable) NSString *backingIvar; -/// The type encoding of the property. -@property (nonatomic, readonly, nullable) NSString *typeEncoding; -/// The \e old type encoding of the property. -@property (nonatomic, readonly, nullable) NSString *oldTypeEncoding; -/// The property's custom getter, if any. -@property (nonatomic, readonly, nullable) SEL customGetter; -/// The property's custom setter, if any. -@property (nonatomic, readonly, nullable) SEL customSetter; -/// The property's custom getter as a string, if any. -@property (nonatomic, readonly, nullable) NSString *customGetterString; -/// The property's custom setter as a string, if any. -@property (nonatomic, readonly, nullable) NSString *customSetterString; - -@property (nonatomic, readonly) BOOL isReadOnly; -@property (nonatomic, readonly) BOOL isCopy; -@property (nonatomic, readonly) BOOL isRetained; -@property (nonatomic, readonly) BOOL isNonatomic; -@property (nonatomic, readonly) BOOL isDynamic; -@property (nonatomic, readonly) BOOL isWeak; -@property (nonatomic, readonly) BOOL isGarbageCollectable; - -@end - - -#pragma mark FLEXPropertyAttributes -@interface FLEXMutablePropertyAttributes : FLEXPropertyAttributes - -/// Creates and returns an empty property attributes object. -+ (instancetype)attributes; - -/// The name of the instance variable backing the property. -@property (nonatomic, nullable) NSString *backingIvar; -/// The type encoding of the property. -@property (nonatomic, nullable) NSString *typeEncoding; -/// The \e old type encoding of the property. -@property (nonatomic, nullable) NSString *oldTypeEncoding; -/// The property's custom getter, if any. -@property (nonatomic, nullable) SEL customGetter; -/// The property's custom setter, if any. -@property (nonatomic, nullable) SEL customSetter; - -@property (nonatomic) BOOL isReadOnly; -@property (nonatomic) BOOL isCopy; -@property (nonatomic) BOOL isRetained; -@property (nonatomic) BOOL isNonatomic; -@property (nonatomic) BOOL isDynamic; -@property (nonatomic) BOOL isWeak; -@property (nonatomic) BOOL isGarbageCollectable; - -/// A more convenient method of setting the \c typeEncoding property. -/// @discussion This will not work for complex types like structs and primitive pointers. -- (void)setTypeEncodingChar:(char)type; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.m deleted file mode 100644 index 88d8f35f..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXPropertyAttributes.m +++ /dev/null @@ -1,376 +0,0 @@ -// -// FLEXPropertyAttributes.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/5/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXPropertyAttributes.h" -#import "FLEXRuntimeUtility.h" -#import "NSString+ObjcRuntime.h" -#import "NSDictionary+ObjcRuntime.h" - - -#pragma mark FLEXPropertyAttributes - -@interface FLEXPropertyAttributes () - -@property (nonatomic) NSString *backingIvar; -@property (nonatomic) NSString *typeEncoding; -@property (nonatomic) NSString *oldTypeEncoding; -@property (nonatomic) SEL customGetter; -@property (nonatomic) SEL customSetter; -@property (nonatomic) BOOL isReadOnly; -@property (nonatomic) BOOL isCopy; -@property (nonatomic) BOOL isRetained; -@property (nonatomic) BOOL isNonatomic; -@property (nonatomic) BOOL isDynamic; -@property (nonatomic) BOOL isWeak; -@property (nonatomic) BOOL isGarbageCollectable; - -- (NSString *)buildFullDeclaration; - -@end - -@implementation FLEXPropertyAttributes -@synthesize list = _list; - -#pragma mark Initializers - -+ (instancetype)attributesForProperty:(objc_property_t)property { - return [self attributesFromDictionary:[NSDictionary attributesDictionaryForProperty:property]]; -} - -+ (instancetype)attributesFromDictionary:(NSDictionary *)attributes { - return [[self alloc] initWithAttributesDictionary:attributes]; -} - -- (id)initWithAttributesDictionary:(NSDictionary *)attributes { - NSParameterAssert(attributes); - - self = [super init]; - if (self) { - _dictionary = attributes; - _string = attributes.propertyAttributesString; - _count = attributes.count; - _typeEncoding = attributes[kFLEXPropertyAttributeKeyTypeEncoding]; - _backingIvar = attributes[kFLEXPropertyAttributeKeyBackingIvarName]; - _oldTypeEncoding = attributes[kFLEXPropertyAttributeKeyOldStyleTypeEncoding]; - _customGetterString = attributes[kFLEXPropertyAttributeKeyCustomGetter]; - _customSetterString = attributes[kFLEXPropertyAttributeKeyCustomSetter]; - _customGetter = NSSelectorFromString(_customGetterString); - _customSetter = NSSelectorFromString(_customSetterString); - _isReadOnly = attributes[kFLEXPropertyAttributeKeyReadOnly] != nil; - _isCopy = attributes[kFLEXPropertyAttributeKeyCopy] != nil; - _isRetained = attributes[kFLEXPropertyAttributeKeyRetain] != nil; - _isNonatomic = attributes[kFLEXPropertyAttributeKeyNonAtomic] != nil; - _isWeak = attributes[kFLEXPropertyAttributeKeyWeak] != nil; - _isGarbageCollectable = attributes[kFLEXPropertyAttributeKeyGarbageCollectable] != nil; - - _fullDeclaration = [self buildFullDeclaration]; - } - - return self; -} - -#pragma mark Misc - -- (NSString *)description { - return [NSString - stringWithFormat:@"<%@ \"%@\", ivar=%@, readonly=%d, nonatomic=%d, getter=%@, setter=%@>", - NSStringFromClass(self.class), - self.string, - self.backingIvar ?: @"none", - self.isReadOnly, - self.isNonatomic, - NSStringFromSelector(self.customGetter) ?: @"none", - NSStringFromSelector(self.customSetter) ?: @"none" - ]; -} - -- (objc_property_attribute_t *)copyAttributesList:(unsigned int *)attributesCount { - NSDictionary *attrs = self.string.propertyAttributes; - objc_property_attribute_t *propertyAttributes = malloc(attrs.count * sizeof(objc_property_attribute_t)); - - if (attributesCount) { - *attributesCount = (unsigned int)attrs.count; - } - - NSUInteger i = 0; - for (NSString *key in attrs.allKeys) { - FLEXPropertyAttribute c = (FLEXPropertyAttribute)[key characterAtIndex:0]; - switch (c) { - case FLEXPropertyAttributeTypeEncoding: { - objc_property_attribute_t pa = { - kFLEXPropertyAttributeKeyTypeEncoding.UTF8String, - self.typeEncoding.UTF8String - }; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeBackingIvarName: { - objc_property_attribute_t pa = { - kFLEXPropertyAttributeKeyBackingIvarName.UTF8String, - self.backingIvar.UTF8String - }; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeCopy: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyCopy.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeCustomGetter: { - objc_property_attribute_t pa = { - kFLEXPropertyAttributeKeyCustomGetter.UTF8String, - NSStringFromSelector(self.customGetter).UTF8String ?: "" - }; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeCustomSetter: { - objc_property_attribute_t pa = { - kFLEXPropertyAttributeKeyCustomSetter.UTF8String, - NSStringFromSelector(self.customSetter).UTF8String ?: "" - }; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeDynamic: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyDynamic.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeGarbageCollectible: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyGarbageCollectable.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeNonAtomic: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyNonAtomic.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeOldTypeEncoding: { - objc_property_attribute_t pa = { - kFLEXPropertyAttributeKeyOldStyleTypeEncoding.UTF8String, - self.oldTypeEncoding.UTF8String ?: "" - }; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeReadOnly: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyReadOnly.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeRetain: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyRetain.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - case FLEXPropertyAttributeWeak: { - objc_property_attribute_t pa = {kFLEXPropertyAttributeKeyWeak.UTF8String, ""}; - propertyAttributes[i] = pa; - break; - } - } - i++; - } - - return propertyAttributes; -} - -- (objc_property_attribute_t *)list { - if (!_list) { - _list = [self copyAttributesList:nil]; - } - - return _list; -} - -- (NSString *)buildFullDeclaration { - NSMutableString *decl = [NSMutableString new]; - - [decl appendFormat:@"%@, ", _isNonatomic ? @"nonatomic" : @"atomic"]; - [decl appendFormat:@"%@, ", _isReadOnly ? @"readonly" : @"readwrite"]; - - BOOL noExplicitMemorySemantics = YES; - if (_isCopy) { noExplicitMemorySemantics = NO; - [decl appendString:@"copy, "]; - } - if (_isRetained) { noExplicitMemorySemantics = NO; - [decl appendString:@"strong, "]; - } - if (_isWeak) { noExplicitMemorySemantics = NO; - [decl appendString:@"weak, "]; - } - - if ([_typeEncoding hasPrefix:@"@"] && noExplicitMemorySemantics) { - // *probably* strong if this is an object; strong is the default. - [decl appendString:@"strong, "]; - } else if (noExplicitMemorySemantics) { - // *probably* assign if this is not an object - [decl appendString:@"assign, "]; - } - - if (_customGetter) { - [decl appendFormat:@"getter=%@, ", NSStringFromSelector(_customGetter)]; - } - if (_customSetter) { - [decl appendFormat:@"setter=%@, ", NSStringFromSelector(_customSetter)]; - } - - [decl deleteCharactersInRange:NSMakeRange(decl.length-2, 2)]; - return decl.copy; -} - -- (void)dealloc { - if (_list) { - free(_list); - _list = nil; - } -} - -#pragma mark Copying - -- (id)copyWithZone:(NSZone *)zone { - return [[FLEXPropertyAttributes class] attributesFromDictionary:self.dictionary]; -} - -- (id)mutableCopyWithZone:(NSZone *)zone { - return [[FLEXMutablePropertyAttributes class] attributesFromDictionary:self.dictionary]; -} - -@end - - - -#pragma mark FLEXMutablePropertyAttributes - -@interface FLEXMutablePropertyAttributes () -@property (nonatomic) BOOL countDelta; -@property (nonatomic) BOOL stringDelta; -@property (nonatomic) BOOL dictDelta; -@property (nonatomic) BOOL listDelta; -@property (nonatomic) BOOL declDelta; -@end - -#define PropertyWithDeltaFlag(type, name, Name) @dynamic name; \ -- (void)set ## Name:(type)name { \ - if (name != _ ## name) { \ - _countDelta = _stringDelta = _dictDelta = _listDelta = _declDelta = YES; \ - _ ## name = name; \ - } \ -} - -@implementation FLEXMutablePropertyAttributes - -PropertyWithDeltaFlag(NSString *, backingIvar, BackingIvar); -PropertyWithDeltaFlag(NSString *, typeEncoding, TypeEncoding); -PropertyWithDeltaFlag(NSString *, oldTypeEncoding, OldTypeEncoding); -PropertyWithDeltaFlag(SEL, customGetter, CustomGetter); -PropertyWithDeltaFlag(SEL, customSetter, CustomSetter); -PropertyWithDeltaFlag(BOOL, isReadOnly, IsReadOnly); -PropertyWithDeltaFlag(BOOL, isCopy, IsCopy); -PropertyWithDeltaFlag(BOOL, isRetained, IsRetained); -PropertyWithDeltaFlag(BOOL, isNonatomic, IsNonatomic); -PropertyWithDeltaFlag(BOOL, isDynamic, IsDynamic); -PropertyWithDeltaFlag(BOOL, isWeak, IsWeak); -PropertyWithDeltaFlag(BOOL, isGarbageCollectable, IsGarbageCollectable); - -+ (instancetype)attributes { - return [self new]; -} - -- (void)setTypeEncodingChar:(char)type { - self.typeEncoding = [NSString stringWithFormat:@"%c", type]; -} - -- (NSUInteger)count { - // Recalculate attribute count after mutations - if (self.countDelta) { - self.countDelta = NO; - _count = self.dictionary.count; - } - - return _count; -} - -- (objc_property_attribute_t *)list { - // Regenerate list after mutations - if (self.listDelta) { - self.listDelta = NO; - if (_list) { - free(_list); - _list = nil; - } - } - - // Super will generate the list if it isn't set - return super.list; -} - -- (NSString *)string { - // Regenerate string after mutations - if (self.stringDelta || !_string) { - self.stringDelta = NO; - _string = self.dictionary.propertyAttributesString; - } - - return _string; -} - -- (NSDictionary *)dictionary { - // Regenerate dictionary after mutations - if (self.dictDelta || !_dictionary) { - // _stringa nd _dictionary depend on each other, - // so we must generate ONE by hand using our properties. - // We arbitrarily choose to generate the dictionary. - NSMutableDictionary *attrs = [NSMutableDictionary new]; - if (self.typeEncoding) - attrs[kFLEXPropertyAttributeKeyTypeEncoding] = self.typeEncoding; - if (self.backingIvar) - attrs[kFLEXPropertyAttributeKeyBackingIvarName] = self.backingIvar; - if (self.oldTypeEncoding) - attrs[kFLEXPropertyAttributeKeyOldStyleTypeEncoding] = self.oldTypeEncoding; - if (self.customGetter) - attrs[kFLEXPropertyAttributeKeyCustomGetter] = NSStringFromSelector(self.customGetter); - if (self.customSetter) - attrs[kFLEXPropertyAttributeKeyCustomSetter] = NSStringFromSelector(self.customSetter); - - if (self.isReadOnly) attrs[kFLEXPropertyAttributeKeyReadOnly] = @YES; - if (self.isCopy) attrs[kFLEXPropertyAttributeKeyCopy] = @YES; - if (self.isRetained) attrs[kFLEXPropertyAttributeKeyRetain] = @YES; - if (self.isNonatomic) attrs[kFLEXPropertyAttributeKeyNonAtomic] = @YES; - if (self.isDynamic) attrs[kFLEXPropertyAttributeKeyDynamic] = @YES; - if (self.isWeak) attrs[kFLEXPropertyAttributeKeyWeak] = @YES; - if (self.isGarbageCollectable) attrs[kFLEXPropertyAttributeKeyGarbageCollectable] = @YES; - - _dictionary = attrs.copy; - } - - return _dictionary; -} - -- (NSString *)fullDeclaration { - if (self.declDelta || !_fullDeclaration) { - _declDelta = NO; - _fullDeclaration = [self buildFullDeclaration]; - } - - return _fullDeclaration; -} - -- (NSString *)customGetterString { - return _customGetter ? NSStringFromSelector(_customGetter) : nil; -} - -- (NSString *)customSetterString { - return _customSetter ? NSStringFromSelector(_customSetter) : nil; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.h deleted file mode 100644 index 30855358..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// FLEXProtocol.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXRuntimeConstants.h" -@class FLEXProperty, FLEXMethodDescription; - -NS_ASSUME_NONNULL_BEGIN - -#pragma mark FLEXProtocol -@interface FLEXProtocol : NSObject - -/// Every protocol registered with the runtime. -+ (NSArray *)allProtocols; -+ (instancetype)protocol:(Protocol *)protocol; - -/// The underlying protocol data structure. -@property (nonatomic, readonly) Protocol *objc_protocol; - -/// The name of the protocol. -@property (nonatomic, readonly) NSString *name; -/// The required methods of the protocol, if any. This includes property getters and setters. -@property (nonatomic, readonly) NSArray *requiredMethods; -/// The optional methods of the protocol, if any. This includes property getters and setters. -@property (nonatomic, readonly) NSArray *optionalMethods; -/// All protocols that this protocol conforms to, if any. -@property (nonatomic, readonly) NSArray *protocols; -/// The full path of the image that contains this protocol definition, -/// or \c nil if this protocol was probably defined at runtime. -@property (nonatomic, readonly, nullable) NSString *imagePath; - -/// The properties in the protocol, if any. \c nil on iOS 10+ -@property (nonatomic, readonly, nullable) NSArray *properties API_DEPRECATED("Use the more specific accessors below", ios(2.0, 10.0)); - -/// The required properties in the protocol, if any. -@property (nonatomic, readonly) NSArray *requiredProperties API_AVAILABLE(ios(10.0)); -/// The optional properties in the protocol, if any. -@property (nonatomic, readonly) NSArray *optionalProperties API_AVAILABLE(ios(10.0)); - -/// For internal use -@property (nonatomic) id tag; - -/// Not to be confused with \c -conformsToProtocol:, which refers to the current -/// \c FLEXProtocol instance and not the underlying \c Protocol object. -- (BOOL)conformsTo:(Protocol *)protocol; - -@end - - -#pragma mark Method descriptions -@interface FLEXMethodDescription : NSObject - -+ (instancetype)description:(struct objc_method_description)description; -+ (instancetype)description:(struct objc_method_description)description instance:(BOOL)isInstance; - -/// The underlying method description data structure. -@property (nonatomic, readonly) struct objc_method_description objc_description; -/// The method's selector. -@property (nonatomic, readonly) SEL selector; -/// The method's type encoding. -@property (nonatomic, readonly) NSString *typeEncoding; -/// The method's return type. -@property (nonatomic, readonly) FLEXTypeEncoding returnType; -/// \c YES if this is an instance method, \c NO if it is a class method, or \c nil if unspecified -@property (nonatomic, readonly) NSNumber *instance; -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.m deleted file mode 100644 index 40003669..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocol.m +++ /dev/null @@ -1,212 +0,0 @@ -// -// FLEXProtocol.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 6/30/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXProtocol.h" -#import "FLEXProperty.h" -#import "FLEXRuntimeUtility.h" -#import "NSArray+FLEX.h" -#include - -@implementation FLEXProtocol - -#pragma mark Initializers - -+ (NSArray *)allProtocols { - unsigned int prcount; - Protocol *__unsafe_unretained*protocols = objc_copyProtocolList(&prcount); - - NSMutableArray *all = [NSMutableArray new]; - for(NSUInteger i = 0; i < prcount; i++) - [all addObject:[self protocol:protocols[i]]]; - - free(protocols); - return all; -} - -+ (instancetype)protocol:(Protocol *)protocol { - return [[self alloc] initWithProtocol:protocol]; -} - -- (id)initWithProtocol:(Protocol *)protocol { - NSParameterAssert(protocol); - - self = [super init]; - if (self) { - _objc_protocol = protocol; - [self examine]; - } - - return self; -} - -#pragma mark Other - -- (NSString *)description { - return self.name; -} - -- (NSString *)debugDescription { - return [NSString stringWithFormat:@"<%@ name=%@, %lu properties, %lu required methods, %lu optional methods, %lu protocols>", - NSStringFromClass(self.class), self.name, (unsigned long)self.properties.count, - (unsigned long)self.requiredMethods.count, (unsigned long)self.optionalMethods.count, (unsigned long)self.protocols.count]; -} - -- (void)examine { - _name = @(protocol_getName(self.objc_protocol)); - - // imagePath - Dl_info exeInfo; - if (dladdr((__bridge const void *)(_objc_protocol), &exeInfo)) { - _imagePath = exeInfo.dli_fname ? @(exeInfo.dli_fname) : nil; - } - - // Conformances and methods // - - unsigned int pccount, mdrcount, mdocount; - struct objc_method_description *objcrMethods, *objcoMethods; - Protocol *protocol = _objc_protocol; - Protocol * __unsafe_unretained *protocols = protocol_copyProtocolList(protocol, &pccount); - - // Protocols - _protocols = [NSArray flex_forEachUpTo:pccount map:^id(NSUInteger i) { - return [FLEXProtocol protocol:protocols[i]]; - }]; - free(protocols); - - // Required instance methods - objcrMethods = protocol_copyMethodDescriptionList(protocol, YES, YES, &mdrcount); - NSArray *rMethods = [NSArray flex_forEachUpTo:mdrcount map:^id(NSUInteger i) { - return [FLEXMethodDescription description:objcrMethods[i] instance:YES]; - }]; - free(objcrMethods); - - // Required class methods - objcrMethods = protocol_copyMethodDescriptionList(protocol, YES, NO, &mdrcount); - _requiredMethods = [[NSArray flex_forEachUpTo:mdrcount map:^id(NSUInteger i) { - return [FLEXMethodDescription description:objcrMethods[i] instance:NO]; - }] arrayByAddingObjectsFromArray:rMethods]; - free(objcrMethods); - - // Optional instance methods - objcoMethods = protocol_copyMethodDescriptionList(protocol, NO, YES, &mdocount); - NSArray *oMethods = [NSArray flex_forEachUpTo:mdocount map:^id(NSUInteger i) { - return [FLEXMethodDescription description:objcoMethods[i] instance:YES]; - }]; - free(objcoMethods); - - // Optional class methods - objcoMethods = protocol_copyMethodDescriptionList(protocol, NO, NO, &mdocount); - _optionalMethods = [[NSArray flex_forEachUpTo:mdocount map:^id(NSUInteger i) { - return [FLEXMethodDescription description:objcoMethods[i] instance:NO]; - }] arrayByAddingObjectsFromArray:oMethods]; - free(objcoMethods); - - // Properties is a hassle because they didn't fix the API until iOS 10 // - - if (@available(iOS 10.0, *)) { - unsigned int prrcount, procount; - Class instance = [NSObject class], meta = objc_getMetaClass("NSObject"); - - // Required class and instance properties // - - // Instance first - objc_property_t *rProps = protocol_copyPropertyList2(protocol, &prrcount, YES, YES); - NSArray *rProperties = [NSArray flex_forEachUpTo:prrcount map:^id(NSUInteger i) { - return [FLEXProperty property:rProps[i] onClass:instance]; - }]; - free(rProps); - - // Then class - rProps = protocol_copyPropertyList2(protocol, &prrcount, NO, YES); - _requiredProperties = [[NSArray flex_forEachUpTo:prrcount map:^id(NSUInteger i) { - return [FLEXProperty property:rProps[i] onClass:instance]; - }] arrayByAddingObjectsFromArray:rProperties]; - free(rProps); - - // Optional class and instance properties // - - // Instance first - objc_property_t *oProps = protocol_copyPropertyList2(protocol, &procount, YES, YES); - NSArray *oProperties = [NSArray flex_forEachUpTo:prrcount map:^id(NSUInteger i) { - return [FLEXProperty property:oProps[i] onClass:meta]; - }]; - free(oProps); - - // Then class - oProps = protocol_copyPropertyList2(protocol, &procount, NO, YES); - _optionalProperties = [[NSArray flex_forEachUpTo:procount map:^id(NSUInteger i) { - return [FLEXProperty property:oProps[i] onClass:meta]; - }] arrayByAddingObjectsFromArray:oProperties]; - free(oProps); - - } else { - unsigned int prcount; - objc_property_t *objcproperties = protocol_copyPropertyList(protocol, &prcount); - _properties = [NSArray flex_forEachUpTo:prcount map:^id(NSUInteger i) { - return [FLEXProperty property:objcproperties[i]]; - }]; - - _requiredProperties = @[]; - _optionalProperties = @[]; - - free(objcproperties); - } -} - -- (BOOL)conformsTo:(Protocol *)protocol { - return protocol_conformsToProtocol(self.objc_protocol, protocol); -} - -@end - -#pragma mark FLEXMethodDescription - -@implementation FLEXMethodDescription - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -+ (instancetype)description:(struct objc_method_description)description { - return [[self alloc] initWithDescription:description instance:nil]; -} - -+ (instancetype)description:(struct objc_method_description)description instance:(BOOL)isInstance { - return [[self alloc] initWithDescription:description instance:@(isInstance)]; -} - -- (id)initWithDescription:(struct objc_method_description)md instance:(NSNumber *)instance { - NSParameterAssert(md.name != NULL); - - self = [super init]; - if (self) { - _objc_description = md; - _selector = md.name; - _typeEncoding = @(md.types); - _returnType = (FLEXTypeEncoding)[self.typeEncoding characterAtIndex:0]; - _instance = instance; - } - - return self; -} - -- (NSString *)description { - return NSStringFromSelector(self.selector); -} - -- (NSString *)debugDescription { - return [NSString stringWithFormat:@"<%@ name=%@, type=%@>", - NSStringFromClass(self.class), NSStringFromSelector(self.selector), self.typeEncoding]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.h b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.h deleted file mode 100644 index e855cd3c..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// FLEXProtocolBuilder.h -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/4/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import -@class FLEXProperty, FLEXProtocol, Protocol; - -@interface FLEXProtocolBuilder : NSObject - -/// Begins to construct a new protocol with the given name. -/// @discussion You must register the protocol with the -/// \c registerProtocol method before you can use it. -+ (instancetype)allocateProtocol:(NSString *)name; - -/// Adds a property to a protocol. -/// @param property The property to add. -/// @param isRequired Whether the property is required to implement the protocol. -- (void)addProperty:(FLEXProperty *)property isRequired:(BOOL)isRequired; -/// Adds a property to a protocol. -/// @param selector The selector of the method to add. -/// @param typeEncoding The type encoding of the method to add. -/// @param isRequired Whether the method is required to implement the protocol. -/// @param isInstanceMethod \c YES if the method is an instance method, \c NO if it is a class method. -- (void)addMethod:(SEL)selector - typeEncoding:(NSString *)typeEncoding - isRequired:(BOOL)isRequired - isInstanceMethod:(BOOL)isInstanceMethod; -/// Makes the recieving protocol conform to the given protocol. -- (void)addProtocol:(Protocol *)protocol; - -/// Registers and returns the recieving protocol, which was previously under construction. -- (FLEXProtocol *)registerProtocol; -/// Whether the protocol is still under construction or already registered. -@property (nonatomic, readonly) BOOL isRegistered; - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.m b/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.m deleted file mode 100644 index fdd12837..00000000 --- a/BHTwitter/Classes/Utility/Runtime/Objc/Reflection/FLEXProtocolBuilder.m +++ /dev/null @@ -1,93 +0,0 @@ -// -// FLEXProtocolBuilder.m -// FLEX -// -// Derived from MirrorKit. -// Created by Tanner on 7/4/15. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXProtocolBuilder.h" -#import "FLEXProtocol.h" -#import "FLEXProperty.h" -#import - -#define MutationAssertion(msg) if (self.isRegistered) { \ - [NSException \ - raise:NSInternalInconsistencyException \ - format:msg \ - ]; \ -} - -@interface FLEXProtocolBuilder () -@property (nonatomic) Protocol *workingProtocol; -@property (nonatomic) NSString *name; -@end - -@implementation FLEXProtocolBuilder - -- (id)init { - [NSException - raise:NSInternalInconsistencyException - format:@"Class instance should not be created with -init" - ]; - return nil; -} - -#pragma mark Initializers -+ (instancetype)allocateProtocol:(NSString *)name { - NSParameterAssert(name); - return [[self alloc] initWithProtocol:objc_allocateProtocol(name.UTF8String)]; - -} - -- (id)initWithProtocol:(Protocol *)protocol { - NSParameterAssert(protocol); - - self = [super init]; - if (self) { - _workingProtocol = protocol; - _name = NSStringFromProtocol(self.workingProtocol); - } - - return self; -} - -- (NSString *)description { - return [NSString stringWithFormat:@"<%@ name=%@, registered=%d>", - NSStringFromClass(self.class), self.name, self.isRegistered]; -} - -#pragma mark Building - -- (void)addProperty:(FLEXProperty *)property isRequired:(BOOL)isRequired { - MutationAssertion(@"Properties cannot be added once a protocol has been registered"); - - unsigned int count; - objc_property_attribute_t *attributes = [property copyAttributesList:&count]; - protocol_addProperty(self.workingProtocol, property.name.UTF8String, attributes, count, isRequired, YES); - free(attributes); -} - -- (void)addMethod:(SEL)selector - typeEncoding:(NSString *)typeEncoding - isRequired:(BOOL)isRequired - isInstanceMethod:(BOOL)isInstanceMethod { - MutationAssertion(@"Methods cannot be added once a protocol has been registered"); - protocol_addMethodDescription(self.workingProtocol, selector, typeEncoding.UTF8String, isRequired, isInstanceMethod); -} - -- (void)addProtocol:(Protocol *)protocol { - MutationAssertion(@"Protocols cannot be added once a protocol has been registered"); - protocol_addProtocol(self.workingProtocol, protocol); -} - -- (FLEXProtocol *)registerProtocol { - MutationAssertion(@"Protocol is already registered"); - - _isRegistered = YES; - objc_registerProtocol(self.workingProtocol); - return [FLEXProtocol protocol:self.workingProtocol]; -} - -@end diff --git a/BHTwitter/Classes/Utility/Runtime/flex_fishhook.c b/BHTwitter/Classes/Utility/Runtime/flex_fishhook.c deleted file mode 100644 index f673f4ff..00000000 --- a/BHTwitter/Classes/Utility/Runtime/flex_fishhook.c +++ /dev/null @@ -1,290 +0,0 @@ -// Copyright (c) 2013, Facebook, Inc. -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name Facebook nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific -// prior written permission. -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "flex_fishhook.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __LP64__ -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -#ifndef SEG_DATA_CONST -#define SEG_DATA_CONST "__DATA_CONST" -#endif - -struct rebindings_entry { - struct rebinding *rebindings; - size_t rebindings_nel; - struct rebindings_entry *next; -}; - -static struct rebindings_entry *_flex_rebindings_head; - -/// @return 0 on success -static int flex_prepend_rebindings(struct rebindings_entry **rebindings_head, - struct rebinding rebindings[], - size_t nel) { - struct rebindings_entry *new_entry = (struct rebindings_entry *) malloc(sizeof(struct rebindings_entry)); - if (!new_entry) { - return -1; - } - - new_entry->rebindings = (struct rebinding *) malloc(sizeof(struct rebinding) * nel); - if (!new_entry->rebindings) { - free(new_entry); - return -1; - } - - memcpy(new_entry->rebindings, rebindings, sizeof(struct rebinding) * nel); - new_entry->rebindings_nel = nel; - new_entry->next = *rebindings_head; - *rebindings_head = new_entry; - - return 0; -} - -static vm_prot_t flex_get_protection(void *sectionStart) { - mach_port_t task = mach_task_self(); - vm_size_t size = 0; - vm_address_t address = (vm_address_t)sectionStart; - memory_object_name_t object; -#if __LP64__ - mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT_64; - vm_region_basic_info_data_64_t info; - kern_return_t info_ret = vm_region_64( - task, &address, &size, VM_REGION_BASIC_INFO_64, - (vm_region_info_64_t)&info, &count, &object - ); -#else - mach_msg_type_number_t count = VM_REGION_BASIC_INFO_COUNT; - vm_region_basic_info_data_t info; - kern_return_t info_ret = vm_region( - task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&info, &count, &object - ); -#endif - if (info_ret == KERN_SUCCESS) { - return info.protection; - } else { - return VM_PROT_READ; - } -} -static void flex_perform_rebinding_with_section(struct rebindings_entry *rebindings, - section_t *section, - intptr_t slide, - nlist_t *symtab, - char *strtab, - uint32_t *indirect_symtab) { - const bool isDataConst = strcmp(section->segname, "__DATA_CONST") == 0; - uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; - void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); - vm_prot_t oldProtection = VM_PROT_READ; - - if (isDataConst) { - oldProtection = flex_get_protection(rebindings); - mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE); - } - - for (uint i = 0; i < section->size / sizeof(void *); i++) { - uint32_t symtab_index = indirect_symbol_indices[i]; - - if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || - symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { - continue; - } - - uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; - char *symbol_name = strtab + strtab_offset; - bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; - struct rebindings_entry *cur = rebindings; - - while (cur) { - for (uint j = 0; j < cur->rebindings_nel; j++) { - if (symbol_name_longer_than_1 && - strcmp(&symbol_name[1], cur->rebindings[j].name) == 0) { - - if (cur->rebindings[j].replaced != NULL && - indirect_symbol_bindings[i] != cur->rebindings[j].replacement) { - - *(cur->rebindings[j].replaced) = indirect_symbol_bindings[i]; - } - - indirect_symbol_bindings[i] = cur->rebindings[j].replacement; - goto symbol_loop; - } - } - - cur = cur->next; - } - - symbol_loop:; - } - - if (isDataConst) { - int protection = 0; - if (oldProtection & VM_PROT_READ) { - protection |= PROT_READ; - } - if (oldProtection & VM_PROT_WRITE) { - protection |= PROT_WRITE; - } - if (oldProtection & VM_PROT_EXECUTE) { - protection |= PROT_EXEC; - } - - mprotect(indirect_symbol_bindings, section->size, protection); - } -} - -static void flex_rebind_symbols_for_image(struct rebindings_entry *rebindings, - const struct mach_header *header, - intptr_t slide) { - Dl_info info; - if (dladdr(header, &info) == 0) { - return; - } - - segment_command_t *cur_seg_cmd; - segment_command_t *linkedit_segment = NULL; - struct symtab_command* symtab_cmd = NULL; - struct dysymtab_command* dysymtab_cmd = NULL; - - uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { - cur_seg_cmd = (segment_command_t *)cur; - - if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(cur_seg_cmd->segname, SEG_LINKEDIT) == 0) { - linkedit_segment = cur_seg_cmd; - } - } else if (cur_seg_cmd->cmd == LC_SYMTAB) { - symtab_cmd = (struct symtab_command*)cur_seg_cmd; - } else if (cur_seg_cmd->cmd == LC_DYSYMTAB) { - dysymtab_cmd = (struct dysymtab_command*)cur_seg_cmd; - } - } - - if (!symtab_cmd || !dysymtab_cmd || !linkedit_segment || - !dysymtab_cmd->nindirectsyms) { - return; - } - - // Find base symbol/string table addresses - uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); - char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); - - // Get indirect symbol table (array of uint32_t indices into symbol table) - uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); - - cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += cur_seg_cmd->cmdsize) { - cur_seg_cmd = (segment_command_t *)cur; - - if (cur_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(cur_seg_cmd->segname, SEG_DATA) != 0 && - strcmp(cur_seg_cmd->segname, SEG_DATA_CONST) != 0) { - continue; - } - - for (uint j = 0; j < cur_seg_cmd->nsects; j++) { - section_t *sect = (section_t *)(cur + sizeof(segment_command_t)) + j; - - if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { - flex_perform_rebinding_with_section( - rebindings, sect, slide, symtab, strtab, indirect_symtab - ); - } - if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { - flex_perform_rebinding_with_section( - rebindings, sect, slide, symtab, strtab, indirect_symtab - ); - } - } - } - } -} - -static void _flex_rebind_symbols_for_image(const struct mach_header *header, - intptr_t slide) { - flex_rebind_symbols_for_image(_flex_rebindings_head, header, slide); -} - -int flex_rebind_symbols_image(void *header, - intptr_t slide, - struct rebinding rebindings[], - size_t rebindings_nel) { - struct rebindings_entry *rebindings_head = NULL; - - int retval = flex_prepend_rebindings(&rebindings_head, rebindings, rebindings_nel); - flex_rebind_symbols_for_image(rebindings_head, (const struct mach_header *) header, slide); - - if (rebindings_head) { - free(rebindings_head->rebindings); - } - - free(rebindings_head); - return retval; -} - -/// @return 0 on success -int flex_rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel) { - int retval = flex_prepend_rebindings(&_flex_rebindings_head, rebindings, rebindings_nel); - if (retval < 0) { - return retval; - } - - // If this was the first call, register callback for image additions (which is also invoked for - // existing images, otherwise, just run on existing images - if (!_flex_rebindings_head->next) { - _dyld_register_func_for_add_image(_flex_rebind_symbols_for_image); - } else { - uint32_t c = _dyld_image_count(); - for (uint32_t i = 0; i < c; i++) { - _flex_rebind_symbols_for_image(_dyld_get_image_header(i), _dyld_get_image_vmaddr_slide(i)); - } - } - - return retval; -} diff --git a/BHTwitter/Classes/Utility/Runtime/flex_fishhook.h b/BHTwitter/Classes/Utility/Runtime/flex_fishhook.h deleted file mode 100644 index 1f02191d..00000000 --- a/BHTwitter/Classes/Utility/Runtime/flex_fishhook.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2013, Facebook, Inc. -// All rights reserved. -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// * Neither the name Facebook nor the names of its contributors may be used to -// endorse or promote products derived from this software without specific -// prior written permission. -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef fishhook_h -#define fishhook_h - -#include -#include - -#if !defined(FISHHOOK_EXPORT) -#define FISHHOOK_VISIBILITY __attribute__((visibility("hidden"))) -#else -#define FISHHOOK_VISIBILITY __attribute__((visibility("default"))) -#endif - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -/** - * A structure representing a particular intended rebinding from a symbol - * name to its replacement - */ -struct rebinding { - const char *name; - void *replacement; - void **replaced; -}; - -/** - * For each rebinding in rebindings, rebinds references to external, indirect - * symbols with the specified name to instead point at replacement for each - * image in the calling process as well as for all future images that are loaded - * by the process. If rebind_functions is called more than once, the symbols to - * rebind are added to the existing list of rebindings, and if a given symbol - * is rebound more than once, the later rebinding will take precedence. - * @return 0 on success - */ -FISHHOOK_VISIBILITY -int flex_rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel); - -/** - * Rebinds as above, but only in the specified image. The header should point - * to the mach-o header, the slide should be the slide offset. Others as above. - * @return 0 on success - */ -FISHHOOK_VISIBILITY -int flex_rebind_symbols_image(void *header, - intptr_t slide, - struct rebinding rebindings[], - size_t rebindings_nel); - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //fishhook_h diff --git a/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.h b/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.h deleted file mode 100644 index 57fe94d5..00000000 --- a/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// FLEXHierarchyViewController.h -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXNavigationController.h" - -@protocol FLEXHierarchyDelegate -- (void)viewHierarchyDidDismiss:(UIView *)selectedView; -@end - -/// A navigation controller which manages two child view controllers: -/// a 3D Reveal-like hierarchy explorer, and a 2D tree-list hierarchy explorer. -@interface FLEXHierarchyViewController : FLEXNavigationController - -+ (instancetype)delegate:(id)delegate; -+ (instancetype)delegate:(id)delegate - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)selectedView; - -- (void)toggleHierarchyMode; - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.m b/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.m deleted file mode 100644 index eb47b534..00000000 --- a/BHTwitter/Classes/ViewHierarchy/FLEXHierarchyViewController.m +++ /dev/null @@ -1,154 +0,0 @@ -// -// FLEXHierarchyViewController.m -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FLEXHierarchyViewController.h" -#import "FLEXHierarchyTableViewController.h" -#import "FHSViewController.h" -#import "FLEXUtility.h" -#import "FLEXTabList.h" -#import "FLEXResources.h" -#import "UIBarButtonItem+FLEX.h" - -typedef NS_ENUM(NSUInteger, FLEXHierarchyViewMode) { - FLEXHierarchyViewModeTree = 1, - FLEXHierarchyViewMode3DSnapshot -}; - -@interface FLEXHierarchyViewController () -@property (nonatomic, readonly, weak) id hierarchyDelegate; -@property (nonatomic, readonly) FHSViewController *snapshotViewController; -@property (nonatomic, readonly) FLEXHierarchyTableViewController *treeViewController; - -@property (nonatomic) FLEXHierarchyViewMode mode; - -@property (nonatomic, readonly) UIView *selectedView; -@end - -@implementation FLEXHierarchyViewController - -#pragma mark - Initialization - -+ (instancetype)delegate:(id)delegate { - return [self delegate:delegate viewsAtTap:nil selectedView:nil]; -} - -+ (instancetype)delegate:(id)delegate - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)selectedView { - return [[self alloc] initWithDelegate:delegate viewsAtTap:viewsAtTap selectedView:selectedView]; -} - -- (id)initWithDelegate:(id)delegate viewsAtTap:(NSArray *)viewsAtTap selectedView:(UIView *)view { - self = [super init]; - if (self) { - NSArray *allWindows = FLEXUtility.allWindows; - _hierarchyDelegate = delegate; - _treeViewController = [FLEXHierarchyTableViewController - windows:allWindows viewsAtTap:viewsAtTap selectedView:view - ]; - - if (viewsAtTap) { - _snapshotViewController = [FHSViewController snapshotViewsAtTap:viewsAtTap selectedView:view]; - } else { - _snapshotViewController = [FHSViewController snapshotWindows:allWindows]; - } - - self.modalPresentationStyle = UIModalPresentationFullScreen; - } - - return self; -} - - -#pragma mark - Lifecycle - -- (void)viewDidLoad { - [super viewDidLoad]; - - // 3D toggle button - self.treeViewController.navigationItem.leftBarButtonItem = [UIBarButtonItem - flex_itemWithImage:FLEXResources.toggle3DIcon target:self action:@selector(toggleHierarchyMode) - ]; - - // Dismiss when tree view row is selected - __weak id delegate = self.hierarchyDelegate; - self.treeViewController.didSelectRowAction = ^(UIView *selectedView) { - [delegate viewHierarchyDidDismiss:selectedView]; - }; - - // Start of in tree view - _mode = FLEXHierarchyViewModeTree; - [self pushViewController:self.treeViewController animated:NO]; -} - -- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated { - // Done button: manually added here because the hierarhcy screens need to actually pass - // data back to the explorer view controller so that it can highlight selected views - viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(donePressed) - ]; - - [super pushViewController:viewController animated:animated]; -} - - -#pragma mark - Private - -- (void)donePressed { - // We need to manually close ourselves here because - // FLEXNavigationController doesn't ever close tabs itself - [FLEXTabList.sharedList closeTab:self]; - [self.hierarchyDelegate viewHierarchyDidDismiss:self.selectedView]; -} - -- (void)toggleHierarchyMode { - switch (self.mode) { - case FLEXHierarchyViewModeTree: - self.mode = FLEXHierarchyViewMode3DSnapshot; - break; - case FLEXHierarchyViewMode3DSnapshot: - self.mode = FLEXHierarchyViewModeTree; - break; - } -} - -- (void)setMode:(FLEXHierarchyViewMode)mode { - if (mode != _mode) { - // The tree view controller is our top stack view controller, and - // changing the mode simply pushes the snapshot view. In the future, - // I would like to have the 3D toggle button transparently switch - // between two views instead of pushing a new view controller. - // This way the views should share the search controller somehow. - switch (mode) { - case FLEXHierarchyViewModeTree: - [self popViewControllerAnimated:NO]; - self.toolbarHidden = YES; - self.treeViewController.selectedView = self.selectedView; - break; - case FLEXHierarchyViewMode3DSnapshot: - [self pushViewController:self.snapshotViewController animated:NO]; - self.toolbarHidden = NO; - self.snapshotViewController.selectedView = self.selectedView; - break; - } - - // Change this last so that self.selectedView works right above - _mode = mode; - } -} - -- (UIView *)selectedView { - switch (self.mode) { - case FLEXHierarchyViewModeTree: - return self.treeViewController.selectedView; - case FLEXHierarchyViewMode3DSnapshot: - return self.snapshotViewController.selectedView; - } -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.h b/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.h deleted file mode 100644 index 72bf7393..00000000 --- a/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.h +++ /dev/null @@ -1,17 +0,0 @@ -// -// FLEXImagePreviewViewController.h -// Flipboard -// -// Created by Ryan Olson on 6/12/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXImagePreviewViewController : UIViewController - -+ (instancetype)previewForView:(UIView *)view; -+ (instancetype)previewForLayer:(CALayer *)layer; -+ (instancetype)forImage:(UIImage *)image; - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.m b/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.m deleted file mode 100644 index a349e029..00000000 --- a/BHTwitter/Classes/ViewHierarchy/FLEXImagePreviewViewController.m +++ /dev/null @@ -1,147 +0,0 @@ -// -// FLEXImagePreviewViewController.m -// Flipboard -// -// Created by Ryan Olson on 6/12/14. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXImagePreviewViewController.h" -#import "FLEXUtility.h" -#import "FLEXColor.h" -#import "FLEXResources.h" - -@interface FLEXImagePreviewViewController () -@property (nonatomic) UIImage *image; -@property (nonatomic) UIScrollView *scrollView; -@property (nonatomic) UIImageView *imageView; -@property (nonatomic) UITapGestureRecognizer *bgColorTapGesture; -@property (nonatomic) NSInteger backgroundColorIndex; -@property (nonatomic, readonly) NSArray *backgroundColors; -@end - -#pragma mark - -@implementation FLEXImagePreviewViewController - -#pragma mark Initialization - -+ (instancetype)previewForView:(UIView *)view { - return [self forImage:[FLEXUtility previewImageForView:view]]; -} - -+ (instancetype)previewForLayer:(CALayer *)layer { - return [self forImage:[FLEXUtility previewImageForLayer:layer]]; -} - -+ (instancetype)forImage:(UIImage *)image { - return [[self alloc] initWithImage:image]; -} - -- (id)initWithImage:(UIImage *)image { - NSParameterAssert(image); - - self = [super init]; - if (self) { - self.title = @"Preview"; - self.image = image; - _backgroundColors = @[FLEXResources.checkerPatternColor, UIColor.whiteColor, UIColor.blackColor]; - } - - return self; -} - - -#pragma mark Lifecycle - -- (void)viewDidLoad { - [super viewDidLoad]; - - self.imageView = [[UIImageView alloc] initWithImage:self.image]; - self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; - self.scrollView.delegate = self; - self.scrollView.backgroundColor = self.backgroundColors.firstObject; - self.scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self.scrollView addSubview:self.imageView]; - self.scrollView.contentSize = self.imageView.frame.size; - self.scrollView.minimumZoomScale = 1.0; - self.scrollView.maximumZoomScale = 2.0; - [self.view addSubview:self.scrollView]; - - self.bgColorTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeBackground)]; - [self.scrollView addGestureRecognizer:self.bgColorTapGesture]; - - self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] - initWithBarButtonSystemItem:UIBarButtonSystemItemAction - target:self - action:@selector(actionButtonPressed:) - ]; -} - -- (void)viewDidLayoutSubviews { - [self centerContentInScrollViewIfNeeded]; -} - - -#pragma mark UIScrollViewDelegate - -- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { - return self.imageView; -} - -- (void)scrollViewDidZoom:(UIScrollView *)scrollView { - [self centerContentInScrollViewIfNeeded]; -} - - -#pragma mark Private - -- (void)centerContentInScrollViewIfNeeded { - CGFloat horizontalInset = 0.0; - CGFloat verticalInset = 0.0; - if (self.scrollView.contentSize.width < self.scrollView.bounds.size.width) { - horizontalInset = (self.scrollView.bounds.size.width - self.scrollView.contentSize.width) / 2.0; - } - if (self.scrollView.contentSize.height < self.scrollView.bounds.size.height) { - verticalInset = (self.scrollView.bounds.size.height - self.scrollView.contentSize.height) / 2.0; - } - self.scrollView.contentInset = UIEdgeInsetsMake(verticalInset, horizontalInset, verticalInset, horizontalInset); -} - -- (void)changeBackground { - self.backgroundColorIndex++; - self.backgroundColorIndex %= self.backgroundColors.count; - self.scrollView.backgroundColor = self.backgroundColors[self.backgroundColorIndex]; -} - -- (void)actionButtonPressed:(id)sender { - static BOOL canSaveToCameraRoll = NO, didShowWarning = NO; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - if (UIDevice.currentDevice.systemVersion.floatValue < 10) { - canSaveToCameraRoll = YES; - return; - } - - NSBundle *mainBundle = NSBundle.mainBundle; - if ([mainBundle.infoDictionary.allKeys containsObject:@"NSPhotoLibraryUsageDescription"]) { - canSaveToCameraRoll = YES; - } - }); - - UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:@[self.image] applicationActivities:@[]]; - - if (!canSaveToCameraRoll && !didShowWarning) { - didShowWarning = YES; - NSString *msg = @"Add 'NSPhotoLibraryUsageDescription' to this app's Info.plist to save images."; - [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Reminder").message(msg); - make.button(@"OK").handler(^(NSArray *strings) { - [self presentViewController:activityVC animated:YES completion:nil]; - }); - } showFrom:self]; - } else { - [self presentViewController:activityVC animated:YES completion:nil]; - } -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.h deleted file mode 100644 index c5d3e60e..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.h +++ /dev/null @@ -1,22 +0,0 @@ -// -// FHSRangeSlider.h -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface FHSRangeSlider : UIControl - -@property (nonatomic) CGFloat allowedMinValue; -@property (nonatomic) CGFloat allowedMaxValue; -@property (nonatomic) CGFloat minValue; -@property (nonatomic) CGFloat maxValue; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.m deleted file mode 100644 index d0277598..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSRangeSlider.m +++ /dev/null @@ -1,201 +0,0 @@ -// -// FHSRangeSlider.m -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSRangeSlider.h" -#import "FLEXResources.h" -#import "FLEXUtility.h" - -@interface FHSRangeSlider () -@property (nonatomic, readonly) UIImageView *track; -@property (nonatomic, readonly) UIImageView *fill; -@property (nonatomic, readonly) UIImageView *leftHandle; -@property (nonatomic, readonly) UIImageView *rightHandle; - -@property (nonatomic, getter=isTrackingLeftHandle) BOOL trackingLeftHandle; -@property (nonatomic, getter=isTrackingRightHandle) BOOL trackingRightHandle; -@end - -@implementation FHSRangeSlider - -#pragma mark - Initialization - -- (instancetype)initWithFrame:(CGRect)frame { - self = [super initWithFrame:frame]; - if (self) { - _allowedMaxValue = 1.f; - _maxValue = 1.f; - [self initSubviews]; - } - - return self; -} - -- (void)initSubviews { - self.userInteractionEnabled = YES; - UIImageView * (^newSubviewImageView)(UIImage *) = ^UIImageView *(UIImage *image) { - UIImageView *iv = [UIImageView new]; - iv.image = image; -// iv.userInteractionEnabled = YES; - [self addSubview:iv]; - return iv; - }; - - _track = newSubviewImageView(FLEXResources.rangeSliderTrack); - _fill = newSubviewImageView(FLEXResources.rangeSliderFill); - _leftHandle = newSubviewImageView(FLEXResources.rangeSliderLeftHandle); - _rightHandle = newSubviewImageView(FLEXResources.rangeSliderRightHandle); -} - -#pragma mark - Setters / Private - -- (CGFloat)valueAt:(CGFloat)x { - CGFloat minX = self.leftHandle.image.size.width; - CGFloat maxX = self.bounds.size.width - self.rightHandle.image.size.width; - CGFloat cappedX = MIN(MAX(x, minX), maxX); - CGFloat delta = maxX - minX; - CGFloat maxDelta = self.allowedMaxValue - self.allowedMinValue; - - return ((delta > 0) ? (cappedX - minX) / delta : 0) * maxDelta + self.allowedMinValue; -} - -- (void)setAllowedMinValue:(CGFloat)allowedMinValue { - _allowedMinValue = allowedMinValue; - - if (self.minValue < self.allowedMaxValue) { - self.minValue = self.allowedMaxValue; - } else { - [self setNeedsLayout]; - } -} - -- (void)setAllowedMaxValue:(CGFloat)allowedMaxValue { - _allowedMaxValue = allowedMaxValue; - - if (self.maxValue > self.allowedMaxValue) { - self.maxValue = self.allowedMaxValue; - } else { - [self valuesChanged:NO]; - } -} - -- (void)setMinValue:(CGFloat)minValue { - _minValue = minValue; - [self valuesChanged:YES]; -} - -- (void)setMaxValue:(CGFloat)maxValue { - _maxValue = maxValue; - [self valuesChanged:YES]; -} - -- (void)valuesChanged:(BOOL)sendActions { - if (NSThread.isMainThread) { - if (sendActions) { - [self sendActionsForControlEvents:UIControlEventValueChanged]; - } - [self setNeedsLayout]; - } -} - -#pragma mark - Overrides - -- (CGSize)intrinsicContentSize { - return CGSizeMake(UIViewNoIntrinsicMetric, self.leftHandle.image.size.height); -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - CGSize lhs = self.leftHandle.image.size; - CGSize rhs = self.rightHandle.image.size; - CGSize trackSize = self.track.image.size; - - CGFloat delta = self.allowedMaxValue - self.allowedMinValue; - CGFloat minPercent, maxPercent; - - if (delta <= 0) { - minPercent = maxPercent = 0; - } else { - minPercent = MAX(0, (self.minValue - self.allowedMinValue) / delta); - maxPercent = MAX(minPercent, (self.maxValue - self.allowedMinValue) / delta); - } - - CGFloat rangeSliderWidth = self.bounds.size.width - lhs.width - rhs.width; - - self.leftHandle.frame = FLEXRectMake( - rangeSliderWidth * minPercent, - CGRectGetMidY(self.bounds) - (lhs.height / 2.f) + 3.f, - lhs.width, - lhs.height - ); - - self.rightHandle.frame = FLEXRectMake( - lhs.width + (rangeSliderWidth * maxPercent), - CGRectGetMidY(self.bounds) - (rhs.height / 2.f) + 3.f, - rhs.width, - rhs.height - ); - - self.track.frame = FLEXRectMake( - lhs.width / 2.f, - CGRectGetMidY(self.bounds) - trackSize.height / 2.f, - self.bounds.size.width - (lhs.width / 2.f) - (rhs.width / 2.f), - trackSize.height - ); - - self.fill.frame = FLEXRectMake( - CGRectGetMidX(self.leftHandle.frame), - CGRectGetMinY(self.track.frame), - CGRectGetMidX(self.rightHandle.frame) - CGRectGetMidX(self.leftHandle.frame), - self.track.frame.size.height - ); -} - -- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { - CGPoint loc = [touch locationInView:self]; - - if (CGRectContainsPoint(self.leftHandle.frame, loc)) { - self.trackingLeftHandle = YES; - self.trackingRightHandle = NO; - } else if (CGRectContainsPoint(self.rightHandle.frame, loc)) { - self.trackingLeftHandle = NO; - self.trackingRightHandle = YES; - } else { - return NO; - } - - return YES; -} - -- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { - CGPoint loc = [touch locationInView:self]; - - if (self.isTrackingLeftHandle) { - self.minValue = MIN(MAX(self.allowedMinValue, [self valueAt:loc.x]), self.maxValue); - } else if (self.isTrackingRightHandle) { - self.maxValue = MAX(MIN(self.allowedMaxValue, [self valueAt:loc.x]), self.minValue); - } else { - return NO; - } - - [self setNeedsLayout]; - [self layoutIfNeeded]; - - return YES; -} - -- (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { - self.trackingLeftHandle = NO; - self.trackingRightHandle = NO; -} - -- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { - return NO; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.h deleted file mode 100644 index c0c92415..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.h +++ /dev/null @@ -1,46 +0,0 @@ -// -// FHSSnapshotView.h -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSViewSnapshot.h" -#import "FHSRangeSlider.h" - -NS_ASSUME_NONNULL_BEGIN - -@protocol FHSSnapshotViewDelegate - -- (void)didSelectView:(FHSViewSnapshot *)snapshot; -- (void)didDeselectView:(FHSViewSnapshot *)snapshot; -- (void)didLongPressView:(FHSViewSnapshot *)snapshot; - -@end - -@interface FHSSnapshotView : UIView - -+ (instancetype)delegate:(id)delegate; - -@property (nonatomic, weak) id delegate; - -@property (nonatomic) NSArray *snapshots; -@property (nonatomic, nullable) FHSViewSnapshot *selectedView; - -/// Views of these classes will have their headers hidden -@property (nonatomic) NSArray *headerExclusions; - -@property (nonatomic, readonly) UISlider *spacingSlider; -@property (nonatomic, readonly) FHSRangeSlider *depthSlider; - -- (void)emphasizeViews:(NSArray *)emphasizedViews; - -- (void)toggleShowHeaders; -- (void)toggleShowBorders; - -- (void)hideView:(FHSViewSnapshot *)view; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.m deleted file mode 100644 index d4b11269..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSSnapshotView.m +++ /dev/null @@ -1,304 +0,0 @@ -// -// FHSSnapshotView.m -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSSnapshotView.h" -#import "FHSSnapshotNodes.h" -#import "SceneKit+Snapshot.h" -#import "FLEXColor.h" - -@interface FHSSnapshotView () -@property (nonatomic, readonly) SCNView *sceneView; -@property (nonatomic) NSString *currentSummary; - -/// Maps nodes by snapshot IDs -@property (nonatomic) NSDictionary *nodesMap; -@property (nonatomic) NSInteger maxDepth; - -@property (nonatomic) FHSSnapshotNodes *highlightedNodes; -@property (nonatomic, getter=wantsHideHeaders) BOOL hideHeaders; -@property (nonatomic, getter=wantsHideBorders) BOOL hideBorders; -@property (nonatomic) BOOL suppressSelectionEvents; - -@property (nonatomic, readonly) BOOL mustHideHeaders; -@end - -@implementation FHSSnapshotView - -#pragma mark - Initialization - -+ (instancetype)delegate:(id)delegate { - FHSSnapshotView *view = [self new]; - view.delegate = delegate; - return view; -} - -- (id)initWithFrame:(CGRect)frame { - self = [super initWithFrame:CGRectZero]; - if (self) { - [self initSpacingSlider]; - [self initDepthSlider]; - [self initSceneView]; // Must be last; calls setMaxDepth -// self.hideHeaders = YES; - - // Self - self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - - // Scene - self.sceneView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; - [self addGestureRecognizer:[[UITapGestureRecognizer alloc] - initWithTarget:self action:@selector(handleTap:) - ]]; - } - - return self; -} - -- (void)initSceneView { - _sceneView = [SCNView new]; - self.sceneView.allowsCameraControl = YES; - - [self addSubview:self.sceneView]; -} - -- (void)initSpacingSlider { - _spacingSlider = [UISlider new]; - self.spacingSlider.minimumValue = 0; - self.spacingSlider.maximumValue = 100; - self.spacingSlider.continuous = YES; - [self.spacingSlider - addTarget:self - action:@selector(spacingSliderDidChange:) - forControlEvents:UIControlEventValueChanged - ]; - - self.spacingSlider.value = 50; -} - -- (void)initDepthSlider { - _depthSlider = [FHSRangeSlider new]; - [self.depthSlider - addTarget:self - action:@selector(depthSliderDidChange:) - forControlEvents:UIControlEventValueChanged - ]; -} - - -#pragma mark - Public - -- (void)setSelectedView:(FHSViewSnapshot *)view { - // Ivar set in selectSnapshot: - [self selectSnapshot:view ? self.nodesMap[view.view.identifier] : nil]; -} - -- (void)setSnapshots:(NSArray *)snapshots { - _snapshots = snapshots; - - // Create new scene (possibly discarding old scene) - SCNScene *scene = [SCNScene new]; - scene.background.contents = FLEXColor.primaryBackgroundColor; - self.sceneView.scene = scene; - - NSInteger depth = 0; - NSMutableDictionary *nodesMap = [NSMutableDictionary new]; - - // Add every root snapshot to the root scene node with increasing depths - SCNNode *root = scene.rootNode; - for (FHSViewSnapshot *snapshot in self.snapshots) { - [SCNNode - snapshot:snapshot - parent:nil - parentNode:nil - root:root - depth:&depth - nodesMap:nodesMap - hideHeaders:_hideHeaders - ]; - } - - self.maxDepth = depth; - self.nodesMap = nodesMap; -} - -- (void)setHeaderExclusions:(NSArray *)headerExclusions { - _headerExclusions = headerExclusions; - - if (headerExclusions.count) { - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - if ([headerExclusions containsObject:nodes.snapshotItem.view.view.class]) { - nodes.forceHideHeader = YES; - } else { - nodes.forceHideHeader = NO; - } - } - } -} - -- (void)emphasizeViews:(NSArray *)emphasizedViews { - if (emphasizedViews.count) { - [self emphasizeViews:emphasizedViews inSnapshots:self.snapshots]; - [self setNeedsLayout]; - } -} - -- (void)emphasizeViews:(NSArray *)emphasizedViews inSnapshots:(NSArray *)snapshots { - for (FHSViewSnapshot *snapshot in snapshots) { - FHSSnapshotNodes *nodes = self.nodesMap[snapshot.view.identifier]; - nodes.dimmed = ![emphasizedViews containsObject:snapshot.view.view]; - [self emphasizeViews:emphasizedViews inSnapshots:snapshot.children]; - } -} - -- (void)toggleShowHeaders { - self.hideHeaders = !self.hideHeaders; -} - -- (void)toggleShowBorders { - self.hideBorders = !self.hideBorders; -} - -- (void)hideView:(FHSViewSnapshot *)view { - NSParameterAssert(view); - FHSSnapshotNodes *nodes = self.nodesMap[view.view.identifier]; - [nodes.snapshot removeFromParentNode]; -} - -#pragma mark - Helper - -- (BOOL)mustHideHeaders { - return self.spacingSlider.value <= kFHSSmallZOffset; -} - -- (void)setMaxDepth:(NSInteger)maxDepth { - _maxDepth = maxDepth; - - self.depthSlider.allowedMinValue = 0; - self.depthSlider.allowedMaxValue = maxDepth; - self.depthSlider.maxValue = maxDepth; - self.depthSlider.minValue = 0; -} - -- (void)setHideHeaders:(BOOL)hideHeaders { - if (_hideHeaders != hideHeaders) { - _hideHeaders = hideHeaders; - - if (!self.mustHideHeaders) { - if (hideHeaders) { - [self hideHeaders]; - } else { - [self unhideHeaders]; - } - } - } -} - -- (void)setHideBorders:(BOOL)hideBorders { - if (_hideBorders != hideBorders) { - _hideBorders = hideBorders; - - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - nodes.border.hidden = hideBorders; - } - } -} - -- (FHSSnapshotNodes *)nodesAtPoint:(CGPoint)point { - NSArray *results = [self.sceneView hitTest:point options:nil]; - for (SCNHitTestResult *result in results) { - SCNNode *nearestSnapshot = result.node.nearestAncestorSnapshot; - if (nearestSnapshot) { - return self.nodesMap[nearestSnapshot.name]; - } - } - - return nil; -} - -- (void)selectSnapshot:(FHSSnapshotNodes *)selected { - // Notify delegate of de-select - if (!selected && self.selectedView) { - [self.delegate didDeselectView:self.selectedView]; - } - - _selectedView = selected.snapshotItem; - - // Case: selected the currently selected node - if (selected == self.highlightedNodes) { - return; - } - - // No-op if nothng is selected (yay objc!) - self.highlightedNodes.highlighted = NO; - self.highlightedNodes = nil; - - // No node means we tapped the background - if (selected) { - selected.highlighted = YES; - // TODO: update description text here - self.highlightedNodes = selected; - } - - // Notify delegate - [self.delegate didSelectView:selected.snapshotItem]; - - [self setNeedsLayout]; -} - -- (void)hideHeaders { - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - nodes.header.hidden = YES; - } -} - -- (void)unhideHeaders { - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - if (!nodes.forceHideHeader) { - nodes.header.hidden = NO; - } - } -} - - -#pragma mark - Event Handlers - -- (void)handleTap:(UITapGestureRecognizer *)gesture { - if (gesture.state == UIGestureRecognizerStateRecognized) { - CGPoint tap = [gesture locationInView:self.sceneView]; - [self selectSnapshot:[self nodesAtPoint:tap]]; - } -} - -- (void)spacingSliderDidChange:(UISlider *)slider { - // TODO: hiding the header when flat logic - - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - nodes.snapshot.position = ({ - SCNVector3 pos = nodes.snapshot.position; - pos.z = MAX(slider.value, kFHSSmallZOffset) * nodes.depth; - pos; - }); - - if (!self.wantsHideHeaders) { - if (self.mustHideHeaders) { - [self hideHeaders]; - } else { - [self unhideHeaders]; - } - } - } -} - -- (void)depthSliderDidChange:(FHSRangeSlider *)slider { - CGFloat min = slider.minValue, max = slider.maxValue; - for (FHSSnapshotNodes *nodes in self.nodesMap.allValues) { - CGFloat depth = nodes.depth; - nodes.snapshot.hidden = depth < min || max < depth; - } -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.h deleted file mode 100644 index 70122c12..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.h +++ /dev/null @@ -1,35 +0,0 @@ -// -// FHSView.h -// FLEX -// -// Created by Tanner Bennett on 1/6/20. -// - -#import - -@interface FHSView : NSObject { - @private - BOOL _inScrollView; -} - -+ (instancetype)forView:(UIView *)view isInScrollView:(BOOL)inScrollView; - -/// Intentionally not weak -@property (nonatomic, readonly) UIView *view; -@property (nonatomic, readonly) NSString *identifier; - -@property (nonatomic, readonly) NSString *title; -/// Whether or not this view item should be visually distinguished -@property (nonatomic, readwrite) BOOL important; - -@property (nonatomic, readonly) CGRect frame; -@property (nonatomic, readonly) BOOL hidden; -@property (nonatomic, readonly) UIImage *snapshotImage; - -@property (nonatomic, readonly) NSArray *children; -@property (nonatomic, readonly) NSString *summary; - -/// @return importantAttr if .important, otherwise normalAttr -//- (id)ifImportant:(id)importantAttr ifNormal:(id)normalAttr; - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.m deleted file mode 100644 index 65bf1cf8..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSView.m +++ /dev/null @@ -1,194 +0,0 @@ -// -// FHSView.m -// FLEX -// -// Created by Tanner Bennett on 1/6/20. -// - -#import "FHSView.h" -#import "FLEXUtility.h" -#import "NSArray+FLEX.h" - -@interface FHSView (Snapshotting) -+ (UIImage *)_snapshotView:(UIView *)view; -@end - -@implementation FHSView - -+ (instancetype)forView:(UIView *)view isInScrollView:(BOOL)inScrollView { - return [[self alloc] initWithView:view isInScrollView:inScrollView]; -} - -- (id)initWithView:(UIView *)view isInScrollView:(BOOL)inScrollView { - self = [super init]; - if (self) { - _view = view; - _inScrollView = inScrollView; - _identifier = NSUUID.UUID.UUIDString; - - UIViewController *controller = [FLEXUtility viewControllerForView:view]; - if (controller) { - _important = YES; - _title = [NSString stringWithFormat: - @"%@ (for %@)", - NSStringFromClass([controller class]), - NSStringFromClass([view class]) - ]; - } else { - _title = NSStringFromClass([view class]); - } - } - - return self; -} - -- (CGRect)frame { - if (_inScrollView) { - CGPoint offset = [(UIScrollView *)self.view.superview contentOffset]; - return CGRectOffset(self.view.frame, -offset.x, -offset.y); - } else { - return self.view.frame; - } -} - -- (BOOL)hidden { - return self.view.isHidden; -} - -- (UIImage *)snapshotImage { - return [FHSView _snapshotView:self.view]; -} - -- (NSArray *)children { - BOOL isScrollView = [self.view isKindOfClass:[UIScrollView class]]; - return [self.view.subviews flex_mapped:^id(UIView *subview, NSUInteger idx) { - return [FHSView forView:subview isInScrollView:isScrollView]; - }]; -} - -- (NSString *)summary { - CGRect f = self.frame; - return [NSString stringWithFormat: - @"%@ (%.1f, %.1f, %.1f, %.1f)", - NSStringFromClass([self.view class]), - f.origin.x, f.origin.y, f.size.width, f.size.height - ]; -} - -- (NSString *)description{ - return self.view.description; -} - -- (id)ifImportant:(id)importantAttr ifNormal:(id)normalAttr { - return self.important ? importantAttr : normalAttr; -} - -@end - -@implementation FHSView (Snapshotting) - -+ (UIImage *)drawView:(UIView *)view { - UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0); - [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:YES]; - UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); - UIGraphicsEndImageContext(); - return image; -} - -/// Recursively hides all views that may be obscuring the given view and collects them -/// in the given array. You should unhide them all when you are done. -+ (BOOL)_hideViewsCoveringView:(UIView *)view - root:(UIView *)rootView - hiddenViews:(NSMutableArray *)hiddenViews { - // Stop when we reach this view - if (view == rootView) { - return YES; - } - - for (UIView *subview in rootView.subviews.reverseObjectEnumerator.allObjects) { - if ([self _hideViewsCoveringView:view root:subview hiddenViews:hiddenViews]) { - return YES; - } - } - - if (!rootView.isHidden) { - rootView.hidden = YES; - [hiddenViews addObject:rootView]; - } - - return NO; -} - - -/// Recursively hides all views that may be obscuring the given view and collects them -/// in the given array. You should unhide them all when you are done. -+ (void)hideViewsCoveringView:(UIView *)view doWhileHidden:(void(^)(void))block { - NSMutableArray *viewsToUnhide = [NSMutableArray new]; - if ([self _hideViewsCoveringView:view root:view.window hiddenViews:viewsToUnhide]) { - block(); - } - - for (UIView *v in viewsToUnhide) { - v.hidden = NO; - } -} - -+ (UIImage *)_snapshotVisualEffectBackdropView:(UIView *)view { - NSParameterAssert(view.window); - - // UIVisualEffectView is a special case that cannot be snapshotted - // the same way as any other view. From Apple docs: - // - // Many effects require support from the window that hosts the - // UIVisualEffectView. Attempting to take a snapshot of only the - // UIVisualEffectView will result in a snapshot that does not - // contain the effect. To take a snapshot of a view hierarchy - // that contains a UIVisualEffectView, you must take a snapshot - // of the entire UIWindow or UIScreen that contains it. - // - // To snapshot this view, we traverse the view hierarchy starting - // from the window and hide any views that are on top of the - // _UIVisualEffectBackdropView so that it is visible in a snapshot - // of the window. We then take a snapshot of the window and crop - // it to the part that contains the backdrop view. This appears to - // be the same technique that Xcode's own view debugger uses to - // snapshot visual effect views. - __block UIImage *image = nil; - [self hideViewsCoveringView:view doWhileHidden:^{ - image = [self drawView:view]; - CGRect cropRect = [view.window convertRect:view.bounds fromView:view]; - image = [UIImage imageWithCGImage:CGImageCreateWithImageInRect(image.CGImage, cropRect)]; - }]; - - return image; -} - -+ (UIImage *)_snapshotView:(UIView *)view { - UIView *superview = view.superview; - // Is this view inside a UIVisualEffectView? - if ([superview isKindOfClass:[UIVisualEffectView class]]) { - // Is it (probably) the "backdrop" view of this UIVisualEffectView? - if (superview.subviews.firstObject == view) { - return [self _snapshotVisualEffectBackdropView:view]; - } - } - - // Hide the view's subviews before we snapshot it - NSMutableIndexSet *toUnhide = [NSMutableIndexSet new]; - [view.subviews flex_forEach:^(UIView *v, NSUInteger idx) { - if (!v.isHidden) { - v.hidden = YES; - [toUnhide addIndex:idx]; - } - }]; - - // Snapshot the view, then unhide the previously-unhidden views - UIImage *snapshot = [self drawView:view]; - for (UIView *v in [view.subviews objectsAtIndexes:toUnhide]) { - v.hidden = NO; - } - - return snapshot; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.h deleted file mode 100644 index 32891dc3..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.h +++ /dev/null @@ -1,29 +0,0 @@ -// -// FHSViewController.h -// FLEX -// -// Created by Tanner Bennett on 1/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import - -NS_ASSUME_NONNULL_BEGIN - -/// The view controller -/// "FHS" stands for "FLEX (view) hierarchy snapshot" -@interface FHSViewController : UIViewController - -/// Use this when you want to snapshot a set of windows. -+ (instancetype)snapshotWindows:(NSArray *)windows; -/// Use this when you want to snapshot a specific slice of the view hierarchy. -+ (instancetype)snapshotView:(UIView *)view; -/// Use this when you want to emphasize specific views on the screen. -/// These views must all be in the same window as the selected view. -+ (instancetype)snapshotViewsAtTap:(NSArray *)viewsAtTap selectedView:(UIView *)view; - -@property (nonatomic, nullable) UIView *selectedView; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.m deleted file mode 100644 index 6fbc933a..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewController.m +++ /dev/null @@ -1,270 +0,0 @@ -// -// FHSViewController.m -// FLEX -// -// Created by Tanner Bennett on 1/6/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSViewController.h" -#import "FHSSnapshotView.h" -#import "FLEXHierarchyViewController.h" -#import "FLEXColor.h" -#import "FLEXAlert.h" -#import "FLEXWindow.h" -#import "FLEXResources.h" -#import "NSArray+FLEX.h" -#import "UIBarButtonItem+FLEX.h" - -BOOL const kFHSViewControllerExcludeFLEXWindows = YES; - -@interface FHSViewController () -/// An array of only the target views whose hierarchies -/// we wish to snapshot, not every view in the snapshot. -@property (nonatomic, readonly) NSArray *targetViews; -@property (nonatomic, readonly) NSArray *views; -@property (nonatomic ) NSArray *snapshots; -@property (nonatomic, ) FHSSnapshotView *snapshotView; - -@property (nonatomic, readonly) UIView *containerView; -@property (nonatomic, readonly) NSArray *viewsAtTap; -@property (nonatomic, readonly) NSMutableSet *forceHideHeaders; -@end - -@implementation FHSViewController -@synthesize views = _views; -@synthesize snapshotView = _snapshotView; - -#pragma mark - Initialization - -+ (instancetype)snapshotWindows:(NSArray *)windows { - return [[self alloc] initWithViews:windows viewsAtTap:nil selectedView:nil]; -} - -+ (instancetype)snapshotView:(UIView *)view { - return [[self alloc] initWithViews:@[view] viewsAtTap:nil selectedView:nil]; -} - -+ (instancetype)snapshotViewsAtTap:(NSArray *)viewsAtTap selectedView:(UIView *)view { - NSParameterAssert(viewsAtTap.count); - NSParameterAssert(view.window); - return [[self alloc] initWithViews:@[view.window] viewsAtTap:viewsAtTap selectedView:view]; -} - -- (id)initWithViews:(NSArray *)views - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)view { - NSParameterAssert(views.count); - - self = [super init]; - if (self) { - _forceHideHeaders = [NSMutableSet setWithObject:NSClassFromString(@"_UITableViewCellSeparatorView")]; - _selectedView = view; - _viewsAtTap = viewsAtTap; - - if (!viewsAtTap && kFHSViewControllerExcludeFLEXWindows) { - Class flexwindow = [FLEXWindow class]; - views = [views flex_filtered:^BOOL(UIView *view, NSUInteger idx) { - return [view class] != flexwindow; - }]; - } - - _targetViews = views; - _views = [views flex_mapped:^id(UIView *view, NSUInteger idx) { - BOOL isScrollView = [view.superview isKindOfClass:[UIScrollView class]]; - return [FHSView forView:view isInScrollView:isScrollView]; - }]; - } - - return self; -} - -- (void)refreshSnapshotView { - // Alert view to block interaction while we load everything - UIAlertController *loading = [FLEXAlert makeAlert:^(FLEXAlert *make) { - make.title(@"Please Wait").message(@"Generating snapshot…"); - }]; - [self presentViewController:loading animated:YES completion:^{ - self.snapshots = [self.views flex_mapped:^id(FHSView *view, NSUInteger idx) { - return [FHSViewSnapshot snapshotWithView:view]; - }]; - FHSSnapshotView *newSnapshotView = [FHSSnapshotView delegate:self]; - - // This work is highly intensive so we do it on a background thread first - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ - // Setting the snapshots computes lots of SCNNodes, takes several seconds - newSnapshotView.snapshots = self.snapshots; - - // After we finish generating all the model objects and scene nodes, display the view - dispatch_async(dispatch_get_main_queue(), ^{ - // Dismiss alert - [loading dismissViewControllerAnimated:YES completion:nil]; - - self.snapshotView = newSnapshotView; - }); - }); - }]; -} - - -#pragma mark - View Controller Lifecycle - -- (void)loadView { - [super loadView]; - self.view.backgroundColor = FLEXColor.primaryBackgroundColor; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Initialize back bar button item for 3D view to look like a button - self.navigationItem.hidesBackButton = YES; - self.navigationItem.leftBarButtonItem = [UIBarButtonItem - flex_itemWithImage:FLEXResources.toggle2DIcon - target:self.navigationController - action:@selector(toggleHierarchyMode) - ]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - if (!_snapshotView) { - [self refreshSnapshotView]; - } -} - - -#pragma mark - Public - -- (void)setSelectedView:(UIView *)view { - _selectedView = view; - self.snapshotView.selectedView = view ? [self snapshotForView:view] : nil; -} - - -#pragma mark - Private - -#pragma mark Properties - -- (FHSSnapshotView *)snapshotView { - return self.isViewLoaded ? _snapshotView : nil; -} - -- (void)setSnapshotView:(FHSSnapshotView *)snapshotView { - NSParameterAssert(snapshotView); - - _snapshotView = snapshotView; - - // Initialize our toolbar items - self.toolbarItems = @[ - [UIBarButtonItem flex_itemWithCustomView:snapshotView.spacingSlider], - UIBarButtonItem.flex_flexibleSpace, - [UIBarButtonItem - flex_itemWithImage:FLEXResources.moreIcon - target:self action:@selector(didPressOptionsButton:) - ], - UIBarButtonItem.flex_flexibleSpace, - [UIBarButtonItem flex_itemWithCustomView:snapshotView.depthSlider] - ]; - [self resizeToolbarItems:self.view.frame.size]; - - // If we have views-at-tap, dim the other views - [snapshotView emphasizeViews:self.viewsAtTap]; - // Set the selected view, if any - snapshotView.selectedView = [self snapshotForView:self.selectedView]; - snapshotView.headerExclusions = self.forceHideHeaders.allObjects; - [snapshotView setNeedsLayout]; - - // Remove old snapshot, if any, and add the new one - [_snapshotView removeFromSuperview]; - snapshotView.frame = self.containerView.bounds; - [self.containerView addSubview:snapshotView]; -} - -- (UIView *)containerView { - return self.view; -} - -#pragma mark Helper - -- (FHSViewSnapshot *)snapshotForView:(UIView *)view { - if (!view || !self.snapshots.count) return nil; - - for (FHSViewSnapshot *snapshot in self.snapshots) { - FHSViewSnapshot *found = [snapshot snapshotForView:view]; - if (found) { - return found; - } - } - - // Error: we have snapshots but the view we requested is not in one - @throw NSInternalInconsistencyException; - return nil; -} - -#pragma mark Events - -- (void)didPressOptionsButton:(UIBarButtonItem *)sender { - [FLEXAlert makeSheet:^(FLEXAlert *make) { - if (self.selectedView) { - make.button(@"Hide selected view").handler(^(NSArray *strings) { - [self.snapshotView hideView:[self snapshotForView:self.selectedView]]; - }); - make.button(@"Hide headers for views like this").handler(^(NSArray *strings) { - Class cls = [self.selectedView class]; - if (![self.forceHideHeaders containsObject:cls]) { - [self.forceHideHeaders addObject:[self.selectedView class]]; - self.snapshotView.headerExclusions = self.forceHideHeaders.allObjects; - } - }); - } - make.title(@"Options"); - make.button(@"Toggle headers").handler(^(NSArray *strings) { - [self.snapshotView toggleShowHeaders]; - }); - make.button(@"Toggle outlines").handler(^(NSArray *strings) { - [self.snapshotView toggleShowBorders]; - }); - make.button(@"Cancel").cancelStyle(); - } showFrom:self source:sender]; -} - -- (void)resizeToolbarItems:(CGSize)viewSize { - CGFloat sliderHeights = self.snapshotView.spacingSlider.bounds.size.height; - CGFloat sliderWidths = viewSize.width / 3.f; - CGRect frame = CGRectMake(0, 0, sliderWidths, sliderHeights); - self.snapshotView.spacingSlider.frame = frame; - self.snapshotView.depthSlider.frame = frame; - - [self.navigationController.toolbar setNeedsLayout]; -} - -- (void)viewWillTransitionToSize:(CGSize)size - withTransitionCoordinator:(id)coordinator { - [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; - - [coordinator animateAlongsideTransition:^(id _Nonnull context) { - [self resizeToolbarItems:self.view.frame.size]; - } completion:nil]; -} - -#pragma mark FHSSnapshotViewDelegate - -- (void)didDeselectView:(FHSViewSnapshot *)snapshot { - // Our setter would also call the setter for the snapshot view, - // which we don't need to do here since it is already selected - _selectedView = nil; -} - -- (void)didLongPressView:(FHSViewSnapshot *)snapshot { - -} - -- (void)didSelectView:(FHSViewSnapshot *)snapshot { - // Our setter would also call the setter for the snapshot view, - // which we don't need to do here since it is already selected - _selectedView = snapshot.view.view; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.h deleted file mode 100644 index eee84e4b..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// FHSViewSnapshot.h -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSView.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FHSViewSnapshot : NSObject - -+ (instancetype)snapshotWithView:(FHSView *)view; - -@property (nonatomic, readonly) FHSView *view; - -@property (nonatomic, readonly) NSString *title; -/// Whether or not this view item should be visually distinguished -@property (nonatomic, readwrite) BOOL important; - -@property (nonatomic, readonly) CGRect frame; -@property (nonatomic, readonly) BOOL hidden; -@property (nonatomic, readonly) UIImage *snapshotImage; - -@property (nonatomic, readonly) NSArray *children; -@property (nonatomic, readonly) NSString *summary; - -/// Returns a different color based on whether or not the view is important -@property (nonatomic, readonly) UIColor *headerColor; - -- (FHSViewSnapshot *)snapshotForView:(UIView *)view; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.m deleted file mode 100644 index 4911e033..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/FHSViewSnapshot.m +++ /dev/null @@ -1,62 +0,0 @@ -// -// FHSViewSnapshot.m -// FLEX -// -// Created by Tanner Bennett on 1/9/20. -// Copyright © 2020 FLEX Team. All rights reserved. -// - -#import "FHSViewSnapshot.h" -#import "NSArray+FLEX.h" - -@implementation FHSViewSnapshot - -+ (instancetype)snapshotWithView:(FHSView *)view { - NSArray *children = [view.children flex_mapped:^id(FHSView *v, NSUInteger idx) { - return [self snapshotWithView:v]; - }]; - return [[self alloc] initWithView:view children:children]; -} - -- (id)initWithView:(FHSView *)view children:(NSArray *)children { - NSParameterAssert(view); NSParameterAssert(children); - - self = [super init]; - if (self) { - _view = view; - _title = view.title; - _important = view.important; - _frame = view.frame; - _hidden = view.hidden; - _snapshotImage = view.snapshotImage; - _children = children; - _summary = view.summary; - } - - return self; -} - -- (UIColor *)headerColor { - if (self.important) { - return [UIColor colorWithRed: 0.000 green: 0.533 blue: 1.000 alpha: 0.900]; - } else { - return [UIColor colorWithRed:0.961 green: 0.651 blue: 0.137 alpha: 0.900]; - } -} - -- (FHSViewSnapshot *)snapshotForView:(UIView *)view { - if (view == self.view.view) { - return self; - } - - for (FHSViewSnapshot *child in self.children) { - FHSViewSnapshot *snapshot = [child snapshotForView:view]; - if (snapshot) { - return snapshot; - } - } - - return nil; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.h deleted file mode 100644 index 8e32249a..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// FHSSnapshotNodes.h -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// - -#import "FHSViewSnapshot.h" -#import - -NS_ASSUME_NONNULL_BEGIN - -/// Container that holds references to the SceneKit nodes associated with a snapshot. -@interface FHSSnapshotNodes : NSObject - -+ (instancetype)snapshot:(FHSViewSnapshot *)snapshot depth:(NSInteger)depth; - -@property (nonatomic, readonly) FHSViewSnapshot *snapshotItem; -@property (nonatomic, readonly) NSInteger depth; - -/// The view image itself -@property (nonatomic, nullable) SCNNode *snapshot; -/// Goes on top of the snapshot, has rounded top corners -@property (nonatomic, nullable) SCNNode *header; -/// The bounding box drawn around the snapshot -@property (nonatomic, nullable) SCNNode *border; - -/// Used to indicate when a view is selected -@property (nonatomic, getter=isHighlighted) BOOL highlighted; -/// Used to indicate when a view is de-emphasized -@property (nonatomic, getter=isDimmed) BOOL dimmed; - -@property (nonatomic) BOOL forceHideHeader; - -@end - -NS_ASSUME_NONNULL_END diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.m deleted file mode 100644 index 052418e8..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/FHSSnapshotNodes.m +++ /dev/null @@ -1,90 +0,0 @@ -// -// FHSSnapshotNodes.m -// FLEX -// -// Created by Tanner Bennett on 1/7/20. -// - -#import "FHSSnapshotNodes.h" -#import "SceneKit+Snapshot.h" - -@interface FHSSnapshotNodes () -@property (nonatomic, nullable) SCNNode *highlight; -@property (nonatomic, nullable) SCNNode *dimming; -@end -@implementation FHSSnapshotNodes - -+ (instancetype)snapshot:(FHSViewSnapshot *)snapshot depth:(NSInteger)depth { - FHSSnapshotNodes *nodes = [self new]; - nodes->_snapshotItem = snapshot; - nodes->_depth = depth; - return nodes; -} - -- (void)setHighlighted:(BOOL)highlighted { - if (_highlighted != highlighted) { - _highlighted = highlighted; - - if (highlighted) { - if (!self.highlight) { - // Create highlight node - self.highlight = [SCNNode - highlight:self.snapshotItem - color:[UIColor.blueColor colorWithAlphaComponent:0.5] - ]; - } - // Add add highlight node, remove dimming node if dimmed - [self.snapshot addChildNode:self.highlight]; - if (self.isDimmed) { - [self.dimming removeFromParentNode]; - } - } else { - // Remove highlight node, add back dimming node if dimmed - [self.highlight removeFromParentNode]; - if (self.isDimmed) { - [self.snapshot addChildNode:self.dimming]; - } - } - } -} - -- (void)setDimmed:(BOOL)dimmed { - if (_dimmed != dimmed) { - _dimmed = dimmed; - - if (dimmed) { - if (!self.dimming) { - // Create dimming node - self.dimming = [SCNNode - highlight:self.snapshotItem - color:[UIColor.blackColor colorWithAlphaComponent:0.5] - ]; - } - // Add add dimming node if not highlighted - if (!self.isHighlighted) { - [self.snapshot addChildNode:self.dimming]; - } - } else { - // Remove dimming node (if not already highlighted) - if (!self.isHighlighted) { - [self.dimming removeFromParentNode]; - } - } - } -} - -- (void)setForceHideHeader:(BOOL)forceHideHeader { - if (_forceHideHeader != forceHideHeader) { - _forceHideHeader = forceHideHeader; - - if (self.header.parentNode) { - self.header.hidden = YES; - [self.header removeFromParentNode]; - } else { - self.header.hidden = NO; - [self.snapshot addChildNode:self.header]; - } - } -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.h b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.h deleted file mode 100644 index 8148ff9b..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.h +++ /dev/null @@ -1,62 +0,0 @@ -// -// SceneKit+Snapshot.h -// FLEX -// -// Created by Tanner Bennett on 1/8/20. -// - -#import -#import "FHSViewSnapshot.h" -@class FHSSnapshotNodes; - -extern CGFloat const kFHSSmallZOffset; - -#pragma mark SCNNode -@interface SCNNode (Snapshot) - -/// @return the nearest ancestor snapshot node starting at this node -@property (nonatomic, readonly) SCNNode *nearestAncestorSnapshot; - -/// @return a node that renders a highlight overlay over a specified snapshot -+ (instancetype)highlight:(FHSViewSnapshot *)view color:(UIColor *)color; -/// @return a node that renders a snapshot image -+ (instancetype)snapshot:(FHSViewSnapshot *)view; -/// @return a node that draws a line between two vertices -+ (instancetype)lineFrom:(SCNVector3)v1 to:(SCNVector3)v2 color:(UIColor *)lineColor; - -/// @return a node that can be used to render a colored border around the specified node -- (instancetype)borderWithColor:(UIColor *)color; -/// @return a node that renders a header above a snapshot node -/// using the title text from the view, if specified -+ (instancetype)header:(FHSViewSnapshot *)view; - -/// @return a SceneKit node that recursively renders a hierarchy -/// of UI elements starting at the specified snapshot -+ (instancetype)snapshot:(FHSViewSnapshot *)view - parent:(FHSViewSnapshot *)parentView - parentNode:(SCNNode *)parentNode - root:(SCNNode *)rootNode - depth:(NSInteger *)depthOut - nodesMap:(NSMutableDictionary *)nodesMap - hideHeaders:(BOOL)hideHeaders; - -@end - - -#pragma mark SCNShape -@interface SCNShape (Snapshot) -/// @return a shape with the given path, 0 extrusion depth, and a double-sided -/// material with the given diffuse contents inserted at index 0 -+ (instancetype)shapeWithPath:(UIBezierPath *)path materialDiffuse:(id)contents; -/// @return a shape that is used to render the background of the snapshot header -+ (instancetype)nameHeader:(UIColor *)color frame:(CGRect)frame corners:(CGFloat)cornerRadius; - -@end - - -#pragma mark SCNText -@interface SCNText (Snapshot) -/// @return text geometry used to render text inside the snapshot header -+ (instancetype)labelGeometry:(NSString *)text font:(UIFont *)font; - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.m b/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.m deleted file mode 100644 index 4dff682c..00000000 --- a/BHTwitter/Classes/ViewHierarchy/SnapshotExplorer/Scene/SceneKit+Snapshot.m +++ /dev/null @@ -1,278 +0,0 @@ -// -// SceneKit+Snapshot.m -// FLEX -// -// Created by Tanner Bennett on 1/8/20. -// - -#import "SceneKit+Snapshot.h" -#import "FHSSnapshotNodes.h" - -/// This value is chosen such that this offset can be applied to avoid -/// z-fighting amongst nodes at the same z-position, but small enough -/// that they appear to visually be on the same plane. -CGFloat const kFHSSmallZOffset = 0.05; -CGFloat const kHeaderVerticalInset = 8.0; - -#pragma mark SCNGeometry -@interface SCNGeometry (SnapshotPrivate) -@end -@implementation SCNGeometry (SnapshotPrivate) - -- (void)addDoubleSidedMaterialWithDiffuseContents:(id)contents { - SCNMaterial *material = [SCNMaterial new]; - material.doubleSided = YES; - material.diffuse.contents = contents; - [self insertMaterial:material atIndex:0]; -} - -@end - -#pragma mark SCNNode -@implementation SCNNode (Snapshot) - -- (SCNNode *)nearestAncestorSnapshot { - SCNNode *node = self; - - while (!node.name && node) { - node = node.parentNode; - } - - return node; -} - -+ (instancetype)shapeNodeWithSize:(CGSize)size materialDiffuse:(id)contents offsetZ:(BOOL)offsetZ { - UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake( - 0, 0, size.width, size.height - )]; - SCNShape *shape = [SCNShape shapeWithPath:path materialDiffuse:contents]; - SCNNode *node = [SCNNode nodeWithGeometry:shape]; - - if (offsetZ) { - node.position = SCNVector3Make(0, 0, kFHSSmallZOffset); - } - return node; -} - -+ (instancetype)highlight:(FHSViewSnapshot *)view color:(UIColor *)color { - return [self shapeNodeWithSize:view.frame.size materialDiffuse:color offsetZ:YES]; -} - -+ (instancetype)snapshot:(FHSViewSnapshot *)view { - id image = view.snapshotImage; - return [self shapeNodeWithSize:view.frame.size materialDiffuse:image offsetZ:NO]; -} - -+ (instancetype)lineFrom:(SCNVector3)v1 to:(SCNVector3)v2 color:(UIColor *)lineColor { - SCNVector3 vertices[2] = { v1, v2 }; - int32_t _indices[2] = { 0, 1 }; - NSData *indices = [NSData dataWithBytes:_indices length:sizeof(_indices)]; - - SCNGeometrySource *source = [SCNGeometrySource geometrySourceWithVertices:vertices count:2]; - SCNGeometryElement *element = [SCNGeometryElement - geometryElementWithData:indices - primitiveType:SCNGeometryPrimitiveTypeLine - primitiveCount:2 - bytesPerIndex:sizeof(int32_t) - ]; - - SCNGeometry *geometry = [SCNGeometry geometryWithSources:@[source] elements:@[element]]; - [geometry addDoubleSidedMaterialWithDiffuseContents:lineColor]; - return [SCNNode nodeWithGeometry:geometry]; -} - -- (instancetype)borderWithColor:(UIColor *)color { - struct { SCNVector3 min, max; } bb; - [self getBoundingBoxMin:&bb.min max:&bb.max]; - - SCNVector3 topLeft = SCNVector3Make(bb.min.x, bb.max.y, kFHSSmallZOffset); - SCNVector3 bottomLeft = SCNVector3Make(bb.min.x, bb.min.y, kFHSSmallZOffset); - SCNVector3 topRight = SCNVector3Make(bb.max.x, bb.max.y, kFHSSmallZOffset); - SCNVector3 bottomRight = SCNVector3Make(bb.max.x, bb.min.y, kFHSSmallZOffset); - - SCNNode *top = [SCNNode lineFrom:topLeft to:topRight color:color]; - SCNNode *left = [SCNNode lineFrom:bottomLeft to:topLeft color:color]; - SCNNode *bottom = [SCNNode lineFrom:bottomLeft to:bottomRight color:color]; - SCNNode *right = [SCNNode lineFrom:bottomRight to:topRight color:color]; - - SCNNode *border = [SCNNode new]; - [border addChildNode:top]; - [border addChildNode:left]; - [border addChildNode:bottom]; - [border addChildNode:right]; - - return border; -} - -+ (instancetype)header:(FHSViewSnapshot *)view { - SCNText *text = [SCNText labelGeometry:view.title font:[UIFont boldSystemFontOfSize:13.0]]; - SCNNode *textNode = [SCNNode nodeWithGeometry:text]; - - struct { SCNVector3 min, max; } bb; - [textNode getBoundingBoxMin:&bb.min max:&bb.max]; - CGFloat textWidth = bb.max.x - bb.min.x; - CGFloat textHeight = bb.max.y - bb.min.y; - - CGFloat snapshotWidth = view.frame.size.width; - CGFloat headerWidth = MAX(snapshotWidth, textWidth); - CGRect frame = CGRectMake(0, 0, headerWidth, textHeight + (kHeaderVerticalInset * 2)); - SCNNode *headerNode = [SCNNode nodeWithGeometry:[SCNShape - nameHeader:view.headerColor frame:frame corners:8 - ]]; - [headerNode addChildNode:textNode]; - - textNode.position = SCNVector3Make( - (frame.size.width / 2.f) - (textWidth / 2.f), - (frame.size.height / 2.f) - (textHeight / 2.f), - kFHSSmallZOffset - ); - headerNode.position = SCNVector3Make( - (snapshotWidth / 2.f) - (headerWidth / 2.f), - view.frame.size.height, - kFHSSmallZOffset - ); - - return headerNode; -} - -+ (instancetype)snapshot:(FHSViewSnapshot *)view - parent:(FHSViewSnapshot *)parent - parentNode:(SCNNode *)parentNode - root:(SCNNode *)rootNode - depth:(NSInteger *)depthOut - nodesMap:(NSMutableDictionary *)nodesMap - hideHeaders:(BOOL)hideHeaders { - NSInteger const depth = *depthOut; - - // Ignore elements that are not visible. - // These should appear in the list, but not in the 3D view. - if (view.hidden || CGSizeEqualToSize(view.frame.size, CGSizeZero)) { - return nil; - } - - // Create a node whose contents are the snapshot of the element - SCNNode *node = [self snapshot:view]; - node.name = view.view.identifier; - - // Begin building node tree - FHSSnapshotNodes *nodes = [FHSSnapshotNodes snapshot:view depth:depth]; - nodes.snapshot = node; - - // The node must be added to the root node - // for the coordinate space calculations below to work - [rootNode addChildNode:node]; - node.position = ({ - // Flip the y-coordinate since SceneKit has a - // flipped version of the UIKit coordinate system - CGRect pframe = parent ? parent.frame : CGRectZero; - CGFloat y = parent ? pframe.size.height - CGRectGetMaxY(view.frame) : 0; - - // To simplify calculating the z-axis spacing between the layers, we make - // each snapshot node a direct child of the root rather than embedding - // the nodes in their parent nodes in the same structure as the UI elements - // themselves. With this flattened hierarchy, the z-position can be - // calculated for every node simply by multiplying the spacing by the depth. - // - // `parentSnapshotNode` as referenced here is NOT the actual parent node - // of `node`, it is the node corresponding to the parent of the UI element. - // It is used to convert from frame coordinates, which are relative to - // the bounds of the parent, to coordinates relative to the root node. - SCNVector3 positionRelativeToParent = SCNVector3Make(view.frame.origin.x, y, 0); - SCNVector3 positionRelativeToRoot; - if (parent) { - positionRelativeToRoot = [rootNode convertPosition:positionRelativeToParent fromNode:parentNode]; - } else { - positionRelativeToRoot = positionRelativeToParent; - } - positionRelativeToRoot.z = 50 * depth; - positionRelativeToRoot; - }); - - // Make border node - nodes.border = [node borderWithColor:view.headerColor]; - [node addChildNode:nodes.border]; - - // Make header node - nodes.header = [SCNNode header:view]; - [node addChildNode:nodes.header]; - if (hideHeaders) { - nodes.header.hidden = YES; - } - - nodesMap[view.view.identifier] = nodes; - - NSMutableArray *checkForIntersect = [NSMutableArray new]; - NSInteger maxChildDepth = depth; - - // Recurse to child nodes; overlapping children have higher depths - for (FHSViewSnapshot *child in view.children) { - NSInteger childDepth = depth + 1; - - // Children that intersect a sibling are rendered - // in a separate layer above the previous siblings - for (FHSViewSnapshot *sibling in checkForIntersect) { - if (CGRectIntersectsRect(sibling.frame, child.frame)) { - childDepth = maxChildDepth + 1; - break; - } - } - - id didMakeNode = [SCNNode - snapshot:child - parent:view - parentNode:node - root:rootNode - depth:&childDepth - nodesMap:nodesMap - hideHeaders:hideHeaders - ]; - if (didMakeNode) { - maxChildDepth = MAX(childDepth, maxChildDepth); - [checkForIntersect addObject:child]; - } - } - - *depthOut = maxChildDepth; - return node; -} - -@end - - -#pragma mark SCNShape -@implementation SCNShape (Snapshot) - -+ (instancetype)shapeWithPath:(UIBezierPath *)path materialDiffuse:(id)contents { - SCNShape *shape = [SCNShape shapeWithPath:path extrusionDepth:0]; - [shape addDoubleSidedMaterialWithDiffuseContents:contents]; - return shape; -} - -+ (instancetype)nameHeader:(UIColor *)color frame:(CGRect)frame corners:(CGFloat)radius { - UIBezierPath *path = [UIBezierPath - bezierPathWithRoundedRect:frame - byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight - cornerRadii:CGSizeMake(radius, radius) - ]; - return [SCNShape shapeWithPath:path materialDiffuse:color]; -} - -@end - - -#pragma mark SCNText -@implementation SCNText (Snapshot) - -+ (instancetype)labelGeometry:(NSString *)text font:(UIFont *)font { - NSParameterAssert(text); - - SCNText *label = [self new]; - label.string = text; - label.font = font; - label.alignmentMode = kCAAlignmentCenter; - label.truncationMode = kCATruncationEnd; - - return label; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.h b/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.h deleted file mode 100644 index 4b694780..00000000 --- a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// FLEXHierarchyTableViewCell.h -// Flipboard -// -// Created by Ryan Olson on 2014-05-02. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import - -@interface FLEXHierarchyTableViewCell : UITableViewCell - -- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier; - -@property (nonatomic) NSInteger viewDepth; -@property (nonatomic) UIColor *randomColorTag; -@property (nonatomic) UIColor *indicatedViewColor; - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.m b/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.m deleted file mode 100644 index f2c60db8..00000000 --- a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewCell.m +++ /dev/null @@ -1,169 +0,0 @@ -// -// FLEXHierarchyTableViewCell.m -// Flipboard -// -// Created by Ryan Olson on 2014-05-02. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXHierarchyTableViewCell.h" -#import "FLEXUtility.h" -#import "FLEXResources.h" -#import "FLEXColor.h" - -@interface FLEXHierarchyTableViewCell () - -/// Indicates how deep the view is in the hierarchy -@property (nonatomic) UIView *depthIndicatorView; -/// Holds the color that visually distinguishes views from one another -@property (nonatomic) UIImageView *colorCircleImageView; -/// A checker-patterned view, used to help show the color of a view, like a photoshop canvas -@property (nonatomic) UIView *backgroundColorCheckerPatternView; -/// The subview of the checker pattern view which holds the actual color of the view -@property (nonatomic) UIView *viewBackgroundColorView; - -@end - -@implementation FLEXHierarchyTableViewCell - -- (id)initWithReuseIdentifier:(NSString *)reuseIdentifier { - return [self initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:reuseIdentifier]; -} - -- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { - self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; - if (self) { - self.depthIndicatorView = [UIView new]; - self.depthIndicatorView.backgroundColor = FLEXUtility.hierarchyIndentPatternColor; - [self.contentView addSubview:self.depthIndicatorView]; - - UIImage *defaultCircleImage = [FLEXUtility circularImageWithColor:UIColor.blackColor radius:5]; - self.colorCircleImageView = [[UIImageView alloc] initWithImage:defaultCircleImage]; - [self.contentView addSubview:self.colorCircleImageView]; - - self.textLabel.font = UIFont.flex_defaultTableCellFont; - self.detailTextLabel.font = UIFont.flex_defaultTableCellFont; - self.accessoryType = UITableViewCellAccessoryDetailButton; - - // Use a pattern-based color to simplify application of the checker pattern - static UIColor *checkerPatternColor = nil; - static dispatch_once_t once; - dispatch_once(&once, ^{ - checkerPatternColor = [UIColor colorWithPatternImage:FLEXResources.checkerPattern]; - }); - - self.backgroundColorCheckerPatternView = [UIView new]; - self.backgroundColorCheckerPatternView.clipsToBounds = YES; - self.backgroundColorCheckerPatternView.layer.borderColor = FLEXColor.tertiaryBackgroundColor.CGColor; - self.backgroundColorCheckerPatternView.layer.borderWidth = 2.f / UIScreen.mainScreen.scale; - self.backgroundColorCheckerPatternView.backgroundColor = checkerPatternColor; - [self.contentView addSubview:self.backgroundColorCheckerPatternView]; - self.viewBackgroundColorView = [UIView new]; - [self.backgroundColorCheckerPatternView addSubview:self.viewBackgroundColorView]; - } - return self; -} - -- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated { - UIColor *originalColour = self.viewBackgroundColorView.backgroundColor; - [super setHighlighted:highlighted animated:animated]; - - // UITableViewCell changes all subviews in the contentView to backgroundColor = clearColor. - // We want to preserve the hierarchy background color when highlighted. - self.depthIndicatorView.backgroundColor = FLEXUtility.hierarchyIndentPatternColor; - - self.viewBackgroundColorView.backgroundColor = originalColour; -} - -- (void)setSelected:(BOOL)selected animated:(BOOL)animated { - UIColor *originalColour = self.viewBackgroundColorView.backgroundColor; - [super setSelected:selected animated:animated]; - - // See setHighlighted above. - self.depthIndicatorView.backgroundColor = FLEXUtility.hierarchyIndentPatternColor; - - self.viewBackgroundColorView.backgroundColor = originalColour; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - const CGFloat kContentPadding = 6; - const CGFloat kDepthIndicatorWidthMultiplier = 4; - const CGFloat kViewColorIndicatorSize = 22; - - const CGRect bounds = self.contentView.bounds; - const CGFloat centerY = CGRectGetMidY(bounds); - const CGFloat textLabelCenterY = CGRectGetMidY(self.textLabel.frame); - - BOOL hideCheckerView = self.backgroundColorCheckerPatternView.hidden; - CGFloat maxWidth = CGRectGetMaxX(bounds); - maxWidth -= (hideCheckerView ? kContentPadding : (kViewColorIndicatorSize + kContentPadding * 2)); - - CGRect depthIndicatorFrame = self.depthIndicatorView.frame = CGRectMake( - kContentPadding, 0, self.viewDepth * kDepthIndicatorWidthMultiplier, CGRectGetHeight(bounds) - ); - - // Circle goes after depth, and its center Y = textLabel's center Y - CGRect circleFrame = self.colorCircleImageView.frame; - circleFrame.origin.x = CGRectGetMaxX(depthIndicatorFrame) + kContentPadding; - circleFrame.origin.y = FLEXFloor(textLabelCenterY - CGRectGetHeight(circleFrame) / 2.f); - self.colorCircleImageView.frame = circleFrame; - - // Text label goes after random color circle, width extends to the edge - // of the contentView or to the padding before the color indicator view - CGRect textLabelFrame = self.textLabel.frame; - CGFloat textOriginX = CGRectGetMaxX(circleFrame) + kContentPadding; - textLabelFrame.origin.x = textOriginX; - textLabelFrame.size.width = maxWidth - textOriginX; - self.textLabel.frame = textLabelFrame; - - // detailTextLabel leading edge lines up with the circle, and the - // width extends to the same max X as the same max X as the textLabel - CGRect detailTextLabelFrame = self.detailTextLabel.frame; - CGFloat detailOriginX = circleFrame.origin.x; - detailTextLabelFrame.origin.x = detailOriginX; - detailTextLabelFrame.size.width = maxWidth - detailOriginX; - self.detailTextLabel.frame = detailTextLabelFrame; - - // Checker pattern view starts after the padding after the max X of textLabel, - // and is centered vertically within the entire contentView - self.backgroundColorCheckerPatternView.frame = CGRectMake( - CGRectGetMaxX(self.textLabel.frame) + kContentPadding, - centerY - kViewColorIndicatorSize / 2.f, - kViewColorIndicatorSize, - kViewColorIndicatorSize - ); - - // Background color view fills it's superview - self.viewBackgroundColorView.frame = self.backgroundColorCheckerPatternView.bounds; - self.backgroundColorCheckerPatternView.layer.cornerRadius = kViewColorIndicatorSize / 2.f; -} - -- (void)setRandomColorTag:(UIColor *)randomColorTag { - if (![_randomColorTag isEqual:randomColorTag]) { - _randomColorTag = randomColorTag; - self.colorCircleImageView.image = [FLEXUtility circularImageWithColor:randomColorTag radius:6]; - } -} - -- (void)setViewDepth:(NSInteger)viewDepth { - if (_viewDepth != viewDepth) { - _viewDepth = viewDepth; - [self setNeedsLayout]; - } -} - -- (UIColor *)indicatedViewColor { - return self.viewBackgroundColorView.backgroundColor; -} - -- (void)setIndicatedViewColor:(UIColor *)color { - self.viewBackgroundColorView.backgroundColor = color; - - // Hide the checker pattern view if there is no background color - self.backgroundColorCheckerPatternView.hidden = color == nil; - [self setNeedsLayout]; -} - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.h b/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.h deleted file mode 100644 index 1eca05e3..00000000 --- a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// FLEXHierarchyTableViewController.h -// Flipboard -// -// Created by Ryan Olson on 2014-05-01. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXTableViewController.h" - -@interface FLEXHierarchyTableViewController : FLEXTableViewController - -+ (instancetype)windows:(NSArray *)allWindows - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)selectedView; - -@property (nonatomic) UIView *selectedView; -@property (nonatomic) void(^didSelectRowAction)(UIView *selectedView); - -@end diff --git a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.m b/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.m deleted file mode 100644 index ef50d9e5..00000000 --- a/BHTwitter/Classes/ViewHierarchy/TreeExplorer/FLEXHierarchyTableViewController.m +++ /dev/null @@ -1,253 +0,0 @@ -// -// FLEXHierarchyTableViewController.m -// Flipboard -// -// Created by Ryan Olson on 2014-05-01. -// Copyright (c) 2020 FLEX Team. All rights reserved. -// - -#import "FLEXColor.h" -#import "FLEXHierarchyTableViewController.h" -#import "NSMapTable+FLEX_Subscripting.h" -#import "FLEXUtility.h" -#import "FLEXHierarchyTableViewCell.h" -#import "FLEXObjectExplorerViewController.h" -#import "FLEXObjectExplorerFactory.h" -#import "FLEXResources.h" -#import "FLEXWindow.h" - -typedef NS_ENUM(NSUInteger, FLEXHierarchyScope) { - FLEXHierarchyScopeFullHierarchy, - FLEXHierarchyScopeViewsAtTap -}; - -@interface FLEXHierarchyTableViewController () - -@property (nonatomic) NSArray *allViews; -@property (nonatomic) NSMapTable *depthsForViews; -@property (nonatomic) NSArray *viewsAtTap; -@property (nonatomic) NSArray *displayedViews; -@property (nonatomic, readonly) BOOL showScopeBar; - -@end - -@implementation FLEXHierarchyTableViewController - -+ (instancetype)windows:(NSArray *)allWindows - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)selected { - NSParameterAssert(allWindows.count); - - NSArray *allViews = [self allViewsInHierarchy:allWindows]; - NSMapTable *depths = [self hierarchyDepthsForViews:allViews]; - return [[self alloc] initWithViews:allViews viewsAtTap:viewsAtTap selectedView:selected depths:depths]; -} - -- (instancetype)initWithViews:(NSArray *)allViews - viewsAtTap:(NSArray *)viewsAtTap - selectedView:(UIView *)selectedView - depths:(NSMapTable *)depthsForViews { - NSParameterAssert(allViews); - NSParameterAssert(depthsForViews.count == allViews.count); - - self = [super initWithStyle:UITableViewStylePlain]; - if (self) { - self.allViews = allViews; - self.depthsForViews = depthsForViews; - self.viewsAtTap = viewsAtTap; - self.selectedView = selectedView; - - self.title = @"View Hierarchy Tree"; - } - - return self; -} - -- (void)viewDidLoad { - [super viewDidLoad]; - - // Preserve selection between presentations - self.clearsSelectionOnViewWillAppear = NO; - - // A little more breathing room - self.tableView.rowHeight = 50.0; - self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; - // Separator inset clashes with persistent cell selection - [self.tableView setSeparatorInset:UIEdgeInsetsZero]; - - self.showsSearchBar = YES; - self.showSearchBarInitially = YES; - // Using pinSearchBar on this screen causes a weird visual - // thing on the next view controller that gets pushed. - // - // self.pinSearchBar = YES; - self.searchBarDebounceInterval = kFLEXDebounceInstant; - self.automaticallyShowsSearchBarCancelButton = NO; - if (self.showScopeBar) { - self.searchController.searchBar.showsScopeBar = YES; - self.searchController.searchBar.scopeButtonTitles = @[@"Full Hierarchy", @"Views at Tap"]; - self.selectedScope = FLEXHierarchyScopeViewsAtTap; - } - - [self updateDisplayedViews]; -} - -- (void)viewWillAppear:(BOOL)animated { - [super viewWillAppear:animated]; - - [self disableToolbar]; -} - -- (void)viewDidAppear:(BOOL)animated { - [super viewDidAppear:animated]; - - [self trySelectCellForSelectedView]; -} - - -#pragma mark - Hierarchy helpers - -+ (NSArray *)allViewsInHierarchy:(NSArray *)windows { - return [windows flex_flatmapped:^id(UIWindow *window, NSUInteger idx) { - if (![window isKindOfClass:[FLEXWindow class]]) { - return [self viewWithRecursiveSubviews:window]; - } - - return nil; - }]; -} - -+ (NSArray *)viewWithRecursiveSubviews:(UIView *)view { - NSMutableArray *subviews = [NSMutableArray arrayWithObject:view]; - for (UIView *subview in view.subviews) { - [subviews addObjectsFromArray:[self viewWithRecursiveSubviews:subview]]; - } - - return subviews; -} - -+ (NSMapTable *)hierarchyDepthsForViews:(NSArray *)views { - NSMapTable *depths = [NSMapTable strongToStrongObjectsMapTable]; - for (UIView *view in views) { - NSInteger depth = 0; - UIView *tryView = view; - while (tryView.superview) { - tryView = tryView.superview; - depth++; - } - depths[(id)view] = @(depth); - } - - return depths; -} - - -#pragma mark Selection and Filtering Helpers - -- (void)trySelectCellForSelectedView { - NSUInteger selectedViewIndex = [self.displayedViews indexOfObject:self.selectedView]; - if (selectedViewIndex != NSNotFound) { - UITableViewScrollPosition scrollPosition = UITableViewScrollPositionMiddle; - NSIndexPath *selectedViewIndexPath = [NSIndexPath indexPathForRow:selectedViewIndex inSection:0]; - [self.tableView selectRowAtIndexPath:selectedViewIndexPath animated:YES scrollPosition:scrollPosition]; - } -} - -- (void)updateDisplayedViews { - NSArray *candidateViews = nil; - if (self.showScopeBar) { - if (self.selectedScope == FLEXHierarchyScopeViewsAtTap) { - candidateViews = self.viewsAtTap; - } else if (self.selectedScope == FLEXHierarchyScopeFullHierarchy) { - candidateViews = self.allViews; - } - } else { - candidateViews = self.allViews; - } - - if (self.searchText.length) { - self.displayedViews = [candidateViews filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(UIView *candidateView, NSDictionary *bindings) { - NSString *title = [FLEXUtility descriptionForView:candidateView includingFrame:NO]; - NSString *candidateViewPointerAddress = [NSString stringWithFormat:@"%p", candidateView]; - BOOL matchedViewPointerAddress = [candidateViewPointerAddress rangeOfString:self.searchText options:NSCaseInsensitiveSearch].location != NSNotFound; - BOOL matchedViewTitle = [title rangeOfString:self.searchText options:NSCaseInsensitiveSearch].location != NSNotFound; - return matchedViewPointerAddress || matchedViewTitle; - }]]; - } else { - self.displayedViews = candidateViews; - } - - [self.tableView reloadData]; -} - -- (void)setSelectedView:(UIView *)selectedView { - _selectedView = selectedView; - if (self.isViewLoaded) { - [self trySelectCellForSelectedView]; - } -} - - -#pragma mark - Search Bar / Scope Bar - -- (BOOL)showScopeBar { - return self.viewsAtTap.count > 0; -} - -- (void)updateSearchResults:(NSString *)newText { - [self updateDisplayedViews]; - - // If the search bar text field is active, don't scroll on selection because we may want - // to continue typing. Otherwise, scroll so that the selected cell is visible. - if (!self.searchController.searchBar.isFirstResponder) { - [self trySelectCellForSelectedView]; - } -} - - -#pragma mark - Table View Data Source - -- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { - return self.displayedViews.count; -} - -- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { - static NSString *CellIdentifier = @"Cell"; - FLEXHierarchyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; - if (!cell) { - cell = [[FLEXHierarchyTableViewCell alloc] initWithReuseIdentifier:CellIdentifier]; - } - - UIView *view = self.displayedViews[indexPath.row]; - - cell.textLabel.text = [FLEXUtility descriptionForView:view includingFrame:NO]; - cell.detailTextLabel.text = [FLEXUtility detailDescriptionForView:view]; - cell.randomColorTag = [FLEXUtility consistentRandomColorForObject:view]; - cell.viewDepth = self.depthsForViews[view].integerValue; - cell.indicatedViewColor = view.backgroundColor; - - if (view.isHidden || view.alpha < 0.01) { - cell.textLabel.textColor = FLEXColor.deemphasizedTextColor; - cell.detailTextLabel.textColor = FLEXColor.deemphasizedTextColor; - } else { - cell.textLabel.textColor = FLEXColor.primaryTextColor; - cell.detailTextLabel.textColor = FLEXColor.primaryTextColor; - } - - return cell; -} - -- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - _selectedView = self.displayedViews[indexPath.row]; // Don't scroll, avoid setter - if (self.didSelectRowAction) { - self.didSelectRowAction(_selectedView); - } -} - -- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath { - UIView *drillInView = self.displayedViews[indexPath.row]; - FLEXObjectExplorerViewController *viewExplorer = [FLEXObjectExplorerFactory explorerViewControllerForObject:drillInView]; - [self.navigationController pushViewController:viewExplorer animated:YES]; -} - -@end diff --git a/BHTwitter/CustomTabBar/CustomTabBarViewController.swift b/BHTwitter/CustomTabBar/CustomTabBarViewController.swift index a297bf22..233849b8 100644 --- a/BHTwitter/CustomTabBar/CustomTabBarViewController.swift +++ b/BHTwitter/CustomTabBar/CustomTabBarViewController.swift @@ -101,15 +101,15 @@ class CustomTabBarViewController: UIViewController { self.navigationItem.rightBarButtonItem = restButton } @objc func restSettingsBarButtonHandler(_ sender: UIBarButtonItem) { - let alert = UIAlertController(title: "Hi", message: "Are sure you want to rest the settings to default?", preferredStyle: .alert) - alert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { _ in + let alert = UIAlertController(title: "BHTwitter", message: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_REST_MESSAGE"), preferredStyle: .alert) + alert.addAction(UIAlertAction(title: BHTBundle.shared().localizedString(forKey: "YES_BUTTON_TITLE"), style: .default, handler: { _ in UserDefaults.standard.removeObject(forKey: "allowed") UserDefaults.standard.removeObject(forKey: "hidden") self.getData() self.tableView.reloadData() })) - alert.addAction(UIAlertAction(title: "No", style: .cancel)) + alert.addAction(UIAlertAction(title: BHTBundle.shared().localizedString(forKey: "NO_BUTTON_TITLE"), style: .cancel)) self.present(alert, animated: true) } private func getItems(for key: String) -> [item]? { @@ -122,20 +122,20 @@ class CustomTabBarViewController: UIViewController { private func getData() { if let savedAllowedArr = getItems(for: "allowed"), let savedHiddenArr = getItems(for: "hidden") { data = [ - section(title: "Active tab bar", items: savedAllowedArr), - section(title: "Hidden tab bar", items: savedHiddenArr) + section(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_SECTION_1_TITLE"), items: savedAllowedArr), + section(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_SECTION_2_TITLE"), items: savedHiddenArr) ] } else { data = [ - section(title: "Active tab bar", items: [ - item(title: "Home", pageID: "home"), - item(title: "Explore", pageID: "guide"), - item(title: "Spaces", pageID: "audiospace"), - item(title: "Communities", pageID: "communities"), - item(title: "Notifications", pageID: "ntab"), - item(title: "Messages", pageID: "messages") + section(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_SECTION_1_TITLE"), items: [ + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_1"), pageID: "home"), + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_2"), pageID: "guide"), + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_3"), pageID: "audiospace"), + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_4"), pageID: "communities"), + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_5"), pageID: "ntab"), + item(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_OPTION_6"), pageID: "messages") ]), - section(title: "Hidden tab bar", items: []) + section(title: BHTBundle.shared().localizedString(forKey: "CUSTOM_TAB_BAR_SECTION_2_TITLE"), items: []) ] } } diff --git a/BHTwitter/JGProgressHUD/JGProgressHUD.m b/BHTwitter/JGProgressHUD/JGProgressHUD.m deleted file mode 100755 index 86fd7ac5..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUD.m +++ /dev/null @@ -1,1058 +0,0 @@ -// -// JGProgressHUD.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUD.h" -#import -#import "JGProgressHUDFadeAnimation.h" -#import "JGProgressHUDIndeterminateIndicatorView.h" - -#if !__has_feature(objc_arc) -#error "JGProgressHUD requires ARC!" -#endif - -static CGRect JGProgressHUD_CGRectIntegral(CGRect rect) { - CGFloat scale = [[UIScreen mainScreen] scale]; - - return (CGRect){{((CGFloat)floor(rect.origin.x*scale))/scale, ((CGFloat)floor(rect.origin.y*scale))/scale}, {((CGFloat)ceil(rect.size.width*scale))/scale, ((CGFloat)ceil(rect.size.height*scale))/scale}}; -} - -@interface JGProgressHUD () { - BOOL _transitioning; - BOOL _updateAfterAppear; - - BOOL _dismissAfterTransitionFinished; - BOOL _dismissAfterTransitionFinishedWithAnimation; - - CFAbsoluteTime _displayTimestamp; - - BOOL _effectiveIndicatorViewNeedsUpdate; - - UIView *__nonnull _blurViewContainer; - UIView *__nonnull _shadowView; - CAShapeLayer *__nonnull _shadowMaskLayer; -} - -@property (nonatomic, strong, readonly, nonnull) UIVisualEffectView *blurView; -@property (nonatomic, strong, readonly, nonnull) UIVisualEffectView *vibrancyView; - -@property (nonatomic, strong, readonly, nonnull) JGProgressHUDIndicatorView *effectiveIndicatorView; - -@end - -@interface JGProgressHUDAnimation (Private) - -@property (nonatomic, weak, nullable) JGProgressHUD *progressHUD; - -@end - -@implementation JGProgressHUD - -@synthesize HUDView = _HUDView; -@synthesize blurView = _blurView; -@synthesize vibrancyView = _vibrancyView; -@synthesize textLabel = _textLabel; -@synthesize detailTextLabel = _detailTextLabel; -@synthesize indicatorView = _indicatorView; -@synthesize animation = _animation; -@synthesize contentView = _contentView; - -@dynamic visible; - -#pragma mark - Keyboard - -static CGRect keyboardFrame = (CGRect){{0.0, 0.0}, {0.0, 0.0}}; - -#if TARGET_OS_IOS -+ (void)keyboardFrameWillChange:(NSNotification *)notification { - keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; - if (CGRectIsEmpty(keyboardFrame)) { - keyboardFrame = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue]; - } -} - -+ (void)keyboardFrameDidChange:(NSNotification *)notification { - keyboardFrame = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; -} - -+ (void)keyboardDidHide { - keyboardFrame = CGRectZero; -} - -+ (void)load { - @autoreleasepool { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameDidChange:) name:UIKeyboardDidChangeFrameNotification object:nil]; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidHide) name:UIKeyboardDidHideNotification object:nil]; - } -} -#endif - -+ (CGRect)currentKeyboardFrame { - return keyboardFrame; -} - -#pragma mark - Initializers - -- (instancetype)init { - return [self initWithStyle:JGProgressHUDStyleExtraLight]; -} - -- (instancetype)initWithFrame:(CGRect __unused)frame { - return [self initWithStyle:JGProgressHUDStyleExtraLight]; -} - -/* - Basic architecture: - - * self covers the entire target view. - * self.HUDView is a subview of self and has the size and position of the visible HUD. The layer has rounded corners set with self.cornerRadius. The layer does not clip to bounds. - * _shadowView is a subview of self.HUDView and always covers the entire HUDView. The corners are also rounded in the same way as self.HUDView. It draws its shadow only on the outside by using a masking layer, so that the shadow does not interfere with the blur view. - * _blurViewContainer is a subview of self.HUDView and always covers the entire self.HUDView. The corners are also rounded in the same way as self.HUDView but it additionally clips to bounds. - * self.blurView is a subview of _blurViewContainer and provides the blur effect. The corners are not rounded and the view does not clip to bounds. - * self.vibrancyView is a subview of self.blurView.contentView and provides the vibrancy effect. The corners are not rounded and the view does not clip to bounds. - * self.contentView is a subview of self.vibrancyView.contentView. It does not always have the same frame as it's superview (during transitions). - * self.contentView contains the labels and the indicator view. - - */ -- (instancetype)initWithStyle:(JGProgressHUDStyle)style { - self = [super initWithFrame:CGRectZero]; - - if (self) { - _style = style; - _voiceOverEnabled = YES; - - _HUDView = [[UIView alloc] init]; - self.HUDView.backgroundColor = [UIColor clearColor]; - [self addSubview:self.HUDView]; - - _blurViewContainer = [[UIView alloc] init]; - _blurViewContainer.backgroundColor = [UIColor clearColor]; - _blurViewContainer.clipsToBounds = YES; - [self.HUDView addSubview:_blurViewContainer]; - - _shadowView = [[UIView alloc] init]; - _shadowView.backgroundColor = [UIColor blackColor]; - _shadowView.userInteractionEnabled = NO; - _shadowView.layer.shadowOpacity = 1.0; - _shadowView.alpha = 0.0; - - _shadowMaskLayer = [CAShapeLayer layer]; - _shadowMaskLayer.fillRule = kCAFillRuleEvenOdd; - _shadowMaskLayer.fillColor = [UIColor blackColor].CGColor; - _shadowMaskLayer.opacity = 1.0; - - _shadowView.layer.mask = _shadowMaskLayer; - - [self.HUDView addSubview:_shadowView]; - - _indicatorView = [[JGProgressHUDIndeterminateIndicatorView alloc] init]; - _effectiveIndicatorView = _indicatorView; - [self.effectiveIndicatorView setUpForHUDStyle:self.style vibrancyEnabled:self.vibrancyEnabled]; - - self.hidden = YES; - self.backgroundColor = [UIColor clearColor]; - - self.contentInsets = UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0); - self.layoutMargins = UIEdgeInsetsMake(20.0, 20.0, 20.0, 20.0); - - self.cornerRadius = 10.0; - -#if TARGET_OS_IOS - [self addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]]; -#elif TARGET_OS_TV - _wantsFocus = YES; -#endif - } - - return self; -} - -+ (instancetype)progressHUDWithStyle:(JGProgressHUDStyle)style { - return [(JGProgressHUD *)[self alloc] initWithStyle:style]; -} - -#pragma mark - Layout - -- (void)setHUDViewFrameCenterWithSize:(CGSize)size insetViewFrame:(CGRect)viewFrame { - CGRect frame = (CGRect){CGPointZero, size}; - - switch (self.position) { - case JGProgressHUDPositionTopLeft: - frame.origin.x = CGRectGetMinX(viewFrame); - frame.origin.y = CGRectGetMinY(viewFrame); - break; - - case JGProgressHUDPositionTopCenter: - frame.origin.x = CGRectGetMidX(viewFrame) - size.width/2.0; - frame.origin.y = CGRectGetMinY(viewFrame); - break; - - case JGProgressHUDPositionTopRight: - frame.origin.x = CGRectGetMaxX(viewFrame) - size.width; - frame.origin.y = CGRectGetMinY(viewFrame); - break; - - case JGProgressHUDPositionCenterLeft: - frame.origin.x = CGRectGetMinX(viewFrame); - frame.origin.y = CGRectGetMidY(viewFrame) - size.height/2.0; - break; - - case JGProgressHUDPositionCenter: - frame.origin.x = CGRectGetMidX(viewFrame) - size.width/2.0; - frame.origin.y = CGRectGetMidY(viewFrame) - size.height/2.0; - break; - - case JGProgressHUDPositionCenterRight: - frame.origin.x = CGRectGetMaxX(viewFrame) - frame.size.width; - frame.origin.y = CGRectGetMidY(viewFrame) - size.height/2.0; - break; - - case JGProgressHUDPositionBottomLeft: - frame.origin.x = CGRectGetMinX(viewFrame); - frame.origin.y = CGRectGetMaxY(viewFrame) - size.height; - break; - - case JGProgressHUDPositionBottomCenter: - frame.origin.x = CGRectGetMidX(viewFrame) - size.width/2.0; - frame.origin.y = CGRectGetMaxY(viewFrame) - frame.size.height; - break; - - case JGProgressHUDPositionBottomRight: - frame.origin.x = CGRectGetMaxX(viewFrame) - size.width; - frame.origin.y = CGRectGetMaxY(viewFrame) - size.height; - break; - } - - CGRect oldHUDFrame = self.HUDView.frame; - CGRect updatedHUDFrame = JGProgressHUD_CGRectIntegral(frame); - - self.HUDView.frame = updatedHUDFrame; - _shadowView.frame = self.HUDView.bounds; - [self updateShadowViewMask]; - - _blurViewContainer.frame = self.HUDView.bounds; - self.blurView.frame = self.HUDView.bounds; - self.vibrancyView.frame = self.HUDView.bounds; - - [UIView performWithoutAnimation:^{ - self.contentView.frame = (CGRect){{(oldHUDFrame.size.width - updatedHUDFrame.size.width)/2.0, (oldHUDFrame.size.height - updatedHUDFrame.size.height)/2.0}, updatedHUDFrame.size}; - }]; - - self.contentView.frame = self.HUDView.bounds; -} - -- (void)updateShadowViewMask { - if (CGRectIsEmpty(_shadowView.layer.bounds)) { - return; - } - - CGRect layerBounds = CGRectMake(0.0, 0.0, _shadowView.layer.bounds.size.width + self.shadow.radius*4.0, _shadowView.layer.bounds.size.height + self.shadow.radius*4.0); - - UIBezierPath *path = [UIBezierPath bezierPathWithRect:layerBounds]; - - CGRect maskRect = CGRectInset(layerBounds, self.shadow.radius*2.0, self.shadow.radius*2.0); - - UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:maskRect cornerRadius:self.cornerRadius]; - - [path appendPath:roundedPath]; - - _shadowMaskLayer.frame = CGRectInset(_shadowView.layer.bounds, -self.shadow.radius*2.0, -self.shadow.radius*2.0); - - CAAnimation *currentAnimation = [self.HUDView.layer animationForKey:@"position"]; - if (currentAnimation != nil) { - [CATransaction begin]; - - [CATransaction setAnimationDuration:currentAnimation.duration]; - [CATransaction setAnimationTimingFunction:currentAnimation.timingFunction]; - - CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"]; - [_shadowMaskLayer addAnimation:pathAnimation forKey:@"path"]; - - _shadowMaskLayer.path = path.CGPath; - - [CATransaction commit]; - } - else { - _shadowMaskLayer.path = path.CGPath; - // Remove implicit CALayer animations: - [_shadowMaskLayer removeAllAnimations]; - } -} - -- (void)layoutHUD { - if (_transitioning) { - _updateAfterAppear = YES; - return; - } - - if (_targetView == nil) { - return; - } - - CGRect indicatorFrame = self.effectiveIndicatorView.frame; - indicatorFrame.origin.y = self.contentInsets.top; - - CGRect insetFrame = [self insetFrameForView:self]; - - CGFloat maxContentWidth = insetFrame.size.width - self.contentInsets.left - self.contentInsets.right; - CGFloat maxContentHeight = insetFrame.size.height - self.contentInsets.top - self.contentInsets.bottom; - - CGRect labelFrame = CGRectZero; - CGRect detailFrame = CGRectZero; - - CGFloat currentY = CGRectGetMaxY(indicatorFrame); - if (!CGRectIsEmpty(indicatorFrame)) { - currentY += 10.0; - } - - if (_textLabel.text.length > 0) { - _textLabel.preferredMaxLayoutWidth = maxContentWidth; - - CGSize neededSize = _textLabel.intrinsicContentSize; - neededSize.height = MIN(neededSize.height, maxContentHeight); - - labelFrame.size = neededSize; - labelFrame.origin.y = currentY; - currentY = CGRectGetMaxY(labelFrame) + 6.0; - } - - if (_detailTextLabel.text.length > 0) { - _detailTextLabel.preferredMaxLayoutWidth = maxContentWidth; - - CGSize neededSize = _detailTextLabel.intrinsicContentSize; - neededSize.height = MIN(neededSize.height, maxContentHeight); - - detailFrame.size = neededSize; - detailFrame.origin.y = currentY; - } - - CGSize size = CGSizeZero; - - CGFloat width = MIN(self.contentInsets.left + MAX(indicatorFrame.size.width, MAX(labelFrame.size.width, detailFrame.size.width)) + self.contentInsets.right, insetFrame.size.width); - - CGFloat height = MAX(CGRectGetMaxY(labelFrame), MAX(CGRectGetMaxY(detailFrame), CGRectGetMaxY(indicatorFrame))) + self.contentInsets.bottom; - - if (self.square) { - CGFloat uniSize = MAX(width, height); - - size.width = uniSize; - size.height = uniSize; - - CGFloat heightDelta = (uniSize-height)/2.0; - - labelFrame.origin.y += heightDelta; - detailFrame.origin.y += heightDelta; - indicatorFrame.origin.y += heightDelta; - } - else { - size.width = width; - size.height = height; - } - - CGPoint center = CGPointMake(size.width/2.0, size.height/2.0); - - indicatorFrame.origin.x = center.x - indicatorFrame.size.width/2.0; - labelFrame.origin.x = center.x - labelFrame.size.width/2.0; - detailFrame.origin.x = center.x - detailFrame.size.width/2.0; - - [UIView performWithoutAnimation:^{ - self.effectiveIndicatorView.frame = indicatorFrame; - self->_textLabel.frame = JGProgressHUD_CGRectIntegral(labelFrame); - self->_detailTextLabel.frame = JGProgressHUD_CGRectIntegral(detailFrame); - }]; - - [self setHUDViewFrameCenterWithSize:size insetViewFrame:insetFrame]; -} - -- (CGRect)insetFrameForView:(UIView *)view { - CGRect localKeyboardFrame = [view convertRect:[[self class] currentKeyboardFrame] fromView:nil]; - CGRect frame = view.bounds; - - if (!CGRectIsEmpty(localKeyboardFrame) && CGRectIntersectsRect(frame, localKeyboardFrame)) { - CGFloat keyboardMinY = CGRectGetMinY(localKeyboardFrame); - - if (@available(iOS 11, tvOS 11, *)) { - if (self.insetsLayoutMarginsFromSafeArea) { - // This makes sure that the bottom safe area inset is only respected when that area is not covered by the keyboard. When the keyboard covers the bottom area outside of the safe area it is not necessary to keep the bottom safe area insets part of the insets for the HUD. - keyboardMinY += self.safeAreaInsets.bottom; - } - } - - frame.size.height = MAX(MIN(frame.size.height, keyboardMinY), 0.0); - } - - return UIEdgeInsetsInsetRect(frame, view.layoutMargins); -} - -- (void)applyCornerRadius { - self.HUDView.layer.cornerRadius = self.cornerRadius; - _blurViewContainer.layer.cornerRadius = self.cornerRadius; - _shadowView.layer.cornerRadius = self.cornerRadius; - - [self updateShadowViewMask]; -} - -#pragma mark - Showing - -- (void)cleanUpAfterPresentation { -#if TARGET_OS_TV - if (self.wantsFocus) { - [self.targetView setNeedsFocusUpdate]; - } -#endif - - self.hidden = NO; - - _transitioning = NO; - // Correct timestamp to the current time for animated presentations: - _displayTimestamp = CFAbsoluteTimeGetCurrent(); - - if (_effectiveIndicatorViewNeedsUpdate) { - self.effectiveIndicatorView = self.indicatorView; - _effectiveIndicatorViewNeedsUpdate = NO; - _updateAfterAppear = NO; - } - else if (_updateAfterAppear) { - [self layoutHUD]; - _updateAfterAppear = NO; - } - - if ([self.delegate respondsToSelector:@selector(progressHUD:didPresentInView:)]){ - [self.delegate progressHUD:self didPresentInView:self.targetView]; - } - - if (_dismissAfterTransitionFinished) { - [self dismissAnimated:_dismissAfterTransitionFinishedWithAnimation]; - _dismissAfterTransitionFinished = NO; - _dismissAfterTransitionFinishedWithAnimation = NO; - } - else if (self.voiceOverEnabled && UIAccessibilityIsVoiceOverRunning()) { - UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, self); - } -} - -- (void)showInView:(UIView *)view { - [self showInView:view animated:YES]; -} - -- (void)layoutSubviews { - [super layoutSubviews]; - - [self layoutHUD]; -} - -- (void)showInView:(UIView *)view animated:(BOOL)animated { - if (_transitioning) { - return; - } - else if (self.targetView != nil) { -#if DEBUG - NSLog(@"[Warning] The HUD is already visible! Ignoring."); -#endif - return; - } - - if ([self.delegate respondsToSelector:@selector(progressHUD:willPresentInView:)]) { - [self.delegate progressHUD:self willPresentInView:view]; - } - - _targetView = view; - - self.frame = _targetView.bounds; - - [_targetView addSubview:self]; - - self.translatesAutoresizingMaskIntoConstraints = NO; - - [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:_targetView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0.0].active = YES; - [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:_targetView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0].active = YES; - [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:_targetView attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0.0].active = YES; - [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:_targetView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0].active = YES; - - [self setNeedsLayout]; - [self layoutIfNeeded]; - - _transitioning = YES; - - _displayTimestamp = CFAbsoluteTimeGetCurrent(); - - if (animated && self.animation != nil) { - [self.animation show]; - } - else { - [self cleanUpAfterPresentation]; - } - -#if TARGET_OS_IOS - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameChanged:) name:UIKeyboardWillChangeFrameNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardFrameChanged:) name:UIKeyboardDidChangeFrameNotification object:nil]; -#endif -} - -#pragma mark - Dismissing - -- (void)cleanUpAfterDismissal { - self.hidden = YES; - [self removeFromSuperview]; - - [self removeObservers]; - - _transitioning = NO; - _dismissAfterTransitionFinished = NO; - _dismissAfterTransitionFinishedWithAnimation = NO; - - __typeof(self.targetView) targetView = self.targetView; - _targetView = nil; - - if ([self.delegate respondsToSelector:@selector(progressHUD:didDismissFromView:)]) { - [self.delegate progressHUD:self didDismissFromView:targetView]; - } -} - -- (void)dismiss { - [self dismissAnimated:YES]; -} - -- (void)dismissAnimated:(BOOL)animated { - if (_transitioning) { - _dismissAfterTransitionFinished = YES; - _dismissAfterTransitionFinishedWithAnimation = animated; - return; - } - - if (self.targetView == nil) { - return; - } - - if (self.minimumDisplayTime > 0.0 && _displayTimestamp > 0.0) { - CFAbsoluteTime displayedTime = CFAbsoluteTimeGetCurrent()-_displayTimestamp; - - if (displayedTime < self.minimumDisplayTime) { - NSTimeInterval delta = self.minimumDisplayTime-displayedTime; - - [self dismissAfterDelay:delta animated:animated]; - - return; - } - } - - if ([self.delegate respondsToSelector:@selector(progressHUD:willDismissFromView:)]) { - [self.delegate progressHUD:self willDismissFromView:self.targetView]; - } - - _transitioning = YES; - - if (animated && self.animation) { - [self.animation hide]; - } - else { - [self cleanUpAfterDismissal]; - } -} - -- (void)dismissAfterDelay:(NSTimeInterval)delay { - [self dismissAfterDelay:delay animated:YES]; -} - -- (void)dismissAfterDelay:(NSTimeInterval)delay animated:(BOOL)animated { - __weak __typeof(self) weakSelf = self; - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - if (weakSelf) { - __strong __typeof(weakSelf) strongSelf = weakSelf; - if (strongSelf.visible) { - [strongSelf dismissAnimated:animated]; - } - } - }); -} - -#pragma mark - Callbacks - -#if TARGET_OS_IOS -- (void)tapped:(UITapGestureRecognizer *)t { - if (CGRectContainsPoint(self.contentView.bounds, [t locationInView:self.contentView])) { - if (self.tapOnHUDViewBlock != nil) { - self.tapOnHUDViewBlock(self); - } - } - else if (self.tapOutsideBlock != nil) { - self.tapOutsideBlock(self); - } -} - -static UIViewAnimationOptions UIViewAnimationOptionsFromUIViewAnimationCurve(UIViewAnimationCurve curve) { - UIViewAnimationOptions testOptions = UIViewAnimationCurveLinear << 16; - - if (testOptions != UIViewAnimationOptionCurveLinear) { - NSLog(@"Unexpected implementation of UIViewAnimationOptionCurveLinear"); - } - - return (UIViewAnimationOptions)(curve << 16); -} - -- (void)keyboardFrameChanged:(NSNotification *)notification { - NSTimeInterval duration = [notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; - - UIViewAnimationCurve curve = (UIViewAnimationCurve)[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] unsignedIntegerValue]; - - [UIView animateWithDuration:duration delay:0.0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionsFromUIViewAnimationCurve(curve) animations:^{ - [self layoutHUD]; - } completion:nil]; -} -#endif - -- (void)updateMotionOnHUDView { - BOOL reduceMotionEnabled = UIAccessibilityIsReduceMotionEnabled(); - - BOOL wantsParallax = ((self.parallaxMode == JGProgressHUDParallaxModeDevice && !reduceMotionEnabled) || self.parallaxMode == JGProgressHUDParallaxModeAlwaysOn); - BOOL hasParallax = (self.HUDView.motionEffects.count > 0); - - if (wantsParallax == hasParallax) { - return; - } - - if (!wantsParallax) { - self.HUDView.motionEffects = @[]; - } - else { - UIInterpolatingMotionEffect *x = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; - - CGFloat maxMovement = 20.0; - - x.minimumRelativeValue = @(-maxMovement); - x.maximumRelativeValue = @(maxMovement); - - UIInterpolatingMotionEffect *y = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y" type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; - - y.minimumRelativeValue = @(-maxMovement); - y.maximumRelativeValue = @(maxMovement); - - self.HUDView.motionEffects = @[x, y]; - } -} - -- (void)animationDidFinish:(BOOL)presenting { - if (presenting) { - [self cleanUpAfterPresentation]; - } - else { - [self cleanUpAfterDismissal]; - } -} - -#pragma mark - Getters - -- (BOOL)isVisible { - return (self.superview != nil); -} - -- (UIVisualEffectView *)blurView { - if (!_blurView) { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateMotionOnHUDView) name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; - - UIBlurEffectStyle effect; - - if (self.style == JGProgressHUDStyleDark) { - effect = UIBlurEffectStyleDark; - } - else if (self.style == JGProgressHUDStyleLight) { - effect = UIBlurEffectStyleLight; - } - else { - effect = UIBlurEffectStyleExtraLight; - } - - UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:effect]; - - _blurView = [[UIVisualEffectView alloc] initWithEffect:blurEffect]; - - [self updateMotionOnHUDView]; - - [_blurViewContainer addSubview:_blurView]; - -#if TARGET_OS_IOS - [self.contentView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]]; -#endif - } - - return _blurView; -} - -- (UIVisualEffectView *)vibrancyView { - if (!_vibrancyView) { - UIVibrancyEffect *vibrancyEffect = (self.vibrancyEnabled ? [UIVibrancyEffect effectForBlurEffect:(UIBlurEffect *)self.blurView.effect] : nil); - - _vibrancyView = [[UIVisualEffectView alloc] initWithEffect:vibrancyEffect]; - - [self.blurView.contentView addSubview:_vibrancyView]; - } - - return _vibrancyView; -} - -- (UIView *)contentView { - if (_contentView == nil) { - _contentView = [[UIView alloc] init]; - [self.vibrancyView.contentView addSubview:_contentView]; - - if (self.effectiveIndicatorView != nil) { - [self.contentView addSubview:self.effectiveIndicatorView]; - } - } - - return _contentView; -} - -- (UILabel *)textLabel { - if (!_textLabel) { - _textLabel = [[UILabel alloc] init]; - _textLabel.backgroundColor = [UIColor clearColor]; - _textLabel.textColor = (self.style == JGProgressHUDStyleDark ? [UIColor whiteColor] : [UIColor blackColor]); - _textLabel.textAlignment = NSTextAlignmentCenter; -#if TARGET_OS_TV - CGFloat fontSize = 20.0; -#else - CGFloat fontSize = 17.0; -#endif - _textLabel.font = [UIFont boldSystemFontOfSize:fontSize]; - _textLabel.numberOfLines = 0; - [_textLabel addObserver:self forKeyPath:@"attributedText" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - [_textLabel addObserver:self forKeyPath:@"text" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - [_textLabel addObserver:self forKeyPath:@"font" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - _textLabel.isAccessibilityElement = YES; - - [self.contentView addSubview:_textLabel]; - } - - return _textLabel; -} - -- (UILabel *)detailTextLabel { - if (!_detailTextLabel) { - _detailTextLabel = [[UILabel alloc] init]; - _detailTextLabel.backgroundColor = [UIColor clearColor]; - _detailTextLabel.textColor = (self.style == JGProgressHUDStyleDark ? [UIColor whiteColor] : [UIColor blackColor]); - _detailTextLabel.textAlignment = NSTextAlignmentCenter; -#if TARGET_OS_TV - CGFloat fontSize = 17.0; -#else - CGFloat fontSize = 15.0; -#endif - _detailTextLabel.font = [UIFont systemFontOfSize:fontSize]; - _detailTextLabel.numberOfLines = 0; - [_detailTextLabel addObserver:self forKeyPath:@"attributedText" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - [_detailTextLabel addObserver:self forKeyPath:@"text" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - [_detailTextLabel addObserver:self forKeyPath:@"font" options:(NSKeyValueObservingOptions)kNilOptions context:NULL]; - _detailTextLabel.isAccessibilityElement = YES; - - [self.contentView addSubview:_detailTextLabel]; - } - - return _detailTextLabel; -} - -- (JGProgressHUDAnimation *)animation { - if (!_animation) { - self.animation = [JGProgressHUDFadeAnimation animation]; - } - - return _animation; -} - -#pragma mark - Setters - -#if TARGET_OS_TV -- (void)setWantsFocus:(BOOL)wantsFocus { - if (self.wantsFocus == wantsFocus) { - return; - } - - _wantsFocus = wantsFocus; - - self.userInteractionEnabled = self.wantsFocus; - - [self.targetView setNeedsFocusUpdate]; -} -#endif - -- (void)setCornerRadius:(CGFloat)cornerRadius { - if (fequal(self.cornerRadius, cornerRadius)) { - return; - } - - _cornerRadius = cornerRadius; - - [self applyCornerRadius]; -} - -- (void)setShadow:(JGProgressHUDShadow *)shadow { - if (shadow == self.shadow) { - return; - } - - _shadow = shadow; - - [self updateShadowViewMask]; - - if (_shadow != nil) { - _shadowView.layer.shadowColor = _shadow.color.CGColor; - _shadowView.layer.shadowOffset = _shadow.offset; - _shadowView.layer.shadowRadius = _shadow.radius; - - _shadowView.alpha = _shadow.opacity; - } - else { - _shadowView.layer.shadowOffset = CGSizeZero; - _shadowView.layer.shadowRadius = 0.0; - - _shadowView.alpha = 0.0; - } -} - -- (void)setAnimation:(JGProgressHUDAnimation *)animation { - if (_animation == animation) { - return; - } - - _animation.progressHUD = nil; - - _animation = animation; - - _animation.progressHUD = self; -} - -- (void)setParallaxMode:(JGProgressHUDParallaxMode)parallaxMode { - if (self.parallaxMode == parallaxMode) { - return; - } - - _parallaxMode = parallaxMode; - - [self updateMotionOnHUDView]; -} - -- (void)setPosition:(JGProgressHUDPosition)position { - if (self.position == position) { - return; - } - - _position = position; - [self layoutHUD]; -} - -- (void)setSquare:(BOOL)square { - if (self.square == square) { - return; - } - - _square = square; - - [self layoutHUD]; -} - -- (void)setVibrancyEnabled:(BOOL)vibrancyEnabled { - if (vibrancyEnabled == self.vibrancyEnabled) { - return; - } - - _vibrancyEnabled = vibrancyEnabled; - - UIVibrancyEffect *vibrancyEffect = (self.vibrancyEnabled ? [UIVibrancyEffect effectForBlurEffect:(UIBlurEffect *)self.blurView.effect] : nil); - - self.vibrancyView.effect = vibrancyEffect; - - [self.effectiveIndicatorView setUpForHUDStyle:self.style vibrancyEnabled:self.vibrancyEnabled]; -} - -- (void)setIndicatorView:(JGProgressHUDIndicatorView *)indicatorView { - if (self.indicatorView == indicatorView) { - return; - } - - _indicatorView = indicatorView; - - if (_transitioning) { - _effectiveIndicatorViewNeedsUpdate = YES; - return; - } - else { - self.effectiveIndicatorView = self.indicatorView; - } -} - -- (void)setEffectiveIndicatorView:(JGProgressHUDIndicatorView * _Nonnull)effectiveIndicatorView { - if (self.effectiveIndicatorView == effectiveIndicatorView) { - return; - } - - [UIView performWithoutAnimation:^{ - [self->_effectiveIndicatorView removeFromSuperview]; - self->_effectiveIndicatorView = effectiveIndicatorView; - - if (self.indicatorView != nil) { - [self.effectiveIndicatorView setUpForHUDStyle:self.style vibrancyEnabled:self.vibrancyEnabled]; - [self.contentView addSubview:self.effectiveIndicatorView]; - } - }]; - - [self layoutHUD]; -} - -- (void)layoutMarginsDidChange { - [super layoutMarginsDidChange]; - - [self layoutHUD]; -} - -- (void)setMarginInsets:(UIEdgeInsets)marginInsets { - [self setLayoutMargins:marginInsets]; -} - -- (UIEdgeInsets)marginInsets { - return [self layoutMargins]; -} - -- (void)setContentInsets:(UIEdgeInsets)contentInsets { - if (UIEdgeInsetsEqualToEdgeInsets(self.contentInsets, contentInsets)) { - return; - } - - _contentInsets = contentInsets; - - [self layoutHUD]; -} - -- (void)setProgress:(float)progress { - [self setProgress:progress animated:NO]; -} - -- (void)setProgress:(float)progress animated:(BOOL)animated { - if (fequal(self.progress, progress)) { - return; - } - - _progress = progress; - - [self.effectiveIndicatorView setProgress:progress animated:animated]; -} - -#pragma mark - Overrides - -#if TARGET_OS_IOS -- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { - if (self.interactionType == JGProgressHUDInteractionTypeBlockNoTouches) { - return nil; - } - else { - UIView *view = [super hitTest:point withEvent:event]; - - if (self.interactionType == JGProgressHUDInteractionTypeBlockAllTouches) { - return view; - } - else if (self.interactionType == JGProgressHUDInteractionTypeBlockTouchesOnHUDView && view != self) { - return view; - } - - return nil; - } -} -#elif TARGET_OS_TV -- (NSArray> *)preferredFocusEnvironments { - return @[self]; -} - -- (UIView *)preferredFocusedView { - return nil; -} - -- (BOOL)canBecomeFocused { - return self.wantsFocus; -} -#endif - -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (object == _textLabel || object == _detailTextLabel) { - [self layoutHUD]; - } - else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - -- (void)dealloc { - [self removeObservers]; - - [_textLabel removeObserver:self forKeyPath:@"attributedText"]; - [_textLabel removeObserver:self forKeyPath:@"text"]; - [_textLabel removeObserver:self forKeyPath:@"font"]; - - [_detailTextLabel removeObserver:self forKeyPath:@"attributedText"]; - [_detailTextLabel removeObserver:self forKeyPath:@"text"]; - [_detailTextLabel removeObserver:self forKeyPath:@"font"]; -} - -- (void)removeObservers { - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIAccessibilityReduceMotionStatusDidChangeNotification object:nil]; - -#if TARGET_OS_IOS - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillChangeFrameNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidChangeFrameNotification object:nil]; -#endif -} - -@end - -@implementation JGProgressHUD (HUDManagement) - -+ (NSArray *)allProgressHUDsInView:(UIView *)view { - NSMutableArray *HUDs = [NSMutableArray array]; - - for (UIView *v in view.subviews) { - if ([v isKindOfClass:[JGProgressHUD class]]) { - [HUDs addObject:v]; - } - } - - return HUDs.copy; -} - -+ (NSMutableArray *)_allProgressHUDsInViewHierarchy:(UIView *)view { - NSMutableArray *HUDs = [NSMutableArray array]; - - for (UIView *v in view.subviews) { - if ([v isKindOfClass:[JGProgressHUD class]]) { - [HUDs addObject:v]; - } - else { - [HUDs addObjectsFromArray:[self _allProgressHUDsInViewHierarchy:v]]; - } - } - - return HUDs; -} - -+ (NSArray *)allProgressHUDsInViewHierarchy:(UIView *)view { - return [self _allProgressHUDsInViewHierarchy:view].copy; -} - -@end - -@implementation JGProgressHUD (Deprecated) - -- (void)showInRect:(CGRect __unused)rect inView:(UIView *)view { - [self showInView:view]; -} - -- (void)showInRect:(CGRect __unused)rect inView:(UIView *)view animated:(BOOL)animated { - [self showInView:view animated:animated]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDAnimation.m b/BHTwitter/JGProgressHUD/JGProgressHUDAnimation.m deleted file mode 100755 index fb2628ff..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDAnimation.m +++ /dev/null @@ -1,48 +0,0 @@ -// -// JGProgressHUDAnimation.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDAnimation.h" -#import "JGProgressHUD.h" - -@interface JGProgressHUD (Private) - -- (void)animationDidFinish:(BOOL)presenting; - -@end - -@interface JGProgressHUDAnimation () { - BOOL _presenting; -} - -@property (nonatomic, weak) JGProgressHUD *progressHUD; - -@end - -@implementation JGProgressHUDAnimation - -#pragma mark - Initializers - -+ (instancetype)animation { - return [[self alloc] init]; -} - -#pragma mark - Public methods - -- (void)show { - _presenting = YES; -} - -- (void)hide { - _presenting = NO; -} - -- (void)animationFinished { - [self.progressHUD animationDidFinish:_presenting]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDErrorIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDErrorIndicatorView.m deleted file mode 100644 index d9a7d31c..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDErrorIndicatorView.m +++ /dev/null @@ -1,57 +0,0 @@ -// -// JGProgressHUDErrorIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 19.08.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDErrorIndicatorView.h" -#import "JGProgressHUD.h" - -static UIBezierPath *errorBezierPath() { - static UIBezierPath *path; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - path = [UIBezierPath bezierPath]; - [path moveToPoint:CGPointMake(3, 3)]; - [path addLineToPoint:CGPointMake(30, 30)]; - [path moveToPoint:CGPointMake(30, 3)]; - [path addLineToPoint:CGPointMake(3, 30)]; - - [path setLineWidth:3]; - [path setLineJoinStyle:kCGLineJoinRound]; - [path setLineCapStyle:kCGLineCapRound]; - }); - - return path; -} - -@implementation JGProgressHUDErrorIndicatorView - -- (instancetype)initWithContentView:(UIView *__unused)contentView { - UIBezierPath *path = errorBezierPath(); - - UIGraphicsBeginImageContextWithOptions(CGSizeMake(33, 33), NO, 0.0); - [[UIColor blackColor] setStroke]; - [path stroke]; - - UIImage *img = [UIGraphicsGetImageFromCurrentImageContext() imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - - UIGraphicsEndImageContext(); - - self = [super initWithImage:img]; - - return self; -} - -- (instancetype)init { - return [self initWithContentView:nil]; -} - -- (void)updateAccessibility { - self.accessibilityLabel = NSLocalizedString(@"Error",); -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDFadeAnimation.m b/BHTwitter/JGProgressHUD/JGProgressHUDFadeAnimation.m deleted file mode 100755 index bd862902..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDFadeAnimation.m +++ /dev/null @@ -1,56 +0,0 @@ -// -// JGProgressHUDFadeAnimation.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDFadeAnimation.h" -#import "JGProgressHUD.h" - -@implementation JGProgressHUDFadeAnimation - -#pragma mark - Initializers - -- (instancetype)init { - self = [super init]; - if (self) { - self.duration = 0.4; - self.animationOptions = UIViewAnimationOptionCurveEaseInOut; - } - return self; -} - -- (void)setAnimationOptions:(UIViewAnimationOptions)animationOptions { - _animationOptions = (animationOptions | UIViewAnimationOptionBeginFromCurrentState); -} - -#pragma mark - Showing - -- (void)show { - [super show]; - - self.progressHUD.alpha = 0.0; - self.progressHUD.hidden = NO; - - [UIView animateWithDuration:self.duration delay:0.0 options:self.animationOptions animations:^{ - self.progressHUD.alpha = 1.0; - } completion:^(BOOL __unused finished) { - [self animationFinished]; - }]; -} - -#pragma mark - Hiding - -- (void)hide { - [super hide]; - - [UIView animateWithDuration:self.duration delay:0.0 options:self.animationOptions animations:^{ - self.progressHUD.alpha = 0.0; - } completion:^(BOOL __unused finished) { - [self animationFinished]; - }]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDFadeZoomAnimation.m b/BHTwitter/JGProgressHUD/JGProgressHUDFadeZoomAnimation.m deleted file mode 100755 index f95af609..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDFadeZoomAnimation.m +++ /dev/null @@ -1,77 +0,0 @@ -// -// JGProgressHUDFadeZoomAnimation.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDFadeZoomAnimation.h" -#import "JGProgressHUD.h" - -@implementation JGProgressHUDFadeZoomAnimation - -#pragma mark - Initializers - -- (instancetype)init { - self = [super init]; - if (self) { - self.shrinkAnimationDuaration = 0.2; - self.expandAnimationDuaration = 0.1; - self.expandScale = CGSizeMake(1.1, 1.1); - } - return self; -} - -#pragma mark - Showing - -- (void)show { - [super show]; - - self.progressHUD.alpha = 0.0; - self.progressHUD.HUDView.transform = CGAffineTransformMakeScale(0.1, 0.1); - - NSTimeInterval totalDuration = self.expandAnimationDuaration+self.shrinkAnimationDuaration; - - self.progressHUD.hidden = NO; - - [UIView animateWithDuration:totalDuration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut) animations:^{ - self.progressHUD.alpha = 1.0; - } completion:nil]; - - [UIView animateWithDuration:self.shrinkAnimationDuaration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) animations:^{ - self.progressHUD.HUDView.transform = CGAffineTransformMakeScale(self.expandScale.width, self.expandScale.height); - } completion:^(BOOL __unused _finished) { - [UIView animateWithDuration:self.expandAnimationDuaration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ - self.progressHUD.HUDView.transform = CGAffineTransformIdentity; - } completion:^(BOOL __unused __finished) { - [self animationFinished]; - }]; - }]; -} - -#pragma mark - Hiding - -- (void)hide { - [super hide]; - - NSTimeInterval totalDuration = self.expandAnimationDuaration+self.shrinkAnimationDuaration; - - [UIView animateWithDuration:totalDuration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseInOut) animations:^{ - self.progressHUD.alpha = 0.0; - } completion:nil]; - - [UIView animateWithDuration:self.expandAnimationDuaration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionCurveEaseIn | UIViewAnimationOptionBeginFromCurrentState) animations:^{ - self.progressHUD.HUDView.transform = CGAffineTransformMakeScale(self.expandScale.width, self.expandScale.height); - } completion:^(BOOL __unused _finished) { - [UIView animateWithDuration:self.shrinkAnimationDuaration delay:0.0 options:(UIViewAnimationOptions)(UIViewAnimationOptionCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState) animations:^{ - self.progressHUD.HUDView.transform = CGAffineTransformMakeScale(0.1, 0.1); - } completion:^(BOOL __unused __finished) { - self.progressHUD.HUDView.transform = CGAffineTransformIdentity; - - [self animationFinished]; - }]; - }]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDImageIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDImageIndicatorView.m deleted file mode 100644 index 0a38d1f0..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDImageIndicatorView.m +++ /dev/null @@ -1,42 +0,0 @@ -// -// JGProgressHUDImageIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 05.08.15. -// Copyright (c) 2015 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDImageIndicatorView.h" - -@implementation JGProgressHUDImageIndicatorView { - BOOL _customizedTintColor; -} - -- (instancetype)initWithImage:(UIImage *)image { - UIImageView *imageView = [[UIImageView alloc] initWithImage:image]; - - self = [super initWithContentView:imageView]; - - return self; -} - -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled { - [super setUpForHUDStyle:style vibrancyEnabled:vibrancyEnabled]; - - if (!_customizedTintColor) { - if (style == JGProgressHUDStyleDark) { - self.tintColor = [UIColor whiteColor]; - } - else { - self.tintColor = [UIColor blackColor]; - } - _customizedTintColor = NO; - } -} - -- (void)setTintColor:(UIColor *)tintColor { - [super setTintColor:tintColor]; - _customizedTintColor = YES; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDIndeterminateIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDIndeterminateIndicatorView.m deleted file mode 100644 index c9880d48..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDIndeterminateIndicatorView.m +++ /dev/null @@ -1,63 +0,0 @@ -// -// JGProgressHUDIndeterminateIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 19.07.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDIndeterminateIndicatorView.h" - -#ifndef __IPHONE_13_0 -#define __IPHONE_13_0 130000 -#endif - -@implementation JGProgressHUDIndeterminateIndicatorView - -- (instancetype)init { - UIActivityIndicatorView *activityIndicatorView; - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_13_0 - if (@available(iOS 13, tvOS 13, *)) { - activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge]; - } - else { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; -#pragma clang diagnostic pop - } -#else - activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]; -#endif - - [activityIndicatorView startAnimating]; - - self = [super initWithContentView:activityIndicatorView]; - return self; -} - -- (instancetype)initWithHUDStyle:(JGProgressHUDStyle)style { - return [self init]; -} - -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled { - [super setUpForHUDStyle:style vibrancyEnabled:vibrancyEnabled]; - - if (style != JGProgressHUDStyleDark) { - self.color = [UIColor blackColor]; - } - else { - self.color = [UIColor whiteColor]; - } -} - -- (void)setColor:(UIColor *)color { - [(UIActivityIndicatorView *)self.contentView setColor:color]; -} - -- (void)updateAccessibility { - self.accessibilityLabel = NSLocalizedString(@"Indeterminate progress",); -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDIndicatorView.m deleted file mode 100755 index 1a696319..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDIndicatorView.m +++ /dev/null @@ -1,103 +0,0 @@ -// -// JGProgressHUDIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDIndicatorView.h" -#import "JGProgressHUD.h" - -@interface JGProgressHUDIndicatorView () { - BOOL _accessibilityUpdateScheduled; -} - -+ (void)runBlock:(void (^)(void))block; - -@end - -static void runOnNextRunLoop(void (^block)(void)) { - [[NSRunLoop currentRunLoop] performSelector:@selector(runBlock:) target:[JGProgressHUDIndicatorView class] argument:(id)block order:0 modes:@[NSRunLoopCommonModes]]; -} - -@implementation JGProgressHUDIndicatorView - -#pragma mark - Initializers - -- (instancetype)initWithFrame:(CGRect __unused)frame { - return [self init]; -} - -- (instancetype)init { - return [self initWithContentView:nil]; -} - -- (instancetype)initWithContentView:(UIView *)contentView { - self = [super initWithFrame:(contentView ? contentView.frame : CGRectMake(0.0, 0.0, 50.0, 50.0))]; - if (self) { - self.opaque = NO; - self.backgroundColor = [UIColor clearColor]; - - self.isAccessibilityElement = YES; - [self setNeedsAccessibilityUpdate]; - - if (contentView) { - _contentView = contentView; - - [self addSubview:self.contentView]; - } - } - return self; -} - -#pragma mark - Setup - -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled {} - -#pragma mark - Accessibility - -+ (void)runBlock:(void (^)(void))block { - if (block != nil) { - block(); - } -} - -- (void)setNeedsAccessibilityUpdate { - if (!_accessibilityUpdateScheduled) { - _accessibilityUpdateScheduled = YES; - - runOnNextRunLoop(^{ - [self updateAccessibilityIfNeeded]; - }); - } -} - -- (void)updateAccessibilityIfNeeded { - if (_accessibilityUpdateScheduled) { - [self updateAccessibility]; - _accessibilityUpdateScheduled = NO; - } -} - -- (void)updateAccessibility { - self.accessibilityLabel = [NSLocalizedString(@"Loading",) stringByAppendingFormat:@" %.f %%", self.progress]; -} - -#pragma mark - Getters & Setters - -- (void)setProgress:(float)progress { - [self setProgress:progress animated:NO]; -} - -- (void)setProgress:(float)progress animated:(__unused BOOL)animated { - if (fequal(self.progress, progress)) { - return; - } - - _progress = progress; - - [self setNeedsAccessibilityUpdate]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDPieIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDPieIndicatorView.m deleted file mode 100755 index 15a65d2f..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDPieIndicatorView.m +++ /dev/null @@ -1,171 +0,0 @@ -// -// JGProgressHUDPieIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 19.07.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDPieIndicatorView.h" - -@interface JGProgressHUDPieIndicatorLayer : CALayer - -@property (nonatomic, assign) float progress; - -@property (nonatomic, weak) UIColor *color; - -@property (nonatomic, weak) UIColor *fillColor; - -@end - -@implementation JGProgressHUDPieIndicatorLayer - -@dynamic progress, color, fillColor; - -+ (BOOL)needsDisplayForKey:(NSString *)key { - return ([key isEqualToString:@"progress"] || [key isEqualToString:@"color"] || [key isEqualToString:@"fillColor"] || [super needsDisplayForKey:key]); -} - -- (id )actionForKey:(NSString *)key { - if ([key isEqualToString:@"progress"]) { - CABasicAnimation *progressAnimation = [CABasicAnimation animation]; - progressAnimation.fromValue = [self.presentationLayer valueForKey:key]; - - progressAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; - - return progressAnimation; - } - - return [super actionForKey:key]; -} - -- (void)drawInContext:(CGContextRef)ctx { - UIGraphicsPushContext(ctx); - - CGRect rect = self.bounds; - - CGPoint center = CGPointMake(rect.origin.x + (CGFloat)floor(rect.size.width/2.0), rect.origin.y + (CGFloat)floor(rect.size.height/2.0)); - CGFloat lineWidth = 2.0; - CGFloat radius = (CGFloat)floor(MIN(rect.size.width, rect.size.height)/2.0)-lineWidth; - - UIBezierPath *borderPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0.0 endAngle:2.0*(CGFloat)M_PI clockwise:NO]; - - [borderPath setLineWidth:lineWidth]; - - if (self.fillColor) { - [self.fillColor setFill]; - - [borderPath fill]; - } - - [self.color set]; - - [borderPath stroke]; - - if (self.progress > 0.0) { - UIBezierPath *processPath = [UIBezierPath bezierPath]; - - [processPath setLineWidth:radius]; - - CGFloat startAngle = -((CGFloat)M_PI/2.0); - CGFloat endAngle = startAngle + 2.0 * (CGFloat)M_PI * self.progress; - - [processPath addArcWithCenter:center radius:radius/2.0 startAngle:startAngle endAngle:endAngle clockwise:YES]; - - [processPath stroke]; - } - - UIGraphicsPopContext(); -} - -@end - - -@implementation JGProgressHUDPieIndicatorView - -#pragma mark - Initializers - -- (instancetype)init { - self = [super initWithContentView:nil]; - - if (self) { - self.layer.contentsScale = [UIScreen mainScreen].scale; - [self.layer setNeedsDisplay]; - - self.color = [UIColor clearColor]; - self.fillColor = [UIColor clearColor]; - } - - return self; -} - -- (instancetype)initWithHUDStyle:(JGProgressHUDStyle)style { - return [self init]; -} - -- (instancetype)initWithContentView:(UIView *)contentView { - return [self init]; -} - -#pragma mark - Getters & Setters - -- (void)setColor:(UIColor *)tintColor { - if ([tintColor isEqual:self.color]) { - return; - } - - _color = tintColor; - - [(JGProgressHUDPieIndicatorLayer *)self.layer setColor:self.color]; -} - -- (void)setFillColor:(UIColor *)fillColor { - if ([fillColor isEqual:self.fillColor]) { - return; - } - - _fillColor = fillColor; - - [(JGProgressHUDPieIndicatorLayer *)self.layer setFillColor:self.fillColor]; -} - -- (void)setProgress:(float)progress animated:(BOOL)animated { - if (fequal(self.progress, progress)) { - return; - } - - [super setProgress:progress animated:animated]; - - [CATransaction begin]; - [CATransaction setAnimationDuration:(animated ? 0.3 : 0.0)]; - - [(JGProgressHUDPieIndicatorLayer *)self.layer setProgress:progress]; - - [CATransaction commit]; -} - -#pragma mark - Overrides - -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled { - [super setUpForHUDStyle:style vibrancyEnabled:vibrancyEnabled]; - - if (style == JGProgressHUDStyleDark) { - self.color = [UIColor colorWithWhite:1.0 alpha:1.0]; - self.fillColor = [UIColor colorWithWhite:0.2 alpha:1.0]; - } - else { - self.color = [UIColor blackColor]; - if (style == JGProgressHUDStyleLight) { - self.fillColor = [UIColor colorWithWhite:0.85 alpha:1.0]; - } - else { - self.fillColor = [UIColor colorWithWhite:0.9 alpha:1.0]; - } - } -} - -+ (Class)layerClass { - return [JGProgressHUDPieIndicatorLayer class]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDRingIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDRingIndicatorView.m deleted file mode 100755 index d19d3e83..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDRingIndicatorView.m +++ /dev/null @@ -1,194 +0,0 @@ -// -// JGProgressHUDRingIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDRingIndicatorView.h" - - -@interface JGProgressHUDRingIndicatorLayer : CALayer - -@property (nonatomic, assign) float progress; - -@property (nonatomic, weak) UIColor *ringColor; -@property (nonatomic, weak) UIColor *ringBackgroundColor; - -@property (nonatomic, assign) BOOL roundProgressLine; - -@property (nonatomic, assign) CGFloat ringWidth; - -@end - -@implementation JGProgressHUDRingIndicatorLayer - -@dynamic progress, ringBackgroundColor, ringColor, ringWidth, roundProgressLine; - -+ (BOOL)needsDisplayForKey:(NSString *)key { - return ([key isEqualToString:@"progress"] || [key isEqualToString:@"ringColor"] || [key isEqualToString:@"ringBackgroundColor"] || [key isEqualToString:@"roundProgressLine"] || [key isEqualToString:@"ringWidth"] || [super needsDisplayForKey:key]); -} - -- (id )actionForKey:(NSString *)key { - if ([key isEqualToString:@"progress"]) { - CABasicAnimation *progressAnimation = [CABasicAnimation animation]; - progressAnimation.fromValue = [self.presentationLayer valueForKey:key]; - - progressAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; - - return progressAnimation; - } - - return [super actionForKey:key]; -} - -- (void)drawInContext:(CGContextRef)ctx { - UIGraphicsPushContext(ctx); - - CGRect rect = self.bounds; - - CGPoint center = CGPointMake(rect.origin.x + (CGFloat)floor(rect.size.width/2.0), rect.origin.y + (CGFloat)floor(rect.size.height/2.0)); - CGFloat lineWidth = self.ringWidth; - CGFloat radius = (CGFloat)floor(MIN(rect.size.width, rect.size.height)/2.0) - lineWidth; - - //Background - [self.ringBackgroundColor setStroke]; - - UIBezierPath *borderPath = [UIBezierPath bezierPathWithArcCenter:center radius:radius startAngle:0.0 endAngle:2.0*(CGFloat)M_PI clockwise:NO]; - - [borderPath setLineWidth:lineWidth]; - [borderPath stroke]; - - //Progress - [self.ringColor setStroke]; - - if (self.progress > 0.0) { - UIBezierPath *processPath = [UIBezierPath bezierPath]; - - [processPath setLineWidth:lineWidth]; - [processPath setLineCapStyle:(self.roundProgressLine ? kCGLineCapRound : kCGLineCapSquare)]; - - CGFloat startAngle = -((CGFloat)M_PI / 2.0); - CGFloat endAngle = startAngle + 2.0 * (CGFloat)M_PI * self.progress; - - [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES]; - - [processPath stroke]; - } - - UIGraphicsPopContext(); -} - -@end - - -@implementation JGProgressHUDRingIndicatorView - -#pragma mark - Initializers - -- (instancetype)init { - self = [super initWithContentView:nil];; - - if (self) { - self.layer.contentsScale = [UIScreen mainScreen].scale; - [self.layer setNeedsDisplay]; - - self.ringWidth = 3.0; - self.ringColor = [UIColor clearColor]; - self.ringBackgroundColor = [UIColor clearColor]; - } - - return self; -} - -- (instancetype)initWithHUDStyle:(JGProgressHUDStyle)style { - return [self init]; -} - -- (instancetype)initWithContentView:(UIView *)contentView { - return [self init]; -} - -#pragma mark - Getters & Setters - -- (void)setRoundProgressLine:(BOOL)roundProgressLine { - if (roundProgressLine == self.roundProgressLine) { - return; - } - - _roundProgressLine = roundProgressLine; - - [(JGProgressHUDRingIndicatorLayer *)self.layer setRoundProgressLine:self.roundProgressLine]; -} - -- (void)setRingColor:(UIColor *)tintColor { - if ([tintColor isEqual:self.ringColor]) { - return; - } - - _ringColor = tintColor; - - [(JGProgressHUDRingIndicatorLayer *)self.layer setRingColor:self.ringColor]; -} - -- (void)setRingBackgroundColor:(UIColor *)backgroundTintColor { - if ([backgroundTintColor isEqual:self.ringBackgroundColor]) { - return; - } - - _ringBackgroundColor = backgroundTintColor; - - [(JGProgressHUDRingIndicatorLayer *)self.layer setRingBackgroundColor:self.ringBackgroundColor]; -} - -- (void)setRingWidth:(CGFloat)ringWidth { - if (fequal(ringWidth, self.ringWidth)) { - return; - } - - _ringWidth = ringWidth; - - [(JGProgressHUDRingIndicatorLayer *)self.layer setRingWidth:self.ringWidth]; -} - -- (void)setProgress:(float)progress animated:(BOOL)animated { - if (fequal(self.progress, progress)) { - return; - } - - [super setProgress:progress animated:animated]; - - [CATransaction begin]; - [CATransaction setAnimationDuration:(animated ? 0.3 : 0.0)]; - - [(JGProgressHUDRingIndicatorLayer *)self.layer setProgress:self.progress]; - - [CATransaction commit]; -} - -#pragma mark - Overrides - -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled { - [super setUpForHUDStyle:style vibrancyEnabled:vibrancyEnabled]; - - if (style == JGProgressHUDStyleDark) { - self.ringColor = [UIColor colorWithWhite:1.0 alpha:1.0]; - self.ringBackgroundColor = [UIColor colorWithWhite:0.0 alpha:1.0]; - } - else { - self.ringColor = [UIColor blackColor]; - if (style == JGProgressHUDStyleLight) { - self.ringBackgroundColor = [UIColor colorWithWhite:0.85 alpha:1.0]; - } - else { - self.ringBackgroundColor = [UIColor colorWithWhite:0.9 alpha:1.0]; - } - } -} - -+ (Class)layerClass { - return [JGProgressHUDRingIndicatorLayer class]; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDShadow.m b/BHTwitter/JGProgressHUD/JGProgressHUDShadow.m deleted file mode 100644 index 3c67bcd5..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDShadow.m +++ /dev/null @@ -1,30 +0,0 @@ -// -// JGProgressHUDShadow.m -// JGProgressHUD -// -// Created by Jonas Gessner on 25.09.17. -// Copyright © 2017 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDShadow.h" - -@implementation JGProgressHUDShadow - -+ (instancetype)shadowWithColor:(UIColor *)color offset:(CGSize)offset radius:(CGFloat)radius opacity:(float)opacity { - return [[self alloc] initWithColor:color offset:offset radius:radius opacity:opacity]; -} - -- (instancetype)initWithColor:(UIColor *)color offset:(CGSize)offset radius:(CGFloat)radius opacity:(float)opacity { - self = [super init]; - - if (self) { - _color = color; - _offset = offset; - _radius = radius; - _opacity = opacity; - } - - return self; -} - -@end diff --git a/BHTwitter/JGProgressHUD/JGProgressHUDSuccessIndicatorView.m b/BHTwitter/JGProgressHUD/JGProgressHUDSuccessIndicatorView.m deleted file mode 100644 index 1fcbae28..00000000 --- a/BHTwitter/JGProgressHUD/JGProgressHUDSuccessIndicatorView.m +++ /dev/null @@ -1,56 +0,0 @@ -// -// JGProgressHUDSuccessIndicatorView.m -// JGProgressHUD -// -// Created by Jonas Gessner on 19.08.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDSuccessIndicatorView.h" -#import "JGProgressHUD.h" - -static UIBezierPath *successBezierPath() { - static UIBezierPath *path; - - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - path = [UIBezierPath bezierPath]; - [path moveToPoint:CGPointMake(1.5, 18)]; - [path addLineToPoint:CGPointMake(11, 28)]; - [path addLineToPoint:CGPointMake(31.5, 5.5)]; - - [path setLineWidth:3]; - [path setLineJoinStyle:kCGLineJoinRound]; - [path setLineCapStyle:kCGLineCapRound]; - }); - - return path; -} - -@implementation JGProgressHUDSuccessIndicatorView - -- (instancetype)initWithContentView:(UIView *__unused)contentView { - UIBezierPath *path = successBezierPath(); - - UIGraphicsBeginImageContextWithOptions(CGSizeMake(33, 33), NO, 0.0); - [[UIColor blackColor] setStroke]; - [path stroke]; - - UIImage *img = [UIGraphicsGetImageFromCurrentImageContext() imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - - UIGraphicsEndImageContext(); - - self = [super initWithImage:img]; - - return self; -} - -- (instancetype)init { - return [self initWithContentView:nil]; -} - -- (void)updateAccessibility { - self.accessibilityLabel = NSLocalizedString(@"Success",); -} - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUD-Defines.h b/BHTwitter/JGProgressHUD/include/JGProgressHUD-Defines.h deleted file mode 100644 index bd18da29..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUD-Defines.h +++ /dev/null @@ -1,79 +0,0 @@ -// -// JGProgressHUD-Defines.h -// JGProgressHUD -// -// Created by Jonas Gessner on 28.04.15. -// Copyright (c) 2015 Jonas Gessner. All rights reserved. -// - -#import - -/** - Positions of the HUD. - */ -typedef NS_ENUM(NSUInteger, JGProgressHUDPosition) { - /** Center position. */ - JGProgressHUDPositionCenter = 0, - /** Top left position. */ - JGProgressHUDPositionTopLeft, - /** Top center position. */ - JGProgressHUDPositionTopCenter, - /** Top right position. */ - JGProgressHUDPositionTopRight, - /** Center left position. */ - JGProgressHUDPositionCenterLeft, - /** Center right position. */ - JGProgressHUDPositionCenterRight, - /** Bottom left position. */ - JGProgressHUDPositionBottomLeft, - /** Bottom center position. */ - JGProgressHUDPositionBottomCenter, - /** Bottom right position. */ - JGProgressHUDPositionBottomRight -}; - -/** - Appearance styles of the HUD. - */ -typedef NS_ENUM(NSUInteger, JGProgressHUDStyle) { - /** Extra light HUD with dark elements. */ - JGProgressHUDStyleExtraLight = 0, - /** Light HUD with dark elemets. */ - JGProgressHUDStyleLight, - /** Dark HUD with light elements. */ - JGProgressHUDStyleDark, - JGProgressHUDStyleAuto -}; - -#if TARGET_OS_IOS -/** - Interaction types. - */ -typedef NS_ENUM(NSUInteger, JGProgressHUDInteractionType) { - /** Block all touches. No interaction behin the HUD is possible. */ - JGProgressHUDInteractionTypeBlockAllTouches = 0, - /** Block touches on the HUD view. */ - JGProgressHUDInteractionTypeBlockTouchesOnHUDView, - /** Block no touches. */ - JGProgressHUDInteractionTypeBlockNoTouches -}; -#endif - -/** - Parallax Modes. - */ -typedef NS_ENUM(NSUInteger, JGProgressHUDParallaxMode) { - /** Follows the device setting for parallax. If "Reduce Motion" is enabled, no parallax effect is added to the HUD, if "Reduce Motion" is disabled the HUD will have a parallax effect. This behaviour is only supported on iOS 8 and higher. */ - JGProgressHUDParallaxModeDevice = 0, - /** Always adds a parallax effect to the HUD. Parallax is only supported on iOS 7 and higher. */ - JGProgressHUDParallaxModeAlwaysOn, - /** Never adds a parallax effect to the HUD. */ - JGProgressHUDParallaxModeAlwaysOff -}; - -#ifndef fequal -/** - Macro for safe floating point comparison (for internal use in JGProgressHUD). - */ -#define fequal(a,b) (fabs((a) - (b)) < FLT_EPSILON) -#endif diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUD.h b/BHTwitter/JGProgressHUD/include/JGProgressHUD.h deleted file mode 100644 index 4a752980..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUD.h +++ /dev/null @@ -1,306 +0,0 @@ -// -// JGProgressHUD.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUD-Defines.h" -#import "JGProgressHUDShadow.h" -#import "JGProgressHUDAnimation.h" -#import "JGProgressHUDFadeAnimation.h" -#import "JGProgressHUDFadeZoomAnimation.h" -#import "JGProgressHUDIndicatorView.h" -#import "JGProgressHUDErrorIndicatorView.h" -#import "JGProgressHUDSuccessIndicatorView.h" -#import "JGProgressHUDRingIndicatorView.h" -#import "JGProgressHUDPieIndicatorView.h" -#import "JGProgressHUDIndeterminateIndicatorView.h" - -@protocol JGProgressHUDDelegate; - -/** - A HUD to indicate progress, success, error, warnings or other notifications to the user. -@discussion @c JGProgressHUD respects its @c layoutMargins when positioning the HUD view. Additionally, on iOS 11 if @c insetsLayoutMarginsFromSafeArea is set to @c YES (default) the @c layoutMargins additionally contain the @c safeAreaInsets. - @note Remember to call every method from the main thread! UIKit => main thread! - @attention You may not add JGProgressHUD to a view which has an alpha value < 1.0 or to a view which is a subview of a view with an alpha value < 1.0. - */ -@interface JGProgressHUD : UIView - -/** - Designated initializer. - @param style The appearance style of the HUD. - */ -- (instancetype __nonnull)initWithStyle:(JGProgressHUDStyle)style; - -/** - Convenience initializer. - @param style The appearance style of the HUD. - */ -+ (instancetype __nonnull)progressHUDWithStyle:(JGProgressHUDStyle)style; - -/** - The appearance style of the HUD. - @b Default: JGProgressHUDStyleExtraLight. - */ -@property (nonatomic, assign, readonly) JGProgressHUDStyle style; - -/** The view in which the HUD is presented. */ -@property (nonatomic, weak, readonly, nullable) UIView *targetView; - -/** - The delegate of the HUD. - @sa JGProgressHUDDelegate. - */ -@property (nonatomic, weak, nullable) id delegate; - -/** The actual HUD view visible on screen. You may add animations to this view. */ -@property (nonatomic, strong, readonly, nonnull) UIView *HUDView; - -/** - The content view inside the @c HUDView. If you want to add additional views to the HUD you should add them as subview to the @c contentView. - */ -@property (nonatomic, strong, readonly, nonnull) UIView *contentView; - -/** - The label used to present text on the HUD. Set the @c text or @c attributedText property of this label to change the displayed text. You may not change the label's @c frame or @c bounds. - */ -@property (nonatomic, strong, readonly, nonnull) UILabel *textLabel; - -/** - The label used to present detail text on the HUD. Set the @c text or @c attributedText property of this label to change the displayed text. You may not change the label's @c frame or @c bounds. - */ -@property (nonatomic, strong, readonly, nonnull) UILabel *detailTextLabel; - -/** - The indicator view. You can assign a custom subclass of @c JGProgressHUDIndicatorView to this property or one of the default indicator views (if you do so, you should assign it before showing the HUD). This value is optional. - @b Default: JGProgressHUDIndeterminateIndicatorView. - */ -@property (nonatomic, strong, nullable) JGProgressHUDIndicatorView *indicatorView; - -/** - The shadow cast by the @c HUDView. This value is optional. Setting this to @c nil means no shadow is cast by the HUD. - @b Default: nil. - */ -@property (nonatomic, strong, nullable) JGProgressHUDShadow *shadow; - -/** - The position of the HUD inside the hosting view's frame, or inside the specified frame. - @b Default: JGProgressHUDPositionCenter - */ -@property (nonatomic, assign) JGProgressHUDPosition position; - -/** - The animation used for showing and dismissing the HUD. - @b Default: JGProgressHUDFadeAnimation. - */ -@property (nonatomic, strong, nonnull) JGProgressHUDAnimation *animation; - -#if TARGET_OS_IOS -/** - Interaction type of the HUD. Determines whether touches should be let through to the views behind the HUD. - @sa JGProgressHUDInteractionType. - @b Default: JGProgressHUDInteractionTypeBlockAllTouches. - */ -@property (nonatomic, assign) JGProgressHUDInteractionType interactionType; -#endif - -/** - Parallax mode for the HUD. This setting determines whether the HUD should have a parallax (@c UIDeviceMotion) effect. This effect is controlled by device motion on iOS and remote touchpad panning gestures on tvOS. - @sa JGProgressHUDParallaxMode. - @b Default: JGProgressHUDParallaxModeDevice. - */ -@property (nonatomic, assign) JGProgressHUDParallaxMode parallaxMode; - -#if TARGET_OS_TV -/** - When this property is set to @c YES the HUD will try to become focused, which prevents interactions with the @c targetView. If set to @c NO the HUD will not become focused and interactions with @c targetView remain possible. Default: @c YES. - */ -@property (nonatomic, assign) BOOL wantsFocus; -#endif - -/** - If the HUD should always have the same width and height. - @b Default: NO. - */ -@property (nonatomic, assign) BOOL square; - -/** - Internally @c JGProgressHUD uses an @c UIVisualEffectView with a @c UIBlurEffect. A second @c UIVisualEffectView can be added on top of that with a @c UIVibrancyEffect which amplifies and adjusts the color of content layered behind the view, allowing content placed inside the contentView to become more vivid. This flag sets whether the @c UIVibrancyEffect should be used. Using the vibrancy effect can sometimes, depending on the contents of the display, result in a weird look (especially on iOS < 9.3). - @b Default: NO. - */ -@property (nonatomic, assign) BOOL vibrancyEnabled; - -/** - The radius used for rounding the four corners of the HUD view. - @b Default: 10.0. - */ -@property (nonatomic, assign) CGFloat cornerRadius; - -/** - Insets the contents of the HUD. - @b Default: (20, 20, 20, 20). - */ -@property (nonatomic, assign) UIEdgeInsets contentInsets; - -/** - Insets the HUD from the frame of the hosting view or from the specified frame to present the HUD from. - @b Default: (20, 20, 20, 20). - */ -@property (nonatomic, assign) UIEdgeInsets marginInsets __attribute((deprecated(("Use layoutMargins instead.")))); - -/** - @attention This property is deprecated and does nothing. - */ -@property (nonatomic, assign) NSTimeInterval layoutChangeAnimationDuration __attribute((deprecated(("Use UIView animation to animate layout changes. This allows setting a custom animation duration, animaiton curve and other options.")))); - -/** - @return Whether the HUD is visible on screen. - */ -@property (nonatomic, assign, readonly, getter = isVisible) BOOL visible; - -/** - The progress to display using the @c progressIndicatorView. A change of this property is not animated. Use the @c setProgress:animated: method for an animated progress change. - @b Default: 0.0. - */ -@property (nonatomic, assign) float progress; - -/** - Adjusts the current progress shown by the receiver, optionally animating the change. - - The current progress is represented by a floating-point value between 0.0 and 1.0, inclusive, where 1.0 indicates the completion of the task. The default value is 0.0. Values less than 0.0 and greater than 1.0 are pinned to those limits. - @param progress The new progress value. - @param animated YES if the change should be animated, NO if the change should happen immediately. - */ -- (void)setProgress:(float)progress animated:(BOOL)animated; - -/** - Specifies a minimum time that the HUD will be on-screen. Useful to prevent the HUD from flashing quickly on the screen when indeterminate tasks complete more quickly than expected. - @b Default: 0.0. - */ -@property (nonatomic, assign) NSTimeInterval minimumDisplayTime; - -/** - Determines whether Voice Over announcements should be made upon displaying the HUD (if Voice Over is active). - @b Default: YES - */ -@property (nonatomic, assign) BOOL voiceOverEnabled; - -#if TARGET_OS_IOS -/** - A block to be invoked when the HUD view is tapped. - @note The interaction type of the HUD must be @c JGProgressHUDInteractionTypeBlockTouchesOnHUDView or @c JGProgressHUDInteractionTypeBlockAllTouches, otherwise this block won't be fired. - */ -@property (nonatomic, copy, nullable) void (^tapOnHUDViewBlock)(JGProgressHUD *__nonnull HUD); - -/** - A block to be invoked when the area outside of the HUD view is tapped. - @note The interaction type of the HUD must be @c JGProgressHUDInteractionTypeBlockAllTouches, otherwise this block won't be fired. - */ -@property (nonatomic, copy, nullable) void (^tapOutsideBlock)(JGProgressHUD *__nonnull HUD); -#endif - -/** - Shows the HUD animated. You should preferably show the HUD in a UIViewController's view. The HUD will be repositioned in response to rotation and keyboard show/hide notifications. - @param view The view to show the HUD in. The frame of the @c view will be used to calculate the position of the HUD. - */ -- (void)showInView:(UIView *__nonnull)view; - -/** - Shows the HUD. You should preferably show the HUD in a UIViewController's view. The HUD will be repositioned in response to rotation and keyboard show/hide notifications. - @param view The view to show the HUD in. The frame of the @c view will be used to calculate the position of the HUD. - @param animated If the HUD should show with an animation. - */ -- (void)showInView:(UIView *__nonnull)view animated:(BOOL)animated; - -/** Dismisses the HUD animated. */ -- (void)dismiss; - -/** - Dismisses the HUD. - @param animated If the HUD should dismiss with an animation. - */ -- (void)dismissAnimated:(BOOL)animated; - -/** - Dismisses the HUD animated after a delay. - @param delay The delay until the HUD will be dismissed. - */ -- (void)dismissAfterDelay:(NSTimeInterval)delay; - -/** - Dismisses the HUD after a delay. - @param delay The delay until the HUD will be dismissed. - @param animated If the HUD should dismiss with an animation. - */ -- (void)dismissAfterDelay:(NSTimeInterval)delay animated:(BOOL)animated; - -@end - -@interface JGProgressHUD (HUDManagement) - -/** - @param view The view to return all visible progress HUDs for. - @return All visible progress HUDs in the view. - */ -+ (NSArray *__nonnull)allProgressHUDsInView:(UIView *__nonnull)view; - -/** - @param view The view to return all visible progress HUDs for. - @return All visible progress HUDs in the view and its subviews. - */ -+ (NSArray *__nonnull)allProgressHUDsInViewHierarchy:(UIView *__nonnull)view; - -@end - -@interface JGProgressHUD (Deprecated) - -#define JG_PROGRESS_HUD_SHOW_IN_RECT_DEPRECATED __attribute((deprecated(("Showing a HUD in a specific frame is no longer supported. Use a blank UIView with the desired frame and present the HUD in that view to achieve this behaviour.")))) - -/** - Shows the HUD animated. You should preferably show the HUD in a UIViewController's view. - @param view The view to show the HUD in. - @param rect The rect allocated in @c view for displaying the HUD. - */ -- (void)showInRect:(CGRect)rect inView:(UIView *__nonnull)view JG_PROGRESS_HUD_SHOW_IN_RECT_DEPRECATED; - -/** - Shows the HUD. You should preferably show the HUD in a UIViewController's view. - @param view The view to show the HUD in. - @param rect The rect allocated in @c view for displaying the HUD. - @param animated If the HUD should show with an animation. - */ -- (void)showInRect:(CGRect)rect inView:(UIView *__nonnull)view animated:(BOOL)animated JG_PROGRESS_HUD_SHOW_IN_RECT_DEPRECATED; - -@end - -@protocol JGProgressHUDDelegate - -@optional - -/** - Called before the HUD will appear. - @param view The view in which the HUD is presented. - */ -- (void)progressHUD:(JGProgressHUD *__nonnull)progressHUD willPresentInView:(UIView *__nonnull)view; - -/** - Called after the HUD appeared. - @param view The view in which the HUD is presented. - */ -- (void)progressHUD:(JGProgressHUD *__nonnull)progressHUD didPresentInView:(UIView *__nonnull)view; - -/** - Called before the HUD will disappear. - @param view The view in which the HUD is presented and will be dismissed from. - */ -- (void)progressHUD:(JGProgressHUD *__nonnull)progressHUD willDismissFromView:(UIView *__nonnull)view; - -/** - Called after the HUD has disappeared. - @param view The view in which the HUD was presented and was be dismissed from. - */ -- (void)progressHUD:(JGProgressHUD *__nonnull)progressHUD didDismissFromView:(UIView *__nonnull)view; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDAnimation.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDAnimation.h deleted file mode 100644 index 67679b63..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDAnimation.h +++ /dev/null @@ -1,43 +0,0 @@ -// -// JGProgressHUDAnimation.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import -#import - -@class JGProgressHUD; - -/** - You may subclass this class to create a custom progress indicator view. - */ -@interface JGProgressHUDAnimation : NSObject - -/** Convenience initializer. */ -+ (instancetype __nonnull)animation; - -/** The HUD using this animation. */ -@property (nonatomic, weak, readonly, nullable) JGProgressHUD *progressHUD; - -/** - The @c progressHUD is hidden from screen with @c alpha = 1 and @c hidden = @c YES. Ideally, you should prepare the HUD for presentation, then set @c hidden to @c NO on the @c progressHUD and then perform the animation. - @post Call @c animationFinished. - */ -- (void)show NS_REQUIRES_SUPER; - -/** - The @c progressHUD wis visible on screen with @c alpha = 1 and @c hidden = @c NO. You should only perform the animation in this method, the @c progressHUD itself will take care of hiding itself and removing itself from superview. - @post Call @c animationFinished. - */ -- (void)hide NS_REQUIRES_SUPER; - -/** - @pre This method should only be called at the end of a @c show or @c hide animaiton. - @attention ALWAYS call this method after completing a @c show or @c hide animation. - */ -- (void)animationFinished NS_REQUIRES_SUPER; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDErrorIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDErrorIndicatorView.h deleted file mode 100644 index 81966cdb..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDErrorIndicatorView.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// JGProgressHUDErrorIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 19.08.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDImageIndicatorView.h" - -/** - An image indicator showing a cross, representing a failed operation. - */ -@interface JGProgressHUDErrorIndicatorView : JGProgressHUDImageIndicatorView - -/** - Default initializer for this class. - */ -- (instancetype __nonnull)init; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeAnimation.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeAnimation.h deleted file mode 100644 index 42fe23c6..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeAnimation.h +++ /dev/null @@ -1,30 +0,0 @@ -// -// JGProgressHUDFadeAnimation.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDAnimation.h" - -/** - A simple fade animation that fades the HUD from alpha @c 0.0 to alpha @c 1.0. - */ -@interface JGProgressHUDFadeAnimation : JGProgressHUDAnimation - -/** - Duration of the animation. - - @b Default: 0.4. - */ -@property (nonatomic, assign) NSTimeInterval duration; - -/** - Animation options - - @b Default: UIViewAnimationOptionCurveEaseInOut. - */ -@property (nonatomic, assign) UIViewAnimationOptions animationOptions; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeZoomAnimation.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeZoomAnimation.h deleted file mode 100644 index 55fe398d..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDFadeZoomAnimation.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// JGProgressHUDFadeZoomAnimation.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDAnimation.h" - -/** - An animation that fades in the HUD and expands the HUD from scale @c (0, 0) to a customizable scale, and finally to scale @c (1, 1), creating a bouncing effect. - */ -@interface JGProgressHUDFadeZoomAnimation : JGProgressHUDAnimation - -/** - Duration of the animation from or to the shrinked state. - - @b Default: 0.2. - */ -@property (nonatomic, assign) NSTimeInterval shrinkAnimationDuaration; - -/** - Duration of the animation from or to the expanded state. - - @b Default: 0.1. - */ -@property (nonatomic, assign) NSTimeInterval expandAnimationDuaration; - -/** - The scale to apply to the HUD when expanding. - - @b Default: (1.1, 1.1). - */ -@property (nonatomic, assign) CGSize expandScale; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDImageIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDImageIndicatorView.h deleted file mode 100644 index 00f4501c..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDImageIndicatorView.h +++ /dev/null @@ -1,25 +0,0 @@ -// -// JGProgressHUDImageIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 05.08.15. -// Copyright (c) 2015 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDIndicatorView.h" - -/** - An indicator for displaying custom images. Supports animated images. - - You may subclass this class to create a custom image indicator view. - */ -@interface JGProgressHUDImageIndicatorView : JGProgressHUDIndicatorView - -/** - Initializes the indicator view with an UIImageView showing the @c image. - - @param image The image to show in the indicator view. - */ -- (instancetype __nonnull)initWithImage:(UIImage *__nonnull)image; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDIndeterminateIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDIndeterminateIndicatorView.h deleted file mode 100644 index 967ced55..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDIndeterminateIndicatorView.h +++ /dev/null @@ -1,28 +0,0 @@ -// -// JGProgressHUDIndeterminateIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 19.07.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUD-Defines.h" -#import "JGProgressHUDIndicatorView.h" - -/** - An indeterminate progress indicator showing a @c UIActivityIndicatorView. - */ -@interface JGProgressHUDIndeterminateIndicatorView : JGProgressHUDIndicatorView - -/** - Initializes the indicator view and sets the correct color to match the HUD style. - */ -- (instancetype __nonnull)initWithHUDStyle:(JGProgressHUDStyle)style __attribute((deprecated(("This initializer is no longer needed. Use the init initializer method.")))); - -/** - Set the color of the activity indicator view. - @param color The color to apply to the activity indicator view. - */ -- (void)setColor:(UIColor *__nonnull)color; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDIndicatorView.h deleted file mode 100644 index 9d702e64..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDIndicatorView.h +++ /dev/null @@ -1,57 +0,0 @@ -// -// JGProgressHUDIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import -#import -#import "JGProgressHUD-Defines.h" - -/** You may subclass this class to create a custom progress indicator view. */ -@interface JGProgressHUDIndicatorView : UIView - -/** - Designated initializer for this class. - - @param contentView The content view to place on the container view (the container is the JGProgressHUDIndicatorView). - */ -- (instancetype __nonnull)initWithContentView:(UIView *__nullable)contentView; - -/** Use this method to set up the indicator view to fit the HUD style and vibrancy setting. This method is called by @c JGProgressHUD when the indicator view is added to the HUD and when the HUD's @c vibrancyEnabled property changes. This method may be called multiple times with different values. The default implementation does nothing. */ -- (void)setUpForHUDStyle:(JGProgressHUDStyle)style vibrancyEnabled:(BOOL)vibrancyEnabled; - -/** Ranges from 0.0 to 1.0. */ -@property (nonatomic, assign) float progress; - -/** - Adjusts the current progress shown by the receiver, optionally animating the change. - - The current progress is represented by a floating-point value between 0.0 and 1.0, inclusive, where 1.0 indicates the completion of the task. The default value is 0.0. Values less than 0.0 and greater than 1.0 are pinned to those limits. - - @param progress The new progress value. - @param animated YES if the change should be animated, NO if the change should happen immediately. - */ -- (void)setProgress:(float)progress animated:(BOOL)animated; - -/** - The content view which displays the progress. - */ -@property (nonatomic, strong, readonly, nullable) UIView *contentView; - -/** Schedules an accessibility update on the next run loop. */ -- (void)setNeedsAccessibilityUpdate; - -/** - Runs @c updateAccessibility immediately if an accessibility update has been scheduled (through @c setNeedsAccessibilityUpdate) but has not executed yet. - */ -- (void)updateAccessibilityIfNeeded; - -/** - Override to set custom accessibility properties. This method gets called once when initializing the view and after calling @c setNeedsAccessibilityUpdate. - */ -- (void)updateAccessibility; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDPieIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDPieIndicatorView.h deleted file mode 100644 index bda9e1b1..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDPieIndicatorView.h +++ /dev/null @@ -1,38 +0,0 @@ -// -// JGProgressHUDPieIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 19.07.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUD-Defines.h" -#import "JGProgressHUDIndicatorView.h" - -/** - A pie shaped determinate progress indicator. - */ -@interface JGProgressHUDPieIndicatorView : JGProgressHUDIndicatorView - -/** - Initializes the indicator view and sets the correct color to match the HUD style. - */ -- (instancetype __nonnull)initWithHUDStyle:(JGProgressHUDStyle)style __attribute((deprecated(("This initializer is no longer needed. Use the init initializer method.")))); - -/** - Tint color of the Pie. - @attention Custom values need to be set after assigning the indicator view to @c JGProgressHUD's @c indicatorView property. - - @b Default: White for JGProgressHUDStyleDark, otherwise black. - */ -@property (nonatomic, strong, nonnull) UIColor *color; - -/** - The background fill color inside the pie. - @attention Custom values need to be set after assigning the indicator view to @c JGProgressHUD's @c indicatorView property. - - @b Default: Dark gray for JGProgressHUDStyleDark, otherwise light gray. - */ -@property (nonatomic, strong, nonnull) UIColor *fillColor; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDRingIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDRingIndicatorView.h deleted file mode 100644 index f348fc39..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDRingIndicatorView.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// JGProgressHUDRingIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 20.7.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUD-Defines.h" -#import "JGProgressHUDIndicatorView.h" - -/** - A ring shaped determinate progress indicator. - */ -@interface JGProgressHUDRingIndicatorView : JGProgressHUDIndicatorView - -/** - Initializes the indicator view and sets the correct color to match the HUD style. - */ -- (instancetype __nonnull)initWithHUDStyle:(JGProgressHUDStyle)style __attribute((deprecated(("This initializer is no longer needed. Use the init initializer method.")))); - -/** - Background color of the ring. - @attention Custom values need to be set after assigning the indicator view to @c JGProgressHUD's @c indicatorView property. - - @b Default: Black for JGProgressHUDStyleDark, light gray otherwise. - */ -@property (nonatomic, strong, nonnull) UIColor *ringBackgroundColor; - -/** - Progress color of the progress ring. - @attention Custom values need to be set after assigning the indicator view to @c JGProgressHUD's @c indicatorView property. - - @b Default: White for JGProgressHUDStyleDark, otherwise black. - */ -@property (nonatomic, strong, nonnull) UIColor *ringColor; - -/** - Sets if the progress ring should have a rounded line cap. - - @b Default: NO. - */ -@property (nonatomic, assign) BOOL roundProgressLine; - -/** - Width of the ring. - - @b Default: 3.0. - */ -@property (nonatomic, assign) CGFloat ringWidth; - -@end - diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDShadow.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDShadow.h deleted file mode 100644 index 105b1fa3..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDShadow.h +++ /dev/null @@ -1,37 +0,0 @@ -// -// JGProgressHUDShadow.h -// JGProgressHUD -// -// Created by Jonas Gessner on 25.09.17. -// Copyright © 2017 Jonas Gessner. All rights reserved. -// - -#import - -/** - A wrapper representing properties of a shadow. - */ -@interface JGProgressHUDShadow : NSObject - -- (instancetype __nonnull)initWithColor:(UIColor *__nonnull)color offset:(CGSize)offset radius:(CGFloat)radius opacity:(float)opacity; - -/** Convenience initializer. */ -+ (instancetype __nonnull)shadowWithColor:(UIColor *__nonnull)color offset:(CGSize)offset radius:(CGFloat)radius opacity:(float)opacity; - -/** - The color of the shadow. Colors created from patterns are currently NOT supported. - */ -@property (nonatomic, strong, readonly, nonnull) UIColor *color; - -/** The shadow offset. */ -@property (nonatomic, assign, readonly) CGSize offset; - -/** The blur radius used to create the shadow. */ -@property (nonatomic, assign, readonly) CGFloat radius; - -/** - The opacity of the shadow. Specifying a value outside the [0,1] range will give undefined results. - */ -@property (nonatomic, assign, readonly) float opacity; - -@end diff --git a/BHTwitter/JGProgressHUD/include/JGProgressHUDSuccessIndicatorView.h b/BHTwitter/JGProgressHUD/include/JGProgressHUDSuccessIndicatorView.h deleted file mode 100644 index 94ac851b..00000000 --- a/BHTwitter/JGProgressHUD/include/JGProgressHUDSuccessIndicatorView.h +++ /dev/null @@ -1,21 +0,0 @@ -// -// JGProgressHUDSuccessIndicatorView.h -// JGProgressHUD -// -// Created by Jonas Gessner on 19.08.14. -// Copyright (c) 2014 Jonas Gessner. All rights reserved. -// - -#import "JGProgressHUDImageIndicatorView.h" - -/** - An image indicator showing a checkmark, representing a failed operation. - */ -@interface JGProgressHUDSuccessIndicatorView : JGProgressHUDImageIndicatorView - -/** - Default initializer for this class. - */ -- (instancetype __nonnull)init; - -@end diff --git a/BHTwitter/Package/DEBIAN/control b/BHTwitter/Package/DEBIAN/control index 19996169..ef246638 100644 --- a/BHTwitter/Package/DEBIAN/control +++ b/BHTwitter/Package/DEBIAN/control @@ -1,6 +1,6 @@ Package: com.bandarhl.BHTwitter Name: BHTwitter -Version: 3.2 +Version: 3.3 Description: Awesome tweak for Twitter Section: Tweaks Depends: firmware (>= 13.0), mobilesubstrate, ws.hbang.common (>= 1.17) diff --git a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/Info.plist b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/Info.plist index 69842e89..456cd1ca 100644 Binary files a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/Info.plist and b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/Info.plist differ diff --git a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/ar.lproj/Localizable.strings b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/ar.lproj/Localizable.strings index 2dc99dd4..f219d083 100644 --- a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/ar.lproj/Localizable.strings +++ b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/ar.lproj/Localizable.strings @@ -107,8 +107,24 @@ "THEME_OPTION_TITLE" = "الثيم"; "THEME_OPTION_DETAIL_TITLE" = "قم بإختيار لون الثيم الذي تريده ."; +"THEME_OPTION_1" = "أزرق"; +"THEME_OPTION_2" = "أصفر"; +"THEME_OPTION_3" = "أحمر"; +"THEME_OPTION_4" = "أرجواني"; +"THEME_OPTION_5" = "البرتقالي"; +"THEME_OPTION_6" = "أخضر"; "CUSTOM_TAB_BAR_OPTION_TITLE" = "تخصيص الشريط السفلي"; +"CUSTOM_TAB_BAR_REST_MESSAGE" = "هل انت متأكد انك تريد أعادة ضبط الاعدادات؟"; +"CUSTOM_TAB_BAR_SECTION_1_TITLE" = "عناصر الشريط السلفي الظاهرة"; +"CUSTOM_TAB_BAR_SECTION_2_TITLE" = "عناصر الشريط السلفي المخفية"; +"CUSTOM_TAB_BAR_OPTION_1" = "الرئيسية"; +"CUSTOM_TAB_BAR_OPTION_2" = "البحث"; +"CUSTOM_TAB_BAR_OPTION_3" = "المساحات"; +"CUSTOM_TAB_BAR_OPTION_4" = "المجتمعات"; +"CUSTOM_TAB_BAR_OPTION_5" = "التنبيهات"; +"CUSTOM_TAB_BAR_OPTION_6" = "الرسائل"; + "TWITTER_BLUE_SECTION_FOOTER_TITLE" = "قم بإغلاق التطبيق لحفظ التغييرات ."; "LAYOUT_CUS_SECTION_HEADER_TITLE" = "تخصيص المظهر"; diff --git a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/en.lproj/Localizable.strings b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/en.lproj/Localizable.strings index 39c95729..902ebdfa 100644 --- a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/en.lproj/Localizable.strings +++ b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/en.lproj/Localizable.strings @@ -1,4 +1,4 @@ -/* +/* en BHTwitter */ @@ -107,8 +107,24 @@ "THEME_OPTION_TITLE" = "Theme"; "THEME_OPTION_DETAIL_TITLE" = "Choose a theme color for you Twitter experience that can only be seen by you."; +"THEME_OPTION_1" = "Blue"; +"THEME_OPTION_2" = "Yellow"; +"THEME_OPTION_3" = "Red"; +"THEME_OPTION_4" = "Purple"; +"THEME_OPTION_5" = "Orange"; +"THEME_OPTION_6" = "Green"; "CUSTOM_TAB_BAR_OPTION_TITLE" = "Custom Tab Bar"; +"CUSTOM_TAB_BAR_REST_MESSAGE" = "Are sure you want to rest the settings to default?"; +"CUSTOM_TAB_BAR_SECTION_1_TITLE" = "Active tab bar"; +"CUSTOM_TAB_BAR_SECTION_2_TITLE" = "Hidden tab bar"; +"CUSTOM_TAB_BAR_OPTION_1" = "Home"; +"CUSTOM_TAB_BAR_OPTION_2" = "Explore"; +"CUSTOM_TAB_BAR_OPTION_3" = "Spaces"; +"CUSTOM_TAB_BAR_OPTION_4" = "Communities"; +"CUSTOM_TAB_BAR_OPTION_5" = "Notifications"; +"CUSTOM_TAB_BAR_OPTION_6" = "Messages"; + "TWITTER_BLUE_SECTION_FOOTER_TITLE" = "You may need to restart Twitter app to apply changes."; "LAYOUT_CUS_SECTION_HEADER_TITLE" = "Layout customization"; diff --git a/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/tr.lproj/Localizable.strings b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/tr.lproj/Localizable.strings new file mode 100644 index 00000000..0afe857e --- /dev/null +++ b/BHTwitter/Package/Library/Application Support/BHT/BHTwitter.bundle/tr.lproj/Localizable.strings @@ -0,0 +1,132 @@ +/* + tr + BHTwitter +*/ + +"BHTWITTER_SETTINGS_TITLE" = "Ayarlar"; +"BHTWITTER_SETTINGS_DETAIL" = "BHTwitter tercihleri"; + +"DOWNLOAD_MENU_TITLE" = "\nİndirmek istediğiniz video kalitesini seçin"; +"CUSTOM_FONTS_MENU_TITLE" = "\nÖzel yazı tipinizi seçin"; +"CUSTOM_FONTS_TUT_ALERT_MESSAGE" = "Bu cihazda herhangi bir özel/yüklü yazı tipi bulunamadı. \nÖzel yazı tiplerini nasıl yükleyebilirim? \nAppStore'a gidin ve iFont uygulamasını yükleyin, iFont'tan yüklemek için yazı tiplerini arayabilir veya içe aktarabilirsiniz, bundan sonra özel yazı tipinizi burada bulabilirsiniz."; + +"OK_BUTTON_TITLE" = "TAMAM"; +"YES_BUTTON_TITLE" = "EVET"; +"NO_BUTTON_TITLE" = "HAYIR"; +"CONFIRM_ALERT_MESSAGE" = "Emin misiniz?"; +"CANCEL_BUTTON_TITLE" = "İptal"; + +"PROGRESS_DOWNLOADING_STATUS_TITLE" = "İndiriliyor"; + +"CUSTOM_FONTS_NAVIGATION_BUTTON_TITLE" = "Özel yazı tipleri"; +"CUSTOM_FONTS_NAVIGATION_TITLE" = "Yazı tipi seç"; +"THEME_SETTINGS_NAVIGATION_TITLE" = "Tema"; +"CUSTOM_TAB_BAR_SETTINGS_NAVIGATION_TITLE" = "Özel Sekme Çubuğu"; +"ACKNOWLEDGEMENTS_SETTINGS_NAVIGATION_TITLE" = "Teşekkürler"; + +"COPY_PROFILE_INFO_MENU_OPTION_1" = "Biyografiyi kopyala"; +"COPY_PROFILE_INFO_MENU_OPTION_2" = "Kullanıcı adını kopyala"; +"COPY_PROFILE_INFO_MENU_OPTION_3" = "Tam Kullanıcı Adını Kopyala"; +"COPY_PROFILE_INFO_MENU_OPTION_4" = "URL'yi biyografiye kopyala"; +"COPY_PROFILE_INFO_MENU_OPTION_5" = "Bio'daki Konumu Kopyala"; + +"MAIN_SECTION_HEADER_TITLE" = "BHTwitter Tercihleri"; +"DOWNLOAD_VIDEOS_OPTION_TITLE" = "Videoları indirme"; +"DOWNLOAD_VIDEOS_OPTION_DETAIL_TITLE" = "Videolar Tweet'e ve video sekme çubuğunun içine eklenen düğmeyle indirilebilir."; + +"DIRECT_SAVE_OPTION_TITLE" = "Doğrudan kaydetme"; +"DIRECT_SAVE_OPTION_DETAIL_TITLE" = "İndirdikten sonra videoyu doğrudan kaydedin."; + +"HIDE_ADS_OPTION_TITLE" = "Reklamları Gizle"; +"HIDE_ADS_OPTION_DETAIL_TITLE" = "Twitter'daki tüm Reklamları kaldırır."; + +"HIDE_TOPICS_OPTION_TITLE" = "Konu tweetlerini gizle"; +"HIDE_TOPICS_OPTION_DETAIL_TITLE" = "Tüm konu tweetlerini zaman çizelgesinden kaldırın."; + +"HIDE_WHO_FOLLOW_OPTION" = "Kimi takip etmeli bölümünü gizle"; +"HIDE_WHO_FOLLOW_OPTION_DETAIL_TITLE" = "Profillerden Kimi takip etmeli bölümünü gizler"; + +"HIDE_TOPICS_TO_FOLLOW_OPTION" = "Takip edilesi konular bölümü gizle"; +"HIDE_TOPICS_TO_FOLLOW_OPTION_DETAIL_TITLE" = "Profillerdeki Takip edilesi konular bölümü gizler"; + +"DISABLE_VIDEO_LAYER_CAPTIONS_OPTION_TITLE" = "Video katmanı altyazılarını devre dışı bırak"; + +"VOICE_OPTION_TITLE" = "Ses özelliği"; +"VOICE_OPTION_DETAIL_TITLE" = "Tweet ve DM'de sesi etkinleştirin."; + +"VIDEO_ZOOM_OPTION_TITLE" = "Video yakınlaştırma özelliği"; +"VIDEO_ZOOM_OPTION_DETAIL_TITLE" = "Videonun ortasına çift tıklayarak videoyu yakınlaştırabilirsiniz."; + +"NO_HISTORY_OPTION_TITLE" = "Arama geçmişini kapat"; +"NO_HISTORY_OPTION_DETAIL_TITLE" = "Twitter'ı arama geçmişini kaydetmeyi durdurmaya zorlar."; + +"BIO_TRANSALTE_OPTION_TITLE" = "Biyografiyi Çevir"; +"BIO_TRANSALTE_OPTION_DETAIL_TITLE" = "Çevirmek için kullanıcı biyografisinde bir düğme gösterir."; + +"LIKE_CONFIRM_OPTION_TITLE" = "Beğeniyi onayla"; +"LIKE_CONFIRM_OPTION_DETAIL_TITLE" = "Beğen düğmesine bastığınızda bir onay uyarısı gösterir."; + +"TWEET_CONFIRM_OPTION_TITLE" = "Tweetlerken onayla"; +"TWEET_CONFIRM_OPTION_DETAIL_TITLE" = "Tweet düğmesine bastığınızda bir onay uyarısı gösterir."; + +"FOLLOW_CONFIRM_OPTION_TITLE" = "Kullanıcı takibini onayla"; +"FOLLOW_CONFIRM_OPTION_DETAIL_TITLE" = "Takip düğmesine bastığınızda bir onay uyarısı gösterir."; + +"PADLOCK_OPTION_TITLE" = "Giriş Kilidi"; +"PADLOCK_OPTION_DETAIL_TITLE" = "Twitter'ı şifre ile kilitler."; + +"DN_MODULAR_SEARCH_OPTION_TITLE" = "DM Modüler Aramayı Etkinleştir"; +"DN_MODULAR_SEARCH_OPTION_DETAIL_TITLE" = "DM aramasının yeni kullanıcı arayüzünü etkinleştirir."; + +"AUTO_HIGHEST_LOAD_OPTION_TITLE" = "Fotoğrafları otomatik olarak en yüksek kalitede yükle"; +"AUTO_HIGHEST_LOAD_OPTION_DETAIL_TITLE" = "Bu seçenek, fotoğrafları mümkün olan en yüksek kalitede karşı tarafa yüklemenize ve görüntülemenize olanak tanır."; + +"DISABLE_SENSITIVE_TWEET_WARNINGS_OPTION_TITLE" = "Hassas tweet uyarısını devre dışı bırak"; +"TRUSTED_FRIENSS_OPTION_TITLE" = "Twitter Çevresi özelliğini etkinleştir"; + +"COPY_PROFILE_INFO_OPTION_TITLE" = "Profil bilgilerini kopyalama özelliğini etkinleştir"; +"COPY_PROFILE_INFO_OPTION_DETAIL_TITLE" = "Twitter profiline, istediğiniz bilgiyi kopyalamanıza izin veren yeni bir düğme ekler."; + +"TWEET_TO_IMAGE_OPTION_TITLE" = "Tweet'i resim olarak kaydet"; +"TWEET_TO_IMAGE_OPTION_DETAIL_TITLE" = "Tweet Paylaş düğmesine uzun basarak tweet'leri resim olarak dışa aktarabilirsiniz."; + +"HIDE_SPACE_OPTION_TITLE" = "Sohbet Odaları(Spaces) çubuğunu gizle"; + +"DISABLE_RTL_OPTION_TITLE" = "Sağdan Sola'yı(RTL) Devre Dışı Bırak"; +"DISABLE_RTL_OPTION_DETAIL_TITLE" = "Twitter'ı Sağdan Sola olan bir dille kullanılırken Soldan Sağa kullanıma zorlar.\nDeğişiklikleri uygulamak için Twitter uygulamasını yeniden başlatın."; + +"ALWAYS_OPEN_SAFARI_OPTION_TITLE" = "Her zaman Safari'de aç"; +"ALWAYS_OPEN_SAFARI_OPTION_DETAIL_TITLE" = "Twitter'ı, URL'leri Safari'de veya varsayılan tarayıcınızda açmaya zorlar."; + +"TWITTER_BLUE_SECTION_HEADER_TITLE" = "Twitter Blue özellikleri"; +"UNDO_TWEET_OPTION_TITLE" = "Tweetleri geri al özelliği"; +"UNDO_TWEET_OPTION_DETAIL_TITLE" = "Tweet'i attıktan sonra tweetleri geri alabilme."; + +"READER_MODE_OPTION_TITLE" = "Okuyucu modu özelliği"; +"READER_MODE_OPTION_DETAIL_TITLE" = "Konularda okuyucu modunu etkinleştirir."; + +"THEME_OPTION_TITLE" = "Tema"; +"THEME_OPTION_DETAIL_TITLE" = "Twitter deneyiminiz için yalnızca sizin görebileceğiniz bir tema rengi seçin."; + +"CUSTOM_TAB_BAR_OPTION_TITLE" = "Özel Sekme Çubuğu"; +"TWITTER_BLUE_SECTION_FOOTER_TITLE" = "Değişiklikleri uygulamak için Twitter uygulamasını yeniden başlatmanız gerekebilir."; + +"LAYOUT_CUS_SECTION_HEADER_TITLE" = "Düzen özelleştirme"; +"ORIG_TWEET_STYLE_OPTION_TITLE" = "Uçtan uca tweet stilini devre dışı bırak"; +"ORIG_TWEET_STYLE_OPTION_DETAIL_TITLE" = "Twitter'ı orijinal tweet stilini kullanmaya zorlar."; + +"FONT_OPTION_TITLE" = "Yazı tipini değiştirmeyi etkinleştir"; +"FONT_OPTION_DETAIL_TITLE" = "Twitter yazı tipini değiştirmeye izin verme ve yazı tipi seçiciyi gösterme seçeneği."; + +"REQULAR_FONTS_PICKER_OPTION_TITLE" = "Yazı tipi"; +"BOLD_FONTS_PICKER_OPTION_TITLE" = "Kalın Yazı Tipi"; +"LAYOUT_CUS_SECTION_FOOTER_TITLE" = "Değişiklikleri uygulamak için Twitter uygulamasını yeniden başlatın."; + +"DEBUG_SECTION_HEADER_TITLE" = "Hata ayıklama"; +"FLEX_OPTION_TITLE" = "FLEX'i etkinleştir"; +"FLEX_OPTION_DETAIL_TITLE" = "Twitter uygulamasında FLEX'i göster."; + +"LEGAL_SECTION_HEADER_TITLE" = "Yasal uyarılar"; +"LEGAL_BUTTON_TITLE" = "Teşekkürler"; + +"DEVELOPER_SECTION_HEADER_TITLE" = "Geliştirici"; diff --git a/BHTwitter/TWHeaders.h b/BHTwitter/TWHeaders.h index 8007a4eb..27d4984e 100644 --- a/BHTwitter/TWHeaders.h +++ b/BHTwitter/TWHeaders.h @@ -10,10 +10,9 @@ #import #import #import -#import "./Classes/Utility/FLEXAlert.h" -#import "./Classes/FLEX.h" +#import #import "BHDownload.h" -#import "JGProgressHUD/include/JGProgressHUD.h" +#import #import "SAMKeychain/keychain.h" #import #import @@ -209,6 +208,7 @@ @interface TFSTwitterEntityMedia : NSObject @property(readonly, nonatomic) TFSTwitterEntityMediaVideoInfo *videoInfo; @property(readonly, copy, nonatomic) NSString *mediaURL; +@property(nonatomic, assign, readonly) NSInteger mediaType; // 1 = photo, 2 = GIF, 3 = video @end @interface TFSTwitterEntitySet : NSObject @@ -217,6 +217,9 @@ @protocol T1StatusViewModel @property(nonatomic, readonly) TFSTwitterEntitySet *entities; +@property(nonatomic, assign, readonly) NSArray *representedMediaEntities; +@property (nonatomic, assign, readonly) BOOL isMediaEntityVideo; +@property (nonatomic, assign, readonly) BOOL isGIF; @end @interface T1StatusInlineActionsView : UIView @@ -229,6 +232,10 @@ @property(nonatomic) id delegate; @end +@interface T1SlideshowStatusView : UIView +@property (nonatomic, strong, readwrite) TFSTwitterEntityMedia *media; +@end + @interface T1StandardStatusView : UIView @property(nonatomic) __weak id eventHandler; @property(readonly, nonatomic) UIView *visibleInlineActionsView; diff --git a/BHTwitter/ThemeColor/BHColorThemeViewController.swift b/BHTwitter/ThemeColor/BHColorThemeViewController.swift index 64a3ffce..1cfbe4c9 100644 --- a/BHTwitter/ThemeColor/BHColorThemeViewController.swift +++ b/BHTwitter/ThemeColor/BHColorThemeViewController.swift @@ -63,12 +63,12 @@ struct ColorThemeItem { class BHColorThemeViewController: UIViewController { var colors = [ - ColorThemeItem(colorID: 1, name: "Blue", color: UIColor(argbHexString: "#1D9BF0")!), - ColorThemeItem(colorID: 2, name: "Yellow", color: UIColor(argbHexString: "#FFD400")!), - ColorThemeItem(colorID: 3, name: "Red", color: UIColor(argbHexString: "#F91880")!), - ColorThemeItem(colorID: 4, name: "Purple", color: UIColor(argbHexString: "#7856FF")!), - ColorThemeItem(colorID: 5, name: "Orange", color: UIColor(argbHexString: "#FF7A00")!), - ColorThemeItem(colorID: 6, name: "Green", color: UIColor(argbHexString: "#00BA7C")!), + ColorThemeItem(colorID: 1, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_1"), color: UIColor(argbHexString: "#1D9BF0")!), + ColorThemeItem(colorID: 2, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_2"), color: UIColor(argbHexString: "#FFD400")!), + ColorThemeItem(colorID: 3, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_3"), color: UIColor(argbHexString: "#F91880")!), + ColorThemeItem(colorID: 4, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_4"), color: UIColor(argbHexString: "#7856FF")!), + ColorThemeItem(colorID: 5, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_5"), color: UIColor(argbHexString: "#FF7A00")!), + ColorThemeItem(colorID: 6, name: BHTBundle.shared().localizedString(forKey: "THEME_OPTION_6"), color: UIColor(argbHexString: "#00BA7C")!), ] { didSet { colorCollectionView.reloadData() @@ -86,7 +86,7 @@ class BHColorThemeViewController: UIViewController { var headerLabel: UILabel = { let label = UILabel() - label.text = "Choose a theme color for your Twitter experience that can be seen by you." + label.text = BHTBundle.shared().localizedString(forKey: "THEME_OPTION_DETAIL_TITLE") label.textColor = .secondaryLabel label.numberOfLines = 0 label.font = .systemFont(ofSize: 15) diff --git a/README.md b/README.md index 3a7392a9..494c30fa 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ - Enable the new UI of DM search. - Auto load photos in highest quality feature. - Undo tweet feature. -- Theme (like Twitter Bule). +- Theme (like Twitter Blue). - Twitter Circle feature. - Copying profile information feature. - Save tweet as an image. @@ -40,14 +40,14 @@ - install [MonkeyDev](https://github.com/AloneMonkey/MonkeyDev) - Open BHTwitter.xcodeproj - Make sure you're selecting (Any iOS Device) - > If you get Code sign error, add an developer account to xcode and then Go to Build settings and select "All" tab then search for "Sign", you should find "Code Signing Identity" chnage it to iOS developer and chnage "Developer Team" to match you're developer account + > If you get Code sign error, add an developer account to Xcode and then Go to Build settings and select "All" tab then search for "Sign", you should find "Code Signing Identity" change it to iOS developer and change "Developer Team" to match you're developer account ### for jailbreak devices - Just press Run button of the project or command+b from you're keyboard - Wait until the build finished - You should find deb file in Packages folder of the project ### for non-jailbreak devices - Go to the Build settings and scroll down to 'user-Defined' section and change "MonkeyDevInstallOnAnyBuild" value to NO -- Select BHTwitter.xm and scoll down to 1237 line or 'Fix login keychain in non-JB (IPA).' section and enable the code below it +- Select BHTwitter.xm and scroll down to 1237 line or 'Fix login keychain in non-JB (IPA).' section and enable the code below it - Press Run button of the project or command+b from you're keyboard - Wait until the build finished - You should find the BHTwitter.dylib in LatestBuild dir of the project