[
  {
    "path": ".gitignore",
    "content": "geoip\ngeoip6\ntor.xcframework\ntor-nolzma.xcframework\ntor.xcframework.zip\ntor-nolzma.xcframework.zip\narti.xcframework\narti.xcframework.zip\n\n# Created by https://www.toptal.com/developers/gitignore/api/macos,xcode,swift,objective-c\n# Edit at https://www.toptal.com/developers/gitignore?templates=macos,xcode,swift,objective-c\n\n### macOS ###\n# General\n.DS_Store\n.AppleDouble\n.LSOverride\n\n# Icon must end with two \\r\nIcon\n\n\n# Thumbnails\n._*\n\n# Files that might appear in the root of a volume\n.DocumentRevisions-V100\n.fseventsd\n.Spotlight-V100\n.TemporaryItems\n.Trashes\n.VolumeIcon.icns\n.com.apple.timemachine.donotpresent\n\n# Directories potentially created on remote AFP share\n.AppleDB\n.AppleDesktop\nNetwork Trash Folder\nTemporary Items\n.apdisk\n\n### Objective-C ###\n# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n## User settings\nxcuserdata/\n\n## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)\n*.xcscmblueprint\n*.xccheckout\n\n## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)\nbuild/\nDerivedData/\n*.moved-aside\n*.pbxuser\n!default.pbxuser\n*.mode1v3\n!default.mode1v3\n*.mode2v3\n!default.mode2v3\n*.perspectivev3\n!default.perspectivev3\n\n## Obj-C/Swift specific\n*.hmap\n\n## App packaging\n*.ipa\n*.dSYM.zip\n*.dSYM\n\n# CocoaPods\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\nPods/\n# Add this line if you want to avoid checking in source code from the Xcode workspace\n# *.xcworkspace\n\n# Carthage\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\nCarthage/Checkouts\n\nCarthage/Build/\n\n# fastlane\n# It is recommended to not store the screenshots in the git repo.\n# Instead, use fastlane to re-generate the screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\nfastlane/report.xml\nfastlane/Preview.html\nfastlane/screenshots/**/*.png\nfastlane/test_output\n\n# Code Injection\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\niOSInjectionProject/\n\n### Objective-C Patch ###\n\n### Swift ###\n# Xcode\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n\n\n\n\n\n## Playgrounds\ntimeline.xctimeline\nplayground.xcworkspace\n\n# Swift Package Manager\n# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.\n# Packages/\n# Package.pins\n# Package.resolved\n# *.xcodeproj\n# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata\n# hence it is not needed unless you have added a package configuration file to your project\n# .swiftpm\n\n.build/\n\n# CocoaPods\n# We recommend against adding the Pods directory to your .gitignore. However\n# you should judge for yourself, the pros and cons are mentioned at:\n# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control\n# Pods/\n# Add this line if you want to avoid checking in source code from the Xcode workspace\n# *.xcworkspace\n\n# Carthage\n# Add this line if you want to avoid checking in source code from Carthage dependencies.\n# Carthage/Checkouts\n\n\n# Accio dependency management\nDependencies/\n.accio/\n\n# fastlane\n# It is recommended to not store the screenshots in the git repo.\n# Instead, use fastlane to re-generate the screenshots whenever they are needed.\n# For more information about the recommended setup visit:\n# https://docs.fastlane.tools/best-practices/source-control/#source-control\n\n\n# Code Injection\n# After new code Injection tools there's a generated folder /iOSInjectionProject\n# https://github.com/johnno1962/injectionforxcode\n\n\n### Xcode ###\n\n## Xcode 8 and earlier\n\n### Xcode Patch ###\n*.xcodeproj/*\n!*.xcodeproj/project.pbxproj\n!*.xcodeproj/xcshareddata/\n!*.xcworkspace/contents.xcworkspacedata\n/*.gcno\n**/xcshareddata/WorkspaceSettings.xcsettings\n\n# End of https://www.toptal.com/developers/gitignore/api/macos,xcode,swift,objective-c\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"Tor/onionmasq\"]\n\tpath = Tor/onionmasq\n\turl = https://gitlab.torproject.org/tpo/core/onionmasq.git\n"
  },
  {
    "path": "Arti.podspec",
    "content": "Pod::Spec.new do |m|\n\n  m.name             = 'Tor'\n  m.version          = '408.22.1'\n  m.summary          = 'Tor.framework is the easiest way to embed Tor in your iOS application.'\n  m.description      = 'Tor.framework is the easiest way to embed Tor in your iOS application.'\n\n  m.homepage         = 'https://github.com/iCepa/Tor.framework'\n  m.license          = { :type => 'MIT', :file => 'LICENSE' }\n  m.authors          = {\n    'Conrad Kramer' => 'conrad@conradkramer.com',\n    'Chris Ballinger' => 'chris@chatsecure.org',\n    'Mike Tigas' => 'mike@tig.as',\n    'Benjamin Erhart' => 'berhart@netzarchitekten.com', }\n  m.source           = {\n    :git => 'https://github.com/iCepa/Tor.framework.git',\n    :branch => 'pure_pod',\n    :tag => \"v#{m.version}\",\n    :submodules => true }\n  m.social_media_url = 'https://chaos.social/@tla'\n\n  m.ios.deployment_target = '15.0'\n  m.macos.deployment_target = '11.0'\n\n  m.prepare_command = \"Tor/download.sh v#{m.version} arti 16a8f88e8b4f09b39462733cefb8b1c5f715b36c03c4745a6a5c6a8eb370c48f\"\n\n  script = <<-ENDSCRIPT\ncd \"${PODS_TARGET_SRCROOT}/Tor/%1$s\"\n../%1$s.sh\n  ENDSCRIPT\n\n  m.subspec 'Core' do |s|\n    s.requires_arc = true\n\n    s.source_files = 'Tor/Classes/Core/**/*'\n  end\n\n  m.subspec 'Arti' do |s|\n    s.dependency 'Tor/Core'\n\n    s.source_files = 'Tor/Classes/Arti/**/*'\n\n    s.vendored_frameworks = 'arti.xcframework'\n\n    s.pod_target_xcconfig = {\n      'HEADER_SEARCH_PATHS' => '$(inherited) \"${PODS_TARGET_SRCROOT}/arti.xcframework/ios-arm64/arti.framework/Headers\"',\n    }\n\n    s.preserve_paths = 'arti.xcframework', 'download.sh'\n\n    s.user_target_xcconfig = {\n      'GCC_PREPROCESSOR_DEFINITIONS' => 'USE_ARTI=1',\n      'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => '$(inherited) USE_ARTI',\n    }\n  end\n\n  m.subspec 'Onionmasq' do |s|\n    s.dependency 'Tor/Core'\n\n    s.source_files = 'Tor/Classes/Onionmasq/**/*'\n\n    s.pod_target_xcconfig = {\n      'HEADER_SEARCH_PATHS' => '$(inherited) \"${PODS_TARGET_SRCROOT}/Tor/onionmasq\"',\n      'OTHER_LDFLAGS' => '$(inherited) -L\"${BUILT_PRODUCTS_DIR}/Tor\" -l\"onionmasq_apple\"',\n    }\n\n    s.user_target_xcconfig = {\n      'GCC_PREPROCESSOR_DEFINITIONS' => 'USE_ONIONMASQ=1',\n      'SWIFT_ACTIVE_COMPILATION_CONDITIONS' => '$(inherited) USE_ONIONMASQ',\n    }\n\n    s.script_phases = [\n    {\n      :name => 'Build Onionmasq',\n      :execution_position => :before_compile,\n      :output_files => ['onionmasq-always-execute-this-but-supress-warning'],\n      :script => sprintf(script, \"onionmasq\")\n    },\n    ]\n\n    s.preserve_paths = 'Tor/onionmasq', 'Tor/onionmasq.sh'\n\n  end\n\n  m.default_subspecs = 'Arti'\n\nend\n"
  },
  {
    "path": "Brewfile",
    "content": "brew \"automake\"\nbrew \"autoconf\"\nbrew \"libtool\"\nbrew \"gettext\"\nbrew \"po4a\"\nbrew \"rustup\"\n"
  },
  {
    "path": "Example/Example-Mac/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  Tor_Example_Mac\n//\n//  Created by Benjamin Erhart on 13.01.22.\n//  Copyright © 2022 Benjamin Erhart. All rights reserved.\n//\n\n#import <Cocoa/Cocoa.h>\n\n@interface AppDelegate : NSObject <NSApplicationDelegate>\n\n\n@end\n\n"
  },
  {
    "path": "Example/Example-Mac/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  Tor_Example_Mac\n//\n//  Created by Benjamin Erhart on 13.01.22.\n//  Copyright © 2022 Benjamin Erhart. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n#import <Tor/NSBundle+GeoIP.h>\n#import <Tor/TORConfiguration.h>\n#import <Tor/TORController.h>\n\n#ifdef USE_ARTI\n    #import <Tor/TORArti.h>\n#else\n    #ifdef USE_ONIONMASQ\n        #import <Tor/Onionmasq.h>\n    #else\n        #import <Tor/TORThread.h>\n    #endif\n#endif\n\n@interface AppDelegate ()\n\n\n@end\n\n@implementation AppDelegate\n\n- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {\n    NSFileManager *fm = NSFileManager.defaultManager;\n    NSURL *appSuppDir = [fm URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask].firstObject;\n\n    TORConfiguration *configuration = [TORConfiguration new];\n    configuration.ignoreMissingTorrc = YES;\n    configuration.avoidDiskWrites = YES;\n    configuration.clientOnly = YES;\n    configuration.cookieAuthentication = YES;\n    configuration.autoControlPort = YES;\n    configuration.dataDirectory = [appSuppDir URLByAppendingPathComponent:@\"tor\"];\n    configuration.geoipFile = NSBundle.geoIpBundle.geoipFile;\n    configuration.geoip6File = NSBundle.geoIpBundle.geoip6File;\n\n    NSURL *cacheDir = [fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask].firstObject;\n\n\n#ifdef USE_ARTI\n\n    configuration.socksPort = 9150;\n    configuration.dnsPort = 1951;\n    configuration.dataDirectory = [appSuppDir URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n    configuration.logfile = [cacheDir URLByAppendingPathComponent:@\"arti.log\"];\n    configuration.cacheDirectory = [cacheDir URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n\n    NSLog(@\"Configuration:\\n%@\", [configuration compile]);\n\n    [TORArti startWithConfiguration:configuration completed:^{\n        NSLog(@\"established\");\n\n        [NSNotificationCenter.defaultCenter\n         postNotificationName:@\"tor-ready\"\n         object:[[NSNumber alloc] initWithUnsignedInteger:configuration.socksPort]];\n    }];\n\n#else\n\n    #ifdef USE_ONIONMASQ\n\n    [Onionmasq startWithReader:^{\n        NSLog(@\"[Read]\");\n\n        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n            [Onionmasq receive:@[]];\n        });\n    }\n                        writer:^_Bool(NSData * _Nonnull packet, NSNumber * _Nonnull version) {\n        NSLog(@\"[Write] version=%@, packet=%@\", version, packet);\n\n        return false;\n    }\n                      stateDir:appSuppDir\n                      cacheDir:cacheDir\n                      pcapFile:nil\n                       onEvent:^(id event) {\n        NSLog(@\"[Event] %@\", event);\n    }\n                         onLog:^(NSString * _Nonnull message) {\n        NSLog(@\"[Log] %@\", message);\n    }];\n\n    #else\n\n    TORThread *thread = [[TORThread alloc] initWithConfiguration:configuration];\n    [thread start];\n\n    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{\n        NSData *cookie = configuration.cookie;\n        TORController *controller = [[TORController alloc] initWithControlPortFile:configuration.controlPortFile];\n        [controller authenticateWithData:cookie completion:^(BOOL success, NSError *error) {\n            __weak TORController *c = controller;\n\n            NSLog(@\"authenticated success=%d\", success);\n\n            if (!success)\n            {\n                return;\n            }\n\n            [c addObserverForCircuitEstablished:^(BOOL established) {\n                NSLog(@\"established=%d\", established);\n\n                if (!established)\n                {\n                    return;\n                }\n\n                CFTimeInterval startTime = CACurrentMediaTime();\n\n                [c getInfoForKeys:@[@\"net/listeners/socks\"] completion:^(NSArray<NSString *> * _Nonnull values) {\n                    if (values.count > 0) {\n                        NSArray<NSString *> *parts = [values[0] componentsSeparatedByString:@\":\"];\n\n                        if (parts.count > 1) {\n                            dispatch_async(dispatch_get_main_queue(), ^{\n                                [NSNotificationCenter.defaultCenter\n                                 postNotificationName:@\"tor-ready\"\n                                 object:[[NSNumber alloc] initWithInteger:parts[1].integerValue]];\n                            });\n                        }\n                    }\n\n                    [c getCircuits:^(NSArray<TORCircuit *> * _Nonnull circuits) {\n                        NSLog(@\"Circuits: %@\", circuits);\n\n                        NSLog(@\"Elapsed Time: %f\", CACurrentMediaTime() - startTime);\n                    }];\n                }];\n            }];\n        }];\n    });\n\n    #endif\n\n#endif\n}\n\n\n- (void)applicationWillTerminate:(NSNotification *)aNotification {\n    // Insert code here to tear down your application\n}\n\n\n- (BOOL)applicationSupportsSecureRestorableState:(NSApplication *)app {\n    return YES;\n}\n\n\n@end\n"
  },
  {
    "path": "Example/Example-Mac/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"24412\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" initialViewController=\"B8D-0N-5wS\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"24412\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Application-->\n        <scene sceneID=\"JPo-4y-FX3\">\n            <objects>\n                <application id=\"hnw-xV-0zn\" sceneMemberID=\"viewController\">\n                    <menu key=\"mainMenu\" title=\"Main Menu\" systemMenu=\"main\" id=\"AYu-sK-qS6\">\n                        <items>\n                            <menuItem title=\"Tor_Example_Mac\" id=\"1Xt-HY-uBw\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Tor_Example_Mac\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                                    <items>\n                                        <menuItem title=\"About Tor_Example_Mac\" id=\"5kV-Vb-QxS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontStandardAboutPanel:\" target=\"Ady-hI-5gd\" id=\"Exp-CZ-Vem\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"VOq-y0-SEH\"/>\n                                        <menuItem title=\"Preferences…\" keyEquivalent=\",\" id=\"BOF-NM-1cW\"/>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"wFC-TO-SCJ\"/>\n                                        <menuItem title=\"Services\" id=\"NMo-om-nkz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Services\" systemMenu=\"services\" id=\"hz9-B4-Xy5\"/>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                                        <menuItem title=\"Hide Tor_Example_Mac\" keyEquivalent=\"h\" id=\"Olw-nP-bQN\">\n                                            <connections>\n                                                <action selector=\"hide:\" target=\"Ady-hI-5gd\" id=\"PnN-Uc-m68\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Hide Others\" keyEquivalent=\"h\" id=\"Vdr-fp-XzO\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"hideOtherApplications:\" target=\"Ady-hI-5gd\" id=\"VT4-aY-XCT\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Show All\" id=\"Kd2-mp-pUS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"unhideAllApplications:\" target=\"Ady-hI-5gd\" id=\"Dhg-Le-xox\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"kCx-OE-vgT\"/>\n                                        <menuItem title=\"Quit Tor_Example_Mac\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                            <connections>\n                                                <action selector=\"terminate:\" target=\"Ady-hI-5gd\" id=\"Te7-pn-YzF\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"File\" id=\"dMs-cI-mzQ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"File\" id=\"bib-Uj-vzu\">\n                                    <items>\n                                        <menuItem title=\"New\" keyEquivalent=\"n\" id=\"Was-JA-tGl\">\n                                            <connections>\n                                                <action selector=\"newDocument:\" target=\"Ady-hI-5gd\" id=\"4Si-XN-c54\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open…\" keyEquivalent=\"o\" id=\"IAo-SY-fd9\">\n                                            <connections>\n                                                <action selector=\"openDocument:\" target=\"Ady-hI-5gd\" id=\"bVn-NM-KNZ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open Recent\" id=\"tXI-mr-wws\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Open Recent\" systemMenu=\"recentDocuments\" id=\"oas-Oc-fiZ\">\n                                                <items>\n                                                    <menuItem title=\"Clear Menu\" id=\"vNY-rz-j42\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"clearRecentDocuments:\" target=\"Ady-hI-5gd\" id=\"Daa-9d-B3U\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"m54-Is-iLE\"/>\n                                        <menuItem title=\"Close\" keyEquivalent=\"w\" id=\"DVo-aG-piG\">\n                                            <connections>\n                                                <action selector=\"performClose:\" target=\"Ady-hI-5gd\" id=\"HmO-Ls-i7Q\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save…\" keyEquivalent=\"s\" id=\"pxx-59-PXV\">\n                                            <connections>\n                                                <action selector=\"saveDocument:\" target=\"Ady-hI-5gd\" id=\"teZ-XB-qJY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save As…\" keyEquivalent=\"S\" id=\"Bw7-FT-i3A\">\n                                            <connections>\n                                                <action selector=\"saveDocumentAs:\" target=\"Ady-hI-5gd\" id=\"mDf-zr-I0C\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Revert to Saved\" keyEquivalent=\"r\" id=\"KaW-ft-85H\">\n                                            <connections>\n                                                <action selector=\"revertDocumentToSaved:\" target=\"Ady-hI-5gd\" id=\"iJ3-Pv-kwq\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"aJh-i4-bef\"/>\n                                        <menuItem title=\"Page Setup…\" keyEquivalent=\"P\" id=\"qIS-W8-SiK\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" shift=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"runPageLayout:\" target=\"Ady-hI-5gd\" id=\"Din-rz-gC5\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Print…\" keyEquivalent=\"p\" id=\"aTl-1u-JFS\">\n                                            <connections>\n                                                <action selector=\"print:\" target=\"Ady-hI-5gd\" id=\"qaZ-4w-aoO\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Edit\" id=\"5QF-Oa-p0T\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                                    <items>\n                                        <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                            <connections>\n                                                <action selector=\"undo:\" target=\"Ady-hI-5gd\" id=\"M6e-cu-g7V\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                            <connections>\n                                                <action selector=\"redo:\" target=\"Ady-hI-5gd\" id=\"oIA-Rs-6OD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                                        <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                            <connections>\n                                                <action selector=\"cut:\" target=\"Ady-hI-5gd\" id=\"YJe-68-I9s\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                            <connections>\n                                                <action selector=\"copy:\" target=\"Ady-hI-5gd\" id=\"G1f-GL-Joy\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                            <connections>\n                                                <action selector=\"paste:\" target=\"Ady-hI-5gd\" id=\"UvS-8e-Qdg\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteAsPlainText:\" target=\"Ady-hI-5gd\" id=\"cEh-KX-wJQ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"delete:\" target=\"Ady-hI-5gd\" id=\"0Mk-Ml-PaM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                            <connections>\n                                                <action selector=\"selectAll:\" target=\"Ady-hI-5gd\" id=\"VNm-Mi-diN\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                                        <menuItem title=\"Find\" id=\"4EN-yA-p0u\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Find\" id=\"1b7-l0-nxx\">\n                                                <items>\n                                                    <menuItem title=\"Find…\" tag=\"1\" keyEquivalent=\"f\" id=\"Xz5-n4-O0W\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"cD7-Qs-BN4\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find and Replace…\" tag=\"12\" keyEquivalent=\"f\" id=\"YEy-JH-Tfz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"WD3-Gg-5AJ\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Next\" tag=\"2\" keyEquivalent=\"g\" id=\"q09-fT-Sye\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"NDo-RZ-v9R\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Previous\" tag=\"3\" keyEquivalent=\"G\" id=\"OwM-mh-QMV\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"HOh-sY-3ay\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use Selection for Find\" tag=\"7\" keyEquivalent=\"e\" id=\"buJ-ug-pKt\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"U76-nv-p5D\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Jump to Selection\" keyEquivalent=\"j\" id=\"S0p-oC-mLd\">\n                                                        <connections>\n                                                            <action selector=\"centerSelectionInVisibleArea:\" target=\"Ady-hI-5gd\" id=\"IOG-6D-g5B\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Spelling and Grammar\" id=\"Dv1-io-Yv7\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Spelling\" id=\"3IN-sU-3Bg\">\n                                                <items>\n                                                    <menuItem title=\"Show Spelling and Grammar\" keyEquivalent=\":\" id=\"HFo-cy-zxI\">\n                                                        <connections>\n                                                            <action selector=\"showGuessPanel:\" target=\"Ady-hI-5gd\" id=\"vFj-Ks-hy3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Document Now\" keyEquivalent=\";\" id=\"hz2-CU-CR7\">\n                                                        <connections>\n                                                            <action selector=\"checkSpelling:\" target=\"Ady-hI-5gd\" id=\"fz7-VC-reM\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"bNw-od-mp5\"/>\n                                                    <menuItem title=\"Check Spelling While Typing\" id=\"rbD-Rh-wIN\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleContinuousSpellChecking:\" target=\"Ady-hI-5gd\" id=\"7w6-Qz-0kB\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Grammar With Spelling\" id=\"mK6-2p-4JG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleGrammarChecking:\" target=\"Ady-hI-5gd\" id=\"muD-Qn-j4w\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Correct Spelling Automatically\" id=\"78Y-hA-62v\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticSpellingCorrection:\" target=\"Ady-hI-5gd\" id=\"2lM-Qi-WAP\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Substitutions\" id=\"9ic-FL-obx\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Substitutions\" id=\"FeM-D8-WVr\">\n                                                <items>\n                                                    <menuItem title=\"Show Substitutions\" id=\"z6F-FW-3nz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"orderFrontSubstitutionsPanel:\" target=\"Ady-hI-5gd\" id=\"oku-mr-iSq\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"gPx-C9-uUO\"/>\n                                                    <menuItem title=\"Smart Copy/Paste\" id=\"9yt-4B-nSM\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleSmartInsertDelete:\" target=\"Ady-hI-5gd\" id=\"3IJ-Se-DZD\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Quotes\" id=\"hQb-2v-fYv\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticQuoteSubstitution:\" target=\"Ady-hI-5gd\" id=\"ptq-xd-QOA\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Dashes\" id=\"rgM-f4-ycn\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDashSubstitution:\" target=\"Ady-hI-5gd\" id=\"oCt-pO-9gS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Links\" id=\"cwL-P1-jid\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticLinkDetection:\" target=\"Ady-hI-5gd\" id=\"Gip-E3-Fov\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Data Detectors\" id=\"tRr-pd-1PS\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDataDetection:\" target=\"Ady-hI-5gd\" id=\"R1I-Nq-Kbl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Text Replacement\" id=\"HFQ-gK-NFA\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticTextReplacement:\" target=\"Ady-hI-5gd\" id=\"DvP-Fe-Py6\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Transformations\" id=\"2oI-Rn-ZJC\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Transformations\" id=\"c8a-y6-VQd\">\n                                                <items>\n                                                    <menuItem title=\"Make Upper Case\" id=\"vmV-6d-7jI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"uppercaseWord:\" target=\"Ady-hI-5gd\" id=\"sPh-Tk-edu\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Make Lower Case\" id=\"d9M-CD-aMd\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"lowercaseWord:\" target=\"Ady-hI-5gd\" id=\"iUZ-b5-hil\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Capitalize\" id=\"UEZ-Bs-lqG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"capitalizeWord:\" target=\"Ady-hI-5gd\" id=\"26H-TL-nsh\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                                <items>\n                                                    <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"startSpeaking:\" target=\"Ady-hI-5gd\" id=\"654-Ng-kyl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"stopSpeaking:\" target=\"Ady-hI-5gd\" id=\"dX8-6p-jy9\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Format\" id=\"jxT-CU-nIS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Format\" id=\"GEO-Iw-cKr\">\n                                    <items>\n                                        <menuItem title=\"Font\" id=\"Gi5-1S-RQB\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Font\" systemMenu=\"font\" id=\"aXa-aM-Jaq\">\n                                                <items>\n                                                    <menuItem title=\"Show Fonts\" keyEquivalent=\"t\" id=\"Q5e-8K-NDq\">\n                                                        <connections>\n                                                            <action selector=\"orderFrontFontPanel:\" target=\"YLy-65-1bz\" id=\"WHr-nq-2xA\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Bold\" tag=\"2\" keyEquivalent=\"b\" id=\"GB9-OM-e27\">\n                                                        <connections>\n                                                            <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"hqk-hr-sYV\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Italic\" tag=\"1\" keyEquivalent=\"i\" id=\"Vjx-xi-njq\">\n                                                        <connections>\n                                                            <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"IHV-OB-c03\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Underline\" keyEquivalent=\"u\" id=\"WRG-CD-K1S\">\n                                                        <connections>\n                                                            <action selector=\"underline:\" target=\"Ady-hI-5gd\" id=\"FYS-2b-JAY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"5gT-KC-WSO\"/>\n                                                    <menuItem title=\"Bigger\" tag=\"3\" keyEquivalent=\"+\" id=\"Ptp-SP-VEL\">\n                                                        <connections>\n                                                            <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"Uc7-di-UnL\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smaller\" tag=\"4\" keyEquivalent=\"-\" id=\"i1d-Er-qST\">\n                                                        <connections>\n                                                            <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"HcX-Lf-eNd\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"kx3-Dk-x3B\"/>\n                                                    <menuItem title=\"Kern\" id=\"jBQ-r6-VK2\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Kern\" id=\"tlD-Oa-oAM\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"GUa-eO-cwY\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardKerning:\" target=\"Ady-hI-5gd\" id=\"6dk-9l-Ckg\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"cDB-IK-hbR\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffKerning:\" target=\"Ady-hI-5gd\" id=\"U8a-gz-Maa\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Tighten\" id=\"46P-cB-AYj\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"tightenKerning:\" target=\"Ady-hI-5gd\" id=\"hr7-Nz-8ro\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Loosen\" id=\"ogc-rX-tC1\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"loosenKerning:\" target=\"Ady-hI-5gd\" id=\"8i4-f9-FKE\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Ligatures\" id=\"o6e-r0-MWq\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Ligatures\" id=\"w0m-vy-SC9\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"agt-UL-0e3\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardLigatures:\" target=\"Ady-hI-5gd\" id=\"7uR-wd-Dx6\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"J7y-lM-qPV\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffLigatures:\" target=\"Ady-hI-5gd\" id=\"iX2-gA-Ilz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use All\" id=\"xQD-1f-W4t\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useAllLigatures:\" target=\"Ady-hI-5gd\" id=\"KcB-kA-TuK\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Baseline\" id=\"OaQ-X3-Vso\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Baseline\" id=\"ijk-EB-dga\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"3Om-Ey-2VK\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"unscript:\" target=\"Ady-hI-5gd\" id=\"0vZ-95-Ywn\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Superscript\" id=\"Rqc-34-cIF\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"superscript:\" target=\"Ady-hI-5gd\" id=\"3qV-fo-wpU\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Subscript\" id=\"I0S-gh-46l\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"subscript:\" target=\"Ady-hI-5gd\" id=\"Q6W-4W-IGz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Raise\" id=\"2h7-ER-AoG\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"raiseBaseline:\" target=\"Ady-hI-5gd\" id=\"4sk-31-7Q9\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Lower\" id=\"1tx-W0-xDw\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"lowerBaseline:\" target=\"Ady-hI-5gd\" id=\"OF1-bc-KW4\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"Ndw-q3-faq\"/>\n                                                    <menuItem title=\"Show Colors\" keyEquivalent=\"C\" id=\"bgn-CT-cEk\">\n                                                        <connections>\n                                                            <action selector=\"orderFrontColorPanel:\" target=\"Ady-hI-5gd\" id=\"mSX-Xz-DV3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"iMs-zA-UFJ\"/>\n                                                    <menuItem title=\"Copy Style\" keyEquivalent=\"c\" id=\"5Vv-lz-BsD\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyFont:\" target=\"Ady-hI-5gd\" id=\"GJO-xA-L4q\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Style\" keyEquivalent=\"v\" id=\"vKC-jM-MkH\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteFont:\" target=\"Ady-hI-5gd\" id=\"JfD-CL-leO\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Text\" id=\"Fal-I4-PZk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Text\" id=\"d9c-me-L2H\">\n                                                <items>\n                                                    <menuItem title=\"Align Left\" keyEquivalent=\"{\" id=\"ZM1-6Q-yy1\">\n                                                        <connections>\n                                                            <action selector=\"alignLeft:\" target=\"Ady-hI-5gd\" id=\"zUv-R1-uAa\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Center\" keyEquivalent=\"|\" id=\"VIY-Ag-zcb\">\n                                                        <connections>\n                                                            <action selector=\"alignCenter:\" target=\"Ady-hI-5gd\" id=\"spX-mk-kcS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Justify\" id=\"J5U-5w-g23\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"alignJustified:\" target=\"Ady-hI-5gd\" id=\"ljL-7U-jND\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Align Right\" keyEquivalent=\"}\" id=\"wb2-vD-lq4\">\n                                                        <connections>\n                                                            <action selector=\"alignRight:\" target=\"Ady-hI-5gd\" id=\"r48-bG-YeY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"4s2-GY-VfK\"/>\n                                                    <menuItem title=\"Writing Direction\" id=\"H1b-Si-o9J\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Writing Direction\" id=\"8mr-sm-Yjd\">\n                                                            <items>\n                                                                <menuItem title=\"Paragraph\" enabled=\"NO\" id=\"ZvO-Gk-QUH\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"YGs-j5-SAR\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"qtV-5e-UBP\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"Lbh-J2-qVU\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"S0X-9S-QSf\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"jFq-tB-4Kx\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"5fk-qB-AqJ\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem isSeparatorItem=\"YES\" id=\"swp-gr-a21\"/>\n                                                                <menuItem title=\"Selection\" enabled=\"NO\" id=\"cqv-fj-IhA\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"Nop-cj-93Q\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"lPI-Se-ZHp\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"BgM-ve-c93\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"caW-Bv-w94\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"RB4-Sm-HuC\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"EXD-6r-ZUu\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"fKy-g9-1gm\"/>\n                                                    <menuItem title=\"Show Ruler\" id=\"vLm-3I-IUL\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleRuler:\" target=\"Ady-hI-5gd\" id=\"FOx-HJ-KwY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Copy Ruler\" keyEquivalent=\"c\" id=\"MkV-Pr-PK5\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyRuler:\" target=\"Ady-hI-5gd\" id=\"71i-fW-3W2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Ruler\" keyEquivalent=\"v\" id=\"LVM-kO-fVI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteRuler:\" target=\"Ady-hI-5gd\" id=\"cSh-wd-qM2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"View\" id=\"H8h-7b-M4v\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"View\" id=\"HyV-fh-RgO\">\n                                    <items>\n                                        <menuItem title=\"Show Toolbar\" keyEquivalent=\"t\" id=\"snW-S8-Cw5\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleToolbarShown:\" target=\"Ady-hI-5gd\" id=\"BXY-wc-z0C\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Customize Toolbar…\" id=\"1UK-8n-QPP\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"runToolbarCustomizationPalette:\" target=\"Ady-hI-5gd\" id=\"pQI-g3-MTW\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"hB3-LF-h0Y\"/>\n                                        <menuItem title=\"Show Sidebar\" keyEquivalent=\"s\" id=\"kIP-vf-haE\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleSidebar:\" target=\"Ady-hI-5gd\" id=\"iwa-gc-5KM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Enter Full Screen\" keyEquivalent=\"f\" id=\"4J7-dP-txa\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleFullScreen:\" target=\"Ady-hI-5gd\" id=\"dU3-MA-1Rq\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                                    <items>\n                                        <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                            <connections>\n                                                <action selector=\"performMiniaturize:\" target=\"Ady-hI-5gd\" id=\"VwT-WD-YPe\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"performZoom:\" target=\"Ady-hI-5gd\" id=\"DIl-cC-cCs\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                                        <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"arrangeInFront:\" target=\"Ady-hI-5gd\" id=\"DRN-fu-gQh\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Help\" id=\"wpr-3q-Mcd\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Help\" systemMenu=\"help\" id=\"F2S-fz-NVQ\">\n                                    <items>\n                                        <menuItem title=\"Tor_Example_Mac Help\" keyEquivalent=\"?\" id=\"FKE-Sm-Kum\">\n                                            <connections>\n                                                <action selector=\"showHelp:\" target=\"Ady-hI-5gd\" id=\"y7X-2Q-9no\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                    <connections>\n                        <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"PrD-fu-P6m\"/>\n                    </connections>\n                </application>\n                <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\"/>\n                <customObject id=\"YLy-65-1bz\" customClass=\"NSFontManager\"/>\n                <customObject id=\"Ady-hI-5gd\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"0.0\"/>\n        </scene>\n        <!--Window Controller-->\n        <scene sceneID=\"R2V-B0-nI4\">\n            <objects>\n                <windowController id=\"B8D-0N-5wS\" sceneMemberID=\"viewController\">\n                    <window key=\"window\" title=\"Window\" allowsToolTipsWhenApplicationIsInactive=\"NO\" autorecalculatesKeyViewLoop=\"NO\" releasedWhenClosed=\"NO\" visibleAtLaunch=\"NO\" animationBehavior=\"default\" id=\"IQv-IB-iLA\">\n                        <windowStyleMask key=\"styleMask\" titled=\"YES\" closable=\"YES\" miniaturizable=\"YES\" resizable=\"YES\"/>\n                        <windowPositionMask key=\"initialPositionMask\" leftStrut=\"YES\" rightStrut=\"YES\" topStrut=\"YES\" bottomStrut=\"YES\"/>\n                        <rect key=\"contentRect\" x=\"196\" y=\"240\" width=\"480\" height=\"270\"/>\n                        <rect key=\"screenRect\" x=\"0.0\" y=\"0.0\" width=\"1680\" height=\"1027\"/>\n                        <connections>\n                            <outlet property=\"delegate\" destination=\"B8D-0N-5wS\" id=\"98r-iN-zZc\"/>\n                        </connections>\n                    </window>\n                    <connections>\n                        <segue destination=\"XfG-lQ-9wD\" kind=\"relationship\" relationship=\"window.shadowedContentViewController\" id=\"cq2-FE-JQM\"/>\n                    </connections>\n                </windowController>\n                <customObject id=\"Oky-zY-oP4\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"250\"/>\n        </scene>\n        <!--View Controller-->\n        <scene sceneID=\"hIz-AP-VOD\">\n            <objects>\n                <viewController id=\"XfG-lQ-9wD\" customClass=\"ViewController\" customModule=\"Tor_Example_Mac\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"m2S-Jp-Qdl\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"270\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </view>\n                </viewController>\n                <customObject id=\"rPt-NT-nkU\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"655\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Example/Example-Mac/Tor-Example-Mac-Bridging-Header.h",
    "content": "//\n//  Use this file to import your target's public headers that you would like to expose to Swift.\n//\n\n"
  },
  {
    "path": "Example/Example-Mac/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  Tor-Example-Mac\n//\n//  Created by Benjamin Erhart on 28.11.25.\n//  Copyright © 2025 Benjamin Erhart. All rights reserved.\n//\n\nimport Cocoa\nimport WebKit\n\nclass ViewController: NSViewController {\n\n    private var webView: WKWebView!\n\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        NotificationCenter.default.addObserver(self, selector: #selector(load), name: .init(\"tor-ready\"), object: nil)\n    }\n\n    @objc\n    func load(_ notification: Notification) {\n        let port = notification.object as? UInt16\n\n        Task {\n            await MainActor.run {\n                let conf = WKWebViewConfiguration()\n\n                if #available(iOS 17.0, macOS 14.0, *), let port = port {\n                    let endpoint = NWEndpoint.hostPort(host: .ipv4(.init(\"127.0.0.1\")!), port: .init(integerLiteral: port))\n\n                    conf.websiteDataStore.proxyConfigurations.removeAll()\n                    conf.websiteDataStore.proxyConfigurations.append(ProxyConfiguration(socksv5Proxy: endpoint))\n                }\n\n                webView = WKWebView(frame: .zero, configuration: conf)\n                webView.translatesAutoresizingMaskIntoConstraints = false\n\n                view.addSubview(webView)\n                webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true\n                webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true\n                webView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true\n                webView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true\n\n                webView.load(.init(url: .init(string: \"https://check.torproject.org\")!))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Example/Example-Mac/main.m",
    "content": "//\n//  main.m\n//  Tor_Example_Mac\n//\n//  Created by Benjamin Erhart on 13.01.22.\n//  Copyright © 2022 Benjamin Erhart. All rights reserved.\n//\n\n#import <Cocoa/Cocoa.h>\n\nint main(int argc, const char * argv[]) {\n    @autoreleasepool {\n        // Setup code that might create autoreleased objects goes here.\n    }\n    return NSApplicationMain(argc, argv);\n}\n"
  },
  {
    "path": "Example/Podfile",
    "content": "use_frameworks!\n\ndef tor\n#  pod 'Tor/Arti',\n#    :path => '../'\n#    :podspec => '../Arti.podspec'\n  pod 'Tor/GeoIP', # -NoLZMA',\n    :path => '../'\nend\n\n\ntarget 'Tor-Example' do\n  platform :ios, '15.0'\n\n  tor\n\n  target 'Tor-Tests' do\n    inherit! :search_paths\n  end\n\nend\n\ntarget 'Tor-Example-Mac' do\n  platform :macos, '11.0'\n\n  tor\nend\n"
  },
  {
    "path": "Example/Tests/TORConfigurationTests.m",
    "content": "//\n//  TORConfigurationTests.m\n//  Tor\n//\n//  Created by Conrad Kramer on 8/11/15.\n//\n\n#import <XCTest/XCTest.h>\n\n@interface TORConfigurationTests : XCTestCase\n\n@end\n\n@implementation TORConfigurationTests\n\n- (void)setUp {\n    [super setUp];\n    // Put setup code here. This method is called before the invocation of each test method in the class.\n}\n\n- (void)tearDown {\n    // Put teardown code here. This method is called after the invocation of each test method in the class.\n    [super tearDown];\n}\n\n@end\n"
  },
  {
    "path": "Example/Tests/TORControllerTests.m",
    "content": "//\n//  Tests.m\n//  Tests\n//\n//  Created by Conrad Kramer on 8/10/15.\n//\n\n#import <XCTest/XCTest.h>\n#import <Tor/Tor.h>\n\n@interface TORControllerTests : XCTestCase\n\n@property (nonatomic, strong) TORController *controller;\n@property (readonly) NSData *cookie;\n\n@end\n\n@implementation TORControllerTests\n\n+ (TORConfiguration *)configuration {\n#if TARGET_IPHONE_SIMULATOR\n    NSString *homeDirectory = nil;\n    for (NSString *variable in @[@\"IPHONE_SIMULATOR_HOST_HOME\", @\"SIMULATOR_HOST_HOME\"]) {\n        char *value = getenv(variable.UTF8String);\n        if (value) {\n            homeDirectory = @(value);\n            break;\n        }\n    }\n#else\n    NSString *homeDirectory = NSHomeDirectory();\n#endif\n\n    TORConfiguration *configuration = [TORConfiguration new];\n    configuration.cookieAuthentication = @YES;\n    configuration.dataDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory()];\n    configuration.controlSocket = [[NSURL fileURLWithPath:homeDirectory] URLByAppendingPathComponent:@\".Trash/control_port\"];\n    configuration.arguments = @[\n        @\"--ignore-missing-torrc\",\n        @\"--GeoIPFile\", [NSBundle.mainBundle pathForResource:@\"geoip\" ofType:nil],\n        @\"--GeoIPv6File\", [NSBundle.mainBundle pathForResource:@\"geoip6\" ofType:nil],\n    ];\n    return configuration;\n}\n\n+ (void)setUp {\n    [super setUp];\n\n    TORThread *thread = [[TORThread alloc] initWithConfiguration:self.configuration];\n    [thread start];\n\n    [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.5f]];\n}\n\n- (void)setUp {\n    [super setUp];\n\n    self.controller = [[TORController alloc] initWithSocketURL:[[[self class] configuration] controlSocket]];\n}\n\n- (void)testCookieAuthenticationFailure {\n    XCTestExpectation *expectation = [self expectationWithDescription:@\"authenticate callback\"];\n    [self.controller authenticateWithData:[@\"invalid\" dataUsingEncoding:NSUTF8StringEncoding] completion:^(BOOL success, NSError *error) {\n        XCTAssertFalse(success);\n        XCTAssertEqualObjects(error.domain, TORControllerErrorDomain);\n        XCTAssertNotEqual(error.code, TORControlReplyCodeOK);\n        XCTAssertGreaterThan(error.localizedDescription, @\"Authentication failed: Wrong length on authentication cookie.\");\n        [expectation fulfill];\n    }];\n\n    [self waitForExpectationsWithTimeout:1.0f handler:nil];\n}\n\n- (void)testCookieAuthenticationSuccess {\n    XCTestExpectation *expectation = [self expectationWithDescription:@\"authenticate callback\"];\n\n    [self.controller authenticateWithData:self.cookie completion:^(BOOL success, NSError *error) {\n        XCTAssertTrue(success);\n        XCTAssertNil(error);\n        [expectation fulfill];\n    }];\n\n    [self waitForExpectationsWithTimeout:1.0f handler:nil];\n}\n\n- (void)testSessionConfiguration {\n    XCTestExpectation *expectation = [self expectationWithDescription:@\"tor callback\"];\n\n    [self exec:^{\n        [self.controller getSessionConfiguration:^(NSURLSessionConfiguration *configuration) {\n            NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];\n            [[session dataTaskWithURL:[NSURL URLWithString:@\"https://facebookcorewwwi.onion/\"] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {\n                XCTAssertEqual([(NSHTTPURLResponse *)response statusCode], 200);\n                XCTAssertNil(error);\n                [expectation fulfill];\n            }] resume];\n        }];\n    }];\n\n    [self waitForExpectationsWithTimeout:120.0f handler:nil];\n}\n\n- (void)testGetAndCloseCircuits\n{\n    XCTestExpectation *expectation = [self expectationWithDescription:@\"resolution callback\"];\n\n    [self exec:^{\n        [self.controller getCircuits:^(NSArray<TORCircuit *> * _Nonnull circuits) {\n            NSLog(@\"circuits=%@\", circuits);\n\n            for (TORCircuit *circuit in circuits)\n            {\n                for (TORNode *node in circuit.nodes) {\n                    XCTAssert(node.fingerprint.length > 0, @\"A circuit should have a fingerprint.\");\n                    XCTAssert(node.ipv4Address.length > 0 || node.ipv6Address.length > 0, @\"A circuit should have an IPv4 or IPv6 address.\");\n                }\n            }\n\n            [self.controller closeCircuits:circuits completion:^(BOOL success) {\n                XCTAssertTrue(success, @\"Circuits were closed successfully.\");\n\n                [expectation fulfill];\n            }];\n        }];\n    }];\n\n    [self waitForExpectationsWithTimeout:120 handler:nil];\n}\n\n- (void)testReset\n{\n    XCTestExpectation *expectation = [self expectationWithDescription:@\"reset callback\"];\n\n    [self exec:^{\n        [self.controller resetConnection:^(BOOL success) {\n            NSLog(@\"success=%d\", success);\n\n            XCTAssertTrue(success, @\"Reset should work correctly.\");\n\n            [expectation fulfill];\n        }];\n    }];\n\n    [self waitForExpectationsWithTimeout:120 handler:nil];\n}\n\n\n// MARK: Helper Properties and Methods\n\n- (NSData *)cookie\n{\n    return [NSData dataWithContentsOfURL:\n            [[self.class configuration].dataDirectory\n             URLByAppendingPathComponent:@\"control_auth_cookie\"]];\n}\n\n- (void)exec:(void (^)(void))callback\n{\n    TORController *controller = self.controller;\n\n    [controller authenticateWithData:self.cookie completion:^(BOOL success, NSError * _Nullable error) {\n        XCTAssertTrue(success);\n        XCTAssertNil(error);\n\n        [controller addObserverForCircuitEstablished:^(BOOL established) {\n            // May be called multiple times. We wait until circuit is established.\n            if (!established)\n            {\n                return;\n            }\n\n            callback();\n        }];\n    }];\n}\n\n@end\n"
  },
  {
    "path": "Example/Tests/Tests-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Example/Tests/Tests-Prefix.pch",
    "content": "//  The contents of this file are implicitly included at the beginning of every test case source file.\n\n#ifdef __OBJC__\n\n  \n\n#endif\n"
  },
  {
    "path": "Example/Tor/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 01/13/2022.\n//  Copyright (c) 2022 Benjamin Erhart. All rights reserved.\n//\n\n@import UIKit;\n\n@interface AppDelegate : UIResponder <UIApplicationDelegate>\n\n@property (strong, nonatomic) UIWindow *window;\n\n@end\n"
  },
  {
    "path": "Example/Tor/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 01/13/2022.\n//  Copyright (c) 2022 Benjamin Erhart. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n#import <Tor/NSBundle+GeoIP.h>\n#import <Tor/TORConfiguration.h>\n#import <Tor/TORController.h>\n\n#ifdef USE_ARTI\n    #import <Tor/TORArti.h>\n#else\n    #ifdef USE_ONIONMASQ\n        #import <Tor/Onionmasq.h>\n    #else\n        #import <Tor/TORThread.h>\n    #endif\n#endif\n\n@implementation AppDelegate\n\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    NSFileManager *fm = NSFileManager.defaultManager;\n    NSURL *docDir = [fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].firstObject;\n\n    TORConfiguration *configuration = [TORConfiguration new];\n    configuration.ignoreMissingTorrc = YES;\n    configuration.avoidDiskWrites = YES;\n    configuration.clientOnly = YES;\n    configuration.cookieAuthentication = YES;\n    configuration.autoControlPort = YES;\n    configuration.dataDirectory = [docDir URLByAppendingPathComponent:@\"tor\"];\n    configuration.geoipFile = NSBundle.geoIpBundle.geoipFile;\n    configuration.geoip6File = NSBundle.geoIpBundle.geoip6File;\n\n    NSURL *cacheDir = [fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask].firstObject;\n\n#ifdef USE_ARTI\n\n    configuration.socksPort = 9150;\n    configuration.dnsPort = 1951;\n    configuration.dataDirectory = [docDir URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n    configuration.logfile = [docDir URLByAppendingPathComponent:@\"arti.log\"];\n    configuration.cacheDirectory = [cacheDir URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n\n    NSLog(@\"Configuration:\\n%@\", [configuration compile]);\n\n    [TORArti startWithConfiguration:configuration completed:^{\n        NSLog(@\"established\");\n\n        [NSNotificationCenter.defaultCenter \n         postNotificationName:@\"tor-ready\"\n         object:[[NSNumber alloc] initWithUnsignedInteger:configuration.socksPort]];\n    }];\n\n#else\n\n    #ifdef USE_ONIONMASQ\n\n    [Onionmasq startWithReader:^{\n        NSLog(@\"[Read]\");\n\n        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{\n            [Onionmasq receive:@[]];\n        });\n    }\n                        writer:^_Bool(NSData * _Nonnull packet, NSNumber * _Nonnull version) {\n        NSLog(@\"[Write] version=%@, packet=%@\", version, packet);\n\n        return false;\n    }\n                      stateDir:docDir\n                      cacheDir:cacheDir\n                      pcapFile:nil\n                       onEvent:^(id event) {\n        NSLog(@\"[Event] %@\", event);\n    }\n                         onLog:^(NSString * _Nonnull message) {\n        NSLog(@\"[Log] %@\", message);\n    }];\n\n    #else\n\n    TORThread *thread = [[TORThread alloc] initWithConfiguration:configuration];\n    [thread start];\n\n    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{\n        NSData *cookie = configuration.cookie;\n        TORController *controller = [[TORController alloc] initWithControlPortFile:configuration.controlPortFile];\n        [controller authenticateWithData:cookie completion:^(BOOL success, NSError *error) {\n            __weak TORController *c = controller;\n\n            NSLog(@\"authenticated success=%d\", success);\n\n            if (!success)\n            {\n                return;\n            }\n\n            [c addObserverForCircuitEstablished:^(BOOL established) {\n                NSLog(@\"established=%d\", established);\n\n                if (!established)\n                {\n                    return;\n                }\n\n                CFTimeInterval startTime = CACurrentMediaTime();\n\n                [c getInfoForKeys:@[@\"net/listeners/socks\"] completion:^(NSArray<NSString *> * _Nonnull values) {\n                    if (values.count > 0) {\n                        NSArray<NSString *> *parts = [values[0] componentsSeparatedByString:@\":\"];\n                        \n                        if (parts.count > 1) {\n                            dispatch_async(dispatch_get_main_queue(), ^{\n                                [NSNotificationCenter.defaultCenter\n                                 postNotificationName:@\"tor-ready\"\n                                 object:[[NSNumber alloc] initWithInteger:parts[1].integerValue]];\n                            });\n                        }\n                    }\n                    \n                    [c getCircuits:^(NSArray<TORCircuit *> * _Nonnull circuits) {\n                        NSLog(@\"Circuits: %@\", circuits);\n                        \n                        NSLog(@\"Elapsed Time: %f\", CACurrentMediaTime() - startTime);\n                    }];\n                }];\n\n//                [c getInfoForKeys:@[@\"ns/all\"] completion:^(NSArray<NSString *> * _Nonnull values) {\n//                    NSLog(@\"Line count: %lu\", values.count);\n//                    NSLog(@\"Elapsed Time: %f\", CACurrentMediaTime() - startTime);\n//\n//\n//                    NSArray<TORNode *> *exitNodes = [TORNode parseFromNsString:values.firstObject exitOnly:YES];\n//\n//                    NSLog(@\"#Exit Nodes: %lu\", exitNodes.count);\n//                    NSLog(@\"Elapsed Time: %f\", CACurrentMediaTime() - startTime);\n//\n//                    [c resolveCountriesOfNodes:exitNodes testCapabilities:NO completion:^{\n//                        for (TORNode *node in exitNodes) {\n//                            NSLog(@\"Node: %@\", node);\n//                        }\n//\n//                        NSLog(@\"Elapsed Time: %f\", CACurrentMediaTime() - startTime);\n//                    }];\n//                }];\n            }];\n        }];\n    });\n\n    #endif\n\n#endif\n\n    return YES;\n}\n\n- (void)applicationWillResignActive:(UIApplication *)application\n{\n    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.\n}\n\n- (void)applicationDidEnterBackground:(UIApplication *)application\n{\n    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n}\n\n- (void)applicationWillEnterForeground:(UIApplication *)application\n{\n    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.\n}\n\n- (void)applicationDidBecomeActive:(UIApplication *)application\n{\n    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n}\n\n- (void)applicationWillTerminate:(UIApplication *)application\n{\n    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n}\n\n@end\n"
  },
  {
    "path": "Example/Tor/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"24412\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"whP-gf-Uak\">\n    <device id=\"retina5_9\" orientation=\"portrait\" appearance=\"light\"/>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"24405\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"System colors in document resources\" minToolsVersion=\"11.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"wQg-tq-qST\">\n            <objects>\n                <viewController id=\"whP-gf-Uak\" customClass=\"ViewController\" customModule=\"Tor_Example\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"TpU-gO-2f1\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"812\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <viewLayoutGuide key=\"safeArea\" id=\"M7B-1c-7bb\"/>\n                        <color key=\"backgroundColor\" systemColor=\"systemBackgroundColor\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"tc2-Qw-aMS\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"305\" y=\"433\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <systemColor name=\"systemBackgroundColor\">\n            <color white=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n        </systemColor>\n    </resources>\n</document>\n"
  },
  {
    "path": "Example/Tor/Launch Screen.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"13142\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" useSafeAreas=\"YES\" colorMatched=\"YES\" initialViewController=\"01J-lp-oVM\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12042\"/>\n        <capability name=\"Constraints with non-1.0 multipliers\" minToolsVersion=\"5.1\"/>\n        <capability name=\"Safe area layout guides\" minToolsVersion=\"9.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--View Controller-->\n        <scene sceneID=\"EHf-IW-A2E\">\n            <objects>\n                <viewController id=\"01J-lp-oVM\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"Ze5-6b-2t3\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Copyright © 2025 Benjamin Erhart. All rights reserved.\" textAlignment=\"center\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"9\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"obG-Y5-kRd\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"626.5\" width=\"375\" height=\"20.5\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                            <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Tor-Example\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GJd-Yh-RWb\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"202\" width=\"375\" height=\"43\"/>\n                                <fontDescription key=\"fontDescription\" type=\"boldSystem\" pointSize=\"36\"/>\n                                <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"Bcu-3y-fUS\" firstAttribute=\"centerX\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"centerX\" id=\"5cz-MP-9tL\"/>\n                            <constraint firstItem=\"Bcu-3y-fUS\" firstAttribute=\"centerX\" secondItem=\"GJd-Yh-RWb\" secondAttribute=\"centerX\" id=\"Q3B-4B-g5h\"/>\n                            <constraint firstItem=\"obG-Y5-kRd\" firstAttribute=\"leading\" secondItem=\"Bcu-3y-fUS\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"SfN-ll-jLj\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"obG-Y5-kRd\" secondAttribute=\"bottom\" constant=\"20\" id=\"Y44-ml-fuU\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"centerY\" secondItem=\"Ze5-6b-2t3\" secondAttribute=\"bottom\" multiplier=\"1/3\" constant=\"1\" id=\"moa-c2-u7t\"/>\n                            <constraint firstItem=\"GJd-Yh-RWb\" firstAttribute=\"leading\" secondItem=\"Bcu-3y-fUS\" secondAttribute=\"leading\" constant=\"20\" symbolic=\"YES\" id=\"x7j-FC-K8j\"/>\n                        </constraints>\n                        <viewLayoutGuide key=\"safeArea\" id=\"Bcu-3y-fUS\"/>\n                    </view>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"iYj-Kq-Ea1\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"53\" y=\"375\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Example/Tor/Tor-Example-Bridging-Header.h",
    "content": "//\n//  Use this file to import your target's public headers that you would like to expose to Swift.\n//\n\n"
  },
  {
    "path": "Example/Tor/Tor-Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundleExecutable</key>\n\t<string>${EXECUTABLE_NAME}</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>${PRODUCT_NAME}</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>LSApplicationCategoryType</key>\n\t<string></string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UIApplicationSceneManifest</key>\n\t<dict>\n\t\t<key>UIApplicationSupportsMultipleScenes</key>\n\t\t<false/>\n\t\t<key>UISceneConfigurations</key>\n\t\t<dict/>\n\t</dict>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n    <key>UILaunchStoryboardName</key>\n    <string>Launch Screen</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations~ipad</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t\t<string>UIInterfaceOrientationPortraitUpsideDown</string>\n\t\t<string>UIInterfaceOrientationLandscapeLeft</string>\n\t\t<string>UIInterfaceOrientationLandscapeRight</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Example/Tor/Tor-Prefix.pch",
    "content": "//\n//  Prefix header\n//\n//  The contents of this file are implicitly included at the beginning of every source file.\n//\n\n#import <Availability.h>\n\n#ifndef __IPHONE_5_0\n#warning \"This project uses features only available in iOS SDK 5.0 and later.\"\n#endif\n\n#ifdef __OBJC__\n    @import UIKit;\n    @import Foundation;\n#endif\n"
  },
  {
    "path": "Example/Tor/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  Tor-Example\n//\n//  Created by Benjamin Erhart on 01.12.25.\n//  Copyright © 2025 Benjamin Erhart. All rights reserved.\n//\n\nimport UIKit\nimport WebKit\n\nclass ViewController: UIViewController {\n\n    private var webView: WKWebView!\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        NotificationCenter.default.addObserver(self, selector: #selector(load), name: .init(\"tor-ready\"), object: nil)\n    }\n\n    @objc\n    func load(_ notification: Notification) {\n        let port = notification.object as? UInt16\n\n        Task {\n            await MainActor.run {\n                let conf = WKWebViewConfiguration()\n\n                if #available(iOS 17.0, macOS 14.0, *), let port = port {\n                    let endpoint = NWEndpoint.hostPort(host: .ipv4(.init(\"127.0.0.1\")!), port: .init(integerLiteral: port))\n\n                    conf.websiteDataStore.proxyConfigurations.removeAll()\n                    conf.websiteDataStore.proxyConfigurations.append(ProxyConfiguration(socksv5Proxy: endpoint))\n                }\n\n                webView = WKWebView(frame: .zero, configuration: conf)\n                webView.translatesAutoresizingMaskIntoConstraints = false\n\n                view.addSubview(webView)\n                webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true\n                webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true\n                webView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true\n                webView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true\n\n                webView.load(.init(url: .init(string: \"https://check.torproject.org\")!))\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Example/Tor/main.m",
    "content": "//\n//  main.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 01/10/2022.\n//  Copyright (c) 2022 Benjamin Erhart. All rights reserved.\n//\n\n@import UIKit;\n#import \"AppDelegate.h\"\n\nint main(int argc, char * argv[])\n{\n    @autoreleasepool {\n        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));\n    }\n}\n"
  },
  {
    "path": "Example/Tor.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 77;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t0314CBC366B59AACC3BD77D9 /* Pods_Tor_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0B3520587D654F10671E7745 /* Pods_Tor_Tests.framework */; };\n\t\t2A7611A3AF4442FB65EAC417 /* Pods_Tor_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01163AA30AD557595178CC35 /* Pods_Tor_Example.framework */; };\n\t\t6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };\n\t\t6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };\n\t\t6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };\n\t\t6003F59E195388D20070C39A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* AppDelegate.m */; };\n\t\t6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };\n\t\t6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };\n\t\t6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };\n\t\t7913583D7355D84D17A5203C /* Pods_Tor_Example_Mac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BEC16FF0E4EF90AB4524CF2 /* Pods_Tor_Example_Mac.framework */; };\n\t\t873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };\n\t\tA057DD272ED9F2800044B431 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A057DD262ED9F2800044B431 /* ViewController.swift */; };\n\t\tA057DDA52EDDE7800044B431 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A057DDA42EDDE7800044B431 /* ViewController.swift */; };\n\t\tA057DDA72EDDEEC80044B431 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A057DDA62EDDEEC80044B431 /* Launch Screen.storyboard */; };\n\t\tA0F008FC27906DBA0073D36D /* TORConfigurationTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F008FA27906DBA0073D36D /* TORConfigurationTests.m */; };\n\t\tA0F008FD27906DBA0073D36D /* TORControllerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F008FB27906DBA0073D36D /* TORControllerTests.m */; };\n\t\tA0F0090D279070B40073D36D /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F0090C279070B40073D36D /* AppDelegate.m */; };\n\t\tA0F00915279070B40073D36D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A0F00913279070B40073D36D /* Main.storyboard */; };\n\t\tA0F00917279070B40073D36D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F00916279070B40073D36D /* main.m */; };\n\t\tA0F0091D279072D60073D36D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A0F0091C279072D60073D36D /* main.m */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 6003F582195388D10070C39A /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 6003F589195388D20070C39A;\n\t\t\tremoteInfo = Tor;\n\t\t};\n\t\tA009806F2F165ECB00FE3A57 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = A009E83F2F1653D800FE3A57 /* ios.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 376EC1C52794D174000D74A9;\n\t\t\tremoteInfo = ios;\n\t\t};\n\t\tA04C21312EE0736C00A8AFFA /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = A04C1E332EE0736B00A8AFFA /* ios.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 376EC1C52794D174000D74A9;\n\t\t\tremoteInfo = ios;\n\t\t};\n\t\tA04CF0EE2EE0632200A8AFFA /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = A04CEDDB2EE0632200A8AFFA /* ios.xcodeproj */;\n\t\t\tproxyType = 2;\n\t\t\tremoteGlobalIDString = 376EC1C52794D174000D74A9;\n\t\t\tremoteInfo = ios;\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXFileReference section */\n\t\t01163AA30AD557595178CC35 /* Pods_Tor_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tor_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t0B3520587D654F10671E7745 /* Pods_Tor_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tor_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t1D7391AAD3752903BDA8A2CC /* Pods-Tor_Example_Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Example_Mac.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor_Example_Mac/Pods-Tor_Example_Mac.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t3369E201AA8D44290EFDB264 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = \"<group>\"; };\n\t\t4BD4F2E4E0599631250E97FC /* Pods-Tor_Example_Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Example_Mac.release.xcconfig\"; path = \"Target Support Files/Pods-Tor_Example_Mac/Pods-Tor_Example_Mac.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t4BEC16FF0E4EF90AB4524CF2 /* Pods_Tor_Example_Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Tor_Example_Mac.framework; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4DFC6FCDC4F8056024E28F5B /* Pods-Tor-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Tests.release.xcconfig\"; path = \"Target Support Files/Pods-Tor-Tests/Pods-Tor-Tests.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t4F31AB271AA16E836CDC5F8D /* Pods-Tor-Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Example.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor-Example/Pods-Tor-Example.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t591053441A46E47D764CDDAB /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = \"<group>\"; };\n\t\t6003F58A195388D20070C39A /* Tor-Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"Tor-Example.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };\n\t\t6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };\n\t\t6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };\n\t\t6003F595195388D20070C39A /* Tor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"Tor-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t6003F59C195388D20070C39A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\t6003F59D195388D20070C39A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\t6003F5AE195388D20070C39A /* Tor-Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = \"Tor-Tests.xctest\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };\n\t\t6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = \"Tests-Info.plist\"; sourceTree = \"<group>\"; };\n\t\t606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Tests-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\t6CF2DE60BF09B91BB81D2E6F /* Pods-Tor_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Example.release.xcconfig\"; path = \"Target Support Files/Pods-Tor_Example/Pods-Tor_Example.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t74CA0FB740D38C49003C1E1A /* Pods-Tor-Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Example.release.xcconfig\"; path = \"Target Support Files/Pods-Tor-Example/Pods-Tor-Example.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t80D47871C3901193EE623A3E /* Pods-Tor_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Tests.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor_Tests/Pods-Tor_Tests.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t8AA26438ED97EA21E1B6572D /* Pods-Tor-Example-Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Example-Mac.release.xcconfig\"; path = \"Target Support Files/Pods-Tor-Example-Mac/Pods-Tor-Example-Mac.release.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t90700F7B59D5C0641E3250C1 /* Pods-Tor_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Example.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor_Example/Pods-Tor_Example.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\t93A4EA262BB0B20934ED644E /* Tor.podspec */ = {isa = PBXFileReference; includeInIndex = 1; indentWidth = 2; lastKnownFileType = text; name = Tor.podspec; path = ../Tor.podspec; sourceTree = \"<group>\"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };\n\t\tA009E83F2F1653D800FE3A57 /* ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; path = ios.xcodeproj; sourceTree = \"<group>\"; };\n\t\tA0463DB82AA0DB0700AC9925 /* onionmasq.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = onionmasq.sh; path = ../Tor/onionmasq.sh; sourceTree = \"<group>\"; };\n\t\tA04C1E332EE0736B00A8AFFA /* ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; path = ios.xcodeproj; sourceTree = \"<group>\"; };\n\t\tA04CEDDB2EE0632200A8AFFA /* ios.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = \"wrapper.pb-project\"; path = ios.xcodeproj; sourceTree = \"<group>\"; };\n\t\tA057DD252ED9F2800044B431 /* Tor-Example-Mac-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Tor-Example-Mac-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\tA057DD262ED9F2800044B431 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\tA057DDA32EDDE7800044B431 /* Tor-Example-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Tor-Example-Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\tA057DDA42EDDE7800044B431 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\tA057DDA62EDDEEC80044B431 /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = \"Launch Screen.storyboard\"; sourceTree = \"<group>\"; };\n\t\tA05D84CE2E180D4200D15D76 /* download.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = download.sh; path = ../Tor/download.sh; sourceTree = SOURCE_ROOT; };\n\t\tA07DA5B42791AED000D62827 /* .gitmodules */ = {isa = PBXFileReference; lastKnownFileType = text; name = .gitmodules; path = ../.gitmodules; sourceTree = \"<group>\"; };\n\t\tA0912FD12DEE026600071F53 /* Brewfile */ = {isa = PBXFileReference; lastKnownFileType = text; name = Brewfile; path = ../Brewfile; sourceTree = SOURCE_ROOT; };\n\t\tA091B5002DEDF93000071F53 /* build-xcframework.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; name = \"build-xcframework.sh\"; path = \"../build-xcframework.sh\"; sourceTree = SOURCE_ROOT; };\n\t\tA0C582562AE8FCA000A81084 /* Arti.podspec */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = text; name = Arti.podspec; path = ../Arti.podspec; sourceTree = \"<group>\"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };\n\t\tA0C981E32A9F52D100E265EE /* mmap-cache.patch */ = {isa = PBXFileReference; lastKnownFileType = text; name = \"mmap-cache.patch\"; path = \"../Tor/mmap-cache.patch\"; sourceTree = \"<group>\"; };\n\t\tA0F008F727906CA30073D36D /* Podfile.lock */ = {isa = PBXFileReference; lastKnownFileType = text; path = Podfile.lock; sourceTree = \"<group>\"; };\n\t\tA0F008F827906CA30073D36D /* Podfile */ = {isa = PBXFileReference; indentWidth = 2; lastKnownFileType = text; path = Podfile; sourceTree = \"<group>\"; tabWidth = 2; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };\n\t\tA0F008FA27906DBA0073D36D /* TORConfigurationTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TORConfigurationTests.m; sourceTree = \"<group>\"; };\n\t\tA0F008FB27906DBA0073D36D /* TORControllerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TORControllerTests.m; sourceTree = \"<group>\"; };\n\t\tA0F008FE27906F620073D36D /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; name = .gitignore; path = ../.gitignore; sourceTree = \"<group>\"; };\n\t\tA0F00909279070B40073D36D /* Tor-Example-Mac.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"Tor-Example-Mac.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\tA0F0090B279070B40073D36D /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = \"<group>\"; };\n\t\tA0F0090C279070B40073D36D /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = \"<group>\"; };\n\t\tA0F00916279070B40073D36D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\tA0F0091C279072D60073D36D /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = \"<group>\"; };\n\t\tA0F0091E279073DA0073D36D /* Tor-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Tor-Prefix.pch\"; sourceTree = \"<group>\"; };\n\t\tA0F0092027907A8A0073D36D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\tC2C4B3C67BC4AA29D918DFE0 /* Pods-Tor-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Tests.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor-Tests/Pods-Tor-Tests.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tCCD44E911F9C4625A303B626 /* Pods-Tor-Example-Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor-Example-Mac.debug.xcconfig\"; path = \"Target Support Files/Pods-Tor-Example-Mac/Pods-Tor-Example-Mac.debug.xcconfig\"; sourceTree = \"<group>\"; };\n\t\tFF35A366A1B1BD8B0C89AE24 /* Pods-Tor_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = \"Pods-Tor_Tests.release.xcconfig\"; path = \"Target Support Files/Pods-Tor_Tests/Pods-Tor_Tests.release.xcconfig\"; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t6003F587195388D20070C39A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,\n\t\t\t\t6003F592195388D20070C39A /* UIKit.framework in Frameworks */,\n\t\t\t\t6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,\n\t\t\t\t2A7611A3AF4442FB65EAC417 /* Pods_Tor_Example.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6003F5AB195388D20070C39A /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,\n\t\t\t\t6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,\n\t\t\t\t6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,\n\t\t\t\t0314CBC366B59AACC3BD77D9 /* Pods_Tor_Tests.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tA0F00906279070B40073D36D /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t7913583D7355D84D17A5203C /* Pods_Tor_Example_Mac.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t6003F581195388D10070C39A = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,\n\t\t\t\t6003F593195388D20070C39A /* Example for Tor */,\n\t\t\t\t6003F5B5195388D20070C39A /* Tests */,\n\t\t\t\tA0F0090A279070B40073D36D /* Example-Mac */,\n\t\t\t\t6003F58C195388D20070C39A /* Frameworks */,\n\t\t\t\t6003F58B195388D20070C39A /* Products */,\n\t\t\t\t8C50D6DACFD9A136564A1BEC /* Pods */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6003F58B195388D20070C39A /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6003F58A195388D20070C39A /* Tor-Example.app */,\n\t\t\t\t6003F5AE195388D20070C39A /* Tor-Tests.xctest */,\n\t\t\t\tA0F00909279070B40073D36D /* Tor-Example-Mac.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6003F58C195388D20070C39A /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6003F58D195388D20070C39A /* Foundation.framework */,\n\t\t\t\t6003F58F195388D20070C39A /* CoreGraphics.framework */,\n\t\t\t\t6003F591195388D20070C39A /* UIKit.framework */,\n\t\t\t\t6003F5AF195388D20070C39A /* XCTest.framework */,\n\t\t\t\t4BEC16FF0E4EF90AB4524CF2 /* Pods_Tor_Example_Mac.framework */,\n\t\t\t\t01163AA30AD557595178CC35 /* Pods_Tor_Example.framework */,\n\t\t\t\t0B3520587D654F10671E7745 /* Pods_Tor_Tests.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6003F593195388D20070C39A /* Example for Tor */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6003F59C195388D20070C39A /* AppDelegate.h */,\n\t\t\t\t6003F59D195388D20070C39A /* AppDelegate.m */,\n\t\t\t\t873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,\n\t\t\t\tA0F0091C279072D60073D36D /* main.m */,\n\t\t\t\t6003F595195388D20070C39A /* Tor-Info.plist */,\n\t\t\t\tA0F0091E279073DA0073D36D /* Tor-Prefix.pch */,\n\t\t\t\tA057DDA42EDDE7800044B431 /* ViewController.swift */,\n\t\t\t\tA057DDA32EDDE7800044B431 /* Tor-Example-Bridging-Header.h */,\n\t\t\t\tA057DDA62EDDEEC80044B431 /* Launch Screen.storyboard */,\n\t\t\t);\n\t\t\tname = \"Example for Tor\";\n\t\t\tpath = Tor;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t6003F5B5195388D20070C39A /* Tests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA0F008FA27906DBA0073D36D /* TORConfigurationTests.m */,\n\t\t\t\tA0F008FB27906DBA0073D36D /* TORControllerTests.m */,\n\t\t\t\t6003F5B7195388D20070C39A /* Tests-Info.plist */,\n\t\t\t\t606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */,\n\t\t\t);\n\t\t\tpath = Tests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA0912FD12DEE026600071F53 /* Brewfile */,\n\t\t\t\t93A4EA262BB0B20934ED644E /* Tor.podspec */,\n\t\t\t\tA0C582562AE8FCA000A81084 /* Arti.podspec */,\n\t\t\t\t3369E201AA8D44290EFDB264 /* README.md */,\n\t\t\t\t591053441A46E47D764CDDAB /* LICENSE */,\n\t\t\t\tA0F008F827906CA30073D36D /* Podfile */,\n\t\t\t\tA0F008F727906CA30073D36D /* Podfile.lock */,\n\t\t\t\tA0F008FE27906F620073D36D /* .gitignore */,\n\t\t\t\tA07DA5B42791AED000D62827 /* .gitmodules */,\n\t\t\t\tA05D84CE2E180D4200D15D76 /* download.sh */,\n\t\t\t\tA0463DB82AA0DB0700AC9925 /* onionmasq.sh */,\n\t\t\t\tA0C981E32A9F52D100E265EE /* mmap-cache.patch */,\n\t\t\t\tA091B5002DEDF93000071F53 /* build-xcframework.sh */,\n\t\t\t);\n\t\t\tname = \"Podspec Metadata\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t8C50D6DACFD9A136564A1BEC /* Pods */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t90700F7B59D5C0641E3250C1 /* Pods-Tor_Example.debug.xcconfig */,\n\t\t\t\t6CF2DE60BF09B91BB81D2E6F /* Pods-Tor_Example.release.xcconfig */,\n\t\t\t\t80D47871C3901193EE623A3E /* Pods-Tor_Tests.debug.xcconfig */,\n\t\t\t\tFF35A366A1B1BD8B0C89AE24 /* Pods-Tor_Tests.release.xcconfig */,\n\t\t\t\t1D7391AAD3752903BDA8A2CC /* Pods-Tor_Example_Mac.debug.xcconfig */,\n\t\t\t\t4BD4F2E4E0599631250E97FC /* Pods-Tor_Example_Mac.release.xcconfig */,\n\t\t\t\tCCD44E911F9C4625A303B626 /* Pods-Tor-Example-Mac.debug.xcconfig */,\n\t\t\t\t8AA26438ED97EA21E1B6572D /* Pods-Tor-Example-Mac.release.xcconfig */,\n\t\t\t\t4F31AB271AA16E836CDC5F8D /* Pods-Tor-Example.debug.xcconfig */,\n\t\t\t\t74CA0FB740D38C49003C1E1A /* Pods-Tor-Example.release.xcconfig */,\n\t\t\t\tC2C4B3C67BC4AA29D918DFE0 /* Pods-Tor-Tests.debug.xcconfig */,\n\t\t\t\t4DFC6FCDC4F8056024E28F5B /* Pods-Tor-Tests.release.xcconfig */,\n\t\t\t);\n\t\t\tpath = Pods;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA009806C2F1653D900FE3A57 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA00980702F165ECB00FE3A57 /* ios.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA04C1E392EE0736B00A8AFFA /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA04C21322EE0736C00A8AFFA /* ios.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA04CEDE12EE0632200A8AFFA /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA04CF0EF2EE0632200A8AFFA /* ios.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\tA0F0090A279070B40073D36D /* Example-Mac */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\tA0F0090B279070B40073D36D /* AppDelegate.h */,\n\t\t\t\tA0F0090C279070B40073D36D /* AppDelegate.m */,\n\t\t\t\tA0F00913279070B40073D36D /* Main.storyboard */,\n\t\t\t\tA0F00916279070B40073D36D /* main.m */,\n\t\t\t\tA057DD262ED9F2800044B431 /* ViewController.swift */,\n\t\t\t\tA057DD252ED9F2800044B431 /* Tor-Example-Mac-Bridging-Header.h */,\n\t\t\t);\n\t\t\tpath = \"Example-Mac\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t6003F589195388D20070C39A /* Tor-Example */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget \"Tor-Example\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t92C23A76A3C3CB7B0EE26734 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t6003F586195388D20070C39A /* Sources */,\n\t\t\t\t6003F587195388D20070C39A /* Frameworks */,\n\t\t\t\t6003F588195388D20070C39A /* Resources */,\n\t\t\t\t90B5FFAA88FED781C1B58A99 /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Tor-Example\";\n\t\t\tproductName = Tor;\n\t\t\tproductReference = 6003F58A195388D20070C39A /* Tor-Example.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t6003F5AD195388D20070C39A /* Tor-Tests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget \"Tor-Tests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t90D8C2DC582D8E6FC6716412 /* [CP] Check Pods Manifest.lock */,\n\t\t\t\t6003F5AA195388D20070C39A /* Sources */,\n\t\t\t\t6003F5AB195388D20070C39A /* Frameworks */,\n\t\t\t\t6003F5AC195388D20070C39A /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t6003F5B4195388D20070C39A /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = \"Tor-Tests\";\n\t\t\tproductName = TorTests;\n\t\t\tproductReference = 6003F5AE195388D20070C39A /* Tor-Tests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\tA0F00908279070B40073D36D /* Tor-Example-Mac */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = A0F00919279070B40073D36D /* Build configuration list for PBXNativeTarget \"Tor-Example-Mac\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t9A118950F57DB5601BC45C3C /* [CP] Check Pods Manifest.lock */,\n\t\t\t\tA0F00905279070B40073D36D /* Sources */,\n\t\t\t\tA0F00906279070B40073D36D /* Frameworks */,\n\t\t\t\tA0F00907279070B40073D36D /* Resources */,\n\t\t\t\tC24010A627399EEA7C17DDED /* [CP] Embed Pods Frameworks */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Tor-Example-Mac\";\n\t\t\tproductName = Tor_Example_Mac;\n\t\t\tproductReference = A0F00909279070B40073D36D /* Tor-Example-Mac.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t6003F582195388D10070C39A /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = YES;\n\t\t\t\tCLASSPREFIX = TOR;\n\t\t\t\tLastUpgradeCheck = 2640;\n\t\t\t\tORGANIZATIONNAME = \"Benjamin Erhart\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t6003F589195388D20070C39A = {\n\t\t\t\t\t\tLastSwiftMigration = 2610;\n\t\t\t\t\t};\n\t\t\t\t\t6003F5AD195388D20070C39A = {\n\t\t\t\t\t\tTestTargetID = 6003F589195388D20070C39A;\n\t\t\t\t\t};\n\t\t\t\t\tA0F00908279070B40073D36D = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 13.2.1;\n\t\t\t\t\t\tLastSwiftMigration = 2610;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject \"Tor\" */;\n\t\t\tdevelopmentRegion = en;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 6003F581195388D10070C39A;\n\t\t\tpreferredProjectObjectVersion = 77;\n\t\t\tproductRefGroup = 6003F58B195388D20070C39A /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectReferences = (\n\t\t\t\t{\n\t\t\t\t\tProductGroup = A009806C2F1653D900FE3A57 /* Products */;\n\t\t\t\t\tProjectRef = A009E83F2F1653D800FE3A57 /* ios.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = A04C1E392EE0736B00A8AFFA /* Products */;\n\t\t\t\t\tProjectRef = A04C1E332EE0736B00A8AFFA /* ios.xcodeproj */;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tProductGroup = A04CEDE12EE0632200A8AFFA /* Products */;\n\t\t\t\t\tProjectRef = A04CEDDB2EE0632200A8AFFA /* ios.xcodeproj */;\n\t\t\t\t},\n\t\t\t);\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t6003F589195388D20070C39A /* Tor-Example */,\n\t\t\t\t6003F5AD195388D20070C39A /* Tor-Tests */,\n\t\t\t\tA0F00908279070B40073D36D /* Tor-Example-Mac */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXReferenceProxy section */\n\t\tA00980702F165ECB00FE3A57 /* ios.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = ios.app;\n\t\t\tremoteRef = A009806F2F165ECB00FE3A57 /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tA04C21322EE0736C00A8AFFA /* ios.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = ios.app;\n\t\t\tremoteRef = A04C21312EE0736C00A8AFFA /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n\t\tA04CF0EF2EE0632200A8AFFA /* ios.app */ = {\n\t\t\tisa = PBXReferenceProxy;\n\t\t\tfileType = wrapper.application;\n\t\t\tpath = ios.app;\n\t\t\tremoteRef = A04CF0EE2EE0632200A8AFFA /* PBXContainerItemProxy */;\n\t\t\tsourceTree = BUILT_PRODUCTS_DIR;\n\t\t};\n/* End PBXReferenceProxy section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t6003F588195388D20070C39A /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA057DDA72EDDEEC80044B431 /* Launch Screen.storyboard in Resources */,\n\t\t\t\t873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6003F5AC195388D20070C39A /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tA0F00907279070B40073D36D /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA0F00915279070B40073D36D /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXShellScriptBuildPhase section */\n\t\t90B5FFAA88FED781C1B58A99 /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example/Pods-Tor-Example-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example/Pods-Tor-Example-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example/Pods-Tor-Example-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t90D8C2DC582D8E6FC6716412 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-Tor-Tests-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t92C23A76A3C3CB7B0EE26734 /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-Tor-Example-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\t9A118950F57DB5601BC45C3C /* [CP] Check Pods Manifest.lock */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t\t\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\",\n\t\t\t\t\"${PODS_ROOT}/Manifest.lock\",\n\t\t\t);\n\t\t\tname = \"[CP] Check Pods Manifest.lock\";\n\t\t\toutputFileListPaths = (\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t\t\"$(DERIVED_FILE_DIR)/Pods-Tor-Example-Mac-checkManifestLockResult.txt\",\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"diff \\\"${PODS_PODFILE_DIR_PATH}/Podfile.lock\\\" \\\"${PODS_ROOT}/Manifest.lock\\\" > /dev/null\\nif [ $? != 0 ] ; then\\n    # print error to STDERR\\n    echo \\\"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\\\" >&2\\n    exit 1\\nfi\\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\\necho \\\"SUCCESS\\\" > \\\"${SCRIPT_OUTPUT_FILE_0}\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n\t\tC24010A627399EEA7C17DDED /* [CP] Embed Pods Frameworks */ = {\n\t\t\tisa = PBXShellScriptBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\tinputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example-Mac/Pods-Tor-Example-Mac-frameworks-${CONFIGURATION}-input-files.xcfilelist\",\n\t\t\t);\n\t\t\tinputPaths = (\n\t\t\t);\n\t\t\tname = \"[CP] Embed Pods Frameworks\";\n\t\t\toutputFileListPaths = (\n\t\t\t\t\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example-Mac/Pods-Tor-Example-Mac-frameworks-${CONFIGURATION}-output-files.xcfilelist\",\n\t\t\t);\n\t\t\toutputPaths = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t\tshellPath = /bin/sh;\n\t\t\tshellScript = \"\\\"${PODS_ROOT}/Target Support Files/Pods-Tor-Example-Mac/Pods-Tor-Example-Mac-frameworks.sh\\\"\\n\";\n\t\t\tshowEnvVarsInLog = 0;\n\t\t};\n/* End PBXShellScriptBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t6003F586195388D20070C39A /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA057DDA52EDDE7800044B431 /* ViewController.swift in Sources */,\n\t\t\t\t6003F59E195388D20070C39A /* AppDelegate.m in Sources */,\n\t\t\t\tA0F0091D279072D60073D36D /* main.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t6003F5AA195388D20070C39A /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA0F008FC27906DBA0073D36D /* TORConfigurationTests.m in Sources */,\n\t\t\t\tA0F008FD27906DBA0073D36D /* TORControllerTests.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\tA0F00905279070B40073D36D /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\tA057DD272ED9F2800044B431 /* ViewController.swift in Sources */,\n\t\t\t\tA0F00917279070B40073D36D /* main.m in Sources */,\n\t\t\t\tA0F0090D279070B40073D36D /* AppDelegate.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t6003F5B4195388D20070C39A /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 6003F589195388D20070C39A /* Tor-Example */;\n\t\t\ttargetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\tA0F00913279070B40073D36D /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\tA0F0092027907A8A0073D36D /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t6003F5BD195388D20070C39A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_SYMBOLS_PRIVATE_EXTERN = NO;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSTRING_CATALOG_GENERATE_SYMBOLS = YES;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6003F5BE195388D20070C39A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCOPY_PHASE_STRIP = YES;\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSTRING_CATALOG_GENERATE_SYMBOLS = YES;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tTARGETED_DEVICE_FAMILY = \"1,2\";\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6003F5C0195388D20070C39A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 4F31AB271AA16E836CDC5F8D /* Pods-Tor-Example.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Tor/Tor-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Tor/Tor-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMODULE_NAME = ExampleApp;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Tor/Tor-Example-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 6.0;\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6003F5C1195388D20070C39A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 74CA0FB740D38C49003C1E1A /* Pods-Tor-Example.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Tor/Tor-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Tor/Tor-Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 15.0;\n\t\t\t\tMODULE_NAME = ExampleApp;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Tor/Tor-Example-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 6.0;\n\t\t\t\tWRAPPER_EXTENSION = app;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t6003F5C3195388D20070C39A /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = C2C4B3C67BC4AA29D918DFE0 /* Pods-Tor-Tests.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(DEVELOPER_FRAMEWORKS_DIR)\",\n\t\t\t\t);\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Tests/Tests-Prefix.pch\";\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"Tests/Tests-Info.plist\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Tor_Example.app/Tor_Example\";\n\t\t\t\tWRAPPER_EXTENSION = xctest;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t6003F5C4195388D20070C39A /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 4DFC6FCDC4F8056024E28F5B /* Pods-Tor-Tests.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(PLATFORM_DIR)/Developer/Library/Frameworks\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(DEVELOPER_FRAMEWORKS_DIR)\",\n\t\t\t\t);\n\t\t\t\tGCC_PRECOMPILE_PREFIX_HEADER = YES;\n\t\t\t\tGCC_PREFIX_HEADER = \"Tests/Tests-Prefix.pch\";\n\t\t\t\tINFOPLIST_FILE = \"Tests/Tests-Info.plist\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Tor_Example.app/Tor_Example\";\n\t\t\t\tWRAPPER_EXTENSION = xctest;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\tA0F0091A279070B40073D36D /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = CCD44E911F9C4625A303B626 /* Pods-Tor-Example-Mac.debug.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_APP_SANDBOX = YES;\n\t\t\t\tENABLE_INCOMING_NETWORK_CONNECTIONS = YES;\n\t\t\t\tENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;\n\t\t\t\tENABLE_USER_SELECTED_FILES = readonly;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"Copyright © 2022 Benjamin Erhart. All rights reserved.\";\n\t\t\t\tINFOPLIST_KEY_NSMainStoryboardFile = Main;\n\t\t\t\tINFOPLIST_KEY_NSPrincipalClass = NSApplication;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.Tor-Example-Mac\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Example-Mac/Tor-Example-Mac-Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 6.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\tA0F0091B279070B40073D36D /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbaseConfigurationReference = 8AA26438ED97EA21E1B6572D /* Pods-Tor-Example-Mac.release.xcconfig */;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++17\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_WEAK = YES;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_APP_SANDBOX = YES;\n\t\t\t\tENABLE_INCOMING_NETWORK_CONNECTIONS = YES;\n\t\t\t\tENABLE_OUTGOING_NETWORK_CONNECTIONS = YES;\n\t\t\t\tENABLE_USER_SELECTED_FILES = readonly;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu11;\n\t\t\t\tGENERATE_INFOPLIST_FILE = YES;\n\t\t\t\tINFOPLIST_KEY_NSHumanReadableCopyright = \"Copyright © 2022 Benjamin Erhart. All rights reserved.\";\n\t\t\t\tINFOPLIST_KEY_NSMainStoryboardFile = Main;\n\t\t\t\tINFOPLIST_KEY_NSPrincipalClass = NSApplication;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 11.0;\n\t\t\t\tMARKETING_VERSION = 1.0;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tMTL_FAST_MATH = YES;\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = \"org.cocoapods.Tor-Example-Mac\";\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_EMIT_LOC_STRINGS = YES;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Example-Mac/Tor-Example-Mac-Bridging-Header.h\";\n\t\t\t\tSWIFT_VERSION = 6.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t6003F585195388D10070C39A /* Build configuration list for PBXProject \"Tor\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6003F5BD195388D20070C39A /* Debug */,\n\t\t\t\t6003F5BE195388D20070C39A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget \"Tor-Example\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6003F5C0195388D20070C39A /* Debug */,\n\t\t\t\t6003F5C1195388D20070C39A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget \"Tor-Tests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t6003F5C3195388D20070C39A /* Debug */,\n\t\t\t\t6003F5C4195388D20070C39A /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\tA0F00919279070B40073D36D /* Build configuration list for PBXNativeTarget \"Tor-Example-Mac\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\tA0F0091A279070B40073D36D /* Debug */,\n\t\t\t\tA0F0091B279070B40073D36D /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\t};\n\trootObject = 6003F582195388D10070C39A /* Project object */;\n}\n"
  },
  {
    "path": "Example/Tor.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:Tor.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Example/Tor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Example/Tor.xcodeproj/xcshareddata/xcschemes/Tor-Example-Mac.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"2640\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"A0F00908279070B40073D36D\"\n               BuildableName = \"Tor-Example-Mac.app\"\n               BlueprintName = \"Tor-Example-Mac\"\n               ReferencedContainer = \"container:Tor.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"A0F00908279070B40073D36D\"\n            BuildableName = \"Tor-Example-Mac.app\"\n            BlueprintName = \"Tor-Example-Mac\"\n            ReferencedContainer = \"container:Tor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"A0F00908279070B40073D36D\"\n            BuildableName = \"Tor-Example-Mac.app\"\n            BlueprintName = \"Tor-Example-Mac\"\n            ReferencedContainer = \"container:Tor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Example/Tor.xcodeproj/xcshareddata/xcschemes/Tor-Example.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"2640\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"6003F589195388D20070C39A\"\n               BuildableName = \"Tor-Example.app\"\n               BlueprintName = \"Tor-Example\"\n               ReferencedContainer = \"container:Tor.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"6003F589195388D20070C39A\"\n            BuildableName = \"Tor-Example.app\"\n            BlueprintName = \"Tor-Example\"\n            ReferencedContainer = \"container:Tor.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"6003F5AD195388D20070C39A\"\n               BuildableName = \"Tor-Tests.xctest\"\n               BlueprintName = \"Tor-Tests\"\n               ReferencedContainer = \"container:Tor.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"6003F589195388D20070C39A\"\n            BuildableName = \"Tor-Example.app\"\n            BlueprintName = \"Tor-Example\"\n            ReferencedContainer = \"container:Tor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"6003F589195388D20070C39A\"\n            BuildableName = \"Tor-Example.app\"\n            BlueprintName = \"Tor-Example\"\n            ReferencedContainer = \"container:Tor.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Example/Tor.xcworkspace/contents.xcworkspacedata",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Tor.xcodeproj\">\n   </FileRef>\n   <FileRef\n      location = \"group:Pods/Pods.xcodeproj\">\n   </FileRef>\n</Workspace>\n"
  },
  {
    "path": "Example/Tor.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2015-2026 The iCepa Contributors:\n\n- Conrad Kramer (https://conradkramer.com)\n- Chris Ballinger (http://chatsecure.org)\n- Mike Tigas (https://mike.tig.as)\n- Benjamin Erhart (https://die.netzarchitekten.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "# Tor.framework\n\n[![Version](https://img.shields.io/cocoapods/v/Tor.svg?style=flat)](https://cocoapods.org/pods/Tor)\n[![License](https://img.shields.io/cocoapods/l/Tor.svg?style=flat)](https://cocoapods.org/pods/Tor)\n[![Platform](https://img.shields.io/cocoapods/p/Tor.svg?style=flat)](https://cocoapods.org/pods/Tor)\n\nTor.framework is the easiest way to embed Tor in your iOS application. The API is *not* stable yet, and subject to change.\n\nCurrently, the framework compiles in the following versions of `tor`, `libevent`, `openssl`, and `liblzma`:\n\n| Component | Version  |\n|:--------- | --------:|\n| tor       | 0.4.9.6  |\n| libevent  | 2.1.12   |\n| OpenSSL   | 3.6.1    |\n| liblzma   | 5.8.2    |\n| Arti      | 1.7.0    |\n| Onionmasq | 0.6.2    |\n\n\n## LATEST CHANGES\n\n- No inline compilation necessary anymore: Now uses precompiled `tor.xcframework`, \n  `tor-nolzma.xcframework` and `arti.xcframework`which will be downloaded from \n  https://github.com/iCepa/Tor.framework/releases on install/update. \n- Finally removed `TorStatic.podspec` as there was no feedback about it and it started to be in the way.\n\n\n## Example\n\nTo run the example project, clone the repo, and run `pod install` from the Example directory first.\n\n## Requirements\n\n- iOS 15.0 or later\n- MacOS 11.0 or later\n- Xcode 26.0 or later\n\n\n## Installation\n\nC-Tor is available through [CocoaPods](https://cocoapods.org). To install it, \nsimply add the following line to your Podfile:\n\n```ruby\nuse_frameworks!\npod 'Tor', '~> 409'\n```\n\n(or `Tor/GeoIP` - see below.)\n\n\nArti is available through it's own Podspec. To install it,\nsimply add the following line to your Podfile:\n\n```ruby\nuse_frameworks!\npod 'Tor/Arti', \n  :podspec => 'https://raw.githubusercontent.com/iCepa/Tor.framework/refs/heads/pure_pod/Arti.podspec'\n```\n\n## Compiling yourself\n\nPrerequesite:\n- [Homebrew](https://brew.sh)\n\n```sh\ngit clone https://github.com/iCepa/Tor.framework.git\ncd Tor.framework\nbrew bundle\nrustup default stable \nrustup target add aarch64-apple-darwin\nrustup target add x86_64-apple-darwin\nrustup target add aarch64-apple-ios\nrustup target add aarch64-apple-ios-sim\nrustup target add x86_64-apple-ios\ncargo install cbindgen\n./build-xcframework.sh -ac\n```\n\n*NOTE*: Builds are not reproducible.\n\n## Preparing a new release\n\nFor maintainers/contributors of Tor.framework, a new release should be prepared by \ndoing the following:\n\n- Update the version numbers of the libraries used in [`build-xcframework.sh`](build-xcframework.sh).\n\n- Follow the instructions in [Compiling yourself](#compiling-yourself)\n\n- Check the logs and test the created `tor.xcframework`, `tor-nolzma.xcframework` and `arti.xcframework` \n  with the contained example apps.\n  \n- Update info, version numbers and checksums in `README.md`, `Tor.podspec` and `Arti.podspec`!\n\n- Commit, tag and push new release.\n\n- Create a pre-release on https://github.com/iCepa/Tor.framework/releases with the latest \n  info as per older releases and upload the created `tor.xcframework.zip`, \n  `tor-nolzma.framework.zip` and `arti.framework.zip` files.\n\n- Then lint like this:\n\n```sh\npod lib lint --allow-warnings Tor.podspec\n```\n\n- If the linting went well, publish to CocoaPods:\n\n```sh\npod trunk push --allow-warnings Tor.podspec \n```\n\n- Then update the [release](https://github.com/iCepa/Tor.framework/releases) in GitHub, \n  setting it as the latest release.\n\n\n## Usage\n\n### All-in-one `TorManager`\n\nFor a headache-free start into the world of Tor on iOS and macOS, check out\nthe new [`TorManager` project](https://github.com/tladesignz/TorManager)!\n\n### Do-it-yourself\n\nStarting an instance of Tor involves using three classes: `TORThread`, `TORConfiguration` and `TORController`.\n\nHere is an example of integrating Tor with `NSURLSession`:\n\n```objc\nTORConfiguration *configuration = [TORConfiguration new];\nconfiguration.ignoreMissingTorrc = YES;\nconfiguration.cookieAuthentication = YES;\nconfiguration.dataDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory()];\nconfiguration.controlSocket = [configuration.dataDirectory URLByAppendingPathComponent:@\"control_port\"];\n\nTORThread *thread = [[TORThread alloc] initWithConfiguration:configuration];\n[thread start];\n\nNSData *cookie = configuration.cookie;\nTORController *controller = [[TORController alloc] initWithSocketURL:configuration.controlSocket];\n\nNSError *error;\n[controller connect:&error];\n\nif (error) {\n    NSLog(@\"Error: %@\", error);\n    return;\n}\n\n[controller authenticateWithData:cookie completion:^(BOOL success, NSError *error) {\n    if (!success)\n        return;\n\n    [controller addObserverForCircuitEstablished:^(BOOL established) {\n        if (!established)\n            return;\n\n        [controller getSessionConfiguration:^(NSURLSessionConfiguration *configuration) {\n            NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];\n            ...\n        }];\n    }];\n}];\n```\n\n\n### GeoIP\n\nIn your `Podfile` use the subspec `GeoIP` instead of the root spec:\n\n```ruby\nuse_frameworks!\npod 'Tor/GeoIP'\n```\n\nThe subspec will create a \"GeoIP\" bundle with the appropriate GeoIP files.\n\nTo use it with Tor, add this to your configuration:\n\n```objc\nTORConfiguration *configuration = [TORConfiguration new];\nconfiguration.geoipFile = NSBundle.geoIpBundle.geoipFile;\nconfiguration.geoip6File = NSBundle.geoIpBundle.geoip6File;\n```\n\n### Experimental Arti and Onionmasq podspec\n\nSince I while, this project also contains a podspec, which uses Arti (A Rust Tor Implementation)\nor Onionmasq (Arti with a wrapper taking in IP packets, useful for VPN-style apps.)\n\n```ruby\npod 'Tor/Arti', :podspec => 'https://raw.githubusercontent.com/iCepa/Tor.framework/pure_pod/Arti.podspec'\n```\n\nor\n\n```ruby\npod 'Tor/Onionmasq', :podspec => 'https://raw.githubusercontent.com/iCepa/Tor.framework/pure_pod/Arti.podspec'\n```\n\nThere's currently a known issue: Onionmasq won't compile if you build for iOS or an iOS simulator right away,\nsince some Rust dependencies use custom build scripts which need to get compiled for MacOS, but will try\nto use the wrong platform (iOS) in this case. \nThis can be fixed, if you compile for your machine first:\n\n```sh\ncd Pods/Tor/Tor/onionmasq\nmake macos-debug-aarch64-apple-darwin # If you run on Apple Silicon\nmake macos-debug-x86_64-apple-darwin # If you're still on Intel\n```\n\nThen, the Rust dependency build scripts will be compiled correctly and the \nXcode build will run correctly.\n\nYou can also precompile your debug and release targets on the command line, if you like:\n\n```sh\nmake macos-release-universal-macos # Release build for MacOS as universal binary\nmake ios-release-aarch64-apple-ios # Release build for iOS\nmake ios-debug-aarch64-apple-ios # Debug build for iOS device\nmake ios-debug-aarch64-apple-ios-sim # Debug build for iOS simulator running on Apple Silicon\nmake ios-debug-x86_64-apple-ios # Debug build for iOS simulator running on Intel\n```\n\n\n## Further reading\n\nhttps://tordev.guardianproject.info\n\n\n## Authors\n\n- Conrad Kramer, conrad@conradkramer.com\n- Chris Ballinger, chris@chatsecure.org\n- Mike Tigas, mike@tig.as\n- Benjamin Erhart, berhart@netzarchitekten.com\n\n\n## License\n\nTor.framework is available under the MIT license. See the \n[`LICENSE`](https://github.com/iCepa/Tor.framework/blob/master/LICENSE) file for more info.\n"
  },
  {
    "path": "Tor/Assets/.gitkeep",
    "content": ""
  },
  {
    "path": "Tor/Classes/Arti/TORArti.h",
    "content": "//\n//  TORArti.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 02.02.23.\n//\n\n#import <Foundation/Foundation.h>\n#import <Tor/TORConfiguration.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nNS_SWIFT_NAME(TorArti)\n@interface TORArti : NSObject\n\n/**\n Start Arti.\n\n @param socksPort The port to use for accepting SOCKS5 requests.\n @param dnsPort The port to use for accepting DNS requests.\n @param logfile A logfile to write to. OPTIONAL\n @param stateDir Directory, where Arti can store its state. OPTIONAL. If not provided, will use \\c Library/Application \\c Support/org.torproject.Arti.\n @param cacheDir Directory, where Arti can store its caching data. OPTIONAL. If not providied, will use \\c Library/Cache/org.torproject.Arti.\n @param obfs4proxyPath The path to the Obfs4proxy binary. OPTIONAL. Only for MacOS! iOS apps are not allowed to start other processes!\n @param bridge A bridge configuration line needed for the provided Obfs4proxy. OPTIONAL.\n @param completed Callback when Arti is ready to connect.\n */\n+ (void)startWithSocksPort:(NSUInteger)socksPort \n                   dnsPort:(NSUInteger)dnsPort\n                 obfs4Port:(NSUInteger)obfs4Port\n             snowflakePort:(NSUInteger)snowflakePort\n                   logfile:(NSURL * _Nullable)logfile\n                  stateDir:(NSURL * _Nullable)stateDir\n                  cacheDir:(NSURL * _Nullable)cacheDir\n            obfs4proxyPath:(NSURL * _Nullable)obfs4proxyPath\n                    bridge:(NSString * _Nullable)bridge\n                 completed:(nullable void (^)(void))completed;\n\n+ (void)startWithConfiguration:(TORConfiguration * _Nonnull)configuration completed:(nullable void (^)(void))completed;\n\n+ (void)stop;\n\n//+ (NSError *)status;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Arti/TORArti.m",
    "content": "//\n//  TORArti.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 02.02.23.\n//\n\n#import \"TORArti.h\"\n#import \"arti-mobile.h\"\n//#import \"arti-rpc-client-core.h\"\n\n@implementation TORArti\n\nNSString *logfilePath;\n\nNSRegularExpression *regex;\n\ntypedef void (^Completed)(void);\n\nCompleted completedBlock;\n\n\n+ (void)startWithSocksPort:(NSUInteger)socksPort\n                   dnsPort:(NSUInteger)dnsPort\n                 obfs4Port:(NSUInteger)obfs4Port\n             snowflakePort:(NSUInteger)snowflakePort\n                   logfile:(NSURL * _Nullable)logfile\n                  stateDir:(NSURL * _Nullable)stateDir\n                  cacheDir:(NSURL * _Nullable)cacheDir\n           obfs4proxyPath:(NSURL * _Nullable)obfs4proxyPath\n                    bridge:(NSString * _Nullable)bridge\n                 completed:(nullable void (^)(void))completed\n{\n    logfilePath = logfile.path;\n    completedBlock = completed;\n\n    NSFileManager *fm = NSFileManager.defaultManager;\n\n    if (![fm fileExistsAtPath:logfilePath]) {\n        [fm createFileAtPath:logfilePath contents:nil attributes:nil];\n    }\n\n    if (!stateDir) {\n        stateDir = [[[fm URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]\n                     firstObject]\n                    URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n    }\n\n    if (!cacheDir) {\n        cacheDir = [[[fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask]\n                     firstObject]\n                    URLByAppendingPathComponent:@\"org.torproject.Arti\"];\n    }\n\n    // Remove ANSI colors.\n    regex = [[NSRegularExpression alloc]\n             initWithPattern:@\"\\\\x1b\\\\[[0-9;]*m\"\n             options:NSRegularExpressionDotMatchesLineSeparators error:nil];\n\n    start_arti([stateDir.path cStringUsingEncoding:NSUTF8StringEncoding],\n               [cacheDir.path cStringUsingEncoding:NSUTF8StringEncoding],\n               (int)obfs4Port,\n               (int)snowflakePort,\n               [obfs4proxyPath.path cStringUsingEncoding:NSUTF8StringEncoding],\n               [bridge cStringUsingEncoding:NSUTF8StringEncoding],\n               (int)socksPort,\n               (int)dnsPort,\n               &loggingCb);\n}\n\n+ (void)startWithConfiguration:(TORConfiguration * _Nonnull)configuration\n                     completed:(nullable void (^)(void))completed\n{\n    NSUInteger obfs4Port = 0;\n    NSUInteger snowflakePort = 0;\n    NSURL *obfs4proxyPath = nil;\n    NSString *bridge = nil;\n\n    if ([configuration valueOf:@\"UseBridges\"]) {\n        NSString *ctp = [configuration valueOf:@\"ClientTransportPlugin\"];\n        NSArray<NSString *> *pieces = [ctp componentsSeparatedByCharactersInSet:NSCharacterSet.whitespaceCharacterSet];\n\n        NSRegularExpression *socksRegex = [[NSRegularExpression alloc]\n                                           initWithPattern:@\"^socks[45]$\"\n                                           options:NSRegularExpressionCaseInsensitive error:nil];\n\n        if (pieces.count > 0) {\n            if (pieces.count > 2\n                && [socksRegex numberOfMatchesInString:pieces[1] options:0 range:NSMakeRange(0, pieces[1].length)] > 0\n            ) {\n                NSRegularExpression *addrRegex = [[NSRegularExpression alloc]\n                                                  initWithPattern:@\"^.+:(\\\\d{1,5})$\"\n                                                  options:0\n                                                  error:nil];\n\n                NSArray<NSTextCheckingResult *> *matches = [addrRegex matchesInString:pieces[2] options:0 range:NSMakeRange(0, pieces[2].length)];\n\n                if (matches.count > 0 && matches[0].numberOfRanges > 1) {\n                    NSRange range = [matches[0] rangeAtIndex:1];\n\n                    NSString *port = [pieces[2] substringWithRange:range];\n\n                    if ([pieces[0] caseInsensitiveCompare:@\"snowflake\"] == NSOrderedSame) {\n                        snowflakePort = [port integerValue];\n                    }\n                    else if ([pieces[0] caseInsensitiveCompare:@\"obfs4\"] == NSOrderedSame) {\n                        obfs4Port = [port integerValue];\n                    }\n                }\n            }\n            else if (pieces.count > 1\n                     && [pieces[0] caseInsensitiveCompare:@\"obfs4\"] == NSOrderedSame\n             ) {\n                obfs4proxyPath = [[NSURL alloc] initFileURLWithPath:pieces[1] isDirectory:NO];\n            }\n        }\n\n        bridge = [configuration valueOf:@\"Bridge\"];\n    }\n\n    [self startWithSocksPort:configuration.socksPort\n                     dnsPort:configuration.dnsPort\n                   obfs4Port:obfs4Port\n               snowflakePort:snowflakePort\n                     logfile:configuration.logfile\n                    stateDir:configuration.dataDirectory\n                    cacheDir:configuration.cacheDirectory\n              obfs4proxyPath:obfs4proxyPath\n                      bridge:bridge\n                   completed:completed];\n}\n\n+ (void)stop\n{\n    stop_arti();\n}\n\n// Experimental! Not working.\n//+ (NSError *)status\n//{\n//    ArtiRpcConnBuilder *builder;\n//    ArtiRpcError *error;\n//\n//    if (arti_rpc_conn_builder_new(&builder, &error) != ARTI_RPC_STATUS_SUCCESS)\n//    {\n//        return [self nsErrorFromArti:error];\n//    }\n//\n//    ArtiRpcConn *conn;\n//\n//    if (arti_rpc_conn_builder_connect(builder, &conn, &error) != ARTI_RPC_STATUS_SUCCESS)\n//    {\n//        arti_rpc_conn_builder_free(builder);\n//\n//        return [self nsErrorFromArti:error];\n//    }\n//\n//    arti_rpc_conn_builder_free(builder);\n//\n//    const char *sessionId = arti_rpc_conn_get_session_id(conn);\n//\n//    NSLog(@\"sessionId=%s\", sessionId);\n//\n//    ArtiRpcStr *response;\n//\n//    if (arti_rpc_conn_execute(conn, [@\"arti:get_client_status\" cStringUsingEncoding:NSUTF8StringEncoding], &response, &error) != ARTI_RPC_STATUS_SUCCESS)\n//    {\n//        arti_rpc_conn_free(conn);\n//\n//        return [self nsErrorFromArti:error];\n//    }\n//\n//    NSLog(@\"response=%s\", arti_rpc_str_get(response));\n//\n//    arti_rpc_str_free(response);\n//\n//    arti_rpc_conn_free(conn);\n//\n//    return nil;\n//}\n//\n//+ (NSError *)nsErrorFromArti:(ArtiRpcError *)error\n//{\n//    NSString *msg = [NSString stringWithCString:arti_rpc_err_message(error) encoding:NSUTF8StringEncoding];\n//    ArtiRpcStatus code = arti_rpc_err_status(error);\n//\n//    NSError *err = [[NSError alloc] initWithDomain:@\"Arti\" code:code userInfo:@{NSLocalizedDescriptionKey: msg}];\n//\n//    arti_rpc_err_free(error);\n//\n//    NSLog(@\"Arti Error=%@\", err);\n//\n//    return err;\n//}\n\nvoid loggingCb(const char * message)\n{\n    NSMutableString *msg = [[NSMutableString alloc] initWithUTF8String:message];\n\n    if (completedBlock && [msg.lowercaseString containsString:@\"directory is complete\"]) {\n        dispatch_async(dispatch_get_main_queue(), ^{\n            completedBlock();\n            completedBlock = nil;\n        });\n    }\n\n    if (logfilePath.length < 1) return;\n\n    [regex replaceMatchesInString:msg options:0 range:NSMakeRange(0, msg.length) withTemplate:@\"\"];\n\n    NSFileHandle *fh = [NSFileHandle fileHandleForUpdatingAtPath: logfilePath];\n    [fh seekToEndOfFile];\n    [fh writeData:[msg dataUsingEncoding:NSUTF8StringEncoding]];\n    [fh closeFile];\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/Classes/CTor/TORLogging.h",
    "content": "//\n//  TORLogging.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 9/9/17.\n//\n\n#import <Foundation/Foundation.h>\n#import <os/log.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef void(* tor_log_cb)(os_log_type_t severity, const char* msg);\n\nextern void TORInstallEventLogging(void);\n\nextern void TORInstallEventLoggingCallback(tor_log_cb cb);\n\nextern void TORInstallTorLogging(void);\n\nextern void TORInstallTorLoggingCallback(tor_log_cb cb);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/CTor/TORLogging.m",
    "content": "//\n//  TORLogging.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 9/9/17.\n//\n\n#import \"TORLogging.h\"\n\n#import <event2/event.h>\n#import <asl.h>\n// XXXX This is not an exposed or supported Tor API.\n// XXXX If Tor changes this header, then this code might break.\n#import <lib/log/log.h>\n\ntor_log_cb tor_log_callback;\ntor_log_cb event_log_callback;\n\nNS_ASSUME_NONNULL_BEGIN\n\nstatic char *subsystem = \"org.torproject.Tor\";\n\nstatic inline const char *TORLegacyLevelFromOSLogType(os_log_type_t type) {\n    switch (type) {\n        case OS_LOG_TYPE_ERROR:\n            return \"3\";\n        case OS_LOG_TYPE_INFO:\n            return \"4\";\n        case OS_LOG_TYPE_DEBUG:\n        default:\n            return \"5\";\n    }\n}\n\n#pragma clang diagnostic push\n#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n\nstatic void TORLegacyLog(os_log_type_t type, const char *msg) {\n    static dispatch_once_t onceToken;\n    static aslclient log = NULL;\n    dispatch_once(&onceToken, ^{\n        log = asl_open(NULL, \"com.apple.console\", 0);\n    });\n\n    char read_uid[16];\n    snprintf(read_uid, sizeof(read_uid), \"%d\", geteuid());\n\n    aslmsg message = asl_new(ASL_TYPE_MSG);\n    if (message != NULL) {\n        if (asl_set(message, ASL_KEY_LEVEL, TORLegacyLevelFromOSLogType(type)) == 0 &&\n            asl_set(message, ASL_KEY_MSG, msg) == 0 &&\n            asl_set(message, ASL_KEY_READ_UID, read_uid) == 0) {\n            asl_send(log, message);\n        }\n        asl_free(message);\n    }\n}\n\n#pragma clang diagnostic pop\n\nstatic inline os_log_type_t TORLogTypeFromEventSeverity(int severity) {\n    switch (severity) {\n        case EVENT_LOG_ERR:\n        case EVENT_LOG_WARN:\n            return OS_LOG_TYPE_ERROR;\n        case EVENT_LOG_MSG:\n            return OS_LOG_TYPE_INFO;\n        case EVENT_LOG_DEBUG:\n            return OS_LOG_TYPE_DEBUG;\n        default:\n            return OS_LOG_TYPE_DEFAULT;\n    }\n}\n\nstatic void TOREventLogCallback(int severity, const char *msg) {\n    os_log_type_t type = TORLogTypeFromEventSeverity(severity);\n\n    if (event_log_callback) {\n        event_log_callback(type, msg);\n    } else if (@available(iOS 10.0, macOS 10.12, *)) {\n        static dispatch_once_t onceToken;\n        static os_log_t log = NULL;\n        dispatch_once(&onceToken, ^{\n            log = os_log_create(subsystem, \"libevent\");\n        });\n\n        os_log_with_type(log, type, \"%{public}s\", msg);\n    } else {\n        TORLegacyLog(type, msg);\n    }\n}\n\nstatic const char * __nullable TORCategoryForDomain(uint32_t domain) {\n    switch (domain) {\n        case LD_GENERAL:\n            return \"general\";\n        case LD_CRYPTO:\n            return \"crypto\";\n        case LD_NET:\n            return \"net\";\n        case LD_CONFIG:\n            return \"config\";\n        case LD_FS:\n            return \"fs\";\n        case LD_PROTOCOL:\n            return \"protocol\";\n        case LD_MM:\n            return \"mm\";\n        case LD_HTTP:\n            return \"http\";\n        case LD_APP:\n            return \"app\";\n        case LD_CONTROL:\n            return \"control\";\n        case LD_CIRC:\n            return \"circ\";\n        case LD_REND:\n            return \"rend\";\n        case LD_BUG:\n            return \"bug\";\n        case LD_DIR:\n            return \"dir\";\n        case LD_DIRSERV:\n            return \"dirserv\";\n        case LD_OR:\n            return \"or\";\n        case LD_EDGE:\n            return \"edge\";\n        case LD_ACCT:\n            return \"acct\";\n        case LD_HIST:\n            return \"hist\";\n        case LD_HANDSHAKE:\n            return \"handshake\";\n        case LD_HEARTBEAT:\n            return \"heartbeat\";\n        case LD_CHANNEL:\n            return \"channel\";\n        case LD_SCHED:\n            return \"sched\";\n        case LD_GUARD:\n            return \"guard\";\n        default:\n            return NULL;\n    }\n}\n\nstatic inline os_log_type_t TORLogTypeFromSeverity(int severity) {\n    switch (severity) {\n        case LOG_ERR:\n            return OS_LOG_TYPE_FAULT;\n        case LOG_WARN:\n            return OS_LOG_TYPE_ERROR;\n        case LOG_NOTICE:\n        case LOG_INFO:\n            return OS_LOG_TYPE_INFO;\n        case LOG_DEBUG:\n            return OS_LOG_TYPE_DEBUG;\n        default:\n            return OS_LOG_TYPE_DEFAULT;\n    }\n}\n\nstatic void TORLogCallback(int severity, uint64_t domain, const char *msg) {\n    if (domain & LD_NOCB) {\n        return;\n    }\n\n    os_log_type_t type = TORLogTypeFromSeverity(severity);\n\n    if (tor_log_callback) {\n        tor_log_callback(type, msg);\n    } else if (@available(iOS 10.0, macOS 10.12, *)) {\n        int index = 0;\n        while (domain >>= 1) {\n            ++index;\n        }\n        if (index >= N_LOGGING_DOMAINS) {\n            return;\n        }\n\n        static os_log_t logs[N_LOGGING_DOMAINS] = { NULL };\n        os_log_t log = logs[index];\n        if (log == NULL) {\n            log = os_log_create(subsystem, TORCategoryForDomain(1u << index));\n            logs[index] = log;\n        }\n\n        os_log_with_type(log, type, \"%{public}s\", msg);\n    } else {\n        TORLegacyLog(type, msg);\n    }\n}\n\nvoid TORInstallEventLogging(void) {\n    event_log_callback = NULL;\n    event_set_log_callback(TOREventLogCallback);\n    event_enable_debug_logging(EVENT_DBG_ALL);\n}\n\nvoid TORInstallEventLoggingCallback(tor_log_cb cb) {\n    event_log_callback = cb;\n    event_set_log_callback(TOREventLogCallback);\n    event_enable_debug_logging(EVENT_DBG_ALL);\n}\n\nvoid TORInstallTorLogging(void) {\n    tor_log_callback = NULL;\n    log_severity_list_t list;\n    set_log_severity_config(LOG_DEBUG, LOG_ERR, &list);\n    add_callback_log(&list, TORLogCallback);\n}\n\nextern void TORInstallTorLoggingCallback(tor_log_cb cb) {\n    tor_log_callback = cb;\n    log_severity_list_t list;\n    set_log_severity_config(LOG_DEBUG, LOG_ERR, &list);\n    add_callback_log(&list, TORLogCallback);\n}\n\nNS_ASSUME_NONNULL_END\n\n"
  },
  {
    "path": "Tor/Classes/CTor/TORThread.h",
    "content": "//\n//  TORThread.h\n//  Tor\n//\n//  Created by Conrad Kramer on 7/19/15.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class TORConfiguration;\n\nNS_SWIFT_NAME(TorThread)\n@interface TORThread : NSThread\n\n#if __has_feature(objc_class_property)\n@property (class, readonly, nullable) TORThread *activeThread;\n#else\n+ (nullable TORThread *)activeThread;\n#endif\n\n- (instancetype)initWithConfiguration:(nullable TORConfiguration *)configuration;\n- (instancetype)initWithArguments:(nullable NSArray<NSString *> *)arguments NS_DESIGNATED_INITIALIZER;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/CTor/TORThread.m",
    "content": "//\n//  TORThread.m\n//  Tor\n//\n//  Created by Conrad Kramer on 7/19/15.\n//\n\n#import <feature/api/tor_api.h>\n\n#import \"TORThread.h\"\n#import \"TORLogging.h\"\n#import \"TORConfiguration.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nstatic __weak TORThread *_thread = nil;\n\n@interface TORThread ()\n\n@property (nonatomic, readonly, copy, nullable) NSArray<NSString *> *arguments;\n\n@end\n\n@implementation TORThread\n\n+ (nullable TORThread *)activeThread {\n    return _thread;\n}\n\n- (instancetype)init {\n    return [self initWithArguments:nil];\n}\n\n- (instancetype)initWithConfiguration:(nullable TORConfiguration *)configuration {\n    return [self initWithArguments:[configuration compile]];\n}\n\n- (instancetype)initWithArguments:(nullable NSArray<NSString *> *)arguments {\n    NSAssert(_thread == nil, @\"There can only be one TORThread per process\");\n    self = [super init];\n    if (!self)\n        return nil;\n    \n    _thread = self;\n    _arguments = [arguments copy];\n    \n    self.name = @\"Tor\";\n    \n    return self;\n}\n\n- (void)main {\n    NSArray *arguments = self.arguments;\n    int argc = (int)(arguments.count + 1);\n    char *argv[argc];\n    argv[0] = \"tor\";\n    for (NSUInteger idx = 0; idx < arguments.count; idx++)\n        argv[idx + 1] = (char *)[arguments[idx] UTF8String];\n    argv[argc] = NULL;\n\n//#if DEBUG\n//    event_enable_debug_mode();\n//#endif\n\n    tor_main_configuration_t *cfg = tor_main_configuration_new();\n    tor_main_configuration_set_command_line(cfg, argc, argv);\n    tor_run_main(cfg);\n    tor_main_configuration_free(cfg);\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/CTor/TORX25519KeyPair.h",
    "content": "//\n//  TORX25519KeyPair.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 11.10.21.\n//\n\n#import <Foundation/Foundation.h>\n#import \"TORAuthKey.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Class to generate or hold a X25519 public/private key pair encoded in BASE32.\n */\nNS_SWIFT_NAME(TorX25519KeyPair)\n@interface TORX25519KeyPair : NSObject\n\n\n/**\n The BASE32 encoded private key. Should be exactly 32 bytes long, resp. 52 characters in BASE32 encoding.\n */\n@property (nonatomic, nullable, readonly) NSString *privateKey;\n\n/**\n The BASE32 encoded public key. Should be exactly 32 bytes long, resp. 52 characters in BASE32 encoding.\n */\n@property (nonatomic, nullable, readonly) NSString *publicKey;\n\n\n/**\n Generate a new X25519 key pair using Tor's implementation.\n\n On iOS 13 and up, another option is also available: CryptoKit's \\c Curve25519.KeyAggreement.PrivateKey\n */\n- (instancetype)init;\n\n/**\n Initialize with a pre-generated, BASE32-encoded X25519 key pair. A valid key pair is exactly 32 bytes long,\n resp. 52 characters in BASE32 encoding.\n\n No validity checks are made! It's your responsibility to provide valid key material.\n\n @param privateKey The private key, BASE32 encoded.\n @param publicKey The public key, BASE32 encoded.\n */\n- (instancetype)initWithBase32PrivateKey:(NSString *)privateKey andPublicKey:(NSString *)publicKey;\n\n/**\n Initialize with a pre-generated X25519 key pair. A valid key pair is exactly 32 bytes long.\n\n No validity checks are made! It's your responsibility to provide valid key material.\n\n @param privateKey The private key.\n @param publicKey The public key.\n  */\n- (instancetype)initWithPrivateKey:(NSData *)privateKey andPublicKey:(NSData *)publicKey;\n\n\n/**\n Create a private \\c TORAuthKey from this key material using the provided domain.\n\n @param domain The domain name, this private key is for. Must include the \\c .onion TLD!\n @returns the private \\c TORAuthKey of this key pair's private key  or \\c nil if the \\c domain is empty or this class doesn't contain a private key.\n*/\n- (nullable TORAuthKey *)getPrivateAuthKeyForDomain:(nonnull NSString *)domain;\n\n/**\n Create a private \\c TORAuthKey from this key material using the provided domain.\n\n @param url The domain, this private key is for.\n @returns the private \\c TORAuthKey of this key pair's private key  or \\c nil if this class doesn't contain a private key.\n*/\n- (nullable TORAuthKey *)getPrivateAuthKeyForUrl:(nonnull NSURL *)url;\n\n/**\n Create a public \\c TORAuthKey from this key material using the provided name.\n\n @param name The name used to store that \\c TORAuthKey, without the extension!\n @returns the public \\c TORAuthKey of this key pair's public key or \\c nil if the \\c name is empty or this class doesn't contain a public key.\n */\n- (nullable TORAuthKey *)getPublicAuthKeyWithName:(nonnull NSString *)name;\n\n\n/**\n Helper method to BASE32 encode raw binary \\c NSData into a \\c NSString.\n\n @param raw The raw binary \\c NSData to encode.\n @returns a BASE32 encoded representation of that binary data.\n */\n+ (nullable NSString *)base32Encode:(NSData *)raw;\n\n/**\n Helper method to decode raw binary \\c NSData contained in a BASE32 encoded \\c NSString.\n\n @param encoded The BASE32 encoded data  to decode.\n @returns binary data.\n */\n+ (nullable NSData *)base32Decode:(NSString *)encoded;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/CTor/TORX25519KeyPair.m",
    "content": "//\n//  TORX25519KeyPair.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 11.10.21.\n//\n\n#import \"TORX25519KeyPair.h\"\n#import <lib/malloc/malloc.h>\n#import <lib/crypt_ops/crypto_curve25519.h>\n#import <lib/encoding/binascii.h>\n\n\n@implementation TORX25519KeyPair\n\n\n- (instancetype)init\n{\n    if ((self = [super init]))\n    {\n        curve25519_keypair_t *keypair = tor_malloc_zero(sizeof(curve25519_keypair_t));\n\n        curve25519_init();\n\n        curve25519_keypair_generate(keypair, 0);\n\n        _privateKey = [TORX25519KeyPair base32Encode:[\n            NSData dataWithBytes:keypair->seckey.secret_key\n            length:sizeof(keypair->seckey.secret_key)]];\n\n        _publicKey = [TORX25519KeyPair base32Encode:[\n            NSData dataWithBytes:keypair->pubkey.public_key\n            length:sizeof(keypair->pubkey.public_key)]];\n\n        tor_free(keypair);\n    }\n\n    return self;\n}\n\n- (instancetype)initWithBase32PrivateKey:(NSString *)privateKey andPublicKey:(NSString *)publicKey\n{\n    if ((self = [super init]))\n    {\n        _privateKey = privateKey;\n        _publicKey = publicKey;\n    }\n\n    return self;\n}\n\n- (instancetype)initWithPrivateKey:(NSData *)privateKey andPublicKey:(NSData *)publicKey\n{\n    if ((self = [super init]))\n    {\n        _privateKey = [TORX25519KeyPair base32Encode:privateKey];\n        _publicKey = [TORX25519KeyPair base32Encode:publicKey];\n    }\n\n    return self;\n}\n\n\n// MARK: Public Methods\n\n- (nullable TORAuthKey *)getPrivateAuthKeyForDomain:(nonnull NSString *)domain\n{\n    if (domain.length < 1) return nil;\n\n    NSURLComponents *urlc = [NSURLComponents new];\n    urlc.scheme = @\"http\";\n    urlc.host = domain;\n\n    NSURL *url = urlc.URL;\n    if (!url) return nil;\n\n    return [self getPrivateAuthKeyForUrl:url];\n}\n\n- (nullable TORAuthKey *)getPrivateAuthKeyForUrl:(nonnull NSURL *)url\n{\n    NSString *privateKey = _privateKey;\n    if (!privateKey) return nil;\n\n    return [[TORAuthKey alloc] initPrivate:privateKey forDomain:url];\n}\n\n- (nullable TORAuthKey *)getPublicAuthKeyWithName:(nonnull NSString *)name\n{\n    NSString *publicKey = _publicKey;\n    if (!publicKey) return nil;\n\n    if (name.length < 1) return nil;\n\n    return [[TORAuthKey alloc] initPublic:publicKey withName:name];\n}\n\n\n// MARK: Public Class Methods\n\n+ (nullable NSString *)base32Encode:(NSData *)raw\n{\n    char dest[base32_encoded_size(raw.length)];\n\n    base32_encode(dest, sizeof(dest), raw.bytes, raw.length);\n\n    return [NSString stringWithUTF8String:dest];\n}\n\n+ (nullable NSData *)base32Decode:(NSString *)encoded\n{\n    const char *src = [encoded cStringUsingEncoding:kCFStringEncodingUTF8];\n\n    char dest[sizeof(src) * 5 / 8];\n\n    base32_decode(dest, sizeof(dest), src, sizeof(src));\n\n    return [NSData dataWithBytes:dest length:sizeof(dest)];\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/NSBundle+GeoIP.h",
    "content": "//\n//  NSBundle+GeoIP.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 02.12.21.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSBundle (GeoIP)\n\n@property (class, readonly, nullable) NSBundle *geoIpBundle;\n@property (readonly, nullable) NSURL *geoipFile;\n@property (readonly, nullable) NSURL *geoip6File;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/NSBundle+GeoIP.m",
    "content": "//\n//  NSBundle+GeoIP.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 02.12.21.\n//\n\n#import \"NSBundle+GeoIP.h\"\n#import \"TORConfiguration.h\"\n\n@implementation NSBundle (GeoIP)\n\n+ (NSBundle *)geoIpBundle\n{\n    NSURL *url = [[NSBundle bundleForClass:TORConfiguration.class] URLForResource:@\"GeoIP\" withExtension:@\"bundle\"];\n    if (!url) return nil;\n\n    return [NSBundle bundleWithURL:url];\n}\n\n- (NSURL *)geoipFile\n{\n    return [self URLForResource:@\"geoip\" withExtension:nil];\n}\n\n- (NSURL *)geoip6File\n{\n    return [self URLForResource:@\"geoip6\" withExtension:nil];\n}\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/NSCharacterSet+PredefinedSets.h",
    "content": "//\n//  NSCharacterSet+PredefinedSets.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 12.12.19.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface NSCharacterSet (PredefinedSets)\n\n@property (class, readonly) NSCharacterSet *doubleQuote;\n@property (class, readonly) NSCharacterSet *longNameDivider;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/NSCharacterSet+PredefinedSets.m",
    "content": "//\n//  NSCharacterSet+Quotes.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 12.12.19.\n//\n\n#import \"NSCharacterSet+PredefinedSets.h\"\n\n@implementation NSCharacterSet (PredefinedSets)\n\nstatic NSCharacterSet *_doubleQuote;\nstatic NSCharacterSet *_longNameDivider;\n\n+ (NSCharacterSet *)doubleQuote\n{\n    if (!_doubleQuote)\n    {\n        _doubleQuote = [NSCharacterSet characterSetWithCharactersInString:@\"\\\"\"];\n    }\n\n    return _doubleQuote;\n}\n\n+ (NSCharacterSet *)longNameDivider\n{\n    if (!_longNameDivider)\n    {\n        _longNameDivider = [NSCharacterSet characterSetWithCharactersInString:@\"~=\"];\n    }\n\n    return _longNameDivider;\n}\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/TORAuthKey.h",
    "content": "//\n//  TORAuthKey.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 29.09.21.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n The representation of one private or public v3 onion service authentication key.\n */\nNS_SWIFT_NAME(TorAuthKey)\n@interface TORAuthKey : NSObject\n\n/**\n The location on disk, where this data was read from/will be written to.\n */\n@property (nonatomic, readonly, nonnull) NSURL *file;\n\n/**\n Flag, if this is a private (\\c YES) or a public (\\c NO) key.\n */\n@property (atomic, readonly) BOOL isPrivate;\n\n/**\n The full  onion service URL.\n */\n@property (nonatomic, readonly, nullable) NSURL *onionAddress;\n\n/**\n The authentication type.\n\nCurrently only the \\c descriptor type is supported. This class will set this value hard for you.\n */\n@property (nonatomic, readonly, nonnull) NSString *authType;\n\n/**\n The key type.\n\n Currently only \\c x25519 is supported. This class will set this value hard for you.\n Make sure, that the key you provide actually is of that type!\n */\n@property (nonatomic, readonly, nonnull) NSString *keyType;\n\n/**\n The actual public OR private key.\n\n This class doesn't enforce it, but Tor wants this to be in a BASE32 encoded format.\n\n Make sure, it is of the type \\c x25519, as this is currently the only supported type by Tor and by this class!\n */\n@property (nonatomic, readonly, nonnull) NSString *key;\n\n\n/**\n Load from a key file on disk.\n\n See https://2019.www.torproject.org/docs/tor-manual.html.en#ClientOnionAuthDir\n and https://2019.www.torproject.org/docs/tor-manual.html.en#_client_authorization\n for the expected format.\n\n @param url The URL to the file containing the key. Expected to be in the correct format.\n */\n- (instancetype)initFromUrl:(NSURL *)url;\n\n/**\n Load from a key file on disk.\n\n See https://2019.www.torproject.org/docs/tor-manual.html.en#ClientOnionAuthDir\n and https://2019.www.torproject.org/docs/tor-manual.html.en#_client_authorization\n for the expected format.\n\n @param path The path to the file containing the key. Expected to be in the correct format.\n */\n- (instancetype)initFromFile:(NSString *)path;\n\n/**\n Create a new private key for a given domain.\n\n Normally, the domain will be used as file name, but this method will generate a UUID, if no domain can be found.\n\n @param key A \\c BASE32 encoded \\c x25519 private key.\n @param url A URL containing the v3 onion service domain for which this key is.\n */\n- (instancetype)initPrivate:(NSString * _Nonnull)key forDomain:(NSURL * _Nonnull)url;\n\n/**\n Create a new public key with the given name.\n\n The name wil be used as the file name.\n\n @param key A \\c BASE32 encoded \\c x25519 public key.\n @param name A name to identify this key to be used as the file name.\n */\n- (instancetype)initPublic:(NSString * _Nonnull)key withName: (NSString *)name;\n\n\n/**\n Set the base directory for the key.\n\n This needs to be called \\b before \\c persist, if you created a fresh key.\n\n @param directory The base directory where this key should be persisted.\n\n @see -persist\n */\n- (void)setDirectory:(NSURL *)directory;\n\n/**\n Persists this key to the file system.\n\n Call \\c setDirectory:, if this instance wasn't created by reading a key from a file!\n\n @returns \\c YES on success, \\c NO on failure.\n\n @see -setDirectory:\n */\n- (BOOL)persist;\n\n/**\n Keys are considered equal, if their file URLs match.\n */\n- (BOOL)isEqualToAuthKey:(TORAuthKey *)authKey;\n\n\n/**\n Checks, if the given file name has the correct extension for either a private or public key.\n\n @param url A file URL to a key file.\n\n @returns \\c YES, if this URL contains a key file extension.\n */\n+ (BOOL)isAuthFile:(NSURL *)url;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORAuthKey.m",
    "content": "//\n//  TORAuthKey.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 29.09.21.\n//\n\n#import \"TORAuthKey.h\"\n\n@implementation TORAuthKey\n\n- (instancetype)initFromUrl:(NSURL *)url\n{\n    if ((self = [super init]))\n    {\n        NSError *error;\n        NSString *raw = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:&error];\n\n        if (error)\n        {\n            NSLog(@\"[%@] Error while setting key: %@\", NSStringFromClass(self.class), error.localizedDescription);\n\n            return nil;\n        }\n\n        _file = url;\n\n        NSMutableArray *parts = [raw componentsSeparatedByString:@\":\"].mutableCopy;\n\n        NSString *piece = [TORAuthKey getNextPieceOf:parts];\n        if (!piece) return nil;\n\n        if (self.isPrivate) {\n            _onionAddress = [[NSURL alloc] initWithString:[NSString stringWithFormat:@\"http://%@.onion\", piece]];\n\n            piece = [TORAuthKey getNextPieceOf:parts];\n            if (!piece) return nil;\n        }\n\n        _authType = piece;\n\n        piece = [TORAuthKey getNextPieceOf:parts];\n        if (!piece) return nil;\n        _keyType = piece;\n\n        piece = [TORAuthKey getNextPieceOf:parts];\n        if (!piece) return nil;\n        _key = piece;\n    }\n\n    return self;\n}\n\n- (instancetype)initFromFile:(NSString *)path\n{\n    return [self initFromUrl:[NSURL fileURLWithPath:path]];\n}\n\n- (instancetype)initPrivate:(NSString * _Nonnull)key forDomain:(NSURL * _Nonnull)url\n{\n    if ((self = [super init]))\n    {\n        NSString *name = url.host.stringByDeletingPathExtension;\n\n        if (!name || [name isEqualToString:@\"\"]) name = [NSUUID UUID].UUIDString;\n\n        _file = [[NSURL alloc] initFileURLWithPath:[NSString stringWithFormat:@\"%@.auth_private\", name]];\n        _onionAddress = url;\n        _authType = @\"descriptor\"; // Currently the only allowed value.\n        _keyType = @\"x25519\"; // Currently the only allowed value.\n        _key = key;\n    }\n\n    return self;\n}\n\n- (instancetype)initPublic:(NSString * _Nonnull)key withName: (NSString * _Nonnull)name\n{\n    if ((self = [super init]))\n    {\n        if (!name || [name isEqualToString:@\"\"]) name = [NSUUID UUID].UUIDString;\n\n        _file = [[NSURL alloc] initFileURLWithPath:[NSString stringWithFormat:@\"%@.auth\", name]];\n        _onionAddress = nil;\n        _authType = @\"descriptor\"; // Currently the only allowed value.\n        _keyType = @\"x25519\"; // Currently the only allowed value.\n        _key = key;\n    }\n    \n    return self;\n}\n\n\n// MARK: Public Methods\n\n- (BOOL)isPrivate\n{\n    return [_file.pathExtension isEqualToString:@\"auth_private\"];\n}\n\n- (void)setDirectory:(NSURL *)directory\n{\n    NSString *filename = _file.lastPathComponent;\n\n    if (filename)\n    {\n        NSURL *file = [directory URLByAppendingPathComponent:filename];\n\n        if (file) _file = file;\n    }\n}\n\n- (BOOL)persist\n{\n    NSError *error;\n    [self.description writeToURL:_file atomically:YES encoding:NSUTF8StringEncoding error:&error];\n\n    if (error)\n    {\n        NSLog(@\"[%@] Error while persisting key: %@\", NSStringFromClass(self.class), error.localizedDescription);\n        NSLog(@\"%@\", self.debugDescription);\n\n        return NO;\n    }\n\n    return YES;\n}\n\n\n- (NSString *)description\n{\n    if (self.isPrivate) {\n        // Spec says: \"MUST NOT have the \".onion\" suffix.\n\n        return [NSString stringWithFormat:@\"%@:%@:%@:%@\",\n                _onionAddress.host.stringByDeletingPathExtension,\n                _authType, _keyType, _key];\n    }\n\n    return [NSString stringWithFormat:@\"%@:%@:%@\", _authType, _keyType, _key];\n}\n\n- (NSString *)debugDescription\n{\n    return [NSString stringWithFormat:@\"%@: file: %@, isPrivate: %d, onionAddress: %@, authType: %@, keyType: %@, key: %@\",\n            NSStringFromClass(self.class), _file, self.isPrivate, _onionAddress, _authType, _keyType, _key];\n}\n\n\n// MARK: Equality\n\n- (BOOL)isEqualToAuthKey:(TORAuthKey *)authKey\n{\n    NSString *url2 = authKey.file.absoluteString;\n\n    if (!url2)\n    {\n        return NO;\n    }\n\n    return [_file.absoluteString isEqualToString:url2];\n}\n\n- (BOOL)isEqual:(id)object\n{\n    if (self == object)\n    {\n        return YES;\n    }\n\n    if (![object isKindOfClass:[TORAuthKey class]])\n    {\n        return NO;\n    }\n\n    return [self isEqualToAuthKey:object];\n}\n\n- (NSUInteger)hash\n{\n    return _file.hash;\n}\n\n\n// MARK: Class Methods\n\n+ (BOOL)isAuthFile:(NSURL *)url\n{\n    return [url.pathExtension isEqualToString:@\"auth\"] || [url.pathExtension isEqualToString:@\"auth_private\"];\n}\n\n\n// MARK: Private Methods\n\n+ (NSString *)getNextPieceOf:(NSMutableArray *)parts\n{\n    NSString *piece = parts.firstObject;\n\n    if (parts.count > 0) [parts removeObjectAtIndex: 0];\n\n    if (!piece) NSLog(@\"Invalid format of auth key file!\");\n\n    return piece;\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/TORCircuit.h",
    "content": "//\n//  TORCircuit.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 11.12.19.\n//\n//  Documentation this class is modelled after:\n\n//  https://gitlab.torproject.org/tpo/core/torspec/-/raw/main/control-spec.txt\n//  Chapter 4.1.1 Circuit status changed\n\n#import <Foundation/Foundation.h>\n#import \"TORNode.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\nNS_SWIFT_NAME(TorCircuit)\n@interface TORCircuit : NSObject<NSSecureCoding>\n\n/**\n Regular expression to identify and extract ID, status and circuit path consisting of \"LongNames\".\n\n Syntax of node \"LongNames\":\n https://torproject.gitlab.io/torspec/control-spec.html#general-use-tokens\n */\n@property (class, readonly) NSRegularExpression *mainInfoRegex;\n\n/**\n - Tag: statusLaunched\n Circuit ID assigned to new circuit.\n */\n@property (class, readonly) NSString *statusLaunched;\n\n/**\n All hops finished, can now accept streams.\n */\n@property (class, readonly) NSString *statusBuilt;\n\n/**\n All hops finished, waiting to see if a circuit with a better guard will be usable.\n */\n@property (class, readonly) NSString *statusGuardWait;\n\n/**\n One more hop has been completed.\n */\n@property (class, readonly) NSString *statusExtended;\n\n/**\n Circuit closed (was not built).\n */\n@property (class, readonly) NSString *statusFailed;\n\n/**\n Circuit closed (was built).\n */\n@property (class, readonly) NSString *statusClosed;\n\n/**\n One-hop circuit, used for tunneled directory conns.\n */\n@property (class, readonly) NSString *buildFlagOneHopTunnel;\n\n/**\n Internal circuit, not to be used for exiting streams.\n */\n@property (class, readonly) NSString *buildFlagIsInternal;\n\n/**\n This circuit must use only high-capacity nodes.\n */\n@property (class, readonly) NSString *buildFlagNeedCapacity;\n\n/**\n This circuit must use only high-uptime nodes.\n */\n@property (class, readonly) NSString *buildFlagNeedUptime;\n\n/**\n Circuit for AP and/or directory request streams.\n */\n@property (class, readonly) NSString *purposeGeneral;\n\n/**\n HS client-side introduction-point circuit.\n */\n@property (class, readonly) NSString *purposeHsClientIntro;\n\n/**\n HS client-side rendezvous circuit; carries AP streams.\n */\n@property (class, readonly) NSString *purposeHsClientRend;\n\n/**\n HS service-side introduction-point circuit.\n */\n@property (class, readonly) NSString *purposeHsServiceIntro;\n\n/**\n HS service-side rendezvous circuit.\n */\n@property (class, readonly) NSString *purposeHsServiceRend;\n\n/**\n Circuit created ahead of time when using HS vanguards, and later repurposed as needed.\n */\n@property (class, readonly) NSString *purposeHsVanguards;\n\n/**\n Reachability-testing circuit; carries no traffic.\n */\n@property (class, readonly) NSString *purposeTesting;\n\n/**\n Circuit built by a controller.\n */\n@property (class, readonly) NSString *purposeController;\n\n/**\n Circuit being kept around to see how long it takes.\n */\n@property (class, readonly) NSString *purposeMeasureTimeout;\n\n/**\n Circuit is part of a conflux multi-path circuit set.\n\n https://tpo.pages.torproject.net/core/doc/tor/structcircuit__t.html#a7826adee26af5def133c43d2fe5f83fa\n */\n@property (class, readonly) NSString *purposeConfluxLinked;\n\n/**\n Circuit is in the pending pool usable in future circuit sets.\n\n https://tpo.pages.torproject.net/core/doc/tor/structcircuit__t.html#acabcbac5225591a5b7731a6994f438e4\n */\n@property (class, readonly) NSString *purposeConfluxUnlinked;\n\n/**\n Client-side introduction-point circuit state: Connecting to intro point.\n */\n@property (class, readonly) NSString *hsStateHsciConnecting;\n\n/**\n Client-side introduction-point circuit state: Sent INTRODUCE1; waiting for reply from IP.\n */\n@property (class, readonly) NSString *hsStateHsciIntroSent;\n\n/**\n Client-side introduction-point circuit state: Received reply from IP relay; closing.\n */\n@property (class, readonly) NSString *hsStateHsciDone;\n\n/**\n Client-side rendezvous-point circuit state: Connecting to or waiting for reply from RP.\n */\n@property (class, readonly) NSString *hsStateHscrConnecting;\n\n/**\n Client-side rendezvous-point circuit state: Established RP; waiting for introduction.\n */\n@property (class, readonly) NSString *hsStateHscrEstablishedIdle;\n\n/**\n Client-side rendezvous-point circuit state: Introduction sent to HS; waiting for rend.\n */\n@property (class, readonly) NSString *hsStateHscrEstablishedWaiting;\n\n/**\nClient-side rendezvous-point circuit state: Connected to HS.\n*/\n@property (class, readonly) NSString *hsStateHscrJoined;\n\n/**\n Service-side introduction-point circuit state: Connecting to intro point.\n */\n@property (class, readonly) NSString *hsStateHssiConnecting;\n\n/**\n Service-side introduction-point circuit state: Established intro point.\n */\n@property (class, readonly) NSString *hsStateHssiEstablished;\n\n/**\n Service-side rendezvous-point circuit state: Connecting to client's rend point.\n */\n@property (class, readonly) NSString *hsStateHssrConnecting;\n\n/**\n Service-side rendezvous-point circuit state: Connected to client's RP circuit.\n */\n@property (class, readonly) NSString *hsStateHssrJoined;\n\n/**\n No reason given.\n */\n@property (class, readonly) NSString *reasonNone;\n\n/**\n Tor protocol violation.\n */\n@property (class, readonly) NSString *reasonTorProtocol;\n\n/**\n Internal error.\n */\n@property (class, readonly) NSString *reasonInternal;\n\n/**\n A client sent a TRUNCATE command.\n */\n@property (class, readonly) NSString *reasonRequested;\n\n/**\n Not currently operating; trying to save bandwidth.\n */\n@property (class, readonly) NSString *reasonHibernating;\n\n/**\n Out of memory, sockets, or circuit IDs.\n */\n@property (class, readonly) NSString *reasonResourceLimit;\n\n/**\n Unable to reach relay.\n */\n@property (class, readonly) NSString *reasonConnectFailed;\n\n/**\n Connected to relay, but its OR identity was not as expected.\n */\n@property (class, readonly) NSString *reasonOrIdentity;\n\n/**\n The OR connection that was carrying this circuit died.\n */\n@property (class, readonly) NSString *reasonOrConnClosed;\n\n/**\n Circuit construction took too long.\n */\n@property (class, readonly) NSString *reasonTimeout;\n\n/**\n The circuit has expired for being dirty or old.\n */\n@property (class, readonly) NSString *reasonFinished;\n\n/**\n The circuit was destroyed w/o client TRUNCATE.\n */\n@property (class, readonly) NSString *reasonDestroyed;\n\n/**\n Not enough nodes to make circuit.\n */\n@property (class, readonly) NSString *reasonNoPath;\n\n/**\n Request for unknown hidden service.\n */\n@property (class, readonly) NSString *reasonNoSuchService;\n\n/**\n As @c reasonTimeout, except that we had left the circuit open for measurement purposes to see how long it would take to finish.\n */\n@property (class, readonly) NSString *reasonMeasurementExpired;\n\n\n/**\n The raw data this object is constructed from. The unchanged argument from @c initFromString:.\n */\n@property (readonly, nullable) NSString *raw;\n\n/**\nThe circuit ID. Currently only numbers beginning with \"1\" but Tor spec says, that could change.\n */\n@property (readonly, nullable) NSString *circuitId;\n\n/**\n The circuit status. Should be one of @c statusLaunched, @c statusBuilt, @c statusGuardWait,\n @c statusExtended, @c statusFailed or @c statusClosed .\n */\n@property (readonly, nullable) NSString *status;\n\n/**\n The circuit path as a list of @c TORNode objects.\n */\n@property (readonly, nullable) NSArray<TORNode *> *nodes;\n\n/**\n Build flags of the circuit. Can be any of @c buildFlagOneHopTunnel, @c buildFlagIsInternal,\n @c buildFlagNeedCapacity, @c buildFlagNeedUptime  or a flag which was unknown at the time of\n writing of this class.\n*/\n@property (readonly, nullable) NSArray<NSString *> *buildFlags;\n\n/**\n Circuit purpose. May be one of @c purposeGeneral, @c purposeHsClientIntro,\n @c purposeHsClientRend, @c purposeHsServiceIntro, @c purposeHsServiceRend,\n @c purposeTesting, @c purposeController or, @c purposeMeasureTimeout.\n */\n@property (readonly, nullable) NSString *purpose;\n\n/**\n Circuit hidden service state. May be one of @c hsStateHsciConnecting, @c hsStateHsciIntroSent,\n @c hsStateHsciDone, @c hsStateHscrConnecting, @c hsStateHscrEstablishedIdle,\n @c hsStateHscrEstablishedWaiting, @c hsStateHscrJoined, @c hsStateHssiConnecting,\n @c hsStateHssiEstablished, @c hsStateHssrConnecting, @c hsStateHssrJoined\n or a state which was unknown at the time of writing of this class.\n */\n@property (readonly, nullable) NSString *hsState;\n\n/**\n The rendevouz query.\n\n Should be equal the onion address this circuit was used for minus the @c .onion postfix.\n */\n@property (readonly, nullable) NSString *rendQuery;\n\n/**\n The circuit's  timestamp at which the circuit was created or cannibalized.\n */\n@property (readonly, nullable) NSDate *timeCreated;\n\n/**\n The @c reason field is provided only for @c FAILED and @c CLOSED  events, and only if\n extended events are enabled.\n\n May be any one of @c reasonNone, @c reasonTorProtocol, @c reasonInternal,\n @c reasonRequested, @c reasonHibernating, @c reasonResourceLimit,\n @c reasonConnectFailed, @c reasonOrIdentity, @c reasonOrConnClosed,\n @c reasonTimeout, @c reasonFinished, @c reasonDestroyed, @c reasonNoPath,\n @c reasonNoSuchService, @c reasonMeasurementExpired  or a reason which was unknown at the\n time of writing of this class.\n */\n@property (readonly, nullable) NSString *reason;\n\n/**\n The @c remoteReason field is provided only when we receive a @c DESTROY or @c TRUNCATE cell, and\n only if extended events are enabled. It contains the actual reason given by the remote OR for closing the circuit.\n\n May be any one of @c reasonNone, @c reasonTorProtocol, @c reasonInternal,\n @c reasonRequested, @c reasonHibernating, @c reasonResourceLimit,\n @c reasonConnectFailed, @c reasonOrIdentity, @c reasonOrConnClosed,\n @c reasonTimeout, @c reasonFinished, @c reasonDestroyed, @c reasonNoPath,\n @c reasonNoSuchService, @c reasonMeasurementExpired  or a reason which was unknown at the\n time of writing of this class.\n */\n@property (readonly, nullable) NSString *remoteReason;\n\n/**\n The @c socksUsername and @c socksPassword fields indicate the credentials that were used by a\n SOCKS client to connect to Tor’s SOCKS port and initiate this circuit.\n */\n@property (readonly, nullable) NSString *socksUsername;\n\n/**\nThe @c socksUsername and @c socksPassword fields indicate the credentials that were used by a\nSOCKS client to connect to Tor’s SOCKS port and initiate this circuit.\n*/\n@property (readonly, nullable) NSString *socksPassword;\n\n\n/**\nExtracts all circuit info from a string which should be the response to a \"GETINFO circuit-status\".\n\nSee https://torproject.gitlab.io/torspec/control-spec.html#getinfo\n\n@param circuitsString A string as returned by \"GETINFO circuit-status\".\n*/\n+ (NSArray<TORCircuit *> *)circuitsFromString:(NSString *)circuitsString;\n\n\n- (instancetype)initFromString:(NSString *)circuitString;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORCircuit.m",
    "content": "//\n//  TORCircuit.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 11.12.19.\n//\n\n#import \"TORCircuit.h\"\n#import \"NSCharacterSet+PredefinedSets.h\"\n\n@implementation TORCircuit\n\n\n// MARK: Class Properties\n\nstatic NSRegularExpression *_mainInfoRegex;\nstatic NSMutableDictionary<NSString *, NSRegularExpression *> *_optionsRegexes;\nstatic NSDateFormatter *_timestampFormatter;\n\n+ (NSRegularExpression *)mainInfoRegex\n{\n    if (!_mainInfoRegex)\n    {\n        _mainInfoRegex =\n        [NSRegularExpression\n         regularExpressionWithPattern:\n         @\"(\\\\w+)\\\\s+(LAUNCHED|BUILT|GUARD_WAIT|EXTENDED|FAILED|CLOSED)\\\\s+((?:\\\\$[\\\\da-f]+[=~]\\\\w+(?:,|\\\\s|\\\\Z))+)?\"\n         options:NSRegularExpressionCaseInsensitive error:nil];\n    }\n\n    return _mainInfoRegex;\n}\n\n+ (NSString *)statusLaunched\n{\n    return @\"LAUNCHED\";\n}\n\n+ (NSString *)statusBuilt\n{\n    return @\"BUILT\";\n}\n\n+ (NSString *)statusGuardWait\n{\n    return @\"GUARD_WAIT\";\n}\n\n+ (NSString *)statusExtended\n{\n    return @\"EXTENDED\";\n}\n\n+ (NSString *)statusFailed\n{\n    return @\"FAILED\";\n}\n\n+ (NSString *)statusClosed\n{\n    return @\"CLOSED\";\n}\n\n+ (NSString *)buildFlagOneHopTunnel\n{\n    return @\"ONEHOP_TUNNEL\";\n}\n\n+ (NSString *)buildFlagIsInternal\n{\n    return @\"IS_INTERNAL\";\n}\n\n+ (NSString *)buildFlagNeedCapacity\n{\n    return @\"NEED_CAPACITY\";\n}\n\n+ (NSString *)buildFlagNeedUptime\n{\n    return @\"NEED_UPTIME\";\n}\n\n+ (NSString *)purposeGeneral\n{\n    return @\"GENERAL\";\n}\n\n+ (NSString *)purposeHsClientIntro\n{\n    return @\"HS_CLIENT_INTRO\";\n}\n\n+ (NSString *)purposeHsClientRend\n{\n    return @\"HS_CLIENT_REND\";\n}\n\n+ (NSString *)purposeHsServiceIntro\n{\n    return @\"HS_SERVICE_INTRO\";\n}\n\n+ (NSString *)purposeHsServiceRend\n{\n    return @\"HS_SERVICE_REND\";\n}\n\n+ (NSString *)purposeHsVanguards\n{\n    return @\"HS_VANGUARDS\";\n}\n\n+ (NSString *)purposeTesting\n{\n    return @\"TESTING\";\n}\n\n+ (NSString *)purposeController\n{\n    return @\"CONTROLLER\";\n}\n\n+ (NSString *)purposeMeasureTimeout\n{\n    return @\"MEASURE_TIMEOUT\";\n}\n\n+ (NSString *)purposeConfluxLinked\n{\n    return @\"CONFLUX_LINKED\";\n}\n\n+ (NSString *)purposeConfluxUnlinked\n{\n    return @\"CONFLUX_UNLINKED\";\n}\n\n+ (NSString *)hsStateHsciConnecting\n{\n    return @\"HSCI_CONNECTING\";\n}\n\n+ (NSString *)hsStateHsciIntroSent\n{\n    return @\"HSCI_INTRO_SENT\";\n}\n\n+ (NSString *)hsStateHsciDone\n{\n    return @\"HSCI_DONE\";\n}\n\n+ (NSString *)hsStateHscrConnecting\n{\n    return @\"HSCR_CONNECTING\";\n}\n\n+ (NSString *)hsStateHscrEstablishedIdle\n{\n    return @\"HSCR_ESTABLISHED_IDLE\";\n}\n\n+ (NSString *)hsStateHscrEstablishedWaiting\n{\n    return @\"HSCR_ESTABLISHED_WAITING\";\n}\n\n+ (NSString *)hsStateHscrJoined\n{\n    return @\"HSCR_JOINED\";\n}\n\n+ (NSString *)hsStateHssiConnecting\n{\n    return @\"HSSI_CONNECTING\";\n}\n\n+ (NSString *)hsStateHssiEstablished\n{\n    return @\"HSSI_ESTABLISHED\";\n}\n\n+ (NSString *)hsStateHssrConnecting\n{\n    return @\"HSSR_CONNECTING\";\n}\n\n+ (NSString *)hsStateHssrJoined\n{\n    return @\"HSSR_JOINED\";\n}\n\n+ (NSString *)reasonNone\n{\n    return @\"NONE\";\n}\n\n+ (NSString *)reasonTorProtocol\n{\n    return @\"TORPROTOCOL\";\n}\n\n+ (NSString *)reasonInternal\n{\n    return @\"INTERNAL\";\n}\n\n+ (NSString *)reasonRequested\n{\n    return @\"REQUESTED\";\n}\n\n+ (NSString *)reasonHibernating\n{\n    return @\"HIBERNATING\";\n}\n\n+ (NSString *)reasonResourceLimit\n{\n    return @\"RESOURCELIMIT\";\n}\n\n+ (NSString *)reasonConnectFailed\n{\n    return @\"CONNECTFAILED\";\n}\n\n+ (NSString *)reasonOrIdentity\n{\n    return @\"OR_IDENTITY\";\n}\n\n+ (NSString *)reasonOrConnClosed\n{\n    return @\"OR_CONN_CLOSED\";\n}\n\n+ (NSString *)reasonTimeout\n{\n    return @\"TIMEOUT\";\n}\n\n+ (NSString *)reasonFinished\n{\n    return @\"FINISHED\";\n}\n\n+ (NSString *)reasonDestroyed\n{\n    return @\"DESTROYED\";\n}\n\n+ (NSString *)reasonNoPath\n{\n    return @\"NOPATH\";\n}\n\n+ (NSString *)reasonNoSuchService\n{\n    return @\"NOSUCHSERVICE\";\n}\n\n+ (NSString *)reasonMeasurementExpired\n{\n    return @\"MEASUREMENT_EXPIRED\";\n}\n\n\n// MARK: Class Methods\n\n+ (NSRegularExpression *)regexForOption:(NSString *)option\n{\n    if (!_optionsRegexes)\n    {\n        _optionsRegexes = [NSMutableDictionary new];\n    }\n\n    if (!_optionsRegexes[option])\n    {\n        _optionsRegexes[option] =\n        [NSRegularExpression\n         regularExpressionWithPattern:[NSString stringWithFormat:@\"(?:%@=(.+?)(?:\\\\s|\\\\Z))\", option]\n         options:NSRegularExpressionCaseInsensitive error:nil];\n    }\n\n    return _optionsRegexes[option];\n}\n\n+ (NSDateFormatter *)timestampFormatter\n{\n    if (!_timestampFormatter)\n    {\n        _timestampFormatter = [NSDateFormatter new];\n        _timestampFormatter.dateFormat = @\"yyyy-MM-dd'T'HH:mm:ss.SSSSSS\";\n        _timestampFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@\"en_US_POSIX\"];\n        _timestampFormatter.timeZone = [NSTimeZone timeZoneWithName:@\"UTC\"];\n    }\n\n    return _timestampFormatter;\n}\n\n+ (NSArray<TORCircuit *> *)circuitsFromString:(NSString *)circuitsString\n{\n    NSMutableArray<TORCircuit *> *circuits = [NSMutableArray new];\n\n    for (NSString *circuitString in [circuitsString componentsSeparatedByString:@\"\\r\\n\"]) {\n        if (circuitString.length > 0)\n        {\n            [circuits addObject:\n             [[TORCircuit alloc] initFromString:circuitString]];\n        }\n    }\n\n    return circuits;\n}\n\n\n// MARK: Initializers\n\n- (instancetype)initFromString:(NSString *)circuitString\n{\n    self = [super init];\n\n    if (self)\n    {\n        _raw = circuitString;\n\n        NSRange range = NSMakeRange(0, circuitString.length);\n\n        NSTextCheckingResult *match = [TORCircuit.mainInfoRegex\n                                                    matchesInString:circuitString options:0\n                                                    range:range].firstObject;\n        \n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _circuitId = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n        \n        if (match && [match rangeAtIndex:2].location != NSNotFound)\n        {\n            _status = [circuitString substringWithRange:[match rangeAtIndex:2]];\n        }\n        \n        if (match && [match rangeAtIndex:3].location != NSNotFound)\n        {\n            NSMutableArray<TORNode *> *nodes = [NSMutableArray new];\n            \n            NSString *path = [circuitString substringWithRange:[match rangeAtIndex:3]];\n\n            NSArray<NSString *> *nodesStrings = [path componentsSeparatedByString:@\",\"];\n\n            for (NSString *nodeString in nodesStrings)\n            {\n                [nodes addObject:\n                [[TORNode alloc] initFromString:\n                    [nodeString stringByTrimmingCharactersInSet:NSCharacterSet.whitespaceCharacterSet]]];\n            }\n\n            _nodes = nodes;\n        }\n        \n        match = [[TORCircuit regexForOption:@\"BUILD_FLAGS\"]\n                   matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _buildFlags = [[circuitString substringWithRange:[match rangeAtIndex:1]]\n                           componentsSeparatedByString:@\",\"];\n        }\n\n        match = [[TORCircuit regexForOption:@\"PURPOSE\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _purpose = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"HS_STATE\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _hsState = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"REND_QUERY\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _rendQuery = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"TIME_CREATED\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _timeCreated = [TORCircuit.timestampFormatter dateFromString:\n                            [circuitString substringWithRange:[match rangeAtIndex:1]]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"REASON\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _reason = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"REMOTE_REASON\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _remoteReason = [circuitString substringWithRange:[match rangeAtIndex:1]];\n        }\n\n        match = [[TORCircuit regexForOption:@\"SOCKS_USERNAME\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _socksUsername = [[circuitString substringWithRange:[match rangeAtIndex:1]]\n                              stringByTrimmingCharactersInSet:NSCharacterSet.doubleQuote];\n        }\n\n        match = [[TORCircuit regexForOption:@\"SOCKS_PASSWORD\"]\n                    matchesInString:circuitString options:0 range:range].firstObject;\n\n        if (match && [match rangeAtIndex:1].location != NSNotFound)\n        {\n            _socksPassword = [[circuitString substringWithRange:[match rangeAtIndex:1]]\n                              stringByTrimmingCharactersInSet:NSCharacterSet.doubleQuote];\n        }\n    }\n\n    return self;\n}\n\n\n// MARK: NSSecureCoding\n\n+ (BOOL)supportsSecureCoding\n{\n  return YES;\n}\n\n- (id)initWithCoder:(NSCoder *)coder\n{\n    if ((self = [super init]))\n    {\n        _raw = [coder decodeObjectOfClass:NSString.class forKey:@\"raw\"];\n        _circuitId = [coder decodeObjectOfClass:NSString.class forKey:@\"circuitId\"];\n        _status = [coder decodeObjectOfClass:NSString.class forKey:@\"status\"];\n        _nodes = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSArray.class, TORNode.class]] forKey:@\"nodes\"];\n        _buildFlags = [coder decodeObjectOfClasses:[NSSet setWithArray:@[NSArray.class, NSString.class]] forKey:@\"buildFlags\"];\n        _purpose = [coder decodeObjectOfClass:NSString.class forKey:@\"purpose\"];\n        _hsState = [coder decodeObjectOfClass:NSString.class forKey:@\"hsState\"];\n        _rendQuery = [coder decodeObjectOfClass:NSString.class forKey:@\"rendQuery\"];\n        _timeCreated = [coder decodeObjectOfClass:NSDate.class forKey:@\"timeCreated\"];\n        _reason = [coder decodeObjectOfClass:NSString.class forKey:@\"reason\"];\n        _remoteReason = [coder decodeObjectOfClass:NSString.class forKey:@\"remoteReason\"];\n        _socksUsername = [coder decodeObjectOfClass:NSString.class forKey:@\"socksUsername\"];\n        _socksPassword = [coder decodeObjectOfClass:NSString.class forKey:@\"socksPassword\"];\n    }\n\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder\n{\n    [coder encodeObject:self.raw forKey:@\"raw\"];\n    [coder encodeObject:self.circuitId forKey:@\"circuitId\"];\n    [coder encodeObject:self.status forKey:@\"status\"];\n    [coder encodeObject:self.nodes forKey:@\"nodes\"];\n    [coder encodeObject:self.buildFlags forKey:@\"buildFlags\"];\n    [coder encodeObject:self.purpose forKey:@\"purpose\"];\n    [coder encodeObject:self.hsState forKey:@\"hsState\"];\n    [coder encodeObject:self.rendQuery forKey:@\"rendQuery\"];\n    [coder encodeObject:self.timeCreated forKey:@\"timeCreated\"];\n    [coder encodeObject:self.reason forKey:@\"reason\"];\n    [coder encodeObject:self.remoteReason forKey:@\"remoteReason\"];\n    [coder encodeObject:self.socksUsername forKey:@\"socksUsername\"];\n    [coder encodeObject:self.socksPassword forKey:@\"socksPassword\"];\n}\n\n\n// MARK: NSObject\n\n- (NSString *)description\n{\n    return [NSString stringWithFormat:@\"<%@: %p> circuitId=%@, status=%@, nodes=%@, buildFlags=%@, purpose=%@, hsState=%@, rendQuery=%@, timeCreated=%@, reason=%@, remoteReason=%@, socksUsername=%@, socksPassword=%@, raw=%@]\",\n            self.class, self, self.circuitId, self.status, self.nodes, self.buildFlags,\n            self.purpose, self.hsState, self.rendQuery, self.timeCreated,\n            self.reason, self.remoteReason, self.socksUsername, self.socksPassword, self.raw];\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/TORConfiguration.h",
    "content": "//\n//  TORConfiguration.h\n//  Tor\n//\n//  Created by Conrad Kramer on 8/10/15.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nNS_SWIFT_NAME(TorConfiguration)\n@interface TORConfiguration : NSObject\n\n@property (nonatomic, copy, nullable) NSURL *dataDirectory;\n@property (nonatomic, copy, nullable) NSURL *cacheDirectory;\n@property (nonatomic, copy, nullable, readonly) NSURL *controlPortFile;\n@property (nonatomic, copy, nullable) NSURL *controlSocket;\n@property (nonatomic, copy, nullable) NSURL *socksURL;\n@property (nonatomic) NSUInteger socksPort;\n@property (nonatomic) NSUInteger dnsPort;\n@property (nonatomic, copy, nullable) NSURL *clientAuthDirectory;\n@property (nonatomic, copy, nullable) NSURL *hiddenServiceDirectory;\n@property (nonatomic, copy, nullable, readonly) NSURL *serviceAuthDirectory;\n@property (nonatomic, copy, nullable) NSURL *geoipFile;\n@property (nonatomic, copy, nullable) NSURL *geoip6File;\n@property (nonatomic, copy, nullable) NSURL *logfile;\n\n@property (nonatomic) BOOL ignoreMissingTorrc;\n@property (nonatomic) BOOL cookieAuthentication;\n@property (nonatomic) BOOL autoControlPort;\n@property (nonatomic) BOOL avoidDiskWrites;\n@property (nonatomic) BOOL clientOnly;\n\n@property (nonatomic, readonly) BOOL isLocked;\n@property (nonatomic, copy, nullable, readonly) NSData *cookie;\n\n@property (nonatomic, copy, null_resettable) NSMutableDictionary<NSString *, NSString *> *options;\n@property (nonatomic, copy, null_resettable) NSMutableArray<NSString *> *arguments;\n\n- (NSString *)valueOf:(NSString *)key;\n- (NSArray<NSString *> *)compile;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORConfiguration.m",
    "content": "//\n//  TORConfiguration.m\n//  Tor\n//\n//  Created by Conrad Kramer on 8/10/15.\n//\n\n#import \"TORConfiguration.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@implementation TORConfiguration\n\n- (NSMutableDictionary *)options\n{\n    if (!_options) _options = [NSMutableDictionary new];\n\n    return _options;\n}\n\n- (NSMutableArray *)arguments\n{\n    if (!_arguments) _arguments = [NSMutableArray new];\n    \n    return _arguments;\n}\n\n- (nullable NSURL *)controlPortFile\n{\n    return [self.dataDirectory URLByAppendingPathComponent:@\"controlport\"];\n}\n\n- (nullable NSURL *)serviceAuthDirectory\n{\n    return [self.hiddenServiceDirectory URLByAppendingPathComponent:@\"authorized_clients\"];\n}\n\n- (BOOL)isLocked\n{\n    NSURL *url = [self.dataDirectory URLByAppendingPathComponent:@\"lock\"];\n    NSString *path = url.path;\n\n    if (!path || !url.isFileURL) return false;\n\n    return [NSFileManager.defaultManager fileExistsAtPath:path];\n}\n\n- (nullable NSData *)cookie\n{\n    NSURL *url = [self.dataDirectory URLByAppendingPathComponent:@\"control_auth_cookie\"];\n\n    if (!url || !url.isFileURL) return nil;\n\n    return [[NSData alloc] initWithContentsOfURL:url];\n}\n\n- (NSString *)valueOf:(NSString *)key\n{\n    for (NSString *dictKey in self.options.allKeys) {\n        if ([dictKey caseInsensitiveCompare:key] == NSOrderedSame) {\n            return self.options[dictKey];\n        }\n    }\n\n    key = [[NSString alloc] initWithFormat:@\"--%@\", key];\n\n    for (NSString *arg in self.arguments) {\n        if ([arg caseInsensitiveCompare:key] == NSOrderedSame) {\n            NSUInteger i = [self.arguments indexOfObject:arg];\n\n            if (i + 1 < self.arguments.count) {\n                return self.arguments[i + 1];\n            }\n        }\n    }\n\n    return nil;\n}\n\n- (NSArray<NSString *> *)compile\n{\n    NSMutableArray<NSString *> *arguments = [NSMutableArray new];\n\n    if (self.ignoreMissingTorrc) {\n        [arguments addObjectsFromArray:@[@\"--allow-missing-torrc\", @\"--ignore-missing-torrc\"]];\n    }\n\n    if (self.avoidDiskWrites) {\n        [arguments addObjectsFromArray:@[@\"--AvoidDiskWrites\", @\"1\"]];\n    }\n\n    if (self.clientOnly) {\n        [arguments addObjectsFromArray:@[@\"--ClientOnly\", @\"1\"]];\n    }\n\n    NSString *dataDir = self.dataDirectory.path;\n    if (self.dataDirectory.isFileURL && dataDir) {\n        [arguments addObjectsFromArray:@[@\"--DataDirectory\", dataDir]];\n    }\n\n    NSString *cacheDir = self.cacheDirectory.path;\n    if (self.cacheDirectory.isFileURL && cacheDir) {\n        [arguments addObjectsFromArray:@[@\"--CacheDirectory\", cacheDir]];\n    }\n\n    if (self.cookieAuthentication) {\n        [arguments addObjectsFromArray:@[@\"--CookieAuthentication\", @\"1\"]];\n    }\n\n    NSString *controlPortFile = self.controlPortFile.path;\n    if (self.autoControlPort && self.controlPortFile.isFileURL && controlPortFile) {\n        [arguments addObjectsFromArray:@[@\"--ControlPort\", @\"auto\", @\"--ControlPortWriteToFile\", controlPortFile]];\n    }\n\n    NSString *controlSocket = self.controlSocket.path;\n    if (self.controlSocket.isFileURL && controlSocket) {\n        [arguments addObjectsFromArray:@[@\"--ControlSocket\", controlSocket]];\n    }\n\n    NSString *socksPath = self.socksURL.path;\n    if (self.socksURL.isFileURL && socksPath) {\n        [arguments addObjectsFromArray:@[@\"--SocksPort\", [NSString stringWithFormat:@\"unix:%@\", socksPath]]];\n    }\n\n    if (self.socksPort > 0) {\n        [arguments addObjectsFromArray:@[@\"--SocksPort\", [NSString stringWithFormat:@\"%lu\", (unsigned long)self.socksPort]]];\n    }\n\n    if (self.dnsPort > 0) {\n        [arguments addObjectsFromArray:@[@\"--DnsPort\", [NSString stringWithFormat:@\"%lu\", (unsigned long)self.dnsPort]]];\n    }\n\n    NSString *clientAuthDir = self.clientAuthDirectory.path;\n    if (self.clientAuthDirectory.isFileURL && clientAuthDir) {\n        [arguments addObjectsFromArray:@[@\"--ClientOnionAuthDir\", clientAuthDir]];\n    }\n\n    NSString *hiddenServiceDir = self.hiddenServiceDirectory.path;\n    if (!self.clientOnly && self.hiddenServiceDirectory.isFileURL && hiddenServiceDir) {\n        [arguments addObjectsFromArray:@[@\"--HiddenServiceDir\", hiddenServiceDir]];\n    }\n\n    NSString *geoipFile = self.geoipFile.path;\n    if (self.geoipFile.isFileURL && geoipFile) {\n        [arguments addObjectsFromArray:@[@\"--GeoIPFile\", geoipFile]];\n    }\n\n    NSString *geoip6File = self.geoip6File.path;\n    if (self.geoip6File.isFileURL && geoip6File) {\n        [arguments addObjectsFromArray:@[@\"--GeoIPv6File\", geoip6File]];\n    }\n\n    NSString *logfile = self.logfile.path;\n    if (self.logfile.isFileURL && logfile) {\n        [arguments addObjectsFromArray:@[@\"--Log\", [NSString stringWithFormat:@\"notice file %@\", logfile]]];\n    }\n\n    [arguments addObjectsFromArray:self.arguments];\n\n    for (NSString *key in self.options.allKeys) {\n        [arguments addObject:[NSString stringWithFormat:@\"--%@\", key]];\n\n        NSString *value = self.options[key];\n        if (value) [arguments addObject:value];\n    }\n\n    return arguments;\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORControlCommand.h",
    "content": "//\n//  TORControlCommand.h\n//  Tor\n//\n//  Created by Denis Kutlubaev on 30.03.2021.\n//\n\n#ifndef TORControlCommand_h\n#define TORControlCommand_h\n\n/** TOR control commands\n https://github.com/torproject/torspec/blob/master/control-spec.txt\n */\nstatic NSString * const TORCommandAuthenticate      = @\"AUTHENTICATE\";\nstatic NSString * const TORCommandSignalShutdown    = @\"SIGNAL SHUTDOWN\";\nstatic NSString * const TORCommandResetConf         = @\"RESETCONF\";\nstatic NSString * const TORCommandSetConf           = @\"SETCONF\";\nstatic NSString * const TORCommandSetEvents         = @\"SETEVENTS\";\nstatic NSString * const TORCommandGetInfo           = @\"GETINFO\";\nstatic NSString * const TORCommandSignalReload      = @\"SIGNAL RELOAD\";\nstatic NSString * const TORCommandSignalNewnym      = @\"SIGNAL NEWNYM\";\nstatic NSString * const TORCommandCloseCircuit      = @\"CLOSECIRCUIT\";\n\n#endif /* TORControlCommand_h */\n"
  },
  {
    "path": "Tor/Classes/Core/TORControlReplyCode.h",
    "content": "//\n//  TORControlReplyCode.h\n//  Tor\n//\n//  Created by Denis Kutlubaev on 30.03.2021.\n//\n\n#ifndef TORControlReplyCode_h\n#define TORControlReplyCode_h\n\n/**\n TOR control reply codes\n https://github.com/torproject/torspec/blob/master/control-spec.txt\n\n The following codes are defined:\n\n 250 OK\n 251 Operation was unnecessary\n [Tor has declined to perform the operation, but no harm was done.]\n\n 451 Resource exhausted\n\n 500 Syntax error: protocol\n\n 510 Unrecognized command\n 511 Unimplemented command\n 512 Syntax error in command argument\n 513 Unrecognized command argument\n 514 Authentication required\n 515 Bad authentication\n\n 550 Unspecified Tor error\n\n 551 Internal error\n [Something went wrong inside Tor, so that the client's\n request couldn't be fulfilled.]\n\n 552 Unrecognized entity\n [A configuration key, a stream ID, circuit ID, event,\n mentioned in the command did not actually exist.]\n\n 553 Invalid configuration value\n [The client tried to set a configuration option to an\n incorrect, ill-formed, or impossible value.]\n\n 554 Invalid descriptor\n\n 555 Unmanaged entity\n\n 650 Asynchronous event notification\n */\ntypedef NS_ENUM(NSInteger, TORControlReplyCode) {\n    TORControlReplyCodeOK                               = 250,\n    TORControlReplyCodeOperationWasUnnecessary          = 251,\n    TORControlReplyCodeResourceExhaused                 = 451,\n    TORControlReplyCodeSyntaxErrorProtocol              = 500,\n    TORControlReplyCodeUnrecognizedCommand              = 510,\n    TORControlReplyCodeUnimplementedCommand             = 511,\n    TORControlReplyCodeSyntaxErrorInCommandArgument     = 512,\n    TORControlReplyCodeUnrecognizedCommandArgument      = 513,\n    TORControlReplyCodeAuthenticationRequired           = 514,\n    TORControlReplyCodeBadAuthentication                = 515,\n    TORControlReplyCodeUnspecifiedTorError              = 550,\n    TORControlReplyCodeInternalError                    = 551,\n    TORControlReplyCodeUnrecognizedEntity               = 552,\n    TORControlReplyCodeInvalidConfigurationValue        = 553,\n    TORControlReplyCodeInvalidDescriptor                = 554,\n    TORControlReplyCodeUnmanagedEntity                  = 555,\n    TORControlReplyCodeAsynchronousEventNotification    = 650\n};\n\n#endif /* TORControlReplyCode_h */\n"
  },
  {
    "path": "Tor/Classes/Core/TORController.h",
    "content": "//\n//  TORController.h\n//  Tor\n//\n//  Created by Conrad Kramer on 5/10/14.\n//\n\n#import <Foundation/Foundation.h>\n#import \"TORCircuit.h\"\n\n#ifdef __cplusplus\n#define TOR_EXTERN extern \"C\" __attribute__((visibility (\"default\")))\n#else\n#define TOR_EXTERN extern __attribute__((visibility (\"default\")))\n#endif\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef BOOL (^TORObserverBlock)(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop);\n\n#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 || __MAC_OS_X_VERSION_MAX_ALLOWED >= 101200\nTOR_EXTERN NSErrorDomain const TORControllerErrorDomain;\n#else\nTOR_EXTERN NSString * const TORControllerErrorDomain;\n#endif\n\nNS_SWIFT_NAME(TorController)\n@interface TORController : NSObject\n\n@property (nonatomic, readonly, copy) NSOrderedSet<NSString *> *events;\n@property (nonatomic, readonly, getter=isConnected) BOOL connected;\n\n- (instancetype)init NS_UNAVAILABLE;\n- (instancetype)initWithSocketURL:(NSURL *)url NS_DESIGNATED_INITIALIZER;\n- (instancetype)initWithSocketHost:(NSString *)host port:(in_port_t)port NS_DESIGNATED_INITIALIZER;\n- (instancetype)initWithControlPortFile:(NSURL *)file;\n\n- (BOOL)connect:(out NSError **)error;\n- (void)disconnect;\n\n// Commands\n- (void)authenticateWithData:(NSData *)data completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion;\n- (void)resetConfForKey:(NSString *)key completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion;\n- (void)setConfForKey:(NSString *)key withValue:(NSString *)value completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion;\n- (void)setConfs:(NSArray<NSDictionary *> *)configs completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion;\n- (void)listenForEvents:(NSArray<NSString *> *)events completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion;\n- (void)getInfoForKeys:(NSArray<NSString *> *)keys completion:(void (^)(NSArray<NSString *> *values))completion; // TODO: Provide errors\n- (void)getSessionConfiguration:(void (^)(NSURLSessionConfiguration * __nullable configuration))completion;\n- (void)sendCommand:(NSString *)command arguments:(nullable NSArray<NSString *> *)arguments data:(nullable NSData *)data observer:(TORObserverBlock)observer;\n\n/**\n Get a list of all currently available circuits with detailed information about their nodes.\n\n @note There's no clear way to determine, which circuit actually was used by a specific request.\n\n @param completion The callback upon completion of the task. Will return A list of `TORCircuit`s . Empty if no circuit could be found.\n */\n- (void)getCircuits:(void (^)(NSArray<TORCircuit *> * _Nonnull circuits))completion;\n\n/**\n Resets the Tor connection: Sends \"SIGNAL RELOAD\" and \"SIGNAL NEWNYM\" to the Tor thread.\n\n See https://torproject.gitlab.io/torspec/control-spec.html#signal\n\n @param completion Completion callback. Will return true, if signal calls where successful, false if not.\n */\n- (void)resetConnection:(void (^__nullable)(BOOL success))completion;\n\n/**\n Try to close a list of circuits identified by their IDs.\n\n If some closings weren't successful, the most obvious reason would be, that the circuit with the given\n ID doesn't exist (anymore). So in many circumstances, you can still consider that an ok outcome.\n\n @param circuitIds List of circuit IDs.\n @param completion Completion callback. Will return true, if *all* closings were successful, false, if *at least one* closing failed.\n */\n- (void)closeCircuitsByIds:(NSArray<NSString *> *)circuitIds completion:(void (^__nullable)(BOOL success))completion;\n\n/**\n Try to close a list of given circuits.\n\n The given circuits are invalid afterwards, as you just closed them. You should throw them away on completion.\n\n@param circuits List of circuits to close.\n@param completion  Completion callback. Will return true, if *all* closings were successful, false, if *at least one* closing failed.\n*/\n- (void)closeCircuits:(NSArray<TORCircuit *> *)circuits completion:(void (^__nullable)(BOOL success))completion;\n\n/**\n Resolve countries of given `TORNode`s and updates their `countryCode` property on success.\n\n Nodes which already contain a `countryCode` will be ignored.\n IPv4 addresses will be preferred, if Tor is able to resolve IPv4 addresses (if it has loaded the IPv4 geoip database),\n and if the node has a `ipv4Address` property of non-zero length.\n\n @param nodes List of `TORNode`s to resolve countries for.\n @param testCapabilities Ask Tor first, if it is actually able to resolve. (If GeoDB databases are loaded.) Pass NO, if you're sure that Tor is able to to save on queries.\n @param completion Completion callback.\n */\n- (void)resolveCountriesOfNodes:(NSArray<TORNode *> * _Nullable)nodes testCapabilities:(BOOL)testCapabilities completion:(void (^__nullable)(void))completion;\n\n// Observers\n- (id)addObserverForCircuitEstablished:(void (^)(BOOL established))block;\n- (id)addObserverForStatusEvents:(BOOL (^)(NSString *type, NSString *severity, NSString *action, NSDictionary<NSString *, NSString *> * __nullable arguments))block;\n- (void)removeObserver:(nullable id)observer;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORController.m",
    "content": "//\n//  TORController.m\n//  Tor\n//\n//  Created by Conrad Kramer on 5/10/14.\n//\n\n#import \"TORController.h\"\n\n#import <sys/socket.h>\n#import <sys/un.h>\n#import <netinet/in.h>\n#import <arpa/inet.h>\n\n#import \"TORControlReplyCode.h\"\n#import \"TORControlCommand.h\"\n#import \"NSCharacterSet+PredefinedSets.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000\nNSErrorDomain const TORControllerErrorDomain = @\"TORControllerErrorDomain\";\n#else\nNSString * const TORControllerErrorDomain = @\"TORControllerErrorDomain\";\n#endif\n\nstatic NSString * const TORControllerMidReplyLineSeparator = @\"-\";\nstatic NSString * const TORControllerDataReplyLineSeparator = @\"+\";\nstatic NSString * const TORControllerEndReplyLineSeparator = @\" \";\n\n@implementation TORController {\n    NSURL *_url;\n    NSString *_host;\n    in_port_t _port;\n    dispatch_io_t _channel;\n    NSMutableArray<TORObserverBlock> *_blocks;\n    int sock;\n}\n\n+ (dispatch_queue_t)controlQueue {\n    static dispatch_queue_t controlQueue = NULL;\n    static dispatch_once_t onceToken;\n    dispatch_once(&onceToken, ^{\n        controlQueue = dispatch_queue_create(\"org.torproject.ios.control\", DISPATCH_QUEUE_SERIAL);\n    });\n    return controlQueue;\n}\n\n- (instancetype)initWithSocketURL:(NSURL *)url {\n    NSParameterAssert(url.fileURL);\n    self = [super init];\n    if (!self)\n        return nil;\n    \n    _url = [url copy];\n    _blocks = [NSMutableArray new];\n\n    [self connect:nil];\n    \n    return self;\n}\n\n- (instancetype)initWithSocketHost:(NSString *)host port:(in_port_t)port {\n    NSParameterAssert(host && port);\n    self = [super init];\n    if (!self)\n        return nil;\n    \n    _host = [host copy];\n    _port = port;\n    _blocks = [NSMutableArray new];\n\n    [self connect:nil];\n    \n    return self;\n}\n\n- (instancetype)initWithControlPortFile:(NSURL *)file {\n    NSParameterAssert(file.fileURL);\n\n    // Expected example content:\n    // PORT=127.0.0.1:49651\n\n    NSError *error;\n    NSString *content = [[NSString alloc]\n                         initWithContentsOfURL:file\n                         encoding:NSUTF8StringEncoding error:&error];\n\n    NSAssert(!error, error.localizedDescription);\n\n    NSArray<NSString *> *address = [[[content componentsSeparatedByString:@\"=\"]\n                                         .lastObject\n                                     stringByTrimmingCharactersInSet:\n                                         NSCharacterSet.whitespaceAndNewlineCharacterSet]\n                                    componentsSeparatedByString:@\":\"];\n\n    NSString *host = address.firstObject;\n    NSAssert(host, @\"Provided file doesn't seem to be a valid control port file as written by Tor!\");\n\n    NSInteger port = address.lastObject.integerValue;\n\n    return [self initWithSocketHost:host port:(in_port_t) port];\n}\n\n- (void)dealloc {\n    if (_channel)\n        dispatch_io_close(_channel, DISPATCH_IO_STOP);\n}\n\n#pragma mark - Connecting\n\n- (BOOL)isConnected {\n    return (_channel != nil);\n}\n\n- (BOOL)connect:(out NSError **)error {\n    if (_channel)\n    {\n        return NO;\n    }\n    \n    self->sock = -1;\n    \n    _events = [NSOrderedSet new];\n    \n    if (_url)\n    {\n        struct sockaddr_un control_addr = {};\n        control_addr.sun_family = AF_UNIX;\n        strncpy(control_addr.sun_path, _url.fileSystemRepresentation, sizeof(control_addr.sun_path) - 1);\n        control_addr.sun_len = (unsigned char)SUN_LEN(&control_addr);\n        \n        self->sock = socket(AF_UNIX, SOCK_STREAM, 0);\n\n        if (connect(self->sock, (struct sockaddr *)&control_addr, control_addr.sun_len) == -1)\n        {\n            if (error)\n            {\n                *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];\n            }\n\n            return NO;\n        }\n    }\n    else if (_host && _port) {\n        struct in_addr addr;\n\n        if (inet_aton(_host.UTF8String, &addr) == 0)\n        {\n            if (error)\n            {\n                *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];\n            }\n\n            return NO;\n        }\n        \n        struct sockaddr_in control_addr = {};\n        control_addr.sin_family = AF_INET;\n        control_addr.sin_port = htons(_port);\n        control_addr.sin_addr = addr;\n        control_addr.sin_len = (__uint8_t)sizeof(control_addr);\n        \n        self->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);\n        \n        if (connect(self->sock, (struct sockaddr *)&control_addr, control_addr.sin_len) == -1)\n        {\n            if (error)\n            {\n                *error = [NSError errorWithDomain:NSPOSIXErrorDomain code:errno userInfo:nil];\n            }\n\n            return NO;\n        }\n    }\n    else {\n        return NO;\n    }\n    \n    __weak TORController *weakSelf = self;\n\n    _channel = dispatch_io_create(DISPATCH_IO_STREAM, self->sock, [self.class controlQueue], ^(int __unused error) {\n        close(self->sock);\n        \n        TORController *strongSelf = weakSelf;\n        if (strongSelf)\n        {\n            strongSelf->_channel = nil;\n        }\n    });\n\n    if (!_channel)\n    {\n        return NO;\n    }\n    \n    NSData *separator = [NSData dataWithBytes:\"\\x0d\\x0a\" length:2]; // also known as CR-LF or \"\\r\\n\"\n    NSData *period = [NSData dataWithBytes:\".\" length:1];\n\n    NSSet<NSString *> *lineSeparators = [NSSet setWithObjects:TORControllerMidReplyLineSeparator,\n                                         TORControllerDataReplyLineSeparator,\n                                         TORControllerEndReplyLineSeparator, nil];\n    \n    __block NSMutableData *buffer = [NSMutableData new];\n    __block NSMutableArray<NSNumber *> *codes = [NSMutableArray new];\n    __block NSMutableArray<NSData *> *lines = [NSMutableArray new];\n    __block BOOL dataBlock = NO;\n    \n    dispatch_io_set_low_water(_channel, 1);\n    dispatch_io_read(_channel, 0, SIZE_MAX, [self.class controlQueue], ^(bool __unused done, dispatch_data_t data, int __unused error) {\n        [buffer appendData:(NSData *)data];\n        \n        NSRange separatorRange;\n        NSRange remainingRange = NSMakeRange(0, buffer.length);\n\n        while ((separatorRange = [buffer rangeOfData:separator options:0 range:remainingRange]).location != NSNotFound)\n        {\n            NSUInteger lineLength = separatorRange.location - remainingRange.location;\n            NSRange lineRange = NSMakeRange(remainingRange.location, lineLength);\n            remainingRange = NSMakeRange(remainingRange.location + lineLength + separator.length,\n                                         remainingRange.length - lineLength - separator.length);\n            \n            if (dataBlock)\n            {\n                NSData *lineData = [buffer subdataWithRange:lineRange];\n\n                if ([lineData isEqualToData:period])\n                {\n                    dataBlock = NO;\n                }\n                else {\n                    if (lines.count > 0)\n                    {\n                        if (lines.lastObject.length > 0)\n                        {\n                            NSMutableData *lastData = lines.lastObject.mutableCopy;\n\n                            // BUGFIX: Add in separator again. It is needed to pick apart multi-line results later!\n                            [lastData appendData:separator];\n                            [lastData appendData:lineData];\n\n                            [lines replaceObjectAtIndex:(lines.count - 1) withObject:lastData];\n                        }\n                        else {\n                            [lines replaceObjectAtIndex:(lines.count - 1) withObject:lineData];\n                        }\n                    }\n                    else {\n                        [lines addObject:lineData];\n                    }\n                }\n\n                continue;\n            }\n            \n            if (lineRange.length < 4)\n            {\n                continue;\n            }\n\n            NSString *statusCodeString = [[NSString alloc] initWithData:[buffer subdataWithRange:NSMakeRange(lineRange.location, 3)]\n                                                               encoding:NSUTF8StringEncoding];\n\n            if ([statusCodeString rangeOfCharacterFromSet:NSCharacterSet.decimalDigitCharacterSet.invertedSet].location != NSNotFound)\n            {\n                continue;\n            }\n            \n            NSString *lineTypeString = [[NSString alloc] initWithData:[buffer subdataWithRange:NSMakeRange(lineRange.location + 3, 1)]\n                                                             encoding:NSUTF8StringEncoding];\n\n            if (![lineSeparators containsObject:lineTypeString])\n            {\n                continue;\n            }\n\n            [codes addObject:@(statusCodeString.integerValue)];\n            [lines addObject:[buffer subdataWithRange:NSMakeRange(lineRange.location + 4, lineRange.length - 4)]];\n            \n            [buffer replaceBytesInRange:NSMakeRange(0, remainingRange.location) withBytes:NULL length:0];\n            remainingRange.location = 0;\n\n            if ([lineTypeString isEqualToString:TORControllerDataReplyLineSeparator])\n            {\n                dataBlock = YES;\n            }\n            \n            if ([lineTypeString isEqualToString:TORControllerEndReplyLineSeparator])\n            {\n                NSArray<NSNumber *> *commandCodes = codes;\n                NSArray<NSData *> *commandLines = lines;\n                codes = [NSMutableArray new];\n                lines = [NSMutableArray new];\n                \n                TORController *strongSelf = weakSelf;\n                if (!strongSelf)\n                {\n                    continue;\n                }\n                \n                for (TORObserverBlock observer in [strongSelf->_blocks copy]) {\n                    BOOL stop = NO;\n                    BOOL handled = observer(commandCodes, commandLines, &stop);\n\n                    if (stop)\n                    {\n                        [strongSelf->_blocks removeObject:observer];\n                    }\n\n                    if (handled)\n                    {\n                        break;\n                    }\n                }\n            }\n        }\n    });\n    \n    return YES;\n}\n\n- (void)disconnect {\n    [self sendCommand:TORCommandSignalShutdown arguments:nil data:nil observer:^BOOL(NSArray<NSNumber *> * __unused codes, NSArray<NSData *> * __unused lines, BOOL * __unused stop) {\n        shutdown(self->sock, SHUT_RDWR);\n        self->_channel = nil;\n     \n        return YES;\n     }];\n}\n\n#pragma mark - Receiving Responses\n\n- (id)addObserverForCircuitEstablished:(void (^)(BOOL established))block {\n    NSParameterAssert(block);\n    \n    NSString *event = @\"STATUS_CLIENT\";\n    id observer = [self addObserverForStatusEvents:^(NSString *type, NSString * __unused severity, NSString *action, NSDictionary<NSString *, NSString *> * __unused arguments) {\n        if ([type isEqualToString:event]) {\n            if ([action isEqualToString:@\"CIRCUIT_ESTABLISHED\"]) {\n                block(YES);\n                return YES;\n            } else if ([action isEqualToString:@\"CIRCUIT_NOT_ESTABLISHED\"]) {\n                block(NO);\n                return YES;\n            }\n        }\n        \n        return NO;\n    }];\n    \n    void (^completion)(BOOL, NSError *) = ^(BOOL success, NSError * __unused error) {\n        if (!success)\n            [self removeObserver:observer];\n        \n        [self getInfoForKeys:@[@\"status/circuit-established\"] completion:^(NSArray<NSString *> *values) {\n            if (values.count != 1)\n                return [self removeObserver:observer];\n            \n            if (block)\n                block([values[0] boolValue]);\n        }];\n    };\n    \n    dispatch_async([self.class controlQueue], ^{\n        if ([self->_events containsObject:event]) {\n            completion(YES, nil);\n        } else {\n            NSMutableOrderedSet *events = [self->_events mutableCopy];\n            [events addObject:event];\n            [self listenForEvents:events.array completion:completion];\n        }\n    });\n    \n    return observer;\n}\n\n- (id)addObserverForStatusEvents:(BOOL (^)(NSString *type, NSString *severity, NSString *action, NSDictionary<NSString *, NSString *> *arguments))block {\n    NSParameterAssert(block);\n    return [self addObserver:^(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL * __unused stop) {\n        if (codes.firstObject.integerValue != 650)\n            return NO;\n        \n        NSString *replyString = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n        if (![replyString hasPrefix:@\"STATUS_\"])\n            return NO;\n\n        NSArray<NSString *> *components = [TORController parseStatus:replyString];\n        if (components.count < 3)\n            return NO;\n        \n        NSMutableDictionary<NSString *, NSString *> *arguments = nil;\n        if (components.count > 3) {\n            arguments = [NSMutableDictionary new];\n            for (NSString *argument in [components subarrayWithRange:NSMakeRange(3, components.count - 3)]) {\n                NSArray<NSString *> *keyValuePair = [argument componentsSeparatedByString:@\"=\"];\n                if (keyValuePair.count == 2) {\n                    NSString *value = [keyValuePair[1] stringByReplacingOccurrencesOfString:@\"\\\"\" withString:@\"\"];\n\n                    [arguments setObject:value forKey:keyValuePair[0]];\n                }\n            }\n        }\n\n        NSString *type = (NSString * _Nonnull)components.firstObject;\n        return block(type, components[1], components[2], arguments);\n    }];\n}\n\n- (id)addObserver:(TORObserverBlock)observer {\n    NSParameterAssert(observer);\n    dispatch_async([self.class controlQueue], ^{\n        [self->_blocks addObject:observer];\n    });\n    return observer;\n}\n\n- (void)removeObserver:(nullable id)observer {\n    if (!observer)\n        return;\n    \n    dispatch_async([self.class controlQueue], ^{\n        [self->_blocks removeObject:(id _Nonnull)observer];\n    });\n}\n\n#pragma mark - Sending Commands\n\n- (void)authenticateWithData:(NSData *)data completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion {\n    NSMutableString *hexString = [NSMutableString new];\n    for (NSUInteger idx = 0; idx < data.length; idx++)\n        [hexString appendFormat:@\"%02x\", ((const unsigned char *)data.bytes)[idx]];\n    \n    [self sendCommand:TORCommandAuthenticate arguments:(hexString.length ? @[hexString] : nil) data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n        NSUInteger code = codes.firstObject.unsignedIntegerValue;\n        if (code != TORControlReplyCodeOK && code != TORControlReplyCodeBadAuthentication)\n            return NO;\n        \n        NSString *message = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n        NSDictionary<NSString *, NSString *> *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];\n        BOOL success = (code == TORControlReplyCodeOK && [message isEqualToString:@\"OK\"]);\n        if (completion)\n            completion(success, success ? nil : [NSError errorWithDomain:TORControllerErrorDomain code:code userInfo:userInfo]);\n        \n        *stop = YES;\n        return YES;\n    }];\n}\n\n- (void)resetConfForKey:(NSString *)key completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion {\n\t[self sendCommand:TORCommandResetConf arguments:@[key] data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n\t\tNSUInteger code = codes.firstObject.unsignedIntegerValue;\n\t\tif (code != TORControlReplyCodeOK && code != TORControlReplyCodeBadAuthentication)\n\t\t\treturn NO;\n\n\t\tNSString *message = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n\t\tNSDictionary<NSString *, NSString *> *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];\n\t\tBOOL success = (code == TORControlReplyCodeOK && [message isEqualToString:@\"OK\"]);\n\t\tif (completion)\n\t\t\tcompletion(success, success ? nil : [NSError errorWithDomain:TORControllerErrorDomain code:code userInfo:userInfo]);\n\n\t\t*stop = YES;\n\t\treturn YES;\n\t}];\n}\n\n- (void)setConfForKey:(NSString *)key withValue:(NSString *)value completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion {\n\tNSString *arg = [NSString stringWithFormat:@\"%@=%@\", key, value];\n\n\t[self sendCommand:TORCommandSetConf arguments:@[arg] data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n\t\tNSUInteger code = codes.firstObject.unsignedIntegerValue;\n\t\tif (code != TORControlReplyCodeOK && code != TORControlReplyCodeBadAuthentication)\n\t\t\treturn NO;\n\n\t\tNSString *message = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n\t\tNSDictionary<NSString *, NSString *> *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];\n\t\tBOOL success = (code == TORControlReplyCodeOK && [message isEqualToString:@\"OK\"]);\n\t\tif (completion)\n\t\t\tcompletion(success, success ? nil : [NSError errorWithDomain:TORControllerErrorDomain code:code userInfo:userInfo]);\n\n\t\t*stop = YES;\n\t\treturn YES;\n\t}];\n}\n- (void)setConfs:(NSArray<NSDictionary *> *)configs completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion {\n    NSMutableArray *conf_arg = [[NSMutableArray alloc] init];\n    for (NSDictionary *config in configs) {\n        NSString *key = [config objectForKey:@\"key\"];\n        NSString *value = [config objectForKey:@\"value\"];\n        NSString *arg = [NSString stringWithFormat:@\"%@=%@\", key, value];\n        [conf_arg addObject:arg];\n    }\n\n    [self sendCommand:TORCommandSetConf arguments:conf_arg data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n        NSUInteger code = codes.firstObject.unsignedIntegerValue;\n        if (code != TORControlReplyCodeOK && code != TORControlReplyCodeBadAuthentication)\n            return NO;\n        \n        NSString *message = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n        NSDictionary<NSString *, NSString *> *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];\n        BOOL success = (code == TORControlReplyCodeOK && [message isEqualToString:@\"OK\"]);\n        if (completion)\n            completion(success, success ? nil : [NSError errorWithDomain:TORControllerErrorDomain code:code userInfo:userInfo]);\n        \n        *stop = YES;\n        return YES;\n    }];\n\n}\n\n- (void)listenForEvents:(NSArray<NSString *> *)events completion:(void (^__nullable)(BOOL success, NSError * __nullable error))completion {\n    [self sendCommand:TORCommandSetEvents arguments:events data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n        NSUInteger code = codes.firstObject.unsignedIntegerValue;\n        if (code != TORControlReplyCodeOK && code != TORControlReplyCodeUnrecognizedEntity)\n            return NO;\n\n        NSString *message = lines.firstObject ? [[NSString alloc] initWithData:(NSData * _Nonnull)lines.firstObject encoding:NSUTF8StringEncoding] : @\"\";\n        NSDictionary<NSString *, NSString *> *userInfo = [NSDictionary dictionaryWithObjectsAndKeys:message, NSLocalizedDescriptionKey, nil];\n        BOOL success = (code == TORControlReplyCodeOK && [message isEqualToString:@\"OK\"]);\n        if (success)\n            self->_events = [NSOrderedSet orderedSetWithArray:events];\n        if (completion)\n            completion(success, success ? nil : [NSError errorWithDomain:TORControllerErrorDomain code:code userInfo:userInfo]);\n        \n        *stop = YES;\n        return YES;\n    }];\n}\n\n- (void)getInfoForKeys:(NSArray<NSString *> *)keys completion:(void (^)(NSArray<NSString *> *values))completion\n{\n    NSData *ok = [NSData dataWithBytes:\"OK\" length:2];\n\n    [self sendCommand:TORCommandGetInfo arguments:keys data:nil observer:^BOOL(NSArray<NSNumber *> *codes, NSArray<NSData *> *lines, BOOL *stop) {\n        *stop = YES;\n\n        if (lines.count - 1 != keys.count || codes.count != lines.count)\n        {\n            if (completion)\n            {\n                completion(@[]);\n            }\n\n            return NO;\n        }\n\n        if (codes.lastObject.integerValue != TORControlReplyCodeOK || ![lines.lastObject isEqual:ok])\n        {\n            if (completion)\n            {\n                completion(@[]);\n            }\n\n            return NO;\n        }\n\n        NSMutableDictionary<NSString *, NSString *> *info = [NSMutableDictionary new];\n\n        for (NSUInteger i = 0; i < codes.count - 1; i++)\n        {\n            if (codes[i].integerValue == TORControlReplyCodeOK)\n            {\n                NSString *string = [[NSString alloc] initWithData:lines[i] encoding:NSUTF8StringEncoding];\n\n                if (!string)\n                {\n                    completion(@[]);\n\n                    return NO;\n                }\n\n                NSRange pos = [string rangeOfString:@\"=\"];\n\n                if (pos.location != NSNotFound)\n                {\n                    NSString *key = [[string substringToIndex:pos.location] stringByTrimmingCharactersInSet:\n                                     NSCharacterSet.doubleQuote];\n\n                    if ([keys containsObject:key])\n                    {\n                        info[key] = [[string substringFromIndex:pos.location + pos.length]\n                                     stringByTrimmingCharactersInSet:NSCharacterSet.doubleQuote];\n                    }\n                    else {\n                        if (completion)\n                        {\n                            completion(@[]);\n\n                            return NO;\n                        }\n                    }\n                }\n            }\n        }\n\n        NSMutableArray *values = [NSMutableArray new];\n\n        for (NSString *key in keys)\n        {\n            [values addObject:(info[key] ?: [NSNull null])];\n        }\n\n        if (completion)\n        {\n            completion(values);\n        }\n\n        return YES;\n    }];\n}\n\n- (void)getSessionConfiguration:(void (^)(NSURLSessionConfiguration * __nullable configuration))completion\n{\n    [self getInfoForKeys:@[@\"net/listeners/socks\"] completion:^(NSArray<NSString *> *values) {\n        if (values.count != 1)\n            return completion(nil);\n        \n        NSArray<NSString *> *components = [values.firstObject componentsSeparatedByString:@\":\"];\n        if (components.count != 2)\n            return completion(nil);\n        \n        if ([components[0] isEqualToString:@\"unix\"])\n            return completion(nil); // TODO: Provide error\n        \n        if ([components[1] rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]].location != NSNotFound)\n            return completion(nil); // TODO: Provide error\n\n        NSString *host = components[0];\n\n        // Replace 127.0.0.1 with localhost, as without this, there's a strange bug\n        // triggered: It won't resolve .onion addresses, but *only on real devices*.\n        // So, on a real device, there's probably the wrong DNS resolver used, which\n        // would mean, DNS queries were leaking, too.\n        if ([host isEqualToString:@\"127.0.0.1\"])\n        {\n            host = @\"localhost\";\n        }\n\n        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];\n        configuration.connectionProxyDictionary = @{(id)kCFProxyTypeKey: (id)kCFProxyTypeSOCKS,\n                                                    (id)kCFStreamPropertySOCKSProxyHost: host,\n                                                    (id)kCFStreamPropertySOCKSProxyPort: @([components[1] integerValue])};\n        completion(configuration);\n    }];\n}\n\n- (void)sendCommand:(NSString *)command\n          arguments:(nullable NSArray<NSString *> *)arguments\n               data:(nullable NSData *)data observer:(TORObserverBlock)observer\n{\n    NSParameterAssert(command.length);\n    if (!_channel)\n    {\n        return;\n    }\n\n    if (arguments == nil)\n    {\n        arguments = @[];\n    }\n\n    NSString *argumentsString = [[@[command] arrayByAddingObjectsFromArray:(NSArray * _Nonnull)arguments]\n                                 componentsJoinedByString:@\" \"];\n    \n    NSMutableData *commandData = [NSMutableData new];\n    if (data.length)\n    {\n        [commandData appendBytes:\"+\" length:1];\n    }\n    [commandData appendData:(NSData * _Nonnull)[argumentsString dataUsingEncoding:NSUTF8StringEncoding]];\n    [commandData appendBytes:\"\\r\\n\" length:2];\n\n    if (data.length)\n    {\n        [commandData appendData:(NSData * _Nonnull)data];\n        [commandData appendBytes:\"\\r\\n.\\r\\n\" length:5];\n    }\n    \n    dispatch_data_t dispatchData = dispatch_data_create(commandData.bytes,\n                                                        commandData.length,\n                                                        [self.class controlQueue],\n                                                        DISPATCH_DATA_DESTRUCTOR_DEFAULT);\n\n    dispatch_io_write(_channel, 0, dispatchData, [self.class controlQueue], ^(bool done, dispatch_data_t __unused data, int error) {\n        if (done && !error && observer) {\n            [self->_blocks insertObject:observer atIndex:0];\n        }\n    });\n}\n\n\n- (void)getCircuits:(void (^)(NSArray<TORCircuit *> * _Nonnull circuits))completion\n{\n    [self getInfoForKeys:@[@\"circuit-status\"] completion:^(NSArray<NSString *> * _Nonnull values) {\n        if (values.count < 1)\n        {\n            if (completion)\n            {\n                completion(@[]);\n            }\n\n            return;\n        }\n\n        NSArray<TORCircuit *> *circuits = [TORCircuit circuitsFromString:(NSString * _Nonnull)values.firstObject];\n\n        NSMutableArray<NSString *> *ipResolveCalls = [NSMutableArray new];\n        NSMutableArray<TORNode *> *map = [NSMutableArray new];\n\n        for (TORCircuit *circuit in circuits)\n        {\n            for (TORNode *node in circuit.nodes)\n            {\n                [ipResolveCalls addObject:[NSString stringWithFormat:@\"ns/id/%@\", node.fingerprint]];\n                [map addObject:node];\n            }\n        }\n\n        [self getInfoForKeys:ipResolveCalls completion:^(NSArray<NSString *> * _Nonnull values) {\n            for (NSUInteger i = 0; i < values.count; i++) {\n                [map[i] acquireIpAddressesFromNsResponse:values[i]];\n            }\n\n            NSMutableArray<TORNode *> *nodes = [NSMutableArray new];\n\n            for (TORCircuit *circuit in circuits)\n            {\n                [nodes addObjectsFromArray:circuit.nodes];\n            }\n\n            [self resolveCountriesOfNodes:nodes testCapabilities:YES completion:^{\n                if (completion)\n                {\n                    completion(circuits);\n                }\n            }];\n        }];\n    }];\n}\n\n- (void)resetConnection:(void (^__nullable)(BOOL success))completion\n{\n    [self sendCommand:TORCommandSignalReload arguments:nil data:nil observer:\n     ^BOOL(NSArray<NSNumber *> * _Nonnull codes, NSArray<NSData *> * _Nonnull __unused lines, BOOL * _Nonnull stop) {\n\n        if (codes.firstObject.integerValue == TORControlReplyCodeOK)\n        {\n            [self sendCommand:TORCommandSignalNewnym arguments:nil data:nil observer:\n             ^BOOL(NSArray<NSNumber *> * _Nonnull codes, NSArray<NSData *> * _Nonnull __unused lines, BOOL * _Nonnull stop) {\n\n                if (completion)\n                {\n                    completion(codes.firstObject.integerValue == TORControlReplyCodeOK);\n                }\n\n                *stop = YES;\n                return YES;\n            }];\n        }\n        else {\n            if (completion)\n            {\n                completion(NO);\n            }\n        }\n\n        *stop = YES;\n        return YES;\n    }];\n}\n\n- (void)closeCircuitsByIds:(NSArray<NSString *> *)circuitIds completion:(void (^__nullable)(BOOL success))completion\n{\n    long queueId;\n\n    if (@available(macOS 10.10, *)) {\n        queueId = QOS_CLASS_USER_INITIATED;\n    }\n    else {\n        queueId = DISPATCH_QUEUE_PRIORITY_HIGH;\n    }\n\n    dispatch_async(dispatch_get_global_queue(queueId, 0), ^{\n        __block BOOL success = YES;\n\n        dispatch_group_t group = dispatch_group_create();\n\n        for (NSString *circuitId in circuitIds)\n        {\n            dispatch_group_enter(group);\n\n            [self sendCommand:TORCommandCloseCircuit arguments:@[circuitId] data:nil observer:\n             ^BOOL(NSArray<NSNumber *> * _Nonnull codes, NSArray<NSData *> * _Nonnull __unused lines, BOOL * _Nonnull stop) {\n\n                success = success && codes.firstObject.integerValue == TORControlReplyCodeOK;\n\n                // Need to deparallelize to not mix up responses.\n                dispatch_group_leave(group);\n\n                *stop = YES;\n                return YES;\n            }];\n        }\n\n        dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 10000000000)); // Wait 10 seconds.\n\n        dispatch_async(dispatch_get_main_queue(), ^{\n            if (completion)\n            {\n                completion(success);\n            }\n        });\n    });\n}\n\n- (void)closeCircuits:(NSArray<TORCircuit *> *)circuits completion:(void (^__nullable)(BOOL success))completion\n{\n    NSMutableArray<NSString *> *circuitIds = [NSMutableArray new];\n\n    for (TORCircuit *circuit in circuits)\n    {\n        if (circuit.circuitId.length > 0)\n        {\n            [circuitIds addObject:(NSString * _Nonnull)circuit.circuitId];\n        }\n    }\n\n    [self closeCircuitsByIds:circuitIds completion:completion];\n}\n\n- (void)resolveCountriesOfNodes:(NSArray<TORNode *> * _Nullable)nodes testCapabilities:(BOOL)testCapabilities completion:(void (^__nullable)(void))completion\n{\n    BOOL __block ipv4Available = YES;\n    BOOL __block ipv6Available = YES;\n\n    if (testCapabilities)\n    {\n        dispatch_group_t group = dispatch_group_create();\n        dispatch_group_enter(group);\n\n        [self getInfoForKeys:@[@\"ip-to-country/ipv4-available\", @\"ip-to-country/ipv6-available\"] completion:^(NSArray<NSString *> * _Nonnull values) {\n\n            ipv4Available = [values.firstObject isEqualToString:@\"1\"];\n            ipv6Available = [values.lastObject isEqualToString:@\"1\"];\n\n            dispatch_group_leave(group);\n        }];\n\n        dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, 1000000000)); // Wait 1 second.\n    }\n\n    if (!ipv4Available && !ipv6Available)\n    {\n        if (completion)\n        {\n            completion();\n        }\n\n        return;\n    }\n\n    NSMutableArray<NSString *> *geoipResolveCalls = [NSMutableArray new];\n    NSMutableArray<TORNode *> *map = [NSMutableArray new];\n\n    for (TORNode *node in nodes)\n    {\n        if (node.countryCode.length)\n        {\n            continue;\n        }\n\n        if (ipv4Available && node.ipv4Address.length)\n        {\n            [geoipResolveCalls addObject:[NSString stringWithFormat:@\"ip-to-country/%@\", node.ipv4Address]];\n            [map addObject:node];\n        }\n        else if (ipv6Available && node.ipv6Address.length)\n        {\n            [geoipResolveCalls addObject:[NSString stringWithFormat:@\"ip-to-country/%@\", node.ipv6Address]];\n            [map addObject:node];\n        }\n    }\n\n    if (geoipResolveCalls.count < 1)\n    {\n        if (completion)\n        {\n            completion();\n        }\n\n        return;\n    }\n\n    [self getInfoForKeys:geoipResolveCalls completion:^(NSArray<NSString *> * _Nonnull values) {\n        for (NSUInteger i = 0; i < values.count; i++)\n        {\n            map[i].countryCode = values[i];\n        }\n\n        if (completion)\n        {\n            completion();\n        }\n    }];\n}\n\n+ (NSArray<NSString *> *)parseStatus:(NSString *)status\n{\n    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@\"[^\\\\s\\\"]+=\\\"[^\\\"]*\\\"|[^\\\\s]+\" options:0 error:nil];\n\n    NSArray<NSTextCheckingResult *> *matches = [regex matchesInString:status options:0 range:NSMakeRange(0, status.length)];\n\n    NSMutableArray *tokens = [NSMutableArray new];\n\n    for (NSTextCheckingResult *match in matches) {\n        [tokens addObject:[status substringWithRange:match.range]];\n    }\n\n    return tokens;\n}\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORNode.h",
    "content": "//\n//  TORNode.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 09.12.19.\n//\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\nNS_SWIFT_NAME(TorNode)\n@interface TORNode : NSObject<NSSecureCoding>\n\n/**\nRegular expression to identify and extract a valid IPv4 address.\n\nTaken from https://nbviewer.jupyter.org/github/rasbt/python_reference/blob/master/tutorials/useful_regex.ipynb\n*/\n@property (class, nonatomic, readonly) NSRegularExpression *ipv4Regex;\n\n/**\nRegular expression to identify and extract a valid IPv6 address.\n\nTaken from https://nbviewer.jupyter.org/github/rasbt/python_reference/blob/master/tutorials/useful_regex.ipynb\n*/\n@property (class, nonatomic, readonly) NSRegularExpression *ipv6Regex;\n\n/**\n The fingerprint aka. ID of a Tor node.\n */\n@property (nonatomic, nullable) NSString *fingerprint;\n\n/**\n The nickname of a Tor node.\n */\n@property (nonatomic, nullable) NSString *nickName;\n\n/**\n The IPv4 address of a Tor node.\n */\n@property (nonatomic, nullable) NSString *ipv4Address;\n\n/**\n The IPv6 address of a Tor node.\n */\n@property (nonatomic, nullable) NSString *ipv6Address;\n\n/**\n The country code of a Tor node's country.\n */\n@property (nonatomic, nullable) NSString *countryCode;\n\n/**\n The localized country name of a Tor node's country.\n */\n@property (nonatomic, readonly, nullable) NSString *localizedCountryName;\n\n/**\n If this node can act as an exit node or not.\n */\n@property BOOL isExit;\n\n/**\n Create a `TORNode` object from a \"LongName\" node string which should contain the fingerprint and the nickname.\n\n See https://torproject.gitlab.io/torspec/control-spec.html#general-use-tokens\n\n @param longName A \"LongName\" identifying a Tor node.\n */\n- (instancetype)initFromString:(NSString *)longName;\n\n/**\n Creates a list of `TORNode` objects from the response of a `ns/[*]` call which should contain the nickname and IP address(es).\n\n See https://torproject.gitlab.io/torspec/control-spec.html#getinfo\n\n @param nsString Response from `ns/[*]` call, identifying one or more Tor nodes.\n @return a list of `TORNode`s discovered in the given string. Might be empty.\n */\n+ (NSArray<TORNode *>  * _Nonnull)parseFromNsString:(NSString * _Nullable)nsString exitOnly:(BOOL)exitOnly;\n\n\n/**\n Acquires IPv4 and IPv6 addresses from the given string.\n\n See https://torproject.gitlab.io/torspec/control-spec.html#getinfo\n\n @param response Should be the response of a `ns/id/<fingerprint>` call.\n */\n- (void)acquireIpAddressesFromNsResponse:(NSString *)response;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TORNode.m",
    "content": "//\n//  TORNode.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 09.12.19.\n//\n\n#import \"TORNode.h\"\n#import \"NSCharacterSet+PredefinedSets.h\"\n\n@implementation TORNode\n\n// MARK: Class Properties\n\nstatic NSRegularExpression *_ipv4Regex;\nstatic NSRegularExpression *_ipv6Regex;\n\n+ (NSRegularExpression *)ipv4Regex\n{\n    if (!_ipv4Regex)\n    {\n        _ipv4Regex =\n        [NSRegularExpression\n         regularExpressionWithPattern:@\"(?:(?:25[0-5]|2[0-4]\\\\d|[01]?\\\\d\\\\d?)\\\\.){3}(?:25[0-5]|2[0-4]\\\\d|[01]?\\\\d\\\\d?)\"\n         options:0 error:nil];\n    }\n\n    return _ipv4Regex;\n}\n\n+ (NSRegularExpression *)ipv6Regex\n{\n    if (!_ipv6Regex)\n    {\n        _ipv6Regex =\n        [NSRegularExpression\n         regularExpressionWithPattern:\n         @\"((([\\\\da-f]{1,4}:){7}([\\\\da-f]{1,4}|:))|(([\\\\da-f]{1,4}:){6}(:[\\\\da-f]{1,4}|((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3})|:))|(([\\\\da-f]{1,4}:){5}(((:[\\\\da-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3})|:))|(([\\\\da-f]{1,4}:){4}(((:[\\\\da-f]{1,4}){1,3})|((:[\\\\da-f]{1,4})?:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}))|:))|(([\\\\da-f]{1,4}:){3}(((:[\\\\da-f]{1,4}){1,4})|((:[\\\\da-f]{1,4}){0,2}:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}))|:))|(([\\\\da-f]{1,4}:){2}(((:[\\\\da-f]{1,4}){1,5})|((:[\\\\da-f]{1,4}){0,3}:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}))|:))|(([\\\\da-f]{1,4}:){1}(((:[\\\\da-f]{1,4}){1,6})|((:[\\\\da-f]{1,4}){0,4}:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}))|:))|(:(((:[\\\\da-f]{1,4}){1,7})|((:[\\\\da-f]{1,4}){0,5}:((25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)(\\\\.(25[0-5]|2[0-4]\\\\d|1\\\\d\\\\d|[1-9]?\\\\d)){3}))|:)))(%.+)?\"\n         options:NSRegularExpressionCaseInsensitive error:nil];\n    }\n\n    return _ipv6Regex;\n}\n\n// MARK: Class Methods:\n\n+ (NSArray<TORNode *>  * _Nonnull)parseFromNsString:(NSString * _Nullable)nsString exitOnly:(BOOL)exitOnly\n{\n    NSMutableArray<TORNode *> *nodes = [NSMutableArray new];\n    NSMutableArray<NSString *> *raw = [NSMutableArray new];\n\n    // A typical NS string for a Tor node might look like this:\n    //  (Line breaks are not for readability but contained in original!)\n    //\n    // r ForPrivacyNET ADb6NqtDX9XQ9kBiZjaGfr+3LGg epP7Gxm+NYhwC3V7SPORQCPoVgc 2022-11-18 00:01:48 185.220.101.33 10133 0\n    // a [2a0b:f4c2:2::33]:10133\n    // s Exit Fast Running V2Dir Valid\n    // w Bandwidth=37000\n    //\n    // So, we watch out for a \"r\" line and add all lines which start with a valid prefix until the\n    // next \"r\" line to get the full description.\n    // But since we currently don't use the \"w\" line information, we ignore that as an optimization.\n\n    for (NSString *line in [nsString componentsSeparatedByCharactersInSet:NSCharacterSet.newlineCharacterSet]) {\n        if ([line hasPrefix:@\"r\"])\n        {\n            if (raw.count > 0)\n            {\n                if (!exitOnly || [raw.lastObject rangeOfString:@\"Exit\"].location != NSNotFound)\n                {\n                    [nodes addObject:[[TORNode alloc] initFromNsString:[raw componentsJoinedByString:@\"\\n\"]]];\n                }\n\n                raw = [[NSMutableArray alloc] initWithObjects:line, nil];\n            }\n        }\n        else if ([line hasPrefix:@\"a\"] || [line hasPrefix:@\"s\"])\n        {\n            [raw addObject:line];\n        }\n    }\n\n    if (raw.count > 0 && (!exitOnly || [raw.lastObject rangeOfString:@\"Exit\"].location != NSNotFound))\n    {\n        [nodes addObject:[[TORNode alloc] initFromNsString:[raw componentsJoinedByString:@\"\\n\"]]];\n    }\n\n    return nodes;\n}\n\n\n// MARK: Initializers\n\n- (instancetype)initFromString:(NSString *)longName\n{\n    self = [super init];\n\n    if (self)\n    {\n        NSArray<NSString *> *components = [longName componentsSeparatedByCharactersInSet:\n                                           NSCharacterSet.longNameDivider];\n\n        if (components.count > 0)\n        {\n            self.fingerprint = components[0];\n        }\n\n        if (components.count > 1)\n        {\n            self.nickName = components[1];\n        }\n    }\n\n    return self;\n}\n\n- (instancetype)initFromNsString:(NSString *)nsString\n{\n    self = [super init];\n\n    if (self)\n    {\n        NSRange r1 = [nsString rangeOfCharacterFromSet:NSCharacterSet.whitespaceAndNewlineCharacterSet];\n\n        if (r1.location != NSNotFound)\n        {\n            NSUInteger p1 = r1.location + r1.length;\n\n            NSRange r2 = [nsString rangeOfCharacterFromSet:NSCharacterSet.whitespaceAndNewlineCharacterSet\n                                                   options:0 range:NSMakeRange(p1, nsString.length - p1)];\n\n            if (r2.location != NSNotFound)\n            {\n                self.nickName = [nsString substringWithRange:NSMakeRange(p1, r2.location - p1)];\n            }\n        }\n\n        [self acquireIpAddressesFromNsResponse:nsString];\n    }\n\n    return self;\n}\n\n\n// MARK: Public Methods\n\n- (void)acquireIpAddressesFromNsResponse:(NSString *)response\n{\n    NSArray<NSTextCheckingResult *> *matches;\n    NSRange range = NSMakeRange(0, response.length);\n\n    matches = [TORNode.ipv4Regex matchesInString:response options:0\n                                            range:range];\n\n    if (matches.firstObject.numberOfRanges > 0)\n    {\n        self.ipv4Address = [response substringWithRange:[matches.firstObject rangeAtIndex:0]];\n    }\n\n    matches = [TORNode.ipv6Regex matchesInString:response options:0\n                                           range:range];\n\n    if (matches.firstObject.numberOfRanges > 0)\n    {\n        self.ipv6Address = [response substringWithRange:[matches.firstObject rangeAtIndex:0]];\n    }\n\n    if ([response rangeOfString:@\"Exit\"].location != NSNotFound)\n    {\n        self.isExit = YES;\n    }\n}\n\n- (NSString *)localizedCountryName\n{\n    if (!self.countryCode)\n    {\n        return nil;\n    }\n\n    NSString *countryCode = (NSString * _Nonnull)self.countryCode;\n    if (@available(iOS 10.0, macOS 10.12, *)) {\n        return [NSLocale.currentLocale localizedStringForCountryCode:countryCode];\n    } else {\n        return [NSLocale.currentLocale displayNameForKey:NSLocaleCountryCode value:countryCode];\n    }\n}\n\n\n// MARK: NSSecureCoding\n\n+ (BOOL)supportsSecureCoding\n{\n  return YES;\n}\n\n- (id)initWithCoder:(NSCoder *)coder\n{\n    if ((self = [super init]))\n    {\n        _fingerprint = [coder decodeObjectOfClass:NSString.class forKey:@\"fingerprint\"];\n        _nickName = [coder decodeObjectOfClass:NSString.class forKey:@\"nickName\"];\n        _ipv4Address = [coder decodeObjectOfClass:NSString.class forKey:@\"ipv4Address\"];\n        _ipv6Address = [coder decodeObjectOfClass:NSString.class forKey:@\"ipv6Address\"];\n        _countryCode = [coder decodeObjectOfClass:NSString.class forKey:@\"countryCode\"];\n    }\n\n    return self;\n}\n\n- (void)encodeWithCoder:(NSCoder *)coder\n{\n    [coder encodeObject:self.fingerprint forKey:@\"fingerprint\"];\n    [coder encodeObject:self.nickName forKey:@\"nickName\"];\n    [coder encodeObject:self.ipv4Address forKey:@\"ipv4Address\"];\n    [coder encodeObject:self.ipv6Address forKey:@\"ipv6Address\"];\n    [coder encodeObject:self.countryCode forKey:@\"countryCode\"];\n}\n\n\n// MARK: NSObject\n\n- (NSString *)description\n{\n    return [NSString stringWithFormat:@\"<%@: %p> fingerprint=%@, nickName=%@, ipv4Address=%@, ipv6Address=%@, countryCode=%@, localizedCountryName=%@\",\n            self.class, self, self.fingerprint, self.nickName, self.ipv4Address,\n            self.ipv6Address, self.countryCode, self.localizedCountryName];\n}\n\n- (BOOL)isEqual:(id)other\n{\n    if (other == self)\n    {\n        return YES;\n    }\n\n    if (!other || ![other isKindOfClass:self.class])\n    {\n        return NO;\n    }\n\n    return [self.fingerprint isEqualToString:(NSString * _Nonnull)((TORNode *)other).fingerprint];\n}\n\n- (NSUInteger)hash\n{\n    return self.fingerprint.hash;\n}\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Core/TOROnionAuth.h",
    "content": "//\n//  TOROnionAuth.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 29.09.21.\n//\n\n#import <Foundation/Foundation.h>\n#import \"TORAuthKey.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Support for Onion v3 service authentication configuration files.\n */\nNS_SWIFT_NAME(TorOnionAuth)\n@interface TOROnionAuth : NSObject\n\n\n/**\n The directory where this instance expects the private key files to be in.\n */\n@property (nonatomic, nullable, readonly) NSURL *privateUrl;\n\n/**\n The directory where this instance expects the public key files to be in.\n */\n@property (nonatomic, nullable, readonly) NSURL *publicUrl;\n\n/**\n The found public and/or private keys in the base \\c directory.\n\n @see -directory\n */\n@property (nonatomic, nonnull, readonly) NSArray<TORAuthKey *> *keys;\n\n\n/**\n Initialize with a given directory. Will immediately read all keys on disk.\n\n If you have a lot of keys, you might want to do this in a background thread!\n\n @param privateUrl  The base directory where the key files live.\n Should be the same as you set in \\c <ClientOnionAuthDir> for clients.\n\n @param publicUrl  The base directory where the key files live.\n Should be the same as you set in \\c <HiddenServiceDir> for servers.\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#ClientOnionAuthDir\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#HiddenServiceDir\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#_client_authorization\n */\n- (instancetype)initWithPrivateDirUrl:(nullable NSURL *)privateUrl andPublicDirUrl:(nullable NSURL *)publicUrl NS_SWIFT_NAME(init(withPrivateDir:andPublicDir:));\n\n/**\n Initialize with a given directory. Will immediately read all keys on disk.\n\n If you have a lot of keys, you might want to do this in a background thread!\n\n @param privatePath  The base directory where the key files live.\n Should be the same as you set in \\c <ClientOnionAuthDir> for clients.\n\n @param publicPath  The base directory where the key files live.\n Should be the same as you set in \\c <HiddenServiceDir> for servers.\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#ClientOnionAuthDir\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#HiddenServiceDir\n\n @see https://2019.www.torproject.org/docs/tor-manual.html.en#_client_authorization\n */\n- (instancetype)initWithPrivateDir:(NSString *)privatePath andPublicDir:(NSString *)publicPath NS_SWIFT_NAME(init(withPrivateDir:andPublicDir:));\n\n\n/**\n Add an authentication key (public or private) to the configuration.\n\n If a key with the same file name already exists, it will be overwritten. If not, it will be added at the end of the\n \\c keys array.\n\n @param key A new or modified key.\n\n @returns \\c YES on success, \\c NO on failure.\n*/\n- (BOOL)set:(TORAuthKey *)key;\n\n/**\n Remove the key at the specified index.\n\n @param idx The index of the key in \\c keys.\n\n @returns \\c YES on success, \\c NO on failure.\n */\n- (BOOL)removeKeyAtIndex:(NSInteger)idx;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Core/TOROnionAuth.m",
    "content": "//\n//  TOROnionAuth.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 29.09.21.\n//\n\n#import \"TOROnionAuth.h\"\n\n@implementation TOROnionAuth\n\n- (instancetype)initWithPrivateDirUrl:(nullable NSURL *)privateUrl andPublicDirUrl:(nullable NSURL *)publicUrl\n{\n    if ((self = [super init]))\n    {\n        if (![publicUrl.lastPathComponent isEqualToString:@\"authorized_clients\"])\n        {\n            publicUrl = [publicUrl URLByAppendingPathComponent:@\"authorized_clients\" isDirectory:YES];\n        }\n\n        _privateUrl = privateUrl;\n        _publicUrl = publicUrl;\n        _keys = [NSMutableArray new];\n\n        NSMutableArray<NSURL *> *files = [NSMutableArray new];\n        NSError *error;\n\n        NSURL *privateUrl = _privateUrl;\n        if (privateUrl) {\n            NSArray<NSURL *> *privateFiles = [NSFileManager.defaultManager\n                                              contentsOfDirectoryAtURL:privateUrl\n                                              includingPropertiesForKeys:nil options:0\n                                              error:&error];\n\n            if (error)\n            {\n                NSLog(@\"[%@] Error while reading keys: %@\", NSStringFromClass(self.class), error.localizedDescription);\n            }\n            else {\n                if (privateFiles) [files addObjectsFromArray:privateFiles];\n            }\n        }\n\n        NSURL *publicUrl = _publicUrl;\n        if (publicUrl) {\n            NSArray<NSURL *> *publicFiles = [NSFileManager.defaultManager\n                                              contentsOfDirectoryAtURL:publicUrl\n                                              includingPropertiesForKeys:nil options:0\n                                              error:&error];\n\n            if (error)\n            {\n                NSLog(@\"[%@] Error while reading keys: %@\", NSStringFromClass(self.class), error.localizedDescription);\n            }\n            else {\n                if (publicFiles) [files addObjectsFromArray:publicFiles];\n            }\n        }\n\n        for (NSURL *file in files)\n        {\n            if ([TORAuthKey isAuthFile:file])\n            {\n                TORAuthKey *key = [[TORAuthKey alloc] initFromUrl:file];\n\n                if (key) [((NSMutableArray *)_keys) addObject:key];\n            }\n        }\n    }\n\n    return self;\n}\n\n- (instancetype)initWithPrivateDir:(NSString *)privatePath andPublicDir:(NSString *)publicPath\n{\n    return [self initWithPrivateDirUrl:[NSURL fileURLWithPath:privatePath] andPublicDirUrl:[NSURL fileURLWithPath:publicPath]];\n}\n\n\n// MARK: Public Methods\n\n- (BOOL)set:(TORAuthKey *)key\n{\n    NSURL *privateUrl = _privateUrl;\n    NSURL *publicUrl = _publicUrl;\n\n    if (key.isPrivate) {\n        if (privateUrl) {\n            [key setDirectory:privateUrl];\n        }\n        else if (publicUrl) {\n            [key setDirectory:publicUrl];\n        }\n    }\n    else {\n        if (publicUrl) {\n            [key setDirectory:publicUrl];\n        }\n        else if (privateUrl) {\n            [key setDirectory:privateUrl];\n        }\n    }\n\n    if ([key persist])\n    {\n        NSUInteger i = [_keys indexOfObject:key];\n\n        if (i == NSNotFound)\n        {\n            [((NSMutableArray *)_keys) addObject:key];\n        }\n        else {\n            ((NSMutableArray *)_keys)[i] = key;\n        }\n\n        return YES;\n    }\n\n    return NO;\n}\n\n- (BOOL)removeKeyAtIndex:(NSInteger)idx\n{\n    if (idx < 0 || (NSUInteger)idx >= _keys.count) return NO;\n\n    TORAuthKey *key = _keys[idx];\n\n    NSError *error;\n    [NSFileManager.defaultManager removeItemAtURL:key.file error:&error];\n\n    if (error)\n    {\n        NSLog(@\"[%@] Error while removing key: %@\", NSStringFromClass(self.class), error.localizedDescription);\n\n        return NO;\n    }\n\n    [((NSMutableArray *)_keys) removeObjectAtIndex:idx];\n\n    return YES;\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/Classes/Onionmasq/Onionmasq.h",
    "content": "//\n//  Onionmasq.h\n//  Tor\n//\n//  Created by Benjamin Erhart on 30.08.23.\n//\n\n#import <Foundation/Foundation.h>\n#import <Tor/TORConfiguration.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface Onionmasq : NSObject\n\n\ntypedef void (^ReaderCb)(void);\ntypedef bool (^WriterCb)(NSData *packet, NSNumber *version);\ntypedef void (^EventCb)(id);\ntypedef void (^LogCb)(NSString *message);\n\n/**\n Start Onionmasq.\n\n @param readerCallback Called, when Onionmasq wants to read to the TUN interface. After read, this method **needs to call** `receive`!\n @param writerCallback Called, when Onionmasq wants to write to the TUN interface.\n @param stateDir Directory, where Arti can store its state. OPTIONAL. If not provided, will use \\c Library/Application \\c Support/org.torproject.Arti.\n @param cacheDir Directory, where Arti can store its caching data. OPTIONAL. If not providied, will use \\c Library/Cache/org.torproject.Arti.\n @param pcapFile File to write a network trace in PCAP format to.\n @param eventCallback Callback, when an event happens.\n @param logCallback Callback, when a log message arrives.\n */\n+ (void)startWithReader:(ReaderCb)readerCallback\n                 writer:(WriterCb)writerCallback\n               stateDir:(NSURL * _Nullable)stateDir\n               cacheDir:(NSURL * _Nullable)cacheDir\n               pcapFile:(NSURL * _Nullable)pcapFile\n                onEvent:(nullable EventCb)eventCallback\n                  onLog:(nullable LogCb)logCallback;\n\n/**\n Stop Onionmasq.\n */\n+ (void)stop;\n\n/**\n Refresh all circuits.\n\n This causes all new connections after the command is sent to use different circuits to the set currently used.\n */\n+ (void)refreshCircuits;\n\n\n+ (void)setPcapPath:(NSURL *)path;\n\n\n/**\n Get the current count of received bytes since last reset.\n */\n+ (long long)getBytesReceived;\n\n/**\n Get the current count of sent bytes since last reset.\n */\n+ (long long)getBytesSent;\n\n/**\n Reset the global bandwidth counter.\n */\n+ (void)resetCounters;\n\n/**\n Set the country code that proxied connections should use.\n\n You can clear it back to \"no country code\" by passing in `nil`.\n */\n+ (void)setCountryCodeWith:(NSString * _Nullable)countryCode;\n\n/**\n You need to call this, when your `readerCallback` has read data from the TUN device.\n\n @param packets Packets of data.\n */\n+ (void)receive:(NSArray<NSData *> *)packets;\n\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "Tor/Classes/Onionmasq/Onionmasq.m",
    "content": "//\n//  Onionmasq.m\n//  Tor\n//\n//  Created by Benjamin Erhart on 30.08.23.\n//\n\n#import \"Onionmasq.h\"\n#import \"onionmasq_apple.h\"\n\n@implementation Onionmasq\n\nBOOL initialized;\n\nReaderCb readerBlock;\n\nWriterCb writerBlock;\n\nEventCb eventBlock;\n\nLogCb logBlock;\n\nNSRegularExpression *regex;\n\n+ (void)startWithReader:(ReaderCb)readerCallback\n                 writer:(WriterCb)writerCallback\n               stateDir:(NSURL * _Nullable)stateDir\n               cacheDir:(NSURL * _Nullable)cacheDir\n               pcapFile:(NSURL * _Nullable)pcapFile\n                onEvent:(nullable EventCb)eventCallback\n                  onLog:(nullable LogCb)logCallback\n{\n    readerBlock = readerCallback;\n    writerBlock = writerCallback;\n    eventBlock = eventCallback;\n    logBlock = logCallback;\n\n    NSFileManager *fm = NSFileManager.defaultManager;\n\n    if (!stateDir) {\n        stateDir = [[fm URLsForDirectory:NSApplicationSupportDirectory inDomains:NSUserDomainMask]\n                     firstObject];\n    }\n\n    if (!cacheDir) {\n        cacheDir = [[fm URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask]\n                     firstObject];\n    }\n\n    assert(stateDir.isFileURL);\n    assert(cacheDir.isFileURL);\n\n    if (!initialized) {\n        // Remove ANSI colors.\n        regex = [[NSRegularExpression alloc] initWithPattern:@\"\\\\x1b\\\\[[0-9;]*m\" options:NSRegularExpressionDotMatchesLineSeparators error:nil];\n\n        init(&eventCb, &logCb);\n\n        if (pcapFile) {\n            [self setPcapPath:pcapFile];\n        }\n    }\n\n    runProxy(&readerCb,\n             &writerCb,\n             [cacheDir.path cStringUsingEncoding:NSUTF8StringEncoding],\n             [stateDir.path cStringUsingEncoding:NSUTF8StringEncoding]);\n}\n\n+ (void)stop\n{\n    closeProxy();\n\n    readerBlock = nil;\n    writerBlock = nil;\n    eventBlock = nil;\n    logBlock = nil;\n}\n\n+ (void)refreshCircuits\n{\n    refreshCircuits();\n}\n\n+ (void)setPcapPath:(NSURL *)path\n{\n    assert(path.isFileURL);\n\n    NSFileManager *fm = NSFileManager.defaultManager;\n\n    if (![fm fileExistsAtPath:path.path]) {\n        [fm createFileAtPath:path.path contents:nil attributes:nil];\n    }\n\n    setPcapPath([path.path cStringUsingEncoding:NSUTF8StringEncoding]);\n}\n\n\n+ (long long)getBytesReceived\n{\n    return getBytesReceived();\n}\n\n+ (long long)getBytesSent\n{\n    return getBytesSent();\n}\n\n+ (void)resetCounters\n{\n    resetCounters();\n}\n\n+ (void)setCountryCodeWith:(NSString *)countryCode\n{\n    setCountryCode([countryCode cStringUsingEncoding:NSUTF8StringEncoding]);\n}\n\n+ (void)receive:(NSArray<NSData *> *)packets\n{\n    const uint8_t * pointers[packets.count];\n    unsigned long lens[packets.count];\n\n    for (NSUInteger i = 0; i < packets.count; i++) {\n        pointers[i] = packets[i].bytes;\n        lens[i] = packets[i].length;\n    }\n\n    receive(pointers, lens, packets.count);\n}\n\n\nvoid readerCb(void)\n{\n    if (readerBlock)\n    {\n        readerBlock();\n    }\n}\n\nbool writerCb(const uint8_t *packet, size_t len)\n{\n    if (writerBlock)\n    {\n        NSData *data = [[NSData alloc] initWithBytes:packet length:len];\n\n        NSNumber *v = [[NSNumber alloc] initWithShort:((const unsigned char *)data.bytes)[0] >> 4];\n\n        return writerBlock(data, v);\n    }\n    else {\n        return false;\n    }\n}\n\nvoid eventCb(const char * event)\n{\n    if (eventBlock)\n    {\n        NSString *evt = [[NSString alloc] initWithUTF8String:event];\n        NSData *data = [evt dataUsingEncoding:NSUTF8StringEncoding];\n        NSError *error = nil;\n\n        id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];\n\n        if (error)\n        {\n            eventBlock(evt);\n        }\n        else {\n            eventBlock(object);\n        }\n    }\n}\n\nvoid logCb(const char * log)\n{\n    if (logBlock)\n    {\n        NSMutableString *msg = [[NSMutableString alloc] initWithUTF8String:log];\n\n        [regex replaceMatchesInString:msg options:0 range:NSMakeRange(0, msg.length) withTemplate:@\"\"];\n\n        logBlock(msg);\n    }\n}\n\n\n@end\n"
  },
  {
    "path": "Tor/download.sh",
    "content": "#!/bin/sh\n\nVERSION=$1\nNAMES=$2\nshift\nshift\nchecksums=( \"$@\" )\n\nload() {\n    curl --remote-name --progress-bar --location $1\n}\n\ncd Tor/Assets\n\n# Test if file is older then 1 week.\nOLD=\"$(find geoip -mmin +10080 2>/dev/null)\"\n\n# Only download, if files are not existing or older than 1 week.\nif [ ! -f geoip -o ! -z \"$OLD\" ]; then\n    load https://gitlab.torproject.org/tpo/core/tor/-/raw/main/src/config/geoip\n    load https://gitlab.torproject.org/tpo/core/tor/-/raw/main/src/config/geoip6\nfi\n\ncd ../..\n\ndeclare -i i=0\n\nfor name in $NAMES\ndo\n    if [ ! -d \"$name.xcframework\" ]; then\n        load \"https://github.com/iCepa/Tor.framework/releases/download/$VERSION/$name.xcframework.zip\"\n\n        actual=$(shasum -a 256 \"$name.xcframework.zip\" | awk '{print $1}')\n\n        if [ \"$actual\" != \"${checksums[$i]}\" ]; then\n            echo \"ERROR: Checksum verification failed: $actual != ${checksums[$i]}\"\n\n            exit 1\n        fi\n\n        unzip \"$name.xcframework.zip\"\n        rm \"$name.xcframework.zip\"\n    fi\n\n    i+=1\ndone\n"
  },
  {
    "path": "Tor/mmap-cache.patch",
    "content": "From 4d6875d271dd5208e2c89a174fbff2e74004921b Mon Sep 17 00:00:00 2001\nFrom: =?UTF-8?q?Alexander=20F=C3=A6r=C3=B8y?= <ahf@torproject.org>\nDate: Sun, 27 Aug 2023 23:12:05 +0200\nSubject: [PATCH] Memory map our journal file instead of reading directly.\n\nSee: tpo/core/tor#40832\n---\n src/feature/nodelist/microdesc.c | 65 ++++++++++++++++++++------------\n 1 file changed, 41 insertions(+), 24 deletions(-)\n\ndiff --git a/src/feature/nodelist/microdesc.c b/src/feature/nodelist/microdesc.c\nindex 9e5f0bb9a4..64a25abb92 100644\n--- a/src/feature/nodelist/microdesc.c\n+++ b/src/feature/nodelist/microdesc.c\n@@ -56,8 +56,8 @@ struct microdesc_cache_t {\n   char *journal_fname;\n   /** Mmap'd contents of the cache file, or NULL if there is none. */\n   tor_mmap_t *cache_content;\n-  /** Number of bytes used in the journal file. */\n-  size_t journal_len;\n+  /** Mmap'd contents of the journal file, or NULL if there is none. */\n+  tor_mmap_t *journal_content;\n   /** Number of bytes in descriptors removed as too old. */\n   size_t bytes_dropped;\n \n@@ -422,9 +422,6 @@ microdescs_add_list_to_cache(microdesc_cache_t *cache,\n         /* we already warned in dump_microdescriptor */\n         abort_writing_to_file(open_file);\n         fd = -1;\n-      } else {\n-        md->saved_location = SAVED_IN_JOURNAL;\n-        cache->journal_len += size;\n       }\n     } else {\n       md->saved_location = where;\n@@ -483,6 +480,17 @@ microdesc_cache_clear(microdesc_cache_t *cache)\n     }\n     cache->cache_content = NULL;\n   }\n+\n+  if (cache->journal_content) {\n+    int res = tor_munmap_file(cache->journal_content);\n+    if (res != 0) {\n+      log_warn(LD_FS,\n+               \"tor_munmap_file() failed clearing journal cache; \"\n+               \"we are probably about to leak memory.\");\n+      /* TODO something smarter? */\n+    }\n+  }\n+\n   cache->total_len_seen = 0;\n   cache->n_seen = 0;\n   cache->bytes_dropped = 0;\n@@ -514,20 +522,19 @@ warn_if_nul_found(const char *inp, size_t len, int64_t offset,\n int\n microdesc_cache_reload(microdesc_cache_t *cache)\n {\n-  struct stat st;\n-  char *journal_content;\n   smartlist_t *added;\n-  tor_mmap_t *mm;\n+  tor_mmap_t *mm_cache;\n+  tor_mmap_t *mm_journal;\n   int total = 0;\n \n   microdesc_cache_clear(cache);\n \n   cache->is_loaded = 1;\n \n-  mm = cache->cache_content = tor_mmap_file(cache->cache_fname);\n-  if (mm) {\n-    warn_if_nul_found(mm->data, mm->size, 0, \"scanning microdesc cache\");\n-    added = microdescs_add_to_cache(cache, mm->data, mm->data+mm->size,\n+  mm_cache = cache->cache_content = tor_mmap_file(cache->cache_fname);\n+  if (mm_cache) {\n+    warn_if_nul_found(mm_cache->data, mm_cache->size, 0, \"scanning microdesc cache\");\n+    added = microdescs_add_to_cache(cache, mm_cache->data, mm_cache->data+mm_cache->size,\n                                     SAVED_IN_CACHE, 0, -1, NULL);\n     if (added) {\n       total += smartlist_len(added);\n@@ -535,21 +542,19 @@ microdesc_cache_reload(microdesc_cache_t *cache)\n     }\n   }\n \n-  journal_content = read_file_to_str(cache->journal_fname,\n-                                     RFTS_IGNORE_MISSING, &st);\n-  if (journal_content) {\n-    cache->journal_len = strlen(journal_content);\n-    warn_if_nul_found(journal_content, (size_t)st.st_size, 0,\n-                      \"reading microdesc journal\");\n-    added = microdescs_add_to_cache(cache, journal_content,\n-                                    journal_content+st.st_size,\n+  mm_journal = cache->journal_content = tor_mmap_file(cache->journal_fname);\n+\n+  if (mm_journal) {\n+    warn_if_nul_found(mm_journal->data, mm_journal->size, 0, \"reading microdesc journal\");\n+    added = microdescs_add_to_cache(cache, mm_journal->data,\n+                                    mm_journal->data+mm_journal->size,\n                                     SAVED_IN_JOURNAL, 0, -1, NULL);\n     if (added) {\n       total += smartlist_len(added);\n       smartlist_free(added);\n     }\n-    tor_free(journal_content);\n   }\n+\n   log_info(LD_DIR, \"Reloaded microdescriptor cache. Found %d descriptors.\",\n            total);\n \n@@ -664,7 +669,8 @@ should_rebuild_md_cache(microdesc_cache_t *cache)\n {\n     const size_t old_len =\n       cache->cache_content ? cache->cache_content->size : 0;\n-    const size_t journal_len = cache->journal_len;\n+    const size_t journal_len =\n+      cache->journal_content ? cache->journal_content->size : 0;\n     const size_t dropped = cache->bytes_dropped;\n \n     if (journal_len < 16384)\n@@ -727,7 +733,7 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)\n   log_info(LD_DIR, \"Rebuilding the microdescriptor cache...\");\n \n   orig_size = (int)(cache->cache_content ? cache->cache_content->size : 0);\n-  orig_size += (int)cache->journal_len;\n+  orig_size += (int)(cache->journal_content ? cache->journal_content->size : 0);\n \n   fd = start_writing_to_file(cache->cache_fname,\n                              OPEN_FLAGS_REPLACE|O_BINARY,\n@@ -826,8 +832,19 @@ microdesc_cache_rebuild(microdesc_cache_t *cache, int force)\n \n   smartlist_free(wrote);\n \n+  // We unmap the journal file and use write_str_to_file() to empty it.\n+  res = tor_munmap_file(cache->journal_content);\n+\n+  if (res != 0) {\n+    log_warn(LD_FS,\n+             \"tor_munmap_file() failed clearing journal; \"\n+             \"we are probably about to leak memory.\");\n+    /* TODO something smarter? */\n+  }\n+\n+  cache->journal_content = NULL;\n   write_str_to_file(cache->journal_fname, \"\", 1);\n-  cache->journal_len = 0;\n+\n   cache->bytes_dropped = 0;\n \n   new_size = cache->cache_content ? (int)cache->cache_content->size : 0;\n-- \n2.41.0\n"
  },
  {
    "path": "Tor/onionmasq.sh",
    "content": "#!/usr/bin/env sh\n\n# Get absolute path to this script.\nSCRIPTDIR=$(cd `dirname $0` && pwd)\nWORKDIR=\"$SCRIPTDIR/onionmasq\"\nFILENAME=\"libonionmasq_apple.a\"\n\n\n# Assume we're in Xcode, which means we're probably cross-compiling.\n# In this case, we need to add an extra library search path for build scripts and proc-macros,\n# which run on the host instead of the target.\n# (macOS Big Sur does not have linkable libraries in /usr/lib/.)\nexport LIBRARY_PATH=\"${SDKROOT}/usr/lib:${LIBRARY_PATH:-}\"\n\n# The $PATH used by Xcode likely won't contain Cargo, fix that.\n# This assumes a default `rustup` setup.\nexport PATH=\"$HOME/.cargo/bin:$PATH\"\n\n\ncd \"$WORKDIR\"\n\n# NOTE: This won't be executed, when this script is set up as a \"build phase script\".\n# There seems no way to configure CocoaPods to make this run as a target script,\n# where it would be executed.\n# However, this is here for documentary purposes and in case you want to set\n# this manually as an \"external target\" script.\n# See https://kelan.io/2009/run-script-while-cleaning-in-xcode/\nif [ \"$ACTION\" = \"clean\" ]; then\n    make clean\n\n    exit 0\nfi\n\nexport MACOSX_DEPLOYMENT_TARGET=10.13\n\nCONF_LOWER=\"$(echo $CONFIGURATION | tr '[:upper:]' '[:lower:]')\"\n\nif [ \"${PLATFORM_NAME:-iphoneos}\" = \"macosx\" ]; then\n    if [ \"${CONF_LOWER:-debug}\" = \"release\" ]; then\n        TARGET_PLATFORM=\"universal-macos\"\n\n        make \"macos-${CONF_LOWER}\"\n    else\n        if [ \"${ARCHS:-x86}\" = \"arm64\" ]; then\n            TARGET_PLATFORM=\"aarch64-apple-darwin\"\n        else\n            TARGET_PLATFORM=\"x86_64-apple-darwin\"\n        fi\n\n        make \"macos-verbose-${TARGET_PLATFORM}\"\n    fi\n\nelif [ \"${PLATFORM_NAME:-iphoneos}\" = \"iphonesimulator\" ]; then\n    if [ \"${ARCHS:-x86}\" = \"arm64\" ]; then\n        TARGET_PLATFORM=\"aarch64-apple-ios-sim\"\n    else\n        TARGET_PLATFORM=\"x86_64-apple-ios\"\n    fi\n\n    make \"ios-${CONF_LOWER}-${TARGET_PLATFORM}\"\nelse\n    TARGET_PLATFORM=\"aarch64-apple-ios\"\n\n    make \"ios-${CONF_LOWER}-${TARGET_PLATFORM}\"\nfi\n\n\nSOURCE=\"${WORKDIR}/target/${TARGET_PLATFORM}/${CONF_LOWER}/${FILENAME}\"\n\nif [ -e \"${SOURCE}\" ]; then\n    echo \"Link '${SOURCE}' to '${BUILT_PRODUCTS_DIR}'\"\n\n    rm -f \"${BUILT_PRODUCTS_DIR}/${FILENAME}\"\n\n    ln -s \"${SOURCE}\" \"${BUILT_PRODUCTS_DIR}\"\nfi\n"
  },
  {
    "path": "Tor.podspec",
    "content": "Pod::Spec.new do |m|\n\n  m.name             = 'Tor'\n  m.version          = '409.6.1'\n  m.summary          = 'Tor.framework is the easiest way to embed Tor in your iOS application.'\n  m.description      = 'Tor.framework is the easiest way to embed Tor in your iOS application. Currently, the framework compiles in static versions of tor, libevent, openssl, and liblzma.'\n\n  m.homepage         = 'https://github.com/iCepa/Tor.framework'\n  m.license          = { :type => 'MIT', :file => 'LICENSE' }\n  m.authors          = {\n    'Conrad Kramer' => 'conrad@conradkramer.com',\n    'Chris Ballinger' => 'chris@chatsecure.org',\n    'Mike Tigas' => 'mike@tig.as',\n    'Benjamin Erhart' => 'berhart@netzarchitekten.com', }\n  m.source           = {\n    :git => 'https://github.com/iCepa/Tor.framework.git',\n    :branch => 'pure_pod',\n    :tag => \"v#{m.version}\" }\n  m.social_media_url = 'https://chaos.social/@tla'\n\n  m.ios.deployment_target = '15.0'\n  m.macos.deployment_target = '11.0'\n\n  m.prepare_command = \"Tor/download.sh v#{m.version} \\\"tor tor-nolzma\\\" 518a2984a6f693265833d31c7ed8c7cb0556765f1a3e5b2d7d0138c14b32f70d 9b621374e184a2634550c6fb5d7590c57b3fd3fc160947950e1f7b013fc62a73\"\n\n  m.subspec 'Core' do |s|\n    s.requires_arc = true\n\n    s.source_files = 'Tor/Classes/Core/**/*'\n  end\n\n  m.subspec 'CTor' do |s|\n    s.dependency 'Tor/Core'\n\n    s.source_files = 'Tor/Classes/CTor/**/*'\n\n    s.vendored_frameworks = 'tor.xcframework'\n    s.libraries = 'z'\n\n    s.pod_target_xcconfig = {\n      'HEADER_SEARCH_PATHS' => '$(inherited) \"${PODS_TARGET_SRCROOT}/tor.xcframework/ios-arm64/tor.framework/Headers\"',\n    }\n\n    s.preserve_paths = 'tor.xcframework', 'download.sh'\n  end\n\n  m.subspec 'CTor-NoLZMA' do |s|\n    s.dependency 'Tor/Core'\n\n    s.source_files = 'Tor/Classes/CTor/**/*'\n\n    s.vendored_frameworks = 'tor-nolzma.xcframework'\n    s.libraries = 'z'\n\n    s.pod_target_xcconfig = {\n      'HEADER_SEARCH_PATHS' => '$(inherited) \"${PODS_TARGET_SRCROOT}/tor-nolzma.xcframework/ios-arm64/tor-nolzma.framework/Headers\"',\n    }\n\n    s.preserve_paths = 'tor-nolzma.xcframework', 'Tor/download.sh'\n  end\n\n  m.subspec 'GeoIP' do |s|\n    s.dependency 'Tor/CTor'\n\n    s.resource_bundles = {\n      'GeoIP' => ['Tor/Assets/geoip', 'Tor/Assets/geoip6']\n    }\n  end\n\n  m.subspec 'GeoIP-NoLZMA' do |s|\n    s.dependency 'Tor/CTor-NoLZMA'\n\n    s.resource_bundles = {\n      'GeoIP' => ['Tor/Assets/geoip', 'Tor/Assets/geoip6']\n    }\n  end\n\n  m.default_subspecs = 'CTor'\n\nend\n"
  },
  {
    "path": "build-xcframework.sh",
    "content": "#!/bin/sh\n\nset -eo pipefail\n\nPATH=$PATH:/usr/local/bin:/usr/local/opt/gettext/bin:/usr/local/opt/automake/bin:/usr/local/opt/aclocal/bin:/opt/homebrew/bin\n\nXZ_VERSION=\"v5.8.2\"\nOPENSSL_VERSION=\"openssl-3.6.1\"\nLIBEVENT_VERSION=\"release-2.1.12-stable\"\nTOR_VERSION=\"tor-0.4.9.6\"\nARTI_MOBILE_VERSION=\"arti-1.7.0\"\nARTI_VERSION=\"main\"\n\n\ncd \"$(dirname \"$0\")\"\nROOT=\"$(pwd -P)\"\n\nDEBUG=\"\"\nWITH_CTOR=\"\"\nWITH_ARTI=\"\"\n\nwhile getopts acdl flag\ndo\n    case \"$flag\" in\n        d) DEBUG=\"1\";;\n        c) WITH_CTOR=\"1\";;\n        a) WITH_ARTI=\"1\";;\n    esac\ndone\n\nif [ -z $DEBUG ]; then\n    BUILDDIR=\"$(mktemp -d)\"\nelse\n    set -x\n    BUILDDIR=\"$ROOT/build\"\n    mkdir -p \"$BUILDDIR\"\nfi\n\necho \"Build dir: $BUILDDIR\"\n\nbuild_liblzma() {\n    SDK=$1\n    ARCH=$2\n    MIN=$3\n\n    SOURCE=\"$BUILDDIR/xz\"\n    LOG=\"$BUILDDIR/liblzma-$SDK-$ARCH.log\"\n\n    if [ ! -d \"$SOURCE\" ]; then\n        echo \"- Check out XZ project\"\n\n        cd \"$BUILDDIR\"\n        git clone --recursive --shallow-submodules --depth 1 --branch \"$XZ_VERSION\" https://github.com/tukaani-project/xz.git >> \"$LOG\" 2>&1\n    fi\n\n    echo \"- Build liblzma for $ARCH ($SDK)\"\n\n    cd \"$SOURCE\"\n\n    if [ -f Makefile ]; then\n        make distclean >> \"$LOG\" 2>&1\n    fi\n\n    # Generate the configure script.\n    if [ ! -f ./configure ]; then\n        LIBTOOLIZE=glibtoolize\n        ./autogen.sh >> \"$LOG\" 2>&1\n    fi\n\n    SDKPATH=\"$(xcrun --sdk ${SDK} --show-sdk-path)\"\n    CLANG=\"$(xcrun -f --sdk ${SDK} clang)\"\n\n    ./configure \\\n        --disable-shared \\\n        --enable-static \\\n        --disable-doc \\\n        --disable-scripts \\\n        --disable-xz \\\n        --disable-xzdec \\\n        --disable-lzmadec \\\n        --disable-lzmainfo \\\n        --disable-lzma-links \\\n        --prefix \"$BUILDDIR/$SDK/liblzma-$ARCH\" \\\n        CC=\"$CLANG -arch ${ARCH}\" \\\n        CPP=\"$CLANG -E -arch ${ARCH}\" \\\n        CFLAGS=\"-isysroot ${SDKPATH} -m$SDK-version-min=$MIN -fembed-bitcode -Wno-unknown-warning-option\" \\\n        LDFLAGS=\"-isysroot ${SDKPATH} -fembed-bitcode\" \\\n        cross_compiling=\"yes\" \\\n        ac_cv_func_clock_gettime=\"no\" \\\n        >> \"$LOG\" 2>&1\n\n    make -j$(sysctl -n hw.logicalcpu_max) >> \"$LOG\" 2>&1\n    make install >> \"$LOG\" 2>&1\n}\n\nbuild_libssl() {\n    SDK=$1\n    ARCH=$2\n    MIN=$3\n\n    SOURCE=\"$BUILDDIR/openssl\"\n    LOG=\"$BUILDDIR/libssl-$SDK-$ARCH.log\"\n\n    if [ ! -d \"$SOURCE\" ]; then\n        echo \"- Check out OpenSSL project\"\n\n        cd \"$BUILDDIR\"\n        git clone --recursive --shallow-submodules --depth 1 --branch \"$OPENSSL_VERSION\" https://github.com/openssl/openssl.git >> \"$LOG\" 2>&1\n    fi\n\n    echo \"- Build OpenSSL for $ARCH ($SDK)\"\n\n    cd \"$SOURCE\"\n\n    if [ -f Makefile ]; then\n        make distclean >> \"$LOG\" 2>&1\n    fi\n\n    if [ \"$SDK\" = \"iphoneos\" ]; then\n        if [ \"$ARCH\" = \"arm64\" ]; then\n            PLATFORM_FLAGS=\"no-async zlib-dynamic enable-ec_nistp_64_gcc_128\"\n            CONFIG=\"ios64-xcrun\"\n        elif [ \"$ARCH\" = \"armv7\" ]; then\n            PLATFORM_FLAGS=\"no-async zlib-dynamic\"\n            CONFIG=\"ios-xcrun\"\n        else\n            echo \"OpenSSL configuration error: $ARCH on $SDK not supported!\"\n        fi\n    elif [ \"$SDK\" = \"iphonesimulator\" ]; then\n        if [ \"$ARCH\" = \"arm64\" ]; then\n            PLATFORM_FLAGS=\"no-async zlib-dynamic enable-ec_nistp_64_gcc_128\"\n            CONFIG=\"iossimulator-xcrun\"\n        elif [ \"$ARCH\" = \"i386\" ]; then\n            PLATFORM_FLAGS=\"no-asm\"\n            CONFIG=\"iossimulator-xcrun\"\n        elif [ \"$ARCH\" = \"x86_64\" ]; then\n            PLATFORM_FLAGS=\"no-asm enable-ec_nistp_64_gcc_128\"\n            CONFIG=\"iossimulator-xcrun\"\n        else\n            echo \"OpenSSL configuration error: $ARCH on $SDK not supported!\"\n        fi\n    elif [ \"$SDK\" = \"macosx\" ]; then\n        if [ \"$ARCH\" = \"i386\" ]; then\n            PLATFORM_FLAGS=\"no-asm\"\n            CONFIG=\"darwin-i386-cc\"\n        elif [ \"$ARCH\" = \"x86_64\" ]; then\n            PLATFORM_FLAGS=\"no-asm enable-ec_nistp_64_gcc_128\"\n            CONFIG=\"darwin64-x86_64-cc\"\n        elif [ \"$ARCH\" = \"arm64\" ]; then\n            PLATFORM_FLAGS=\"no-asm enable-ec_nistp_64_gcc_128\"\n            CONFIG=\"darwin64-arm64-cc\"\n        else\n            echo \"OpenSSL configuration error: $ARCH on $SDK not supported!\"\n        fi\n    fi\n\n    if [ -n \"$CONFIG\" ]; then\n        ./Configure \\\n            no-shared \\\n            ${PLATFORM_FLAGS} \\\n            --prefix=\"$BUILDDIR/$SDK/libssl-$ARCH\" \\\n            ${CONFIG} \\\n            CC=\"$(xcrun --sdk $SDK --find clang) -isysroot $(xcrun --sdk $SDK --show-sdk-path) -arch ${ARCH} -m$SDK-version-min=$MIN -fembed-bitcode\" \\\n            >> \"$LOG\" 2>&1\n\n        make depend >> \"$LOG\" 2>&1\n        make \"-j$(sysctl -n hw.logicalcpu_max)\" build_libs >> \"$LOG\" 2>&1\n        make install_dev >> \"$LOG\" 2>&1\n    fi\n}\n\nbuild_libevent() {\n    SDK=$1\n    ARCH=$2\n    MIN=$3\n\n    SOURCE=\"$BUILDDIR/libevent\"\n    LOG=\"$BUILDDIR/libevent-$SDK-$ARCH.log\"\n\n    if [ ! -d \"$SOURCE\" ]; then\n        echo \"- Check out libevent project\"\n\n        cd \"$BUILDDIR\"\n        git clone --recursive --shallow-submodules --depth 1 --branch \"$LIBEVENT_VERSION\" https://github.com/libevent/libevent.git >> \"$LOG\" 2>&1\n    fi\n\n    echo \"- Build libevent for $ARCH ($SDK)\"\n\n    cd \"$SOURCE\"\n\n    if [ -f Makefile ]; then\n        make distclean >> \"$LOG\" 2>&1\n    fi\n\n    # Generate the configure script.\n    if [ ! -f ./configure ]; then\n        ./autogen.sh >> \"$LOG\" 2>&1\n    fi\n\n    CLANG=\"$(xcrun -f --sdk ${SDK} clang)\"\n    SDKPATH=\"$(xcrun --sdk ${SDK} --show-sdk-path)\"\n    DEST=\"$BUILDDIR/$SDK/libevent-$ARCH\"\n\n    ./configure \\\n        --disable-shared \\\n        --disable-openssl \\\n        --disable-libevent-regress \\\n        --disable-samples \\\n        --disable-doxygen-html \\\n        --enable-static \\\n        --enable-gcc-hardening \\\n        --disable-debug-mode \\\n        --prefix=\"$DEST\" \\\n        CC=\"$CLANG -arch ${ARCH}\" \\\n        CPP=\"$CLANG -E -arch ${ARCH}\" \\\n        CFLAGS=\"-isysroot ${SDKPATH} -m$SDK-version-min=$MIN -fembed-bitcode\" \\\n        LDFLAGS=\"-isysroot ${SDKPATH} -L$DEST -fembed-bitcode\" \\\n        cross_compiling=\"yes\" \\\n        ac_cv_func_clock_gettime=\"no\" \\\n        ac_cv_func_pipe2=\"no\" \\\n        >> \"$LOG\" 2>&1\n\n    make -j$(sysctl -n hw.logicalcpu_max) >> \"$LOG\" 2>&1\n    make install >> \"$LOG\" 2>&1\n}\n\nbuild_libtor() {\n    SDK=$1\n    ARCH=$2\n    MIN=$3\n    NO_LZMA=$4\n\n    SOURCE=\"$BUILDDIR/tor\"\n\n    if [ -z \"$NO_LZMA\" ]; then\n        LOG=\"$BUILDDIR/libtor-$SDK-$ARCH.log\"\n        LZMA=\"yes\"\n        DEST=\"$BUILDDIR/$SDK/libtor-$ARCH\"\n    else\n        LOG=\"$BUILDDIR/libtor-nolzma-$SDK-$ARCH.log\"\n        LZMA=\"no\"\n        DEST=\"$BUILDDIR/$SDK/libtor-nolzma-$ARCH\"\n    fi\n\n    if [ ! -d \"$SOURCE\" ]; then\n        echo \"- Check out Tor project\"\n\n        cd \"$BUILDDIR\"\n        git clone --recursive --shallow-submodules --depth 1 --branch \"$TOR_VERSION\" https://gitlab.torproject.org/tpo/core/tor.git >> \"$LOG\" 2>&1\n    fi\n\n    if [ -z \"$NO_LZMA\" ]; then\n        echo \"- Build libtor for $ARCH ($SDK)\"\n    else\n        echo \"- Build libtor-nolzma for $ARCH ($SDK)\"\n    fi\n\n    cd \"$SOURCE\"\n\n    if [ -f Makefile ]; then\n        make distclean >> \"$LOG\" 2>&1\n    fi\n\n    ## Apply patches:\n    git restore . >> \"$LOG\" 2>&1\n    git apply \"$ROOT/Tor/mmap-cache.patch\" >> \"$LOG\" 2>&1\n\n    # Generate the configure script.\n    if [ ! -f ./configure ]; then\n        # FIXME: This fixes `Tor/tor/autogen.sh`. Check if that was changed and remove this patch.\n        sed -i'.backup' -e 's/all,error/no-obsolete,error/' autogen.sh\n\n        ./autogen.sh >> \"$LOG\" 2>&1\n\n        # FIXME: Undoes the patch. Remove, when it becomes unnecessary.\n        rm autogen.sh && mv autogen.sh.backup autogen.sh\n    fi\n\n    CLANG=\"$(xcrun -f --sdk ${SDK} clang)\"\n    SDKPATH=\"$(xcrun --sdk ${SDK} --show-sdk-path)\"\n\n    ./configure \\\n        --enable-silent-rules \\\n        --enable-pic \\\n        --disable-module-relay \\\n        --disable-module-dirauth \\\n        --disable-tool-name-check \\\n        --disable-unittests \\\n        --enable-static-openssl \\\n        --enable-static-libevent \\\n        --disable-asciidoc \\\n        --disable-system-torrc \\\n        --disable-linker-hardening \\\n        --disable-dependency-tracking \\\n        --disable-manpage \\\n        --disable-html-manual \\\n        --disable-gcc-warnings-advisory \\\n        --enable-lzma=\"$LZMA\" \\\n        --disable-zstd \\\n        --with-libevent-dir=\"$BUILDDIR/$SDK/libevent-$ARCH\" \\\n        --with-openssl-dir=\"$BUILDDIR/$SDK/libssl-$ARCH\" \\\n        --prefix=\"$DEST\" \\\n        CC=\"$CLANG -arch ${ARCH} -isysroot ${SDKPATH}\" \\\n        CPP=\"$CLANG -E -arch ${ARCH} -isysroot ${SDKPATH}\" \\\n        CPPFLAGS=\"-fembed-bitcode -Isrc/core -I$BUILDDIR/$SDK/libssl-$ARCH/include -I$BUILDDIR/$SDK/libevent-$ARCH/include -m$SDK-version-min=$MIN\" \\\n        LDFLAGS=\"-lz -fembed-bitcode\" \\\n        LZMA_CFLAGS=\"-I$BUILDDIR/$SDK/liblzma-$ARCH/include\" \\\n        LZMA_LIBS=\"$BUILDDIR/$SDK/liblzma-$ARCH/lib/liblzma.a\" \\\n        cross_compiling=\"yes\" \\\n        ac_cv_func__NSGetEnviron=\"no\" \\\n        ac_cv_func_clock_gettime=\"no\" \\\n        ac_cv_func_getentropy=\"no\" \\\n        ac_cv_func_pipe2=\"no\" \\\n        >> \"$LOG\" 2>&1\n\n    # There seems to be a race condition with the above configure and the later cp.\n    # Just sleep a little so the correct file is copied and delete the old one before.\n    sleep 2\n    rm -f src/lib/cc/orconfig.h >> \"$LOG\" 2>&1\n    cp orconfig.h \"src/lib/cc/\" >> \"$LOG\" 2>&1\n\n    make libtor.a -j$(sysctl -n hw.logicalcpu_max) V=1 >> \"$LOG\" 2>&1\n\n    mkdir -p \"$DEST/lib\" >> \"$LOG\" 2>&1\n    mkdir -p \"$DEST/include\" >> \"$LOG\" 2>&1\n    mv libtor.a \"$DEST/lib\" >> \"$LOG\" 2>&1\n    rsync --archive --include='*.h' -f 'hide,! */' --prune-empty-dirs src/* \"$DEST/include\" >> \"$LOG\" 2>&1\n    cp orconfig.h \"$DEST/include/\" >> \"$LOG\" 2>&1\n\n    mv micro-revision.i \"$DEST\" >> \"$LOG\" 2>&1\n}\n\nrust_target() {\n    SDK=$1\n    ARCH=$2\n\n    export IPHONEOS_DEPLOYMENT_TARGET=15.0\n    export MACOSX_DEPLOYMENT_TARGET=11.0\n\n    TARGET=\"aarch64-apple-ios\"\n\n    if [ \"${SDK:-iphoneos}\" = \"macosx\" ]; then\n        if [ \"${ARCH:-x86}\" = \"arm64\" ]; then\n            TARGET=\"aarch64-apple-darwin\"\n        else\n            TARGET=\"x86_64-apple-darwin\"\n        fi\n    elif [ \"${SDK:-iphoneos}\" = \"iphonesimulator\" ]; then\n        if [ \"${ARCH:-x86}\" = \"arm64\" ]; then\n            TARGET=\"aarch64-apple-ios-sim\"\n        else\n            TARGET=\"x86_64-apple-ios\"\n        fi\n    fi\n}\n\nbuild_libarti() {\n    SDK=$1\n    ARCH=$2\n\n    SOURCE=\"$BUILDDIR/arti-mobile-ex\"\n    LOG=\"$BUILDDIR/arti-$SDK-$ARCH.log\"\n\n    if [ ! -d \"$SOURCE\" ]; then\n        echo \"- Check out arti-mobile-ex project\"\n\n        cd \"$BUILDDIR\"\n        git clone --recursive --shallow-submodules --depth 1 --branch \"$ARTI_MOBILE_VERSION\" https://gitlab.com/guardianproject/tormobile/arti-mobile-ex.git >> \"$LOG\" 2>&1\n    fi\n\n    echo \"- Build arti-mobile-ex for $ARCH ($SDK)\"\n\n    cd \"$SOURCE/common\"\n\n    rust_target $SDK $ARCH\n\n    cargo build --locked --target \"$TARGET\" --release --target-dir \"$BUILDDIR/$SDK/libarti-$ARCH\" >> \"$LOG\" 2>&1\n\n    mkdir -p \"$BUILDDIR/$SDK/libarti-$ARCH/lib\" >> \"$LOG\" 2>&1\n    mv \"$BUILDDIR/$SDK/libarti-$ARCH/$TARGET/release/libarti_mobile_ex.a\" \"$BUILDDIR/$SDK/libarti-$ARCH/lib/\" >> \"$LOG\" 2>&1\n}\n\n### Experimental! Not working.\n#build_libartirpc() {\n#    SDK=$1\n#    ARCH=$2\n#\n#    SOURCE=\"$BUILDDIR/arti\"\n#    LOG=\"$BUILDDIR/artirpc-$SDK-$ARCH.log\"\n#\n#    if [ ! -d \"$SOURCE\" ]; then\n#        echo \"- Check out arti project\"\n#\n#        cd \"$BUILDDIR\"\n#        git clone --recursive --shallow-submodules --depth 1 --branch \"$ARTI_VERSION\" https://gitlab.torproject.org/tpo/core/arti.git >> \"$LOG\" 2>&1\n#    fi\n#\n#    echo \"- Build arti-rpc-client-core for $ARCH ($SDK)\"\n#\n#    cd \"$SOURCE\"\n#\n#    rust_target $SDK $ARCH\n#\n#    cargo build --locked --package arti-rpc-client-core --features=full --target \"$TARGET\" --release --target-dir \"$BUILDDIR/$SDK/libartirpc-$ARCH\" >> \"$LOG\" 2>&1\n#\n#    mkdir -p \"$BUILDDIR/$SDK/libartirpc-$ARCH/lib\" >> \"$LOG\" 2>&1\n#    mv \"$BUILDDIR/$SDK/libartirpc-$ARCH/$TARGET/release/libarti_rpc_client_core.a\" \"$BUILDDIR/$SDK/libartirpc-$ARCH/lib/\" >> \"$LOG\" 2>&1\n#}\n\nfatten() {\n    NAME=$1\n    SDK=$2\n    LIB=${3:-$NAME}\n\n    LOG=\"$BUILDDIR/framework.log\"\n\n    echo \"- Fatten $LIB in $NAME ($SDK)\"\n\n    mkdir -p \"$BUILDDIR/$SDK/$NAME/lib\" >> \"$LOG\" 2>&1\n\n    lipo \\\n        -arch arm64 \"$BUILDDIR/$SDK/$NAME-arm64/lib/$LIB.a\" \\\n        -arch x86_64 \"$BUILDDIR/$SDK/$NAME-x86_64/lib/$LIB.a\" \\\n        -create -output \"$BUILDDIR/$SDK/$NAME/lib/$LIB.a\" >> \"$LOG\" 2>&1\n}\n\nwrite_info_plist() {\n    SDK=$1\n    NAME=$2\n    VERSION=$3\n\n# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102088\n    cat > \"$BUILDDIR/$SDK/$NAME.framework/Info.plist\" <<EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n  <key>CFBundleExecutable</key>\n  <string>$NAME</string>\n  <key>CFBundleIdentifier</key>\n  <string>org.torproject.$NAME</string>\n  <key>CFBundleInfoDictionaryVersion</key>\n  <string>6.0</string>\n  <key>CFBundleName</key>\n  <string>$NAME</string>\n  <key>CFBundlePackageType</key>\n  <string>FMWK</string>\n  <key>CFBundleShortVersionString</key>\n  <string>$VERSION</string>\n  <key>CFBundleSupportedPlatforms</key>\n  <array>\n    <string>$SDK</string>\n  </array>\n  <key>CFBundleVersion</key>\n  <string>$VERSION</string>\n</dict>\n</plist>\nEOF\n}\n\ncreate_framework() {\n    SDK=$1\n    IS_FAT=$2\n    NO_LZMA=$3\n\n    LOG=\"$BUILDDIR/framework.log\"\n\n    if [ -z \"$NO_LZMA\" ]; then\n        NAME=\"tor\"\n    else\n        NAME=\"tor-nolzma\"\n    fi\n\n    rm -rf \"$BUILDDIR/$SDK/$NAME.framework\" >> \"$LOG\" 2>&1\n    mkdir -p \"$BUILDDIR/$SDK/$NAME.framework/Headers\" >> \"$LOG\" 2>&1\n\n    if [ -z \"$IS_FAT\" ]; then\n        echo \"- Create framework for $SDK\"\n\n        POSTFIX=\"-arm64\"\n    else\n        echo \"- Create framework for fat $SDK\"\n\n        POSTFIX=\"\"\n    fi\n\n    if [ -z \"$NO_LZMA\" ]; then\n        LIBS=(\"$BUILDDIR/$SDK/libssl$POSTFIX/lib/libssl.a\" \\\n            \"$BUILDDIR/$SDK/libssl$POSTFIX/lib/libcrypto.a\" \\\n            \"$BUILDDIR/$SDK/libevent$POSTFIX/lib/libevent.a\" \\\n            \"$BUILDDIR/$SDK/liblzma$POSTFIX/lib/liblzma.a\" \\\n            \"$BUILDDIR/$SDK/libtor$POSTFIX/lib/libtor.a\")\n    else\n        LIBS=(\"$BUILDDIR/$SDK/libssl$POSTFIX/lib/libssl.a\" \\\n            \"$BUILDDIR/$SDK/libssl$POSTFIX/lib/libcrypto.a\" \\\n            \"$BUILDDIR/$SDK/libevent$POSTFIX/lib/libevent.a\" \\\n            \"$BUILDDIR/$SDK/libtor-nolzma$POSTFIX/lib/libtor.a\")\n    fi\n\n    libtool -static -o \"$BUILDDIR/$SDK/$NAME.framework/$NAME\" \"${LIBS[@]}\" >> \"$LOG\" 2>&1\n\n    HEADERS=(\"$BUILDDIR/$SDK/libssl-arm64/include\"/* \\\n        \"$BUILDDIR/$SDK/libevent-arm64/include\"/* \\\n        \"$BUILDDIR/$SDK/libtor-arm64/include\"/*)\n\n    if [ ! -z \"$NO_LZMA\" ]; then\n        HEADERS=(\"$BUILDDIR/$SDK/liblzma-arm64/include\"/* \"${HEADERS[@]}\")\n    fi\n\n    cp -r \"${HEADERS[@]}\" \"$BUILDDIR/$SDK/$NAME.framework/Headers\" >> \"$LOG\" 2>&1\n\n    write_info_plist \"$SDK\" \"$NAME\" \"${TOR_VERSION##*-}\"\n}\n\ncreate_framework_a() {\n    SDK=$1\n    IS_FAT=$2\n\n    LOG=\"$BUILDDIR/framework.log\"\n\n    NAME=\"arti\"\n\n    rm -rf \"$BUILDDIR/$SDK/$NAME.framework\" >> \"$LOG\" 2>&1\n    mkdir -p \"$BUILDDIR/$SDK/$NAME.framework/Headers\" >> \"$LOG\" 2>&1\n\n    if [ -z \"$IS_FAT\" ]; then\n        echo \"- Create framework for $SDK\"\n\n        POSTFIX=\"-arm64\"\n    else\n        echo \"- Create framework for fat $SDK\"\n\n        POSTFIX=\"\"\n    fi\n\n    LIBS=(\"$BUILDDIR/$SDK/libarti$POSTFIX/lib/libarti_mobile_ex.a\")\n#        \"$BUILDDIR/$SDK/libartirpc$POSTFIX/lib/libarti_rpc_client_core.a\")\n\n    libtool -static -o \"$BUILDDIR/$SDK/$NAME.framework/$NAME\" \"${LIBS[@]}\" >> \"$LOG\" 2>&1\n\n    cd \"$BUILDDIR/arti-mobile-ex/common\"\n    cbindgen --lang c --output \"$BUILDDIR/$SDK/$NAME.framework/Headers/arti-mobile.h\" src/apple.rs >> \"$LOG\" 2>&1\n\n#    cp \"$BUILDDIR/arti/crates/arti-rpc-client-core/arti-rpc-client-core.h\" \\\n#    \"$BUILDDIR/$SDK/$NAME.framework/Headers\" >> \"$LOG\" 2>&1\n\n    write_info_plist \"$SDK\" \"$NAME\" \"${ARTI_MOBILE_VERSION##*-}\"\n}\n\ncreate_xcframework() {\n    NAMES=$1\n\n    LOG=\"$BUILDDIR/framework.log\"\n\n    for name in $NAMES\n    do\n        echo \"- Create xcframework for $name\"\n\n        rm -rf \"$ROOT/$name.xcframework\" \"$ROOT/$name.xcframework.zip\" >> \"$LOG\" 2>&1\n\n        xcodebuild -create-xcframework \\\n            -framework \"$BUILDDIR/iphoneos/$name.framework\" \\\n            -framework \"$BUILDDIR/iphonesimulator/$name.framework\" \\\n            -framework \"$BUILDDIR/macosx/$name.framework\" \\\n            -output \"$ROOT/$name.xcframework\" >> \"$LOG\" 2>&1\n\n        cd \"$ROOT\"\n\n        zip -r -9 \"$name.xcframework.zip\" \"$name.xcframework\" >> \"$LOG\" 2>&1\n        shasum -a 256 \"$name.xcframework.zip\"\n    done\n}\n\nif [ ! -z $WITH_CTOR ]; then\n    build_liblzma       iphoneos            arm64           15.0\n    build_libssl        iphoneos            arm64           15.0\n    build_libevent      iphoneos            arm64           15.0\n    build_libtor        iphoneos            arm64           15.0\n    build_libtor        iphoneos            arm64           15.0    nolzma\n    create_framework    iphoneos\n    create_framework    iphoneos            \"\"              nolzma\n\n    build_liblzma       iphonesimulator     arm64           15.0\n    build_liblzma       iphonesimulator     x86_64          15.0\n    fatten              liblzma             iphonesimulator\n    build_libssl        iphonesimulator     arm64           15.0\n    build_libssl        iphonesimulator     x86_64          15.0\n    fatten              libssl              iphonesimulator\n    fatten              libssl              iphonesimulator libcrypto\n    build_libevent      iphonesimulator     arm64           15.0\n    build_libevent      iphonesimulator     x86_64          15.0\n    fatten              libevent            iphonesimulator\n    build_libtor        iphonesimulator     arm64           15.0\n    build_libtor        iphonesimulator     x86_64          15.0\n    fatten              libtor              iphonesimulator\n    build_libtor        iphonesimulator     arm64           15.0    nolzma\n    build_libtor        iphonesimulator     x86_64          15.0    nolzma\n    fatten              libtor-nolzma       iphonesimulator libtor\n    create_framework    iphonesimulator     fat\n    create_framework    iphonesimulator     fat             nolzma\n\n    build_liblzma       macosx              arm64           11.0\n    build_liblzma       macosx              x86_64          11.0\n    fatten              liblzma             macosx\n    build_libssl        macosx              arm64           11.0\n    build_libssl        macosx              x86_64          11.0\n    fatten              libssl              macosx\n    fatten              libssl              macosx          libcrypto\n    build_libevent      macosx              arm64           11.0\n    build_libevent      macosx              x86_64          11.0\n    fatten              libevent            macosx\n    build_libtor        macosx              arm64           11.0\n    build_libtor        macosx              x86_64          11.0\n    fatten              libtor              macosx\n    build_libtor        macosx              arm64           11.0    nolzma\n    build_libtor        macosx              x86_64          11.0    nolzma\n    fatten              libtor-nolzma       macosx          libtor\n    create_framework    macosx              fat\n    create_framework    macosx              fat             nolzma\n    create_xcframework  \"tor tor-nolzma\"\nfi\n\nif [ ! -z $WITH_ARTI ]; then\n    build_libarti       iphoneos            arm64\n#    build_libartirpc    iphoneos            arm64\n    create_framework_a  iphoneos\n    build_libarti       iphonesimulator     arm64\n    build_libarti       iphonesimulator     x86_64\n    fatten              libarti             iphonesimulator libarti_mobile_ex\n#    build_libartirpc    iphonesimulator     arm64\n#    build_libartirpc    iphonesimulator     x86_64\n#    fatten              libartirpc          iphonesimulator libarti_rpc_client_core\n    create_framework_a  iphonesimulator     fat\n    build_libarti       macosx              arm64\n    build_libarti       macosx              x86_64\n    fatten              libarti             macosx          libarti_mobile_ex\n#    build_libartirpc    macosx              arm64\n#    build_libartirpc    macosx              x86_64\n#    fatten              libartirpc          macosx          libarti_rpc_client_core\n    create_framework_a  macosx              fat\n    create_xcframework  arti\nfi\n\nif [ -z $DEBUG ]; then\n    rm -rf \"$BUILDDIR\"\nfi\n"
  },
  {
    "path": "docs/Tor.json",
    "content": "{\n    \"406.8.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v406.8.2/Tor.framework.zip\",\n    \"406.8.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v406.8.1/Tor.framework.zip\",\n    \"406.7.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v406.7.2/Tor.framework.zip\",\n    \"406.7.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v406.7.1/Tor.framework.zip\",\n    \"406.5.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v406.5.1/Tor.framework.zip\",\n    \"405.8.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v405.8.1/Tor.framework.zip\",\n    \"405.7.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v405.7.1/Tor.framework.zip\",\n    \"404.6.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v404.6.2/Tor.framework.zip\",\n    \"404.6.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v404.6.1/Tor.framework.zip\",\n    \"404.5.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v404.5.1/Tor.framework.zip\",\n    \"403.6.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v403.6.1/Tor.framework.zip\",\n    \"403.5.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v403.5.1/Tor.framework.zip\",\n    \"401.6.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v401.6.1/Tor.framework.zip\",\n    \"400.6.3\": \"https://github.com/iCepa/Tor.framework/releases/download/v400.6.3/Tor.framework.zip\",\n    \"400.6.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v400.6.2/Tor.framework.zip\",\n    \"400.6.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v400.6.1/Tor.framework.zip\",\n    \"400.5.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v400.5.2/Tor.framework.zip\",\n    \"400.5.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v400.5.1/Tor.framework.zip\",\n    \"305.8.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v305.8.1/Tor.framework.zip\",\n\t\"305.7.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v305.7.2/Tor.framework.zip\",\n\t\"305.7.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v305.7.1/Tor.framework.zip\",\n\t\"305.2.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v305.2.1/Tor.framework.zip\",\n\t\"31.9.2\": \"https://github.com/mtigas/Tor.framework/releases/download/v31.9.2/Tor.framework.zip\",\n\t\"31.9.1\": \"https://github.com/mtigas/Tor.framework/releases/download/v31.9.1/Tor.framework.zip\",\n\t\"31.8.3\": \"https://github.com/iCepa/Tor.framework/releases/download/v31.8.3/Tor.framework.zip\",\n\t\"31.8.2\": \"https://github.com/iCepa/Tor.framework/releases/download/v31.8.2/Tor.framework.zip\",\n\t\"31.8.1\": \"https://github.com/iCepa/Tor.framework/releases/download/v31.8.1/Tor.framework.zip\"\n}\n"
  },
  {
    "path": "docs/index.html",
    "content": "<!doctype html>\n<html lang=\"en\">\n<head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\"/><meta charset=\"utf-8\" />\n<title>tor.framework</title>\n</head>\n<body>\n<!-- TODO -->\n</body>\n</html>\n"
  }
]